Adjusted panels and fixed bugs; version up
[sdk/tools/web-simulator.git] / web / ripple.js
1 /*! 
2   Ripple Mobile Environment Emulator v0.9.8 :: Built On Mon Mar 24 2014 20:05:21 GMT+0800 (CST)
3
4                                 Apache License
5                            Version 2.0, January 2004
6                         http://www.apache.org/licenses/
7
8    TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
9
10    1. Definitions.
11
12       "License" shall mean the terms and conditions for use, reproduction,
13       and distribution as defined by Sections 1 through 9 of this document.
14
15       "Licensor" shall mean the copyright owner or entity authorized by
16       the copyright owner that is granting the License.
17
18       "Legal Entity" shall mean the union of the acting entity and all
19       other entities that control, are controlled by, or are under common
20       control with that entity. For the purposes of this definition,
21       "control" means (i) the power, direct or indirect, to cause the
22       direction or management of such entity, whether by contract or
23       otherwise, or (ii) ownership of fifty percent (50%) or more of the
24       outstanding shares, or (iii) beneficial ownership of such entity.
25
26       "You" (or "Your") shall mean an individual or Legal Entity
27       exercising permissions granted by this License.
28
29       "Source" form shall mean the preferred form for making modifications,
30       including but not limited to software source code, documentation
31       source, and configuration files.
32
33       "Object" form shall mean any form resulting from mechanical
34       transformation or translation of a Source form, including but
35       not limited to compiled object code, generated documentation,
36       and conversions to other media types.
37
38       "Work" shall mean the work of authorship, whether in Source or
39       Object form, made available under the License, as indicated by a
40       copyright notice that is included in or attached to the work
41       (an example is provided in the Appendix below).
42
43       "Derivative Works" shall mean any work, whether in Source or Object
44       form, that is based on (or derived from) the Work and for which the
45       editorial revisions, annotations, elaborations, or other modifications
46       represent, as a whole, an original work of authorship. For the purposes
47       of this License, Derivative Works shall not include works that remain
48       separable from, or merely link (or bind by name) to the interfaces of,
49       the Work and Derivative Works thereof.
50
51       "Contribution" shall mean any work of authorship, including
52       the original version of the Work and any modifications or additions
53       to that Work or Derivative Works thereof, that is intentionally
54       submitted to Licensor for inclusion in the Work by the copyright owner
55       or by an individual or Legal Entity authorized to submit on behalf of
56       the copyright owner. For the purposes of this definition, "submitted"
57       means any form of electronic, verbal, or written communication sent
58       to the Licensor or its representatives, including but not limited to
59       communication on electronic mailing lists, source code control systems,
60       and issue tracking systems that are managed by, or on behalf of, the
61       Licensor for the purpose of discussing and improving the Work, but
62       excluding communication that is conspicuously marked or otherwise
63       designated in writing by the copyright owner as "Not a Contribution."
64
65       "Contributor" shall mean Licensor and any individual or Legal Entity
66       on behalf of whom a Contribution has been received by Licensor and
67       subsequently incorporated within the Work.
68
69    2. Grant of Copyright License. Subject to the terms and conditions of
70       this License, each Contributor hereby grants to You a perpetual,
71       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
72       copyright license to reproduce, prepare Derivative Works of,
73       publicly display, publicly perform, sublicense, and distribute the
74       Work and such Derivative Works in Source or Object form.
75
76    3. Grant of Patent License. Subject to the terms and conditions of
77       this License, each Contributor hereby grants to You a perpetual,
78       worldwide, non-exclusive, no-charge, royalty-free, irrevocable
79       (except as stated in this section) patent license to make, have made,
80       use, offer to sell, sell, import, and otherwise transfer the Work,
81       where such license applies only to those patent claims licensable
82       by such Contributor that are necessarily infringed by their
83       Contribution(s) alone or by combination of their Contribution(s)
84       with the Work to which such Contribution(s) was submitted. If You
85       institute patent litigation against any entity (including a
86       cross-claim or counterclaim in a lawsuit) alleging that the Work
87       or a Contribution incorporated within the Work constitutes direct
88       or contributory patent infringement, then any patent licenses
89       granted to You under this License for that Work shall terminate
90       as of the date such litigation is filed.
91
92    4. Redistribution. You may reproduce and distribute copies of the
93       Work or Derivative Works thereof in any medium, with or without
94       modifications, and in Source or Object form, provided that You
95       meet the following conditions:
96
97       (a) You must give any other recipients of the Work or
98           Derivative Works a copy of this License; and
99
100       (b) You must cause any modified files to carry prominent notices
101           stating that You changed the files; and
102
103       (c) You must retain, in the Source form of any Derivative Works
104           that You distribute, all copyright, patent, trademark, and
105           attribution notices from the Source form of the Work,
106           excluding those notices that do not pertain to any part of
107           the Derivative Works; and
108
109       (d) If the Work includes a "NOTICE" text file as part of its
110           distribution, then any Derivative Works that You distribute must
111           include a readable copy of the attribution notices contained
112           within such NOTICE file, excluding those notices that do not
113           pertain to any part of the Derivative Works, in at least one
114           of the following places: within a NOTICE text file distributed
115           as part of the Derivative Works; within the Source form or
116           documentation, if provided along with the Derivative Works; or,
117           within a display generated by the Derivative Works, if and
118           wherever such third-party notices normally appear. The contents
119           of the NOTICE file are for informational purposes only and
120           do not modify the License. You may add Your own attribution
121           notices within Derivative Works that You distribute, alongside
122           or as an addendum to the NOTICE text from the Work, provided
123           that such additional attribution notices cannot be construed
124           as modifying the License.
125
126       You may add Your own copyright statement to Your modifications and
127       may provide additional or different license terms and conditions
128       for use, reproduction, or distribution of Your modifications, or
129       for any such Derivative Works as a whole, provided Your use,
130       reproduction, and distribution of the Work otherwise complies with
131       the conditions stated in this License.
132
133    5. Submission of Contributions. Unless You explicitly state otherwise,
134       any Contribution intentionally submitted for inclusion in the Work
135       by You to the Licensor shall be under the terms and conditions of
136       this License, without any additional terms or conditions.
137       Notwithstanding the above, nothing herein shall supersede or modify
138       the terms of any separate license agreement you may have executed
139       with Licensor regarding such Contributions.
140
141    6. Trademarks. This License does not grant permission to use the trade
142       names, trademarks, service marks, or product names of the Licensor,
143       except as required for reasonable and customary use in describing the
144       origin of the Work and reproducing the content of the NOTICE file.
145
146    7. Disclaimer of Warranty. Unless required by applicable law or
147       agreed to in writing, Licensor provides the Work (and each
148       Contributor provides its Contributions) on an "AS IS" BASIS,
149       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
150       implied, including, without limitation, any warranties or conditions
151       of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
152       PARTICULAR PURPOSE. You are solely responsible for determining the
153       appropriateness of using or redistributing the Work and assume any
154       risks associated with Your exercise of permissions under this License.
155
156    8. Limitation of Liability. In no event and under no legal theory,
157       whether in tort (including negligence), contract, or otherwise,
158       unless required by applicable law (such as deliberate and grossly
159       negligent acts) or agreed to in writing, shall any Contributor be
160       liable to You for damages, including any direct, indirect, special,
161       incidental, or consequential damages of any character arising as a
162       result of this License or out of the use or inability to use the
163       Work (including but not limited to damages for loss of goodwill,
164       work stoppage, computer failure or malfunction, or any and all
165       other commercial damages or losses), even if such Contributor
166       has been advised of the possibility of such damages.
167
168    9. Accepting Warranty or Additional Liability. While redistributing
169       the Work or Derivative Works thereof, You may choose to offer,
170       and charge a fee for, acceptance of support, warranty, indemnity,
171       or other liability obligations and/or rights consistent with this
172       License. However, in accepting such obligations, You may act only
173       on Your own behalf and on Your sole responsibility, not on behalf
174       of any other Contributor, and only if You agree to indemnify,
175       defend, and hold each Contributor harmless for any liability
176       incurred by, or claims asserted against, such Contributor by reason
177       of your accepting any such warranty or additional liability.
178
179    END OF TERMS AND CONDITIONS
180
181    APPENDIX: How to apply the Apache License to your work.
182
183       To apply the Apache License to your work, attach the following
184       boilerplate notice, with the fields enclosed by brackets "[]"
185       replaced with your own identifying information. (Don't include
186       the brackets!)  The text should be enclosed in the appropriate
187       comment syntax for the file format. We also recommend that a
188       file or class name and description of purpose be included on the
189       same "printed page" as the copyright notice for easier
190       identification within third-party archives.
191
192    Copyright [yyyy] [name of copyright owner]
193
194    Licensed under the Apache License, Version 2.0 (the "License");
195    you may not use this file except in compliance with the License.
196    You may obtain a copy of the License at
197
198        http://www.apache.org/licenses/LICENSE-2.0
199
200    Unless required by applicable law or agreed to in writing, software
201    distributed under the License is distributed on an "AS IS" BASIS,
202    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
203    See the License for the specific language governing permissions and
204    limitations under the License.
205
206 -------------------------------------------------------
207 Copyright 2011 Research In Motion Limited.
208
209 Contributors:
210         Brent Lintner (blintner@rim.com)
211         Dan Silivestru (dsilivestru@rim.com)
212         Gord Tanner (gtanner@rim.com)
213         Nino D'Aversa (ndaversa@rim.com)
214         Nukul Bhasin (nbhasin@rim.com)
215
216 -------------------------------------------------------
217 --> Kudos to third party awesomeness:
218
219 * browser-require *
220
221 https://github.com/rsms/browser-require
222
223 The MIT License
224 http://www.opensource.org/licenses/mit-license.php
225 Copyright (c) 2010 Rasmus Andersson http://hunch.se/
226
227 -------------------------------------------------------
228 * jWorkflow *
229
230 http://github.com/tinyhippos/jWorkflow/
231
232 The MIT License
233 http://www.opensource.org/licenses/mit-license.php
234 Copyright (c) 2010 all contributors:
235 Gord Tanner
236
237 -------------------------------------------------------
238 * jXHR.js (JSON-P XHR) *
239  v0.1 (c) Kyle Simpson 
240  MIT License
241
242 -------------------------------------------------------
243 * UI.Acceleromter Control (panel plugin) *
244
245 Licensed under the MIT license:
246   Copyright Train Hack 2010
247   Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
248   http://www.opensource.org/licenses/mit-license.php
249
250 -------------------------------------------------------
251 * jQuery JavaScript Library *
252
253 http://jquery.com/
254
255 Copyright 2010, John Resig
256 Licensed under MIT
257 http://jquery.org/license
258
259 Includes Sizzle.js
260 http://sizzlejs.com/
261 Copyright 2010, The Dojo Foundation
262 Released under the MIT, BSD, and GPL Licenses.
263
264 -------------------------------------------------------
265 * jQuery UI *
266
267 Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
268 licensed under the MIT (MIT-LICENSE.txt)
269
270 http://docs.jquery.com/UI
271
272 -------------------------------------------------------
273 * jQuery Tooltip plugin *
274
275 http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
276 http://docs.jquery.com/Plugins/Tooltip
277
278 Copyright (c) 2006 - 2008 Jörn Zaefferer
279
280 Dual licensed under the MIT and GPL licenses:
281   http://www.opensource.org/licenses/mit-license.php
282   http://www.gnu.org/licenses/gpl.html
283
284 -------------------------------------------------------
285 * Math.uuid.js (v1.4) *
286
287 http://www.broofa.com
288 mailto:robert@broofa.com
289
290 Copyright (c) 2010 Robert Kieffer
291 Dual licensed under the MIT and GPL licenses.
292
293 -------------------------------------------------------
294 * Wii Opera SDK - 3D Math Class v2.7.22 2008-12-14 *
295 (c) 2007-2008 Daniel Gump. All Rights Reserved.                          
296  http://wiioperasdk.com, http://hullbreachonline.com                      
297  hullbreach@hullbreachonline.com                                          
298                                                                           
299 * Wii Opera SDK - Drawing Class v2.6.16 2008-12-14 * 
300 (c) 2007-2008 Daniel Gump. All Rights Reserved
301 http://wiioperasdk.com, http://hullbreachonline.com
302 hullbreach@hullbreachonline.com
303
304   Wii is a trademark of Nintendo Co., Ltd.                                
305   Opera is a trademark of Opera, ASA.                                     
306   This software package is not associated with either company             
307   but was created to support users of both.  Its alternative name         
308   when supporting other products is the HULLBREACH SDK.                   
309                                                                           
310   Redistribution and use in source and binary forms, with or without      
311   modification, are permitted provided that the following conditions      
312   are met:                                                                
313     * Redistributions of source code must retain the above copyright      
314       notice, this list of conditions and the following disclaimer.       
315     * Redistributions in binary form must reproduce the above copyright   
316       notice, this list of conditions and the following disclaimer in     
317       the documentation and/or other materials provided with the          
318       distribution.                                                       
319     * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names 
320       of its contributors may be used to endorse or promote products      
321       derived from this software without specific prior written           
322       permission.                                                         
323     * If the explicit purpose of the software is not to support the       
324       Nintendo Wii or the Opera Web browser, then the names of such must  
325       not be used in any derived product. The name shall be the           
326       HULLBREACH SDK with a reference link to http://hullbreachonline.    
327                                                                           
328   THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   
329   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          
330   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  
331   DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     
332   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      
333   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      
334   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      
335   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     
336   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   
337   IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      
338   POSSIBILITY OF SUCH DAMAGE.                                             
339
340 -------------------------------------------------------
341   OpenLayers.js -- OpenLayers Map Viewer Library
342
343   Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
344   license. Full license text below taken from http://svn.openlayers.org/trunk/openlayers/license.txt
345
346         Copyright 2005-2011 OpenLayers Contributors. All rights reserved. See
347         authors.txt for full list.
348          
349         Redistribution and use in source and binary forms, with or without modification,
350         are permitted provided that the following conditions are met:
351          
352         1. Redistributions of source code must retain the above copyright notice, this
353         list of conditions and the following disclaimer.
354          
355         2. Redistributions in binary form must reproduce the above copyright notice,
356         this list of conditions and the following disclaimer in the documentation and/or
357         other materials provided with the distribution.
358          
359         THIS SOFTWARE IS PROVIDED BY OPENLAYERS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
360         OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
361         MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
362         SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
363         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
364         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
365         PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
366         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
367         OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
368         ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
369          
370         The views and conclusions contained in the software and documentation are those
371         of the authors and should not be interpreted as representing official policies,
372         either expressed or implied, of OpenLayers Contributors.
373
374   Includes compressed code under the following licenses:
375
376   (For uncompressed versions of the code used please see the
377   OpenLayers SVN repository: <http://openlayers.org/>)
378
379 -------------------------------------------------------
380   Contains portions of Rico <http://openrico.org/>
381  
382   Copyright 2005 Sabre Airline Solutions  
383   
384   Licensed under the Apache License, Version 2.0 (the "License"); you
385   may not use this file except in compliance with the License. You
386   may obtain a copy of the License at the top of this file or a the following
387   link:
388   
389          http://www.apache.org/licenses/LICENSE-2.0  
390   
391   Unless required by applicable law or agreed to in writing, software
392   distributed under the License is distributed on an "AS IS" BASIS,
393   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
394   implied. See the License for the specific language governing
395   permissions and limitations under the License. 
396
397 -------------------------------------------------------
398   Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
399   Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
400  
401   Licensed under the Apache License, Version 2.0 (the "License");
402   you may not use this file except in compliance with the License.
403   You may obtain a copy of the License at
404   http://www.apache.org/licenses/LICENSE-2.0
405
406 -------------------------------------------------------
407   Contains portions of Gears <http://code.google.com/apis/gears/>
408
409   Copyright 2007, Google Inc.
410
411   Redistribution and use in source and binary forms, with or without
412   modification, are permitted provided that the following conditions are met:
413
414    1. Redistributions of source code must retain the above copyright notice,
415       this list of conditions and the following disclaimer.
416    2. Redistributions in binary form must reproduce the above copyright notice,
417       this list of conditions and the following disclaimer in the documentation
418       and/or other materials provided with the distribution.
419    3. Neither the name of Google Inc. nor the names of its contributors may be
420       used to endorse or promote products derived from this software without
421       specific prior written permission.
422  
423   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
424   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
425   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
426   EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
427   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
428   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
429   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
430   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
431   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
432   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
433  
434   Sets up google.gears.*, which is *the only* supported way to access Gears.
435
436   Circumvent this file at your own risk!
437  
438   In the future, Gears may automatically define google.gears.* without this
439   file. Gears may use these objects to transparently fix bugs and compatibility
440   issues. Applications that use the code below will continue to work seamlessly
441   when that happens.
442 */
443 window.require = null;window.define = null;/**
444  * almond 0.0.3 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
445  * Available via the MIT or new BSD license.
446  * see: http://github.com/jrburke/almond for details
447  */
448 /*jslint strict: false, plusplus: false */
449 /*global setTimeout: false */
450
451 var requirejs, require, define;
452 (function (undef) {
453
454     var defined = {},
455         waiting = {},
456         aps = [].slice,
457         main, req;
458
459     if (typeof define === "function") {
460         //If a define is already in play via another AMD loader,
461         //do not overwrite.
462         return;
463     }
464
465     /**
466      * Given a relative module name, like ./something, normalize it to
467      * a real name that can be mapped to a path.
468      * @param {String} name the relative name
469      * @param {String} baseName a real name that the name arg is relative
470      * to.
471      * @returns {String} normalized name
472      */
473     function normalize(name, baseName) {
474         //Adjust any relative paths.
475         if (name && name.charAt(0) === ".") {
476             //If have a base name, try to normalize against it,
477             //otherwise, assume it is a top-level require that will
478             //be relative to baseUrl in the end.
479             if (baseName) {
480                 //Convert baseName to array, and lop off the last part,
481                 //so that . matches that "directory" and not name of the baseName's
482                 //module. For instance, baseName of "one/two/three", maps to
483                 //"one/two/three.js", but we want the directory, "one/two" for
484                 //this normalization.
485                 baseName = baseName.split("/");
486                 baseName = baseName.slice(0, baseName.length - 1);
487
488                 name = baseName.concat(name.split("/"));
489
490                 //start trimDots
491                 var i, part;
492                 for (i = 0; (part = name[i]); i++) {
493                     if (part === ".") {
494                         name.splice(i, 1);
495                         i -= 1;
496                     } else if (part === "..") {
497                         if (i === 1 && (name[2] === '..' || name[0] === '..')) {
498                             //End of the line. Keep at least one non-dot
499                             //path segment at the front so it can be mapped
500                             //correctly to disk. Otherwise, there is likely
501                             //no path mapping for a path starting with '..'.
502                             //This can still fail, but catches the most reasonable
503                             //uses of ..
504                             break;
505                         } else if (i > 0) {
506                             name.splice(i - 1, 2);
507                             i -= 2;
508                         }
509                     }
510                 }
511                 //end trimDots
512
513                 name = name.join("/");
514             }
515         }
516         return name;
517     }
518
519     function makeRequire(relName, forceSync) {
520         return function () {
521             //A version of a require function that passes a moduleName
522             //value for items that may need to
523             //look up paths relative to the moduleName
524             return req.apply(undef, aps.call(arguments, 0).concat([relName, forceSync]));
525         };
526     }
527
528     function makeNormalize(relName) {
529         return function (name) {
530             return normalize(name, relName);
531         };
532     }
533
534     function makeLoad(depName) {
535         return function (value) {
536             defined[depName] = value;
537         };
538     }
539
540     function callDep(name) {
541         if (waiting.hasOwnProperty(name)) {
542             var args = waiting[name];
543             delete waiting[name];
544             main.apply(undef, args);
545         }
546         return defined[name];
547     }
548
549     /**
550      * Makes a name map, normalizing the name, and using a plugin
551      * for normalization if necessary. Grabs a ref to plugin
552      * too, as an optimization.
553      */
554     function makeMap(name, relName) {
555         var prefix, plugin,
556             index = name.indexOf('!');
557
558         if (index !== -1) {
559             prefix = normalize(name.slice(0, index), relName);
560             name = name.slice(index + 1);
561             plugin = callDep(prefix);
562
563             //Normalize according
564             if (plugin && plugin.normalize) {
565                 name = plugin.normalize(name, makeNormalize(relName));
566             } else {
567                 name = normalize(name, relName);
568             }
569         } else {
570             name = normalize(name, relName);
571         }
572
573         //Using ridiculous property names for space reasons
574         return {
575             f: prefix ? prefix + '!' + name : name, //fullName
576             n: name,
577             p: plugin
578         };
579     }
580
581     main = function (name, deps, callback, relName) {
582         var args = [],
583             usingExports,
584             cjsModule, depName, i, ret, map;
585
586         //Use name if no relName
587         if (!relName) {
588             relName = name;
589         }
590
591         //Call the callback to define the module, if necessary.
592         if (typeof callback === 'function') {
593
594             //Default to require, exports, module if no deps if
595             //the factory arg has any arguments specified.
596             if (!deps.length && callback.length) {
597                 deps = ['require', 'exports', 'module'];
598             }
599
600             //Pull out the defined dependencies and pass the ordered
601             //values to the callback.
602             for (i = 0; i < deps.length; i++) {
603                 map = makeMap(deps[i], relName);
604                 depName = map.f;
605
606                 //Fast path CommonJS standard dependencies.
607                 if (depName === "require") {
608                     args[i] = makeRequire(name);
609                 } else if (depName === "exports") {
610                     //CommonJS module spec 1.1
611                     args[i] = defined[name] = {};
612                     usingExports = true;
613                 } else if (depName === "module") {
614                     //CommonJS module spec 1.1
615                     cjsModule = args[i] = {
616                         id: name,
617                         uri: '',
618                         exports: defined[name]
619                     };
620                 } else if (defined.hasOwnProperty(depName) || waiting.hasOwnProperty(depName)) {
621                     args[i] = callDep(depName);
622                 } else if (map.p) {
623                     map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
624                     args[i] = defined[depName];
625                 } else {
626                     throw name + ' missing ' + depName;
627                 }
628             }
629
630             ret = callback.apply(defined[name], args);
631
632             if (name) {
633                 //If setting exports via "module" is in play,
634                 //favor that over return value and exports. After that,
635                 //favor a non-undefined return value over exports use.
636                 if (cjsModule && cjsModule.exports !== undef) {
637                     defined[name] = cjsModule.exports;
638                 } else if (!usingExports) {
639                     //Use the return value from the function.
640                     defined[name] = ret;
641                 }
642             }
643         } else if (name) {
644             //May just be an object definition for the module. Only
645             //worry about defining if have a module name.
646             defined[name] = callback;
647         }
648     };
649
650     requirejs = req = function (deps, callback, relName, forceSync) {
651         if (typeof deps === "string") {
652
653             //Just return the module wanted. In this scenario, the
654             //deps arg is the module name, and second arg (if passed)
655             //is just the relName.
656             //Normalize module name, if it contains . or ..
657             return callDep(makeMap(deps, callback).f);
658         } else if (!deps.splice) {
659             //deps is a config object, not an array.
660             //Drop the config stuff on the ground.
661             if (callback.splice) {
662                 //callback is an array, which means it is a dependency list.
663                 //Adjust args if there are dependencies
664                 deps = callback;
665                 callback = arguments[2];
666             } else {
667                 deps = [];
668             }
669         }
670
671         //Simulate async callback;
672         if (forceSync) {
673             main(undef, deps, callback, relName);
674         } else {
675             setTimeout(function () {
676                 main(undef, deps, callback, relName);
677             }, 15);
678         }
679
680         return req;
681     };
682
683     /**
684      * Just drops the config on the floor, but returns req in case
685      * the config return value is used.
686      */
687     req.config = function () {
688         return req;
689     };
690
691     /**
692      * Export require as a global, but only if it does not already exist.
693      */
694     if (!require) {
695         require = req;
696     }
697
698     define = function (name, deps, callback) {
699
700         //This module may not have dependencies
701         if (!deps.splice) {
702             //deps is not an array, so probably means
703             //an object literal or factory function for
704             //the value. Adjust args.
705             callback = deps;
706             deps = [];
707         }
708
709         if (define.unordered) {
710             waiting[name] = [name, deps, callback];
711         } else {
712             main(name, deps, callback);
713         }
714     };
715
716     define.amd = {
717         jQuery: true
718     };
719 }());
720 /*!
721  * jQuery JavaScript Library v1.6
722  * http://jquery.com/
723  *
724  * Copyright 2011, John Resig
725  * licensed under the MIT 
726  * http://jquery.org/license
727  *
728  * Includes Sizzle.js
729  * http://sizzlejs.com/
730  * Copyright 2011, The Dojo Foundation
731  * Released under the MIT, BSD, and GPL Licenses.
732  *
733  * Date: Mon May 2 13:50:00 2011 -0400
734  */
735 (function( window, undefined ) {
736
737 // Use the correct document accordingly with window argument (sandbox)
738 var document = window.document,
739         navigator = window.navigator,
740         location = window.location;
741 var jQuery = (function() {
742
743 // Define a local copy of jQuery
744 var jQuery = function( selector, context ) {
745                 // The jQuery object is actually just the init constructor 'enhanced'
746                 return new jQuery.fn.init( selector, context, rootjQuery );
747         },
748
749         // Map over jQuery in case of overwrite
750         _jQuery = window.jQuery,
751
752         // Map over the $ in case of overwrite
753         _$ = window.$,
754
755         // A central reference to the root jQuery(document)
756         rootjQuery,
757
758         // A simple way to check for HTML strings or ID strings
759         // (both of which we optimize for)
760         quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
761
762         // Check if a string has a non-whitespace character in it
763         rnotwhite = /\S/,
764
765         // Used for trimming whitespace
766         trimLeft = /^\s+/,
767         trimRight = /\s+$/,
768
769         // Check for digits
770         rdigit = /\d/,
771
772         // Match a standalone tag
773         rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
774
775         // JSON RegExp
776         rvalidchars = /^[\],:{}\s]*$/,
777         rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
778         rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
779         rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
780
781         // Useragent RegExp
782         rwebkit = /(webkit)[ \/]([\w.]+)/,
783         ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
784         rmsie = /(msie) ([\w.]+)/,
785         rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
786
787         // Keep a UserAgent string for use with jQuery.browser
788         userAgent = navigator.userAgent,
789
790         // For matching the engine and version of the browser
791         browserMatch,
792
793         // The deferred used on DOM ready
794         readyList,
795
796         // The ready event handler
797         DOMContentLoaded,
798
799         // Save a reference to some core methods
800         toString = Object.prototype.toString,
801         hasOwn = Object.prototype.hasOwnProperty,
802         push = Array.prototype.push,
803         slice = Array.prototype.slice,
804         trim = String.prototype.trim,
805         indexOf = Array.prototype.indexOf,
806
807         // [[Class]] -> type pairs
808         class2type = {};
809
810 jQuery.fn = jQuery.prototype = {
811         constructor: jQuery,
812         init: function( selector, context, rootjQuery ) {
813                 var match, elem, ret, doc;
814
815                 // Handle $(""), $(null), or $(undefined)
816                 if ( !selector ) {
817                         return this;
818                 }
819
820                 // Handle $(DOMElement)
821                 if ( selector.nodeType ) {
822                         this.context = this[0] = selector;
823                         this.length = 1;
824                         return this;
825                 }
826
827                 // The body element only exists once, optimize finding it
828                 if ( selector === "body" && !context && document.body ) {
829                         this.context = document;
830                         this[0] = document.body;
831                         this.selector = selector;
832                         this.length = 1;
833                         return this;
834                 }
835
836                 // Handle HTML strings
837                 if ( typeof selector === "string" ) {
838                         // Are we dealing with HTML string or an ID?
839                         if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
840                                 // Assume that strings that start and end with <> are HTML and skip the regex check
841                                 match = [ null, selector, null ];
842
843                         } else {
844                                 match = quickExpr.exec( selector );
845                         }
846
847                         // Verify a match, and that no context was specified for #id
848                         if ( match && (match[1] || !context) ) {
849
850                                 // HANDLE: $(html) -> $(array)
851                                 if ( match[1] ) {
852                                         context = context instanceof jQuery ? context[0] : context;
853                                         doc = (context ? context.ownerDocument || context : document);
854
855                                         // If a single string is passed in and it's a single tag
856                                         // just do a createElement and skip the rest
857                                         ret = rsingleTag.exec( selector );
858
859                                         if ( ret ) {
860                                                 if ( jQuery.isPlainObject( context ) ) {
861                                                         selector = [ document.createElement( ret[1] ) ];
862                                                         jQuery.fn.attr.call( selector, context, true );
863
864                                                 } else {
865                                                         selector = [ doc.createElement( ret[1] ) ];
866                                                 }
867
868                                         } else {
869                                                 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
870                                                 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
871                                         }
872
873                                         return jQuery.merge( this, selector );
874
875                                 // HANDLE: $("#id")
876                                 } else {
877                                         elem = document.getElementById( match[2] );
878
879                                         // Check parentNode to catch when Blackberry 4.6 returns
880                                         // nodes that are no longer in the document #6963
881                                         if ( elem && elem.parentNode ) {
882                                                 // Handle the case where IE and Opera return items
883                                                 // by name instead of ID
884                                                 if ( elem.id !== match[2] ) {
885                                                         return rootjQuery.find( selector );
886                                                 }
887
888                                                 // Otherwise, we inject the element directly into the jQuery object
889                                                 this.length = 1;
890                                                 this[0] = elem;
891                                         }
892
893                                         this.context = document;
894                                         this.selector = selector;
895                                         return this;
896                                 }
897
898                         // HANDLE: $(expr, $(...))
899                         } else if ( !context || context.jquery ) {
900                                 return (context || rootjQuery).find( selector );
901
902                         // HANDLE: $(expr, context)
903                         // (which is just equivalent to: $(context).find(expr)
904                         } else {
905                                 return this.constructor( context ).find( selector );
906                         }
907
908                 // HANDLE: $(function)
909                 // Shortcut for document ready
910                 } else if ( jQuery.isFunction( selector ) ) {
911                         return rootjQuery.ready( selector );
912                 }
913
914                 if (selector.selector !== undefined) {
915                         this.selector = selector.selector;
916                         this.context = selector.context;
917                 }
918
919                 return jQuery.makeArray( selector, this );
920         },
921
922         // Start with an empty selector
923         selector: "",
924
925         // The current version of jQuery being used
926         jquery: "1.6",
927
928         // The default length of a jQuery object is 0
929         length: 0,
930
931         // The number of elements contained in the matched element set
932         size: function() {
933                 return this.length;
934         },
935
936         toArray: function() {
937                 return slice.call( this, 0 );
938         },
939
940         // Get the Nth element in the matched element set OR
941         // Get the whole matched element set as a clean array
942         get: function( num ) {
943                 return num == null ?
944
945                         // Return a 'clean' array
946                         this.toArray() :
947
948                         // Return just the object
949                         ( num < 0 ? this[ this.length + num ] : this[ num ] );
950         },
951
952         // Take an array of elements and push it onto the stack
953         // (returning the new matched element set)
954         pushStack: function( elems, name, selector ) {
955                 // Build a new jQuery matched element set
956                 var ret = this.constructor();
957
958                 if ( jQuery.isArray( elems ) ) {
959                         push.apply( ret, elems );
960
961                 } else {
962                         jQuery.merge( ret, elems );
963                 }
964
965                 // Add the old object onto the stack (as a reference)
966                 ret.prevObject = this;
967
968                 ret.context = this.context;
969
970                 if ( name === "find" ) {
971                         ret.selector = this.selector + (this.selector ? " " : "") + selector;
972                 } else if ( name ) {
973                         ret.selector = this.selector + "." + name + "(" + selector + ")";
974                 }
975
976                 // Return the newly-formed element set
977                 return ret;
978         },
979
980         // Execute a callback for every element in the matched set.
981         // (You can seed the arguments with an array of args, but this is
982         // only used internally.)
983         each: function( callback, args ) {
984                 return jQuery.each( this, callback, args );
985         },
986
987         ready: function( fn ) {
988                 // Attach the listeners
989                 jQuery.bindReady();
990
991                 // Add the callback
992                 readyList.done( fn );
993
994                 return this;
995         },
996
997         eq: function( i ) {
998                 return i === -1 ?
999                         this.slice( i ) :
1000                         this.slice( i, +i + 1 );
1001         },
1002
1003         first: function() {
1004                 return this.eq( 0 );
1005         },
1006
1007         last: function() {
1008                 return this.eq( -1 );
1009         },
1010
1011         slice: function() {
1012                 return this.pushStack( slice.apply( this, arguments ),
1013                         "slice", slice.call(arguments).join(",") );
1014         },
1015
1016         map: function( callback ) {
1017                 return this.pushStack( jQuery.map(this, function( elem, i ) {
1018                         return callback.call( elem, i, elem );
1019                 }));
1020         },
1021
1022         end: function() {
1023                 return this.prevObject || this.constructor(null);
1024         },
1025
1026         // For internal use only.
1027         // Behaves like an Array's method, not like a jQuery method.
1028         push: push,
1029         sort: [].sort,
1030         splice: [].splice
1031 };
1032
1033 // Give the init function the jQuery prototype for later instantiation
1034 jQuery.fn.init.prototype = jQuery.fn;
1035
1036 jQuery.extend = jQuery.fn.extend = function() {
1037         var options, name, src, copy, copyIsArray, clone,
1038                 target = arguments[0] || {},
1039                 i = 1,
1040                 length = arguments.length,
1041                 deep = false;
1042
1043         // Handle a deep copy situation
1044         if ( typeof target === "boolean" ) {
1045                 deep = target;
1046                 target = arguments[1] || {};
1047                 // skip the boolean and the target
1048                 i = 2;
1049         }
1050
1051         // Handle case when target is a string or something (possible in deep copy)
1052         if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
1053                 target = {};
1054         }
1055
1056         // extend jQuery itself if only one argument is passed
1057         if ( length === i ) {
1058                 target = this;
1059                 --i;
1060         }
1061
1062         for ( ; i < length; i++ ) {
1063                 // Only deal with non-null/undefined values
1064                 if ( (options = arguments[ i ]) != null ) {
1065                         // Extend the base object
1066                         for ( name in options ) {
1067                                 src = target[ name ];
1068                                 copy = options[ name ];
1069
1070                                 // Prevent never-ending loop
1071                                 if ( target === copy ) {
1072                                         continue;
1073                                 }
1074
1075                                 // Recurse if we're merging plain objects or arrays
1076                                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
1077                                         if ( copyIsArray ) {
1078                                                 copyIsArray = false;
1079                                                 clone = src && jQuery.isArray(src) ? src : [];
1080
1081                                         } else {
1082                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
1083                                         }
1084
1085                                         // Never move original objects, clone them
1086                                         target[ name ] = jQuery.extend( deep, clone, copy );
1087
1088                                 // Don't bring in undefined values
1089                                 } else if ( copy !== undefined ) {
1090                                         target[ name ] = copy;
1091                                 }
1092                         }
1093                 }
1094         }
1095
1096         // Return the modified object
1097         return target;
1098 };
1099
1100 jQuery.extend({
1101         noConflict: function( deep ) {
1102                 if ( window.$ === jQuery ) {
1103                         window.$ = _$;
1104                 }
1105
1106                 if ( deep && window.jQuery === jQuery ) {
1107                         window.jQuery = _jQuery;
1108                 }
1109
1110                 return jQuery;
1111         },
1112
1113         // Is the DOM ready to be used? Set to true once it occurs.
1114         isReady: false,
1115
1116         // A counter to track how many items to wait for before
1117         // the ready event fires. See #6781
1118         readyWait: 1,
1119
1120         // Hold (or release) the ready event
1121         holdReady: function( hold ) {
1122                 if ( hold ) {
1123                         jQuery.readyWait++;
1124                 } else {
1125                         jQuery.ready( true );
1126                 }
1127         },
1128
1129         // Handle when the DOM is ready
1130         ready: function( wait ) {
1131                 // Either a released hold or an DOMready/load event and not yet ready
1132                 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
1133                         // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
1134                         if ( !document.body ) {
1135                                 return setTimeout( jQuery.ready, 1 );
1136                         }
1137
1138                         // Remember that the DOM is ready
1139                         jQuery.isReady = true;
1140
1141                         // If a normal DOM Ready event fired, decrement, and wait if need be
1142                         if ( wait !== true && --jQuery.readyWait > 0 ) {
1143                                 return;
1144                         }
1145
1146                         // If there are functions bound, to execute
1147                         readyList.resolveWith( document, [ jQuery ] );
1148
1149                         // Trigger any bound ready events
1150                         if ( jQuery.fn.trigger ) {
1151                                 jQuery( document ).trigger( "ready" ).unbind( "ready" );
1152                         }
1153                 }
1154         },
1155
1156         bindReady: function() {
1157                 if ( readyList ) {
1158                         return;
1159                 }
1160
1161                 readyList = jQuery._Deferred();
1162
1163                 // Catch cases where $(document).ready() is called after the
1164                 // browser event has already occurred.
1165                 if ( document.readyState === "complete" ) {
1166                         // Handle it asynchronously to allow scripts the opportunity to delay ready
1167                         return setTimeout( jQuery.ready, 1 );
1168                 }
1169
1170                 // Mozilla, Opera and webkit nightlies currently support this event
1171                 if ( document.addEventListener ) {
1172                         // Use the handy event callback
1173                         document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
1174
1175                         // A fallback to window.onload, that will always work
1176                         window.addEventListener( "load", jQuery.ready, false );
1177
1178                 // If IE event model is used
1179                 } else if ( document.attachEvent ) {
1180                         // ensure firing before onload,
1181                         // maybe late but safe also for iframes
1182                         document.attachEvent( "onreadystatechange", DOMContentLoaded );
1183
1184                         // A fallback to window.onload, that will always work
1185                         window.attachEvent( "onload", jQuery.ready );
1186
1187                         // If IE and not a frame
1188                         // continually check to see if the document is ready
1189                         var toplevel = false;
1190
1191                         try {
1192                                 toplevel = window.frameElement == null;
1193                         } catch(e) {}
1194
1195                         if ( document.documentElement.doScroll && toplevel ) {
1196                                 doScrollCheck();
1197                         }
1198                 }
1199         },
1200
1201         // See test/unit/core.js for details concerning isFunction.
1202         // Since version 1.3, DOM methods and functions like alert
1203         // aren't supported. They return false on IE (#2968).
1204         isFunction: function( obj ) {
1205                 return jQuery.type(obj) === "function";
1206         },
1207
1208         isArray: Array.isArray || function( obj ) {
1209                 return jQuery.type(obj) === "array";
1210         },
1211
1212         // A crude way of determining if an object is a window
1213         isWindow: function( obj ) {
1214                 return obj && typeof obj === "object" && "setInterval" in obj;
1215         },
1216
1217         isNaN: function( obj ) {
1218                 return obj == null || !rdigit.test( obj ) || isNaN( obj );
1219         },
1220
1221         type: function( obj ) {
1222                 return obj == null ?
1223                         String( obj ) :
1224                         class2type[ toString.call(obj) ] || "object";
1225         },
1226
1227         isPlainObject: function( obj ) {
1228                 // Must be an Object.
1229                 // Because of IE, we also have to check the presence of the constructor property.
1230                 // Make sure that DOM nodes and window objects don't pass through, as well
1231                 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
1232                         return false;
1233                 }
1234
1235                 // Not own constructor property must be Object
1236                 if ( obj.constructor &&
1237                         !hasOwn.call(obj, "constructor") &&
1238                         !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
1239                         return false;
1240                 }
1241
1242                 // Own properties are enumerated firstly, so to speed up,
1243                 // if last one is own, then all properties are own.
1244
1245                 var key;
1246                 for ( key in obj ) {}
1247
1248                 return key === undefined || hasOwn.call( obj, key );
1249         },
1250
1251         isEmptyObject: function( obj ) {
1252                 for ( var name in obj ) {
1253                         return false;
1254                 }
1255                 return true;
1256         },
1257
1258         error: function( msg ) {
1259                 throw msg;
1260         },
1261
1262         parseJSON: function( data ) {
1263                 if ( typeof data !== "string" || !data ) {
1264                         return null;
1265                 }
1266
1267                 // Make sure leading/trailing whitespace is removed (IE can't handle it)
1268                 data = jQuery.trim( data );
1269
1270                 // Attempt to parse using the native JSON parser first
1271                 if ( window.JSON && window.JSON.parse ) {
1272                         return window.JSON.parse( data );
1273                 }
1274
1275                 // Make sure the incoming data is actual JSON
1276                 // Logic borrowed from http://json.org/json2.js
1277                 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
1278                         .replace( rvalidtokens, "]" )
1279                         .replace( rvalidbraces, "")) ) {
1280
1281                         return (new Function( "return " + data ))();
1282
1283                 }
1284                 jQuery.error( "Invalid JSON: " + data );
1285         },
1286
1287         // Cross-browser xml parsing
1288         // (xml & tmp used internally)
1289         parseXML: function( data , xml , tmp ) {
1290
1291                 if ( window.DOMParser ) { // Standard
1292                         tmp = new DOMParser();
1293                         xml = tmp.parseFromString( data , "text/xml" );
1294                 } else { // IE
1295                         xml = new ActiveXObject( "Microsoft.XMLDOM" );
1296                         xml.async = "false";
1297                         xml.loadXML( data );
1298                 }
1299
1300                 tmp = xml.documentElement;
1301
1302                 if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
1303                         jQuery.error( "Invalid XML: " + data );
1304                 }
1305
1306                 return xml;
1307         },
1308
1309         noop: function() {},
1310
1311         // Evaluates a script in a global context
1312         // Workarounds based on findings by Jim Driscoll
1313         // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
1314         globalEval: function( data ) {
1315                 if ( data && rnotwhite.test( data ) ) {
1316                         // We use execScript on Internet Explorer
1317                         // We use an anonymous function so that context is window
1318                         // rather than jQuery in Firefox
1319                         ( window.execScript || function( data ) {
1320                                 window[ "eval" ].call( window, data );
1321                         } )( data );
1322                 }
1323         },
1324
1325         nodeName: function( elem, name ) {
1326                 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
1327         },
1328
1329         // args is for internal usage only
1330         each: function( object, callback, args ) {
1331                 var name, i = 0,
1332                         length = object.length,
1333                         isObj = length === undefined || jQuery.isFunction( object );
1334
1335                 if ( args ) {
1336                         if ( isObj ) {
1337                                 for ( name in object ) {
1338                                         if ( callback.apply( object[ name ], args ) === false ) {
1339                                                 break;
1340                                         }
1341                                 }
1342                         } else {
1343                                 for ( ; i < length; ) {
1344                                         if ( callback.apply( object[ i++ ], args ) === false ) {
1345                                                 break;
1346                                         }
1347                                 }
1348                         }
1349
1350                 // A special, fast, case for the most common use of each
1351                 } else {
1352                         if ( isObj ) {
1353                                 for ( name in object ) {
1354                                         if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
1355                                                 break;
1356                                         }
1357                                 }
1358                         } else {
1359                                 for ( ; i < length; ) {
1360                                         if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
1361                                                 break;
1362                                         }
1363                                 }
1364                         }
1365                 }
1366
1367                 return object;
1368         },
1369
1370         // Use native String.trim function wherever possible
1371         trim: trim ?
1372                 function( text ) {
1373                         return text == null ?
1374                                 "" :
1375                                 trim.call( text );
1376                 } :
1377
1378                 // Otherwise use our own trimming functionality
1379                 function( text ) {
1380                         return text == null ?
1381                                 "" :
1382                                 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
1383                 },
1384
1385         // results is for internal usage only
1386         makeArray: function( array, results ) {
1387                 var ret = results || [];
1388
1389                 if ( array != null ) {
1390                         // The window, strings (and functions) also have 'length'
1391                         // The extra typeof function check is to prevent crashes
1392                         // in Safari 2 (See: #3039)
1393                         // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
1394                         var type = jQuery.type( array );
1395
1396                         if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
1397                                 push.call( ret, array );
1398                         } else {
1399                                 jQuery.merge( ret, array );
1400                         }
1401                 }
1402
1403                 return ret;
1404         },
1405
1406         inArray: function( elem, array ) {
1407
1408                 if ( indexOf ) {
1409                         return indexOf.call( array, elem );
1410                 }
1411
1412                 for ( var i = 0, length = array.length; i < length; i++ ) {
1413                         if ( array[ i ] === elem ) {
1414                                 return i;
1415                         }
1416                 }
1417
1418                 return -1;
1419         },
1420
1421         merge: function( first, second ) {
1422                 var i = first.length,
1423                         j = 0;
1424
1425                 if ( typeof second.length === "number" ) {
1426                         for ( var l = second.length; j < l; j++ ) {
1427                                 first[ i++ ] = second[ j ];
1428                         }
1429
1430                 } else {
1431                         while ( second[j] !== undefined ) {
1432                                 first[ i++ ] = second[ j++ ];
1433                         }
1434                 }
1435
1436                 first.length = i;
1437
1438                 return first;
1439         },
1440
1441         grep: function( elems, callback, inv ) {
1442                 var ret = [], retVal;
1443                 inv = !!inv;
1444
1445                 // Go through the array, only saving the items
1446                 // that pass the validator function
1447                 for ( var i = 0, length = elems.length; i < length; i++ ) {
1448                         retVal = !!callback( elems[ i ], i );
1449                         if ( inv !== retVal ) {
1450                                 ret.push( elems[ i ] );
1451                         }
1452                 }
1453
1454                 return ret;
1455         },
1456
1457         // arg is for internal usage only
1458         map: function( elems, callback, arg ) {
1459                 var value, key, ret = [],
1460                         i = 0,
1461                         length = elems.length,
1462                         // jquery objects are treated as arrays
1463                         isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
1464
1465                 // Go through the array, translating each of the items to their
1466                 if ( isArray ) {
1467                         for ( ; i < length; i++ ) {
1468                                 value = callback( elems[ i ], i, arg );
1469
1470                                 if ( value != null ) {
1471                                         ret[ ret.length ] = value;
1472                                 }
1473                         }
1474
1475                 // Go through every key on the object,
1476                 } else {
1477                         for ( key in elems ) {
1478                                 value = callback( elems[ key ], key, arg );
1479
1480                                 if ( value != null ) {
1481                                         ret[ ret.length ] = value;
1482                                 }
1483                         }
1484                 }
1485
1486                 // Flatten any nested arrays
1487                 return ret.concat.apply( [], ret );
1488         },
1489
1490         // A global GUID counter for objects
1491         guid: 1,
1492
1493         // Bind a function to a context, optionally partially applying any
1494         // arguments.
1495         proxy: function( fn, context ) {
1496                 if ( typeof context === "string" ) {
1497                         var tmp = fn[ context ];
1498                         context = fn;
1499                         fn = tmp;
1500                 }
1501
1502                 // Quick check to determine if target is callable, in the spec
1503                 // this throws a TypeError, but we will just return undefined.
1504                 if ( !jQuery.isFunction( fn ) ) {
1505                         return undefined;
1506                 }
1507
1508                 // Simulated bind
1509                 var args = slice.call( arguments, 2 ),
1510                         proxy = function() {
1511                                 return fn.apply( context, args.concat( slice.call( arguments ) ) );
1512                         };
1513
1514                 // Set the guid of unique handler to the same of original handler, so it can be removed
1515                 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
1516
1517                 return proxy;
1518         },
1519
1520         // Mutifunctional method to get and set values to a collection
1521         // The value/s can be optionally by executed if its a function
1522         access: function( elems, key, value, exec, fn, pass ) {
1523                 var length = elems.length;
1524
1525                 // Setting many attributes
1526                 if ( typeof key === "object" ) {
1527                         for ( var k in key ) {
1528                                 jQuery.access( elems, k, key[k], exec, fn, value );
1529                         }
1530                         return elems;
1531                 }
1532
1533                 // Setting one attribute
1534                 if ( value !== undefined ) {
1535                         // Optionally, function values get executed if exec is true
1536                         exec = !pass && exec && jQuery.isFunction(value);
1537
1538                         for ( var i = 0; i < length; i++ ) {
1539                                 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
1540                         }
1541
1542                         return elems;
1543                 }
1544
1545                 // Getting an attribute
1546                 return length ? fn( elems[0], key ) : undefined;
1547         },
1548
1549         now: function() {
1550                 return (new Date()).getTime();
1551         },
1552
1553         // Use of jQuery.browser is frowned upon.
1554         // More details: http://docs.jquery.com/Utilities/jQuery.browser
1555         uaMatch: function( ua ) {
1556                 ua = ua.toLowerCase();
1557
1558                 var match = rwebkit.exec( ua ) ||
1559                         ropera.exec( ua ) ||
1560                         rmsie.exec( ua ) ||
1561                         ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
1562                         [];
1563
1564                 return { browser: match[1] || "", version: match[2] || "0" };
1565         },
1566
1567         sub: function() {
1568                 function jQuerySub( selector, context ) {
1569                         return new jQuerySub.fn.init( selector, context );
1570                 }
1571                 jQuery.extend( true, jQuerySub, this );
1572                 jQuerySub.superclass = this;
1573                 jQuerySub.fn = jQuerySub.prototype = this();
1574                 jQuerySub.fn.constructor = jQuerySub;
1575                 jQuerySub.sub = this.sub;
1576                 jQuerySub.fn.init = function init( selector, context ) {
1577                         if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
1578                                 context = jQuerySub( context );
1579                         }
1580
1581                         return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
1582                 };
1583                 jQuerySub.fn.init.prototype = jQuerySub.fn;
1584                 var rootjQuerySub = jQuerySub(document);
1585                 return jQuerySub;
1586         },
1587
1588         browser: {}
1589 });
1590
1591 // Populate the class2type map
1592 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
1593         class2type[ "[object " + name + "]" ] = name.toLowerCase();
1594 });
1595
1596 browserMatch = jQuery.uaMatch( userAgent );
1597 if ( browserMatch.browser ) {
1598         jQuery.browser[ browserMatch.browser ] = true;
1599         jQuery.browser.version = browserMatch.version;
1600 }
1601
1602 // Deprecated, use jQuery.browser.webkit instead
1603 if ( jQuery.browser.webkit ) {
1604         jQuery.browser.safari = true;
1605 }
1606
1607 // IE doesn't match non-breaking spaces with \s
1608 if ( rnotwhite.test( "\xA0" ) ) {
1609         trimLeft = /^[\s\xA0]+/;
1610         trimRight = /[\s\xA0]+$/;
1611 }
1612
1613 // All jQuery objects should point back to these
1614 rootjQuery = jQuery(document);
1615
1616 // Cleanup functions for the document ready method
1617 if ( document.addEventListener ) {
1618         DOMContentLoaded = function() {
1619                 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
1620                 jQuery.ready();
1621         };
1622
1623 } else if ( document.attachEvent ) {
1624         DOMContentLoaded = function() {
1625                 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
1626                 if ( document.readyState === "complete" ) {
1627                         document.detachEvent( "onreadystatechange", DOMContentLoaded );
1628                         jQuery.ready();
1629                 }
1630         };
1631 }
1632
1633 // The DOM ready check for Internet Explorer
1634 function doScrollCheck() {
1635         if ( jQuery.isReady ) {
1636                 return;
1637         }
1638
1639         try {
1640                 // If IE is used, use the trick by Diego Perini
1641                 // http://javascript.nwbox.com/IEContentLoaded/
1642                 document.documentElement.doScroll("left");
1643         } catch(e) {
1644                 setTimeout( doScrollCheck, 1 );
1645                 return;
1646         }
1647
1648         // and execute any waiting functions
1649         jQuery.ready();
1650 }
1651
1652 // Expose jQuery to the global object
1653 return jQuery;
1654
1655 })();
1656
1657
1658 var // Promise methods
1659         promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
1660         // Static reference to slice
1661         sliceDeferred = [].slice;
1662
1663 jQuery.extend({
1664         // Create a simple deferred (one callbacks list)
1665         _Deferred: function() {
1666                 var // callbacks list
1667                         callbacks = [],
1668                         // stored [ context , args ]
1669                         fired,
1670                         // to avoid firing when already doing so
1671                         firing,
1672                         // flag to know if the deferred has been cancelled
1673                         cancelled,
1674                         // the deferred itself
1675                         deferred  = {
1676
1677                                 // done( f1, f2, ...)
1678                                 done: function() {
1679                                         if ( !cancelled ) {
1680                                                 var args = arguments,
1681                                                         i,
1682                                                         length,
1683                                                         elem,
1684                                                         type,
1685                                                         _fired;
1686                                                 if ( fired ) {
1687                                                         _fired = fired;
1688                                                         fired = 0;
1689                                                 }
1690                                                 for ( i = 0, length = args.length; i < length; i++ ) {
1691                                                         elem = args[ i ];
1692                                                         type = jQuery.type( elem );
1693                                                         if ( type === "array" ) {
1694                                                                 deferred.done.apply( deferred, elem );
1695                                                         } else if ( type === "function" ) {
1696                                                                 callbacks.push( elem );
1697                                                         }
1698                                                 }
1699                                                 if ( _fired ) {
1700                                                         deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
1701                                                 }
1702                                         }
1703                                         return this;
1704                                 },
1705
1706                                 // resolve with given context and args
1707                                 resolveWith: function( context, args ) {
1708                                         if ( !cancelled && !fired && !firing ) {
1709                                                 // make sure args are available (#8421)
1710                                                 args = args || [];
1711                                                 firing = 1;
1712                                                 try {
1713                                                         while( callbacks[ 0 ] ) {
1714                                                                 callbacks.shift().apply( context, args );
1715                                                         }
1716                                                 }
1717                                                 finally {
1718                                                         fired = [ context, args ];
1719                                                         firing = 0;
1720                                                 }
1721                                         }
1722                                         return this;
1723                                 },
1724
1725                                 // resolve with this as context and given arguments
1726                                 resolve: function() {
1727                                         deferred.resolveWith( this, arguments );
1728                                         return this;
1729                                 },
1730
1731                                 // Has this deferred been resolved?
1732                                 isResolved: function() {
1733                                         return !!( firing || fired );
1734                                 },
1735
1736                                 // Cancel
1737                                 cancel: function() {
1738                                         cancelled = 1;
1739                                         callbacks = [];
1740                                         return this;
1741                                 }
1742                         };
1743
1744                 return deferred;
1745         },
1746
1747         // Full fledged deferred (two callbacks list)
1748         Deferred: function( func ) {
1749                 var deferred = jQuery._Deferred(),
1750                         failDeferred = jQuery._Deferred(),
1751                         promise;
1752                 // Add errorDeferred methods, then and promise
1753                 jQuery.extend( deferred, {
1754                         then: function( doneCallbacks, failCallbacks ) {
1755                                 deferred.done( doneCallbacks ).fail( failCallbacks );
1756                                 return this;
1757                         },
1758                         always: function() {
1759                                 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1760                         },
1761                         fail: failDeferred.done,
1762                         rejectWith: failDeferred.resolveWith,
1763                         reject: failDeferred.resolve,
1764                         isRejected: failDeferred.isResolved,
1765                         pipe: function( fnDone, fnFail ) {
1766                                 return jQuery.Deferred(function( newDefer ) {
1767                                         jQuery.each( {
1768                                                 done: [ fnDone, "resolve" ],
1769                                                 fail: [ fnFail, "reject" ]
1770                                         }, function( handler, data ) {
1771                                                 var fn = data[ 0 ],
1772                                                         action = data[ 1 ],
1773                                                         returned;
1774                                                 if ( jQuery.isFunction( fn ) ) {
1775                                                         deferred[ handler ](function() {
1776                                                                 returned = fn.apply( this, arguments );
1777                                                                 if ( jQuery.isFunction( returned.promise ) ) {
1778                                                                         returned.promise().then( newDefer.resolve, newDefer.reject );
1779                                                                 } else {
1780                                                                         newDefer[ action ]( returned );
1781                                                                 }
1782                                                         });
1783                                                 } else {
1784                                                         deferred[ handler ]( newDefer[ action ] );
1785                                                 }
1786                                         });
1787                                 }).promise();
1788                         },
1789                         // Get a promise for this deferred
1790                         // If obj is provided, the promise aspect is added to the object
1791                         promise: function( obj ) {
1792                                 if ( obj == null ) {
1793                                         if ( promise ) {
1794                                                 return promise;
1795                                         }
1796                                         promise = obj = {};
1797                                 }
1798                                 var i = promiseMethods.length;
1799                                 while( i-- ) {
1800                                         obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1801                                 }
1802                                 return obj;
1803                         }
1804                 });
1805                 // Make sure only one callback list will be used
1806                 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1807                 // Unexpose cancel
1808                 delete deferred.cancel;
1809                 // Call given func if any
1810                 if ( func ) {
1811                         func.call( deferred, deferred );
1812                 }
1813                 return deferred;
1814         },
1815
1816         // Deferred helper
1817         when: function( firstParam ) {
1818                 var args = arguments,
1819                         i = 0,
1820                         length = args.length,
1821                         count = length,
1822                         deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1823                                 firstParam :
1824                                 jQuery.Deferred();
1825                 function resolveFunc( i ) {
1826                         return function( value ) {
1827                                 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1828                                 if ( !( --count ) ) {
1829                                         // Strange bug in FF4:
1830                                         // Values changed onto the arguments object sometimes end up as undefined values
1831                                         // outside the $.when method. Cloning the object into a fresh array solves the issue
1832                                         deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1833                                 }
1834                         };
1835                 }
1836                 if ( length > 1 ) {
1837                         for( ; i < length; i++ ) {
1838                                 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1839                                         args[ i ].promise().then( resolveFunc(i), deferred.reject );
1840                                 } else {
1841                                         --count;
1842                                 }
1843                         }
1844                         if ( !count ) {
1845                                 deferred.resolveWith( deferred, args );
1846                         }
1847                 } else if ( deferred !== firstParam ) {
1848                         deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1849                 }
1850                 return deferred.promise();
1851         }
1852 });
1853
1854
1855
1856 jQuery.support = (function() {
1857
1858         var div = document.createElement( "div" ),
1859                 all,
1860                 a,
1861                 select,
1862                 opt,
1863                 input,
1864                 marginDiv,
1865                 support,
1866                 fragment,
1867                 body,
1868                 bodyStyle,
1869                 tds,
1870                 events,
1871                 eventName,
1872                 i,
1873                 isSupported;
1874
1875         // Preliminary tests
1876         div.setAttribute("className", "t");
1877         div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
1878
1879         all = div.getElementsByTagName( "*" );
1880         a = div.getElementsByTagName( "a" )[ 0 ];
1881
1882         // Can't get basic test support
1883         if ( !all || !all.length || !a ) {
1884                 return {};
1885         }
1886
1887         // First batch of supports tests
1888         select = document.createElement( "select" );
1889         opt = select.appendChild( document.createElement("option") );
1890         input = div.getElementsByTagName( "input" )[ 0 ];
1891
1892         support = {
1893                 // IE strips leading whitespace when .innerHTML is used
1894                 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1895
1896                 // Make sure that tbody elements aren't automatically inserted
1897                 // IE will insert them into empty tables
1898                 tbody: !div.getElementsByTagName( "tbody" ).length,
1899
1900                 // Make sure that link elements get serialized correctly by innerHTML
1901                 // This requires a wrapper element in IE
1902                 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1903
1904                 // Get the style information from getAttribute
1905                 // (IE uses .cssText instead)
1906                 style: /top/.test( a.getAttribute("style") ),
1907
1908                 // Make sure that URLs aren't manipulated
1909                 // (IE normalizes it by default)
1910                 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1911
1912                 // Make sure that element opacity exists
1913                 // (IE uses filter instead)
1914                 // Use a regex to work around a WebKit issue. See #5145
1915                 opacity: /^0.55$/.test( a.style.opacity ),
1916
1917                 // Verify style float existence
1918                 // (IE uses styleFloat instead of cssFloat)
1919                 cssFloat: !!a.style.cssFloat,
1920
1921                 // Make sure that if no value is specified for a checkbox
1922                 // that it defaults to "on".
1923                 // (WebKit defaults to "" instead)
1924                 checkOn: ( input.value === "on" ),
1925
1926                 // Make sure that a selected-by-default option has a working selected property.
1927                 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1928                 optSelected: opt.selected,
1929
1930                 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1931                 getSetAttribute: div.className !== "t",
1932
1933                 // Will be defined later
1934                 submitBubbles: true,
1935                 changeBubbles: true,
1936                 focusinBubbles: false,
1937                 deleteExpando: true,
1938                 noCloneEvent: true,
1939                 inlineBlockNeedsLayout: false,
1940                 shrinkWrapBlocks: false,
1941                 reliableMarginRight: true
1942         };
1943
1944         // Make sure checked status is properly cloned
1945         input.checked = true;
1946         support.noCloneChecked = input.cloneNode( true ).checked;
1947
1948         // Make sure that the options inside disabled selects aren't marked as disabled
1949         // (WebKit marks them as disabled)
1950         select.disabled = true;
1951         support.optDisabled = !opt.disabled;
1952
1953         // Test to see if it's possible to delete an expando from an element
1954         // Fails in Internet Explorer
1955         try {
1956                 delete div.test;
1957         } catch( e ) {
1958                 support.deleteExpando = false;
1959         }
1960
1961         if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1962                 div.attachEvent( "onclick", function click() {
1963                         // Cloning a node shouldn't copy over any
1964                         // bound event handlers (IE does this)
1965                         support.noCloneEvent = false;
1966                         div.detachEvent( "onclick", click );
1967                 });
1968                 div.cloneNode( true ).fireEvent( "onclick" );
1969         }
1970
1971         // Check if a radio maintains it's value
1972         // after being appended to the DOM
1973         input = document.createElement("input");
1974         input.value = "t";
1975         input.setAttribute("type", "radio");
1976         support.radioValue = input.value === "t";
1977
1978         input.setAttribute("checked", "checked");
1979         div.appendChild( input );
1980         fragment = document.createDocumentFragment();
1981         fragment.appendChild( div.firstChild );
1982
1983         // WebKit doesn't clone checked state correctly in fragments
1984         support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1985
1986         div.innerHTML = "";
1987
1988         // Figure out if the W3C box model works as expected
1989         div.style.width = div.style.paddingLeft = "1px";
1990
1991         // We use our own, invisible, body
1992         body = document.createElement( "body" );
1993         bodyStyle = {
1994                 visibility: "hidden",
1995                 width: 0,
1996                 height: 0,
1997                 border: 0,
1998                 margin: 0,
1999                 // Set background to avoid IE crashes when removing (#9028)
2000                 background: "none"
2001         };
2002         for ( i in bodyStyle ) {
2003                 body.style[ i ] = bodyStyle[ i ];
2004         }
2005         body.appendChild( div );
2006         document.documentElement.appendChild( body );
2007
2008         // Check if a disconnected checkbox will retain its checked
2009         // value of true after appended to the DOM (IE6/7)
2010         support.appendChecked = input.checked;
2011
2012         support.boxModel = div.offsetWidth === 2;
2013
2014         if ( "zoom" in div.style ) {
2015                 // Check if natively block-level elements act like inline-block
2016                 // elements when setting their display to 'inline' and giving
2017                 // them layout
2018                 // (IE < 8 does this)
2019                 div.style.display = "inline";
2020                 div.style.zoom = 1;
2021                 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
2022
2023                 // Check if elements with layout shrink-wrap their children
2024                 // (IE 6 does this)
2025                 div.style.display = "";
2026                 div.innerHTML = "<div style='width:4px;'></div>";
2027                 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
2028         }
2029
2030         div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
2031         tds = div.getElementsByTagName( "td" );
2032
2033         // Check if table cells still have offsetWidth/Height when they are set
2034         // to display:none and there are still other visible table cells in a
2035         // table row; if so, offsetWidth/Height are not reliable for use when
2036         // determining if an element has been hidden directly using
2037         // display:none (it is still safe to use offsets if a parent element is
2038         // hidden; don safety goggles and see bug #4512 for more information).
2039         // (only IE 8 fails this test)
2040         isSupported = ( tds[ 0 ].offsetHeight === 0 );
2041
2042         tds[ 0 ].style.display = "";
2043         tds[ 1 ].style.display = "none";
2044
2045         // Check if empty table cells still have offsetWidth/Height
2046         // (IE < 8 fail this test)
2047         support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
2048         div.innerHTML = "";
2049
2050         // Check if div with explicit width and no margin-right incorrectly
2051         // gets computed margin-right based on width of container. For more
2052         // info see bug #3333
2053         // Fails in WebKit before Feb 2011 nightlies
2054         // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
2055         if ( document.defaultView && document.defaultView.getComputedStyle ) {
2056                 marginDiv = document.createElement( "div" );
2057                 marginDiv.style.width = "0";
2058                 marginDiv.style.marginRight = "0";
2059                 div.appendChild( marginDiv );
2060                 support.reliableMarginRight =
2061                         ( parseInt( document.defaultView.getComputedStyle( marginDiv, null ).marginRight, 10 ) || 0 ) === 0;
2062         }
2063
2064         // Remove the body element we added
2065         body.innerHTML = "";
2066         document.documentElement.removeChild( body );
2067
2068         // Technique from Juriy Zaytsev
2069         // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
2070         // We only care about the case where non-standard event systems
2071         // are used, namely in IE. Short-circuiting here helps us to
2072         // avoid an eval call (in setAttribute) which can cause CSP
2073         // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
2074         if ( div.attachEvent ) {
2075                 for( i in {
2076                         submit: 1,
2077                         change: 1,
2078                         focusin: 1
2079                 } ) {
2080                         eventName = "on" + i;
2081                         isSupported = ( eventName in div );
2082                         if ( !isSupported ) {
2083                                 div.setAttribute( eventName, "return;" );
2084                                 isSupported = ( typeof div[ eventName ] === "function" );
2085                         }
2086                         support[ i + "Bubbles" ] = isSupported;
2087                 }
2088         }
2089
2090         return support;
2091 })();
2092
2093 // Keep track of boxModel
2094 jQuery.boxModel = jQuery.support.boxModel;
2095
2096
2097
2098
2099 var rbrace = /^(?:\{.*\}|\[.*\])$/,
2100         rmultiDash = /([a-z])([A-Z])/g;
2101
2102 jQuery.extend({
2103         cache: {},
2104
2105         // Please use with caution
2106         uuid: 0,
2107
2108         // Unique for each copy of jQuery on the page
2109         // Non-digits removed to match rinlinejQuery
2110         expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
2111
2112         // The following elements throw uncatchable exceptions if you
2113         // attempt to add expando properties to them.
2114         noData: {
2115                 "embed": true,
2116                 // Ban all objects except for Flash (which handle expandos)
2117                 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
2118                 "applet": true
2119         },
2120
2121         hasData: function( elem ) {
2122                 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
2123
2124                 return !!elem && !isEmptyDataObject( elem );
2125         },
2126
2127         data: function( elem, name, data, pvt /* Internal Use Only */ ) {
2128                 if ( !jQuery.acceptData( elem ) ) {
2129                         return;
2130                 }
2131
2132                 var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
2133
2134                         // We have to handle DOM nodes and JS objects differently because IE6-7
2135                         // can't GC object references properly across the DOM-JS boundary
2136                         isNode = elem.nodeType,
2137
2138                         // Only DOM nodes need the global jQuery cache; JS object data is
2139                         // attached directly to the object so GC can occur automatically
2140                         cache = isNode ? jQuery.cache : elem,
2141
2142                         // Only defining an ID for JS objects if its cache already exists allows
2143                         // the code to shortcut on the same path as a DOM node with no cache
2144                         id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
2145
2146                 // Avoid doing any more work than we need to when trying to get data on an
2147                 // object that has no data at all
2148                 if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
2149                         return;
2150                 }
2151
2152                 if ( !id ) {
2153                         // Only DOM nodes need a new unique ID for each element since their data
2154                         // ends up in the global cache
2155                         if ( isNode ) {
2156                                 elem[ jQuery.expando ] = id = ++jQuery.uuid;
2157                         } else {
2158                                 id = jQuery.expando;
2159                         }
2160                 }
2161
2162                 if ( !cache[ id ] ) {
2163                         cache[ id ] = {};
2164
2165                         // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
2166                         // metadata on plain JS objects when the object is serialized using
2167                         // JSON.stringify
2168                         if ( !isNode ) {
2169                                 cache[ id ].toJSON = jQuery.noop;
2170                         }
2171                 }
2172
2173                 // An object can be passed to jQuery.data instead of a key/value pair; this gets
2174                 // shallow copied over onto the existing cache
2175                 if ( typeof name === "object" || typeof name === "function" ) {
2176                         if ( pvt ) {
2177                                 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
2178                         } else {
2179                                 cache[ id ] = jQuery.extend(cache[ id ], name);
2180                         }
2181                 }
2182
2183                 thisCache = cache[ id ];
2184
2185                 // Internal jQuery data is stored in a separate object inside the object's data
2186                 // cache in order to avoid key collisions between internal data and user-defined
2187                 // data
2188                 if ( pvt ) {
2189                         if ( !thisCache[ internalKey ] ) {
2190                                 thisCache[ internalKey ] = {};
2191                         }
2192
2193                         thisCache = thisCache[ internalKey ];
2194                 }
2195
2196                 if ( data !== undefined ) {
2197                         thisCache[ name ] = data;
2198                 }
2199
2200                 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
2201                 // not attempt to inspect the internal events object using jQuery.data, as this
2202                 // internal data object is undocumented and subject to change.
2203                 if ( name === "events" && !thisCache[name] ) {
2204                         return thisCache[ internalKey ] && thisCache[ internalKey ].events;
2205                 }
2206
2207                 return getByName ? thisCache[ name ] : thisCache;
2208         },
2209
2210         removeData: function( elem, name, pvt /* Internal Use Only */ ) {
2211                 if ( !jQuery.acceptData( elem ) ) {
2212                         return;
2213                 }
2214
2215                 var internalKey = jQuery.expando, isNode = elem.nodeType,
2216
2217                         // See jQuery.data for more information
2218                         cache = isNode ? jQuery.cache : elem,
2219
2220                         // See jQuery.data for more information
2221                         id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
2222
2223                 // If there is already no cache entry for this object, there is no
2224                 // purpose in continuing
2225                 if ( !cache[ id ] ) {
2226                         return;
2227                 }
2228
2229                 if ( name ) {
2230                         var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
2231
2232                         if ( thisCache ) {
2233                                 delete thisCache[ name ];
2234
2235                                 // If there is no data left in the cache, we want to continue
2236                                 // and let the cache object itself get destroyed
2237                                 if ( !isEmptyDataObject(thisCache) ) {
2238                                         return;
2239                                 }
2240                         }
2241                 }
2242
2243                 // See jQuery.data for more information
2244                 if ( pvt ) {
2245                         delete cache[ id ][ internalKey ];
2246
2247                         // Don't destroy the parent cache unless the internal data object
2248                         // had been the only thing left in it
2249                         if ( !isEmptyDataObject(cache[ id ]) ) {
2250                                 return;
2251                         }
2252                 }
2253
2254                 var internalCache = cache[ id ][ internalKey ];
2255
2256                 // Browsers that fail expando deletion also refuse to delete expandos on
2257                 // the window, but it will allow it on all other JS objects; other browsers
2258                 // don't care
2259                 if ( jQuery.support.deleteExpando || cache != window ) {
2260                         delete cache[ id ];
2261                 } else {
2262                         cache[ id ] = null;
2263                 }
2264
2265                 // We destroyed the entire user cache at once because it's faster than
2266                 // iterating through each key, but we need to continue to persist internal
2267                 // data if it existed
2268                 if ( internalCache ) {
2269                         cache[ id ] = {};
2270                         // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
2271                         // metadata on plain JS objects when the object is serialized using
2272                         // JSON.stringify
2273                         if ( !isNode ) {
2274                                 cache[ id ].toJSON = jQuery.noop;
2275                         }
2276
2277                         cache[ id ][ internalKey ] = internalCache;
2278
2279                 // Otherwise, we need to eliminate the expando on the node to avoid
2280                 // false lookups in the cache for entries that no longer exist
2281                 } else if ( isNode ) {
2282                         // IE does not allow us to delete expando properties from nodes,
2283                         // nor does it have a removeAttribute function on Document nodes;
2284                         // we must handle all of these cases
2285                         if ( jQuery.support.deleteExpando ) {
2286                                 delete elem[ jQuery.expando ];
2287                         } else if ( elem.removeAttribute ) {
2288                                 elem.removeAttribute( jQuery.expando );
2289                         } else {
2290                                 elem[ jQuery.expando ] = null;
2291                         }
2292                 }
2293         },
2294
2295         // For internal use only.
2296         _data: function( elem, name, data ) {
2297                 return jQuery.data( elem, name, data, true );
2298         },
2299
2300         // A method for determining if a DOM node can handle the data expando
2301         acceptData: function( elem ) {
2302                 if ( elem.nodeName ) {
2303                         var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
2304
2305                         if ( match ) {
2306                                 return !(match === true || elem.getAttribute("classid") !== match);
2307                         }
2308                 }
2309
2310                 return true;
2311         }
2312 });
2313
2314 jQuery.fn.extend({
2315         data: function( key, value ) {
2316                 var data = null;
2317
2318                 if ( typeof key === "undefined" ) {
2319                         if ( this.length ) {
2320                                 data = jQuery.data( this[0] );
2321
2322                                 if ( this[0].nodeType === 1 ) {
2323                             var attr = this[0].attributes, name;
2324                                         for ( var i = 0, l = attr.length; i < l; i++ ) {
2325                                                 name = attr[i].name;
2326
2327                                                 if ( name.indexOf( "data-" ) === 0 ) {
2328                                                         name = jQuery.camelCase( name.substring(5) );
2329
2330                                                         dataAttr( this[0], name, data[ name ] );
2331                                                 }
2332                                         }
2333                                 }
2334                         }
2335
2336                         return data;
2337
2338                 } else if ( typeof key === "object" ) {
2339                         return this.each(function() {
2340                                 jQuery.data( this, key );
2341                         });
2342                 }
2343
2344                 var parts = key.split(".");
2345                 parts[1] = parts[1] ? "." + parts[1] : "";
2346
2347                 if ( value === undefined ) {
2348                         data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
2349
2350                         // Try to fetch any internally stored data first
2351                         if ( data === undefined && this.length ) {
2352                                 data = jQuery.data( this[0], key );
2353                                 data = dataAttr( this[0], key, data );
2354                         }
2355
2356                         return data === undefined && parts[1] ?
2357                                 this.data( parts[0] ) :
2358                                 data;
2359
2360                 } else {
2361                         return this.each(function() {
2362                                 var $this = jQuery( this ),
2363                                         args = [ parts[0], value ];
2364
2365                                 $this.triggerHandler( "setData" + parts[1] + "!", args );
2366                                 jQuery.data( this, key, value );
2367                                 $this.triggerHandler( "changeData" + parts[1] + "!", args );
2368                         });
2369                 }
2370         },
2371
2372         removeData: function( key ) {
2373                 return this.each(function() {
2374                         jQuery.removeData( this, key );
2375                 });
2376         }
2377 });
2378
2379 function dataAttr( elem, key, data ) {
2380         // If nothing was found internally, try to fetch any
2381         // data from the HTML5 data-* attribute
2382         if ( data === undefined && elem.nodeType === 1 ) {
2383                 name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
2384
2385                 data = elem.getAttribute( name );
2386
2387                 if ( typeof data === "string" ) {
2388                         try {
2389                                 data = data === "true" ? true :
2390                                 data === "false" ? false :
2391                                 data === "null" ? null :
2392                                 !jQuery.isNaN( data ) ? parseFloat( data ) :
2393                                         rbrace.test( data ) ? jQuery.parseJSON( data ) :
2394                                         data;
2395                         } catch( e ) {}
2396
2397                         // Make sure we set the data so it isn't changed later
2398                         jQuery.data( elem, key, data );
2399
2400                 } else {
2401                         data = undefined;
2402                 }
2403         }
2404
2405         return data;
2406 }
2407
2408 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
2409 // property to be considered empty objects; this property always exists in
2410 // order to make sure JSON.stringify does not expose internal metadata
2411 function isEmptyDataObject( obj ) {
2412         for ( var name in obj ) {
2413                 if ( name !== "toJSON" ) {
2414                         return false;
2415                 }
2416         }
2417
2418         return true;
2419 }
2420
2421
2422
2423
2424 function handleQueueMarkDefer( elem, type, src ) {
2425         var deferDataKey = type + "defer",
2426                 queueDataKey = type + "queue",
2427                 markDataKey = type + "mark",
2428                 defer = jQuery.data( elem, deferDataKey, undefined, true );
2429         if ( defer &&
2430                 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
2431                 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
2432                 // Give room for hard-coded callbacks to fire first
2433                 // and eventually mark/queue something else on the element
2434                 setTimeout( function() {
2435                         if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
2436                                 !jQuery.data( elem, markDataKey, undefined, true ) ) {
2437                                 jQuery.removeData( elem, deferDataKey, true );
2438                                 defer.resolve();
2439                         }
2440                 }, 0 );
2441         }
2442 }
2443
2444 jQuery.extend({
2445
2446         _mark: function( elem, type ) {
2447                 if ( elem ) {
2448                         type = (type || "fx") + "mark";
2449                         jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
2450                 }
2451         },
2452
2453         _unmark: function( force, elem, type ) {
2454                 if ( force !== true ) {
2455                         type = elem;
2456                         elem = force;
2457                         force = false;
2458                 }
2459                 if ( elem ) {
2460                         type = type || "fx";
2461                         var key = type + "mark",
2462                                 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
2463                         if ( count ) {
2464                                 jQuery.data( elem, key, count, true );
2465                         } else {
2466                                 jQuery.removeData( elem, key, true );
2467                                 handleQueueMarkDefer( elem, type, "mark" );
2468                         }
2469                 }
2470         },
2471
2472         queue: function( elem, type, data ) {
2473                 if ( elem ) {
2474                         type = (type || "fx") + "queue";
2475                         var q = jQuery.data( elem, type, undefined, true );
2476                         // Speed up dequeue by getting out quickly if this is just a lookup
2477                         if ( data ) {
2478                                 if ( !q || jQuery.isArray(data) ) {
2479                                         q = jQuery.data( elem, type, jQuery.makeArray(data), true );
2480                                 } else {
2481                                         q.push( data );
2482                                 }
2483                         }
2484                         return q || [];
2485                 }
2486         },
2487
2488         dequeue: function( elem, type ) {
2489                 type = type || "fx";
2490
2491                 var queue = jQuery.queue( elem, type ),
2492                         fn = queue.shift(),
2493                         defer;
2494
2495                 // If the fx queue is dequeued, always remove the progress sentinel
2496                 if ( fn === "inprogress" ) {
2497                         fn = queue.shift();
2498                 }
2499
2500                 if ( fn ) {
2501                         // Add a progress sentinel to prevent the fx queue from being
2502                         // automatically dequeued
2503                         if ( type === "fx" ) {
2504                                 queue.unshift("inprogress");
2505                         }
2506
2507                         fn.call(elem, function() {
2508                                 jQuery.dequeue(elem, type);
2509                         });
2510                 }
2511
2512                 if ( !queue.length ) {
2513                         jQuery.removeData( elem, type + "queue", true );
2514                         handleQueueMarkDefer( elem, type, "queue" );
2515                 }
2516         }
2517 });
2518
2519 jQuery.fn.extend({
2520         queue: function( type, data ) {
2521                 if ( typeof type !== "string" ) {
2522                         data = type;
2523                         type = "fx";
2524                 }
2525
2526                 if ( data === undefined ) {
2527                         return jQuery.queue( this[0], type );
2528                 }
2529                 return this.each(function() {
2530                         var queue = jQuery.queue( this, type, data );
2531
2532                         if ( type === "fx" && queue[0] !== "inprogress" ) {
2533                                 jQuery.dequeue( this, type );
2534                         }
2535                 });
2536         },
2537         dequeue: function( type ) {
2538                 return this.each(function() {
2539                         jQuery.dequeue( this, type );
2540                 });
2541         },
2542         // Based off of the plugin by Clint Helfers, with permission.
2543         // http://blindsignals.com/index.php/2009/07/jquery-delay/
2544         delay: function( time, type ) {
2545                 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
2546                 type = type || "fx";
2547
2548                 return this.queue( type, function() {
2549                         var elem = this;
2550                         setTimeout(function() {
2551                                 jQuery.dequeue( elem, type );
2552                         }, time );
2553                 });
2554         },
2555         clearQueue: function( type ) {
2556                 return this.queue( type || "fx", [] );
2557         },
2558         // Get a promise resolved when queues of a certain type
2559         // are emptied (fx is the type by default)
2560         promise: function( type, object ) {
2561                 if ( typeof type !== "string" ) {
2562                         object = type;
2563                         type = undefined;
2564                 }
2565                 type = type || "fx";
2566                 var defer = jQuery.Deferred(),
2567                         elements = this,
2568                         i = elements.length,
2569                         count = 1,
2570                         deferDataKey = type + "defer",
2571                         queueDataKey = type + "queue",
2572                         markDataKey = type + "mark";
2573                 function resolve() {
2574                         if ( !( --count ) ) {
2575                                 defer.resolveWith( elements, [ elements ] );
2576                         }
2577                 }
2578                 while( i-- ) {
2579                         if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
2580                                         ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
2581                                                 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
2582                                         jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
2583                                 count++;
2584                                 tmp.done( resolve );
2585                         }
2586                 }
2587                 resolve();
2588                 return defer.promise();
2589         }
2590 });
2591
2592
2593
2594
2595 var rclass = /[\n\t\r]/g,
2596         rspace = /\s+/,
2597         rreturn = /\r/g,
2598         rtype = /^(?:button|input)$/i,
2599         rfocusable = /^(?:button|input|object|select|textarea)$/i,
2600         rclickable = /^a(?:rea)?$/i,
2601         rspecial = /^(?:data-|aria-)/,
2602         rinvalidChar = /\:/,
2603         formHook;
2604
2605 jQuery.fn.extend({
2606         attr: function( name, value ) {
2607                 return jQuery.access( this, name, value, true, jQuery.attr );
2608         },
2609
2610         removeAttr: function( name ) {
2611                 return this.each(function() {
2612                         jQuery.removeAttr( this, name );
2613                 });
2614         },
2615         
2616         prop: function( name, value ) {
2617                 return jQuery.access( this, name, value, true, jQuery.prop );
2618         },
2619         
2620         removeProp: function( name ) {
2621                 return this.each(function() {
2622                         // try/catch handles cases where IE balks (such as removing a property on window)
2623                         try {
2624                                 this[ name ] = undefined;
2625                                 delete this[ name ];
2626                         } catch( e ) {}
2627                 });
2628         },
2629
2630         addClass: function( value ) {
2631                 if ( jQuery.isFunction( value ) ) {
2632                         return this.each(function(i) {
2633                                 var self = jQuery(this);
2634                                 self.addClass( value.call(this, i, self.attr("class") || "") );
2635                         });
2636                 }
2637
2638                 if ( value && typeof value === "string" ) {
2639                         var classNames = (value || "").split( rspace );
2640
2641                         for ( var i = 0, l = this.length; i < l; i++ ) {
2642                                 var elem = this[i];
2643
2644                                 if ( elem.nodeType === 1 ) {
2645                                         if ( !elem.className ) {
2646                                                 elem.className = value;
2647
2648                                         } else {
2649                                                 var className = " " + elem.className + " ",
2650                                                         setClass = elem.className;
2651
2652                                                 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
2653                                                         if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
2654                                                                 setClass += " " + classNames[c];
2655                                                         }
2656                                                 }
2657                                                 elem.className = jQuery.trim( setClass );
2658                                         }
2659                                 }
2660                         }
2661                 }
2662
2663                 return this;
2664         },
2665
2666         removeClass: function( value ) {
2667                 if ( jQuery.isFunction(value) ) {
2668                         return this.each(function(i) {
2669                                 var self = jQuery(this);
2670                                 self.removeClass( value.call(this, i, self.attr("class")) );
2671                         });
2672                 }
2673
2674                 if ( (value && typeof value === "string") || value === undefined ) {
2675                         var classNames = (value || "").split( rspace );
2676
2677                         for ( var i = 0, l = this.length; i < l; i++ ) {
2678                                 var elem = this[i];
2679
2680                                 if ( elem.nodeType === 1 && elem.className ) {
2681                                         if ( value ) {
2682                                                 var className = (" " + elem.className + " ").replace(rclass, " ");
2683                                                 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
2684                                                         className = className.replace(" " + classNames[c] + " ", " ");
2685                                                 }
2686                                                 elem.className = jQuery.trim( className );
2687
2688                                         } else {
2689                                                 elem.className = "";
2690                                         }
2691                                 }
2692                         }
2693                 }
2694
2695                 return this;
2696         },
2697
2698         toggleClass: function( value, stateVal ) {
2699                 var type = typeof value,
2700                         isBool = typeof stateVal === "boolean";
2701
2702                 if ( jQuery.isFunction( value ) ) {
2703                         return this.each(function(i) {
2704                                 var self = jQuery(this);
2705                                 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
2706                         });
2707                 }
2708
2709                 return this.each(function() {
2710                         if ( type === "string" ) {
2711                                 // toggle individual class names
2712                                 var className,
2713                                         i = 0,
2714                                         self = jQuery( this ),
2715                                         state = stateVal,
2716                                         classNames = value.split( rspace );
2717
2718                                 while ( (className = classNames[ i++ ]) ) {
2719                                         // check each className given, space seperated list
2720                                         state = isBool ? state : !self.hasClass( className );
2721                                         self[ state ? "addClass" : "removeClass" ]( className );
2722                                 }
2723
2724                         } else if ( type === "undefined" || type === "boolean" ) {
2725                                 if ( this.className ) {
2726                                         // store className if set
2727                                         jQuery._data( this, "__className__", this.className );
2728                                 }
2729
2730                                 // toggle whole className
2731                                 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2732                         }
2733                 });
2734         },
2735
2736         hasClass: function( selector ) {
2737                 var className = " " + selector + " ";
2738                 for ( var i = 0, l = this.length; i < l; i++ ) {
2739                         if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2740                                 return true;
2741                         }
2742                 }
2743
2744                 return false;
2745         },
2746
2747         val: function( value ) {
2748                 var hooks, ret,
2749                         elem = this[0];
2750                 
2751                 if ( !arguments.length ) {
2752                         if ( elem ) {
2753                                 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2754
2755                                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2756                                         return ret;
2757                                 }
2758
2759                                 return (elem.value || "").replace(rreturn, "");
2760                         }
2761
2762                         return undefined;
2763                 }
2764
2765                 var isFunction = jQuery.isFunction( value );
2766
2767                 return this.each(function( i ) {
2768                         var self = jQuery(this), val;
2769
2770                         if ( this.nodeType !== 1 ) {
2771                                 return;
2772                         }
2773
2774                         if ( isFunction ) {
2775                                 val = value.call( this, i, self.val() );
2776                         } else {
2777                                 val = value;
2778                         }
2779
2780                         // Treat null/undefined as ""; convert numbers to string
2781                         if ( val == null ) {
2782                                 val = "";
2783                         } else if ( typeof val === "number" ) {
2784                                 val += "";
2785                         } else if ( jQuery.isArray( val ) ) {
2786                                 val = jQuery.map(val, function ( value ) {
2787                                         return value == null ? "" : value + "";
2788                                 });
2789                         }
2790
2791                         hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2792
2793                         // If set returns undefined, fall back to normal setting
2794                         if ( !hooks || ("set" in hooks && hooks.set( this, val, "value" ) === undefined) ) {
2795                                 this.value = val;
2796                         }
2797                 });
2798         }
2799 });
2800
2801 jQuery.extend({
2802         valHooks: {
2803                 option: {
2804                         get: function( elem ) {
2805                                 // attributes.value is undefined in Blackberry 4.7 but
2806                                 // uses .value. See #6932
2807                                 var val = elem.attributes.value;
2808                                 return !val || val.specified ? elem.value : elem.text;
2809                         }
2810                 },
2811                 select: {
2812                         get: function( elem ) {
2813                                 var index = elem.selectedIndex,
2814                                         values = [],
2815                                         options = elem.options,
2816                                         one = elem.type === "select-one";
2817
2818                                 // Nothing was selected
2819                                 if ( index < 0 ) {
2820                                         return null;
2821                                 }
2822
2823                                 // Loop through all the selected options
2824                                 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2825                                         var option = options[ i ];
2826
2827                                         // Don't return options that are disabled or in a disabled optgroup
2828                                         if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2829                                                         (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2830
2831                                                 // Get the specific value for the option
2832                                                 value = jQuery( option ).val();
2833
2834                                                 // We don't need an array for one selects
2835                                                 if ( one ) {
2836                                                         return value;
2837                                                 }
2838
2839                                                 // Multi-Selects return an array
2840                                                 values.push( value );
2841                                         }
2842                                 }
2843
2844                                 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2845                                 if ( one && !values.length && options.length ) {
2846                                         return jQuery( options[ index ] ).val();
2847                                 }
2848
2849                                 return values;
2850                         },
2851
2852                         set: function( elem, value ) {
2853                                 var values = jQuery.makeArray( value );
2854
2855                                 jQuery(elem).find("option").each(function() {
2856                                         this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2857                                 });
2858
2859                                 if ( !values.length ) {
2860                                         elem.selectedIndex = -1;
2861                                 }
2862                                 return values;
2863                         }
2864                 }
2865         },
2866
2867         attrFn: {
2868                 val: true,
2869                 css: true,
2870                 html: true,
2871                 text: true,
2872                 data: true,
2873                 width: true,
2874                 height: true,
2875                 offset: true
2876         },
2877         
2878         attrFix: {
2879                 // Always normalize to ensure hook usage
2880                 tabindex: "tabIndex",
2881                 readonly: "readOnly"
2882         },
2883         
2884         attr: function( elem, name, value, pass ) {
2885                 var nType = elem.nodeType;
2886                 
2887                 // don't get/set attributes on text, comment and attribute nodes
2888                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2889                         return undefined;
2890                 }
2891
2892                 if ( pass && name in jQuery.attrFn ) {
2893                         return jQuery( elem )[ name ]( value );
2894                 }
2895                 
2896                 var ret, hooks,
2897                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2898                 
2899                 // Normalize the name if needed
2900                 name = notxml && jQuery.attrFix[ name ] || name;
2901
2902                 // Get the appropriate hook, or the formHook
2903                 // if getSetAttribute is not supported and we have form objects in IE6/7
2904                 hooks = jQuery.attrHooks[ name ] ||
2905                         ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ?
2906                                 formHook :
2907                                 undefined );
2908
2909                 if ( value !== undefined ) {
2910
2911                         if ( value === null || (value === false && !rspecial.test( name )) ) {
2912                                 jQuery.removeAttr( elem, name );
2913                                 return undefined;
2914
2915                         } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2916                                 return ret;
2917
2918                         } else {
2919
2920                                 // Set boolean attributes to the same name
2921                                 if ( value === true && !rspecial.test( name ) ) {
2922                                         value = name;
2923                                 }
2924
2925                                 elem.setAttribute( name, "" + value );
2926                                 return value;
2927                         }
2928
2929                 } else {
2930
2931                         if ( hooks && "get" in hooks && notxml ) {
2932                                 return hooks.get( elem, name );
2933
2934                         } else {
2935
2936                                 ret = elem.getAttribute( name );
2937
2938                                 // Non-existent attributes return null, we normalize to undefined
2939                                 return ret === null ?
2940                                         undefined :
2941                                         ret;
2942                         }
2943                 }
2944         },
2945         
2946         removeAttr: function( elem, name ) {
2947                 if ( elem.nodeType === 1 ) {
2948                         name = jQuery.attrFix[ name ] || name;
2949                 
2950                         if ( jQuery.support.getSetAttribute ) {
2951                                 // Use removeAttribute in browsers that support it
2952                                 elem.removeAttribute( name );
2953                         } else {
2954                                 jQuery.attr( elem, name, "" );
2955                                 elem.removeAttributeNode( elem.getAttributeNode( name ) );
2956                         }
2957                 }
2958         },
2959
2960         attrHooks: {
2961                 type: {
2962                         set: function( elem, value ) {
2963                                 // We can't allow the type property to be changed (since it causes problems in IE)
2964                                 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2965                                         jQuery.error( "type property can't be changed" );
2966                                 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2967                                         // Setting the type on a radio button after the value resets the value in IE6-9
2968                                         // Reset value to it's default in case type is set after value
2969                                         // This is for element creation
2970                                         var val = elem.getAttribute("value");
2971                                         elem.setAttribute( "type", value );
2972                                         if ( val ) {
2973                                                 elem.value = val;
2974                                         }
2975                                         return value;
2976                                 }
2977                         }
2978                 },
2979                 tabIndex: {
2980                         get: function( elem ) {
2981                                 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2982                                 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2983                                 var attributeNode = elem.getAttributeNode("tabIndex");
2984
2985                                 return attributeNode && attributeNode.specified ?
2986                                         parseInt( attributeNode.value, 10 ) :
2987                                         rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2988                                                 0 :
2989                                                 undefined;
2990                         }
2991                 }
2992         },
2993         
2994         propFix: {},
2995         
2996         prop: function( elem, name, value ) {
2997                 var nType = elem.nodeType;
2998                 
2999                 // don't get/set properties on text, comment and attribute nodes
3000                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
3001                         return undefined;
3002                 }
3003                 
3004                 var ret, hooks,
3005                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
3006                 
3007                 // Try to normalize/fix the name
3008                 name = notxml && jQuery.propFix[ name ] || name;
3009                 
3010                 hooks = jQuery.propHooks[ name ];
3011                 
3012                 if ( value !== undefined ) {
3013                         if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
3014                                 return ret;
3015                         
3016                         } else {
3017                                 return (elem[ name ] = value);
3018                         }
3019                 
3020                 } else {
3021                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
3022                                 return ret;
3023                                 
3024                         } else {
3025                                 return elem[ name ];
3026                         }
3027                 }
3028         },
3029         
3030         propHooks: {}
3031 });
3032
3033 // IE6/7 do not support getting/setting some attributes with get/setAttribute
3034 if ( !jQuery.support.getSetAttribute ) {
3035         jQuery.attrFix = jQuery.extend( jQuery.attrFix, {
3036                 "for": "htmlFor",
3037                 "class": "className",
3038                 maxlength: "maxLength",
3039                 cellspacing: "cellSpacing",
3040                 cellpadding: "cellPadding",
3041                 rowspan: "rowSpan",
3042                 colspan: "colSpan",
3043                 usemap: "useMap",
3044                 frameborder: "frameBorder"
3045         });
3046         
3047         // Use this for any attribute on a form in IE6/7
3048         formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = {
3049                 get: function( elem, name ) {
3050                         var ret;
3051                         if ( name === "value" && !jQuery.nodeName( elem, "button" ) ) {
3052                                 return elem.getAttribute( name );
3053                         }
3054                         ret = elem.getAttributeNode( name );
3055                         // Return undefined if not specified instead of empty string
3056                         return ret && ret.specified ?
3057                                 ret.nodeValue :
3058                                 undefined;
3059                 },
3060                 set: function( elem, value, name ) {
3061                         // Check form objects in IE (multiple bugs related)
3062                         // Only use nodeValue if the attribute node exists on the form
3063                         var ret = elem.getAttributeNode( name );
3064                         if ( ret ) {
3065                                 ret.nodeValue = value;
3066                                 return value;
3067                         }
3068                 }
3069         };
3070
3071         // Set width and height to auto instead of 0 on empty string( Bug #8150 )
3072         // This is for removals
3073         jQuery.each([ "width", "height" ], function( i, name ) {
3074                 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
3075                         set: function( elem, value ) {
3076                                 if ( value === "" ) {
3077                                         elem.setAttribute( name, "auto" );
3078                                         return value;
3079                                 }
3080                         }
3081                 });
3082         });
3083 }
3084
3085
3086 // Some attributes require a special call on IE
3087 if ( !jQuery.support.hrefNormalized ) {
3088         jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
3089                 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
3090                         get: function( elem ) {
3091                                 var ret = elem.getAttribute( name, 2 );
3092                                 return ret === null ? undefined : ret;
3093                         }
3094                 });
3095         });
3096 }
3097
3098 if ( !jQuery.support.style ) {
3099         jQuery.attrHooks.style = {
3100                 get: function( elem ) {
3101                         // Return undefined in the case of empty string
3102                         // Normalize to lowercase since IE uppercases css property names
3103                         return elem.style.cssText.toLowerCase() || undefined;
3104                 },
3105                 set: function( elem, value ) {
3106                         return (elem.style.cssText = "" + value);
3107                 }
3108         };
3109 }
3110
3111 // Safari mis-reports the default selected property of an option
3112 // Accessing the parent's selectedIndex property fixes it
3113 if ( !jQuery.support.optSelected ) {
3114         jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
3115                 get: function( elem ) {
3116                         var parent = elem.parentNode;
3117
3118                         if ( parent ) {
3119                                 parent.selectedIndex;
3120
3121                                 // Make sure that it also works with optgroups, see #5701
3122                                 if ( parent.parentNode ) {
3123                                         parent.parentNode.selectedIndex;
3124                                 }
3125                         }
3126                 }
3127         });
3128 }
3129
3130 // Radios and checkboxes getter/setter
3131 if ( !jQuery.support.checkOn ) {
3132         jQuery.each([ "radio", "checkbox" ], function() {
3133                 jQuery.valHooks[ this ] = {
3134                         get: function( elem ) {
3135                                 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
3136                                 return elem.getAttribute("value") === null ? "on" : elem.value;
3137                         }
3138                 };
3139         });
3140 }
3141 jQuery.each([ "radio", "checkbox" ], function() {
3142         jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
3143                 set: function( elem, value ) {
3144                         if ( jQuery.isArray( value ) ) {
3145                                 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
3146                         }
3147                 }
3148         });
3149 });
3150
3151
3152
3153
3154 var hasOwn = Object.prototype.hasOwnProperty,
3155         rnamespaces = /\.(.*)$/,
3156         rformElems = /^(?:textarea|input|select)$/i,
3157         rperiod = /\./g,
3158         rspaces = / /g,
3159         rescape = /[^\w\s.|`]/g,
3160         fcleanup = function( nm ) {
3161                 return nm.replace(rescape, "\\$&");
3162         };
3163
3164 /*
3165  * A number of helper functions used for managing events.
3166  * Many of the ideas behind this code originated from
3167  * Dean Edwards' addEvent library.
3168  */
3169 jQuery.event = {
3170
3171         // Bind an event to an element
3172         // Original by Dean Edwards
3173         add: function( elem, types, handler, data ) {
3174                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
3175                         return;
3176                 }
3177
3178                 if ( handler === false ) {
3179                         handler = returnFalse;
3180                 } else if ( !handler ) {
3181                         // Fixes bug #7229. Fix recommended by jdalton
3182                         return;
3183                 }
3184
3185                 var handleObjIn, handleObj;
3186
3187                 if ( handler.handler ) {
3188                         handleObjIn = handler;
3189                         handler = handleObjIn.handler;
3190                 }
3191
3192                 // Make sure that the function being executed has a unique ID
3193                 if ( !handler.guid ) {
3194                         handler.guid = jQuery.guid++;
3195                 }
3196
3197                 // Init the element's event structure
3198                 var elemData = jQuery._data( elem );
3199
3200                 // If no elemData is found then we must be trying to bind to one of the
3201                 // banned noData elements
3202                 if ( !elemData ) {
3203                         return;
3204                 }
3205
3206                 var events = elemData.events,
3207                         eventHandle = elemData.handle;
3208
3209                 if ( !events ) {
3210                         elemData.events = events = {};
3211                 }
3212
3213                 if ( !eventHandle ) {
3214                         elemData.handle = eventHandle = function( e ) {
3215                                 // Discard the second event of a jQuery.event.trigger() and
3216                                 // when an event is called after a page has unloaded
3217                                 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
3218                                         jQuery.event.handle.apply( eventHandle.elem, arguments ) :
3219                                         undefined;
3220                         };
3221                 }
3222
3223                 // Add elem as a property of the handle function
3224                 // This is to prevent a memory leak with non-native events in IE.
3225                 eventHandle.elem = elem;
3226
3227                 // Handle multiple events separated by a space
3228                 // jQuery(...).bind("mouseover mouseout", fn);
3229                 types = types.split(" ");
3230
3231                 var type, i = 0, namespaces;
3232
3233                 while ( (type = types[ i++ ]) ) {
3234                         handleObj = handleObjIn ?
3235                                 jQuery.extend({}, handleObjIn) :
3236                                 { handler: handler, data: data };
3237
3238                         // Namespaced event handlers
3239                         if ( type.indexOf(".") > -1 ) {
3240                                 namespaces = type.split(".");
3241                                 type = namespaces.shift();
3242                                 handleObj.namespace = namespaces.slice(0).sort().join(".");
3243
3244                         } else {
3245                                 namespaces = [];
3246                                 handleObj.namespace = "";
3247                         }
3248
3249                         handleObj.type = type;
3250                         if ( !handleObj.guid ) {
3251                                 handleObj.guid = handler.guid;
3252                         }
3253
3254                         // Get the current list of functions bound to this event
3255                         var handlers = events[ type ],
3256                                 special = jQuery.event.special[ type ] || {};
3257
3258                         // Init the event handler queue
3259                         if ( !handlers ) {
3260                                 handlers = events[ type ] = [];
3261
3262                                 // Check for a special event handler
3263                                 // Only use addEventListener/attachEvent if the special
3264                                 // events handler returns false
3265                                 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
3266                                         // Bind the global event handler to the element
3267                                         if ( elem.addEventListener ) {
3268                                                 elem.addEventListener( type, eventHandle, false );
3269
3270                                         } else if ( elem.attachEvent ) {
3271                                                 elem.attachEvent( "on" + type, eventHandle );
3272                                         }
3273                                 }
3274                         }
3275
3276                         if ( special.add ) {
3277                                 special.add.call( elem, handleObj );
3278
3279                                 if ( !handleObj.handler.guid ) {
3280                                         handleObj.handler.guid = handler.guid;
3281                                 }
3282                         }
3283
3284                         // Add the function to the element's handler list
3285                         handlers.push( handleObj );
3286
3287                         // Keep track of which events have been used, for event optimization
3288                         jQuery.event.global[ type ] = true;
3289                 }
3290
3291                 // Nullify elem to prevent memory leaks in IE
3292                 elem = null;
3293         },
3294
3295         global: {},
3296
3297         // Detach an event or set of events from an element
3298         remove: function( elem, types, handler, pos ) {
3299                 // don't do events on text and comment nodes
3300                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
3301                         return;
3302                 }
3303
3304                 if ( handler === false ) {
3305                         handler = returnFalse;
3306                 }
3307
3308                 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
3309                         elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
3310                         events = elemData && elemData.events;
3311
3312                 if ( !elemData || !events ) {
3313                         return;
3314                 }
3315
3316                 // types is actually an event object here
3317                 if ( types && types.type ) {
3318                         handler = types.handler;
3319                         types = types.type;
3320                 }
3321
3322                 // Unbind all events for the element
3323                 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
3324                         types = types || "";
3325
3326                         for ( type in events ) {
3327                                 jQuery.event.remove( elem, type + types );
3328                         }
3329
3330                         return;
3331                 }
3332
3333                 // Handle multiple events separated by a space
3334                 // jQuery(...).unbind("mouseover mouseout", fn);
3335                 types = types.split(" ");
3336
3337                 while ( (type = types[ i++ ]) ) {
3338                         origType = type;
3339                         handleObj = null;
3340                         all = type.indexOf(".") < 0;
3341                         namespaces = [];
3342
3343                         if ( !all ) {
3344                                 // Namespaced event handlers
3345                                 namespaces = type.split(".");
3346                                 type = namespaces.shift();
3347
3348                                 namespace = new RegExp("(^|\\.)" +
3349                                         jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
3350                         }
3351
3352                         eventType = events[ type ];
3353
3354                         if ( !eventType ) {
3355                                 continue;
3356                         }
3357
3358                         if ( !handler ) {
3359                                 for ( j = 0; j < eventType.length; j++ ) {
3360                                         handleObj = eventType[ j ];
3361
3362                                         if ( all || namespace.test( handleObj.namespace ) ) {
3363                                                 jQuery.event.remove( elem, origType, handleObj.handler, j );
3364                                                 eventType.splice( j--, 1 );
3365                                         }
3366                                 }
3367
3368                                 continue;
3369                         }
3370
3371                         special = jQuery.event.special[ type ] || {};
3372
3373                         for ( j = pos || 0; j < eventType.length; j++ ) {
3374                                 handleObj = eventType[ j ];
3375
3376                                 if ( handler.guid === handleObj.guid ) {
3377                                         // remove the given handler for the given type
3378                                         if ( all || namespace.test( handleObj.namespace ) ) {
3379                                                 if ( pos == null ) {
3380                                                         eventType.splice( j--, 1 );
3381                                                 }
3382
3383                                                 if ( special.remove ) {
3384                                                         special.remove.call( elem, handleObj );
3385                                                 }
3386                                         }
3387
3388                                         if ( pos != null ) {
3389                                                 break;
3390                                         }
3391                                 }
3392                         }
3393
3394                         // remove generic event handler if no more handlers exist
3395                         if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
3396                                 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
3397                                         jQuery.removeEvent( elem, type, elemData.handle );
3398                                 }
3399
3400                                 ret = null;
3401                                 delete events[ type ];
3402                         }
3403                 }
3404
3405                 // Remove the expando if it's no longer used
3406                 if ( jQuery.isEmptyObject( events ) ) {
3407                         var handle = elemData.handle;
3408                         if ( handle ) {
3409                                 handle.elem = null;
3410                         }
3411
3412                         delete elemData.events;
3413                         delete elemData.handle;
3414
3415                         if ( jQuery.isEmptyObject( elemData ) ) {
3416                                 jQuery.removeData( elem, undefined, true );
3417                         }
3418                 }
3419         },
3420         
3421         // Events that are safe to short-circuit if no handlers are attached.
3422         // Native DOM events should not be added, they may have inline handlers.
3423         customEvent: {
3424                 "getData": true,
3425                 "setData": true,
3426                 "changeData": true
3427         },
3428
3429         trigger: function( event, data, elem, onlyHandlers ) {
3430                 // Event object or event type
3431                 var type = event.type || event,
3432                         namespaces = [],
3433                         exclusive;
3434
3435                 if ( type.indexOf("!") >= 0 ) {
3436                         // Exclusive events trigger only for the exact event (no namespaces)
3437                         type = type.slice(0, -1);
3438                         exclusive = true;
3439                 }
3440
3441                 if ( type.indexOf(".") >= 0 ) {
3442                         // Namespaced trigger; create a regexp to match event type in handle()
3443                         namespaces = type.split(".");
3444                         type = namespaces.shift();
3445                         namespaces.sort();
3446                 }
3447
3448                 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
3449                         // No jQuery handlers for this event type, and it can't have inline handlers
3450                         return;
3451                 }
3452
3453                 // Caller can pass in an Event, Object, or just an event type string
3454                 event = typeof event === "object" ?
3455                         // jQuery.Event object
3456                         event[ jQuery.expando ] ? event :
3457                         // Object literal
3458                         new jQuery.Event( type, event ) :
3459                         // Just the event type (string)
3460                         new jQuery.Event( type );
3461
3462                 event.type = type;
3463                 event.exclusive = exclusive;
3464                 event.namespace = namespaces.join(".");
3465                 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
3466                 
3467                 // triggerHandler() and global events don't bubble or run the default action
3468                 if ( onlyHandlers || !elem ) {
3469                         event.preventDefault();
3470                         event.stopPropagation();
3471                 }
3472
3473                 // Handle a global trigger
3474                 if ( !elem ) {
3475                         // TODO: Stop taunting the data cache; remove global events and always attach to document
3476                         jQuery.each( jQuery.cache, function() {
3477                                 // internalKey variable is just used to make it easier to find
3478                                 // and potentially change this stuff later; currently it just
3479                                 // points to jQuery.expando
3480                                 var internalKey = jQuery.expando,
3481                                         internalCache = this[ internalKey ];
3482                                 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
3483                                         jQuery.event.trigger( event, data, internalCache.handle.elem );
3484                                 }
3485                         });
3486                         return;
3487                 }
3488
3489                 // Don't do events on text and comment nodes
3490                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
3491                         return;
3492                 }
3493
3494                 // Clean up the event in case it is being reused
3495                 event.result = undefined;
3496                 event.target = elem;
3497
3498                 // Clone any incoming data and prepend the event, creating the handler arg list
3499                 data = data ? jQuery.makeArray( data ) : [];
3500                 data.unshift( event );
3501
3502                 var cur = elem,
3503                         // IE doesn't like method names with a colon (#3533, #8272)
3504                         ontype = type.indexOf(":") < 0 ? "on" + type : "";
3505
3506                 // Fire event on the current element, then bubble up the DOM tree
3507                 do {
3508                         var handle = jQuery._data( cur, "handle" );
3509
3510                         event.currentTarget = cur;
3511                         if ( handle ) {
3512                                 handle.apply( cur, data );
3513                         }
3514
3515                         // Trigger an inline bound script
3516                         if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
3517                                 event.result = false;
3518                                 event.preventDefault();
3519                         }
3520
3521                         // Bubble up to document, then to window
3522                         cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
3523                 } while ( cur && !event.isPropagationStopped() );
3524
3525                 // If nobody prevented the default action, do it now
3526                 if ( !event.isDefaultPrevented() ) {
3527                         var old,
3528                                 special = jQuery.event.special[ type ] || {};
3529
3530                         if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
3531                                 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
3532
3533                                 // Call a native DOM method on the target with the same name name as the event.
3534                                 // Can't use an .isFunction)() check here because IE6/7 fails that test.
3535                                 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
3536                                 try {
3537                                         if ( ontype && elem[ type ] ) {
3538                                                 // Don't re-trigger an onFOO event when we call its FOO() method
3539                                                 old = elem[ ontype ];
3540
3541                                                 if ( old ) {
3542                                                         elem[ ontype ] = null;
3543                                                 }
3544
3545                                                 jQuery.event.triggered = type;
3546                                                 elem[ type ]();
3547                                         }
3548                                 } catch ( ieError ) {}
3549
3550                                 if ( old ) {
3551                                         elem[ ontype ] = old;
3552                                 }
3553
3554                                 jQuery.event.triggered = undefined;
3555                         }
3556                 }
3557                 
3558                 return event.result;
3559         },
3560
3561         handle: function( event ) {
3562                 event = jQuery.event.fix( event || window.event );
3563                 // Snapshot the handlers list since a called handler may add/remove events.
3564                 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
3565                         run_all = !event.exclusive && !event.namespace,
3566                         args = Array.prototype.slice.call( arguments, 0 );
3567
3568                 // Use the fix-ed Event rather than the (read-only) native event
3569                 args[0] = event;
3570                 event.currentTarget = this;
3571
3572                 for ( var j = 0, l = handlers.length; j < l; j++ ) {
3573                         var handleObj = handlers[ j ];
3574
3575                         // Triggered event must 1) be non-exclusive and have no namespace, or
3576                         // 2) have namespace(s) a subset or equal to those in the bound event.
3577                         if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
3578                                 // Pass in a reference to the handler function itself
3579                                 // So that we can later remove it
3580                                 event.handler = handleObj.handler;
3581                                 event.data = handleObj.data;
3582                                 event.handleObj = handleObj;
3583
3584                                 var ret = handleObj.handler.apply( this, args );
3585
3586                                 if ( ret !== undefined ) {
3587                                         event.result = ret;
3588                                         if ( ret === false ) {
3589                                                 event.preventDefault();
3590                                                 event.stopPropagation();
3591                                         }
3592                                 }
3593
3594                                 if ( event.isImmediatePropagationStopped() ) {
3595                                         break;
3596                                 }
3597                         }
3598                 }
3599                 return event.result;
3600         },
3601
3602         props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
3603
3604         fix: function( event ) {
3605                 if ( event[ jQuery.expando ] ) {
3606                         return event;
3607                 }
3608
3609                 // store a copy of the original event object
3610                 // and "clone" to set read-only properties
3611                 var originalEvent = event;
3612                 event = jQuery.Event( originalEvent );
3613
3614                 for ( var i = this.props.length, prop; i; ) {
3615                         prop = this.props[ --i ];
3616                         event[ prop ] = originalEvent[ prop ];
3617                 }
3618
3619                 // Fix target property, if necessary
3620                 if ( !event.target ) {
3621                         // Fixes #1925 where srcElement might not be defined either
3622                         event.target = event.srcElement || document;
3623                 }
3624
3625                 // check if target is a textnode (safari)
3626                 if ( event.target.nodeType === 3 ) {
3627                         event.target = event.target.parentNode;
3628                 }
3629
3630                 // Add relatedTarget, if necessary
3631                 if ( !event.relatedTarget && event.fromElement ) {
3632                         event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
3633                 }
3634
3635                 // Calculate pageX/Y if missing and clientX/Y available
3636                 if ( event.pageX == null && event.clientX != null ) {
3637                         var eventDocument = event.target.ownerDocument || document,
3638                                 doc = eventDocument.documentElement,
3639                                 body = eventDocument.body;
3640
3641                         event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
3642                         event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
3643                 }
3644
3645                 // Add which for key events
3646                 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3647                         event.which = event.charCode != null ? event.charCode : event.keyCode;
3648                 }
3649
3650                 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3651                 if ( !event.metaKey && event.ctrlKey ) {
3652                         event.metaKey = event.ctrlKey;
3653                 }
3654
3655                 // Add which for click: 1 === left; 2 === middle; 3 === right
3656                 // Note: button is not normalized, so don't use it
3657                 if ( !event.which && event.button !== undefined ) {
3658                         event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3659                 }
3660
3661                 return event;
3662         },
3663
3664         // Deprecated, use jQuery.guid instead
3665         guid: 1E8,
3666
3667         // Deprecated, use jQuery.proxy instead
3668         proxy: jQuery.proxy,
3669
3670         special: {
3671                 ready: {
3672                         // Make sure the ready event is setup
3673                         setup: jQuery.bindReady,
3674                         teardown: jQuery.noop
3675                 },
3676
3677                 live: {
3678                         add: function( handleObj ) {
3679                                 jQuery.event.add( this,
3680                                         liveConvert( handleObj.origType, handleObj.selector ),
3681                                         jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3682                         },
3683
3684                         remove: function( handleObj ) {
3685                                 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3686                         }
3687                 },
3688
3689                 beforeunload: {
3690                         setup: function( data, namespaces, eventHandle ) {
3691                                 // We only want to do this special case on windows
3692                                 if ( jQuery.isWindow( this ) ) {
3693                                         this.onbeforeunload = eventHandle;
3694                                 }
3695                         },
3696
3697                         teardown: function( namespaces, eventHandle ) {
3698                                 if ( this.onbeforeunload === eventHandle ) {
3699                                         this.onbeforeunload = null;
3700                                 }
3701                         }
3702                 }
3703         }
3704 };
3705
3706 jQuery.removeEvent = document.removeEventListener ?
3707         function( elem, type, handle ) {
3708                 if ( elem.removeEventListener ) {
3709                         elem.removeEventListener( type, handle, false );
3710                 }
3711         } :
3712         function( elem, type, handle ) {
3713                 if ( elem.detachEvent ) {
3714                         elem.detachEvent( "on" + type, handle );
3715                 }
3716         };
3717
3718 jQuery.Event = function( src, props ) {
3719         // Allow instantiation without the 'new' keyword
3720         if ( !this.preventDefault ) {
3721                 return new jQuery.Event( src, props );
3722         }
3723
3724         // Event object
3725         if ( src && src.type ) {
3726                 this.originalEvent = src;
3727                 this.type = src.type;
3728
3729                 // Events bubbling up the document may have been marked as prevented
3730                 // by a handler lower down the tree; reflect the correct value.
3731                 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3732                         src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3733
3734         // Event type
3735         } else {
3736                 this.type = src;
3737         }
3738
3739         // Put explicitly provided properties onto the event object
3740         if ( props ) {
3741                 jQuery.extend( this, props );
3742         }
3743
3744         // timeStamp is buggy for some events on Firefox(#3843)
3745         // So we won't rely on the native value
3746         this.timeStamp = jQuery.now();
3747
3748         // Mark it as fixed
3749         this[ jQuery.expando ] = true;
3750 };
3751
3752 function returnFalse() {
3753         return false;
3754 }
3755 function returnTrue() {
3756         return true;
3757 }
3758
3759 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3760 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3761 jQuery.Event.prototype = {
3762         preventDefault: function() {
3763                 this.isDefaultPrevented = returnTrue;
3764
3765                 var e = this.originalEvent;
3766                 if ( !e ) {
3767                         return;
3768                 }
3769
3770                 // if preventDefault exists run it on the original event
3771                 if ( e.preventDefault ) {
3772                         e.preventDefault();
3773
3774                 // otherwise set the returnValue property of the original event to false (IE)
3775                 } else {
3776                         e.returnValue = false;
3777                 }
3778         },
3779         stopPropagation: function() {
3780                 this.isPropagationStopped = returnTrue;
3781
3782                 var e = this.originalEvent;
3783                 if ( !e ) {
3784                         return;
3785                 }
3786                 // if stopPropagation exists run it on the original event
3787                 if ( e.stopPropagation ) {
3788                         e.stopPropagation();
3789                 }
3790                 // otherwise set the cancelBubble property of the original event to true (IE)
3791                 e.cancelBubble = true;
3792         },
3793         stopImmediatePropagation: function() {
3794                 this.isImmediatePropagationStopped = returnTrue;
3795                 this.stopPropagation();
3796         },
3797         isDefaultPrevented: returnFalse,
3798         isPropagationStopped: returnFalse,
3799         isImmediatePropagationStopped: returnFalse
3800 };
3801
3802 // Checks if an event happened on an element within another element
3803 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3804 var withinElement = function( event ) {
3805         // Check if mouse(over|out) are still within the same parent element
3806         var parent = event.relatedTarget;
3807
3808         // Firefox sometimes assigns relatedTarget a XUL element
3809         // which we cannot access the parentNode property of
3810         try {
3811
3812                 // Chrome does something similar, the parentNode property
3813                 // can be accessed but is null.
3814                 if ( parent && parent !== document && !parent.parentNode ) {
3815                         return;
3816                 }
3817                 // Traverse up the tree
3818                 while ( parent && parent !== this ) {
3819                         parent = parent.parentNode;
3820                 }
3821
3822                 if ( parent !== this ) {
3823                         // set the correct event type
3824                         event.type = event.data;
3825
3826                         // handle event if we actually just moused on to a non sub-element
3827                         jQuery.event.handle.apply( this, arguments );
3828                 }
3829
3830         // assuming we've left the element since we most likely mousedover a xul element
3831         } catch(e) { }
3832 },
3833
3834 // In case of event delegation, we only need to rename the event.type,
3835 // liveHandler will take care of the rest.
3836 delegate = function( event ) {
3837         event.type = event.data;
3838         jQuery.event.handle.apply( this, arguments );
3839 };
3840
3841 // Create mouseenter and mouseleave events
3842 jQuery.each({
3843         mouseenter: "mouseover",
3844         mouseleave: "mouseout"
3845 }, function( orig, fix ) {
3846         jQuery.event.special[ orig ] = {
3847                 setup: function( data ) {
3848                         jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3849                 },
3850                 teardown: function( data ) {
3851                         jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3852                 }
3853         };
3854 });
3855
3856 // submit delegation
3857 if ( !jQuery.support.submitBubbles ) {
3858
3859         jQuery.event.special.submit = {
3860                 setup: function( data, namespaces ) {
3861                         if ( !jQuery.nodeName( this, "form" ) ) {
3862                                 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3863                                         var elem = e.target,
3864                                                 type = elem.type;
3865
3866                                         if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3867                                                 trigger( "submit", this, arguments );
3868                                         }
3869                                 });
3870
3871                                 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3872                                         var elem = e.target,
3873                                                 type = elem.type;
3874
3875                                         if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3876                                                 trigger( "submit", this, arguments );
3877                                         }
3878                                 });
3879
3880                         } else {
3881                                 return false;
3882                         }
3883                 },
3884
3885                 teardown: function( namespaces ) {
3886                         jQuery.event.remove( this, ".specialSubmit" );
3887                 }
3888         };
3889
3890 }
3891
3892 // change delegation, happens here so we have bind.
3893 if ( !jQuery.support.changeBubbles ) {
3894
3895         var changeFilters,
3896
3897         getVal = function( elem ) {
3898                 var type = elem.type, val = elem.value;
3899
3900                 if ( type === "radio" || type === "checkbox" ) {
3901                         val = elem.checked;
3902
3903                 } else if ( type === "select-multiple" ) {
3904                         val = elem.selectedIndex > -1 ?
3905                                 jQuery.map( elem.options, function( elem ) {
3906                                         return elem.selected;
3907                                 }).join("-") :
3908                                 "";
3909
3910                 } else if ( jQuery.nodeName( elem, "select" ) ) {
3911                         val = elem.selectedIndex;
3912                 }
3913
3914                 return val;
3915         },
3916
3917         testChange = function testChange( e ) {
3918                 var elem = e.target, data, val;
3919
3920                 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3921                         return;
3922                 }
3923
3924                 data = jQuery._data( elem, "_change_data" );
3925                 val = getVal(elem);
3926
3927                 // the current data will be also retrieved by beforeactivate
3928                 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3929                         jQuery._data( elem, "_change_data", val );
3930                 }
3931
3932                 if ( data === undefined || val === data ) {
3933                         return;
3934                 }
3935
3936                 if ( data != null || val ) {
3937                         e.type = "change";
3938                         e.liveFired = undefined;
3939                         jQuery.event.trigger( e, arguments[1], elem );
3940                 }
3941         };
3942
3943         jQuery.event.special.change = {
3944                 filters: {
3945                         focusout: testChange,
3946
3947                         beforedeactivate: testChange,
3948
3949                         click: function( e ) {
3950                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3951
3952                                 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3953                                         testChange.call( this, e );
3954                                 }
3955                         },
3956
3957                         // Change has to be called before submit
3958                         // Keydown will be called before keypress, which is used in submit-event delegation
3959                         keydown: function( e ) {
3960                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3961
3962                                 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3963                                         (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3964                                         type === "select-multiple" ) {
3965                                         testChange.call( this, e );
3966                                 }
3967                         },
3968
3969                         // Beforeactivate happens also before the previous element is blurred
3970                         // with this event you can't trigger a change event, but you can store
3971                         // information
3972                         beforeactivate: function( e ) {
3973                                 var elem = e.target;
3974                                 jQuery._data( elem, "_change_data", getVal(elem) );
3975                         }
3976                 },
3977
3978                 setup: function( data, namespaces ) {
3979                         if ( this.type === "file" ) {
3980                                 return false;
3981                         }
3982
3983                         for ( var type in changeFilters ) {
3984                                 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3985                         }
3986
3987                         return rformElems.test( this.nodeName );
3988                 },
3989
3990                 teardown: function( namespaces ) {
3991                         jQuery.event.remove( this, ".specialChange" );
3992
3993                         return rformElems.test( this.nodeName );
3994                 }
3995         };
3996
3997         changeFilters = jQuery.event.special.change.filters;
3998
3999         // Handle when the input is .focus()'d
4000         changeFilters.focus = changeFilters.beforeactivate;
4001 }
4002
4003 function trigger( type, elem, args ) {
4004         // Piggyback on a donor event to simulate a different one.
4005         // Fake originalEvent to avoid donor's stopPropagation, but if the
4006         // simulated event prevents default then we do the same on the donor.
4007         // Don't pass args or remember liveFired; they apply to the donor event.
4008         var event = jQuery.extend( {}, args[ 0 ] );
4009         event.type = type;
4010         event.originalEvent = {};
4011         event.liveFired = undefined;
4012         jQuery.event.handle.call( elem, event );
4013         if ( event.isDefaultPrevented() ) {
4014                 args[ 0 ].preventDefault();
4015         }
4016 }
4017
4018 // Create "bubbling" focus and blur events
4019 if ( !jQuery.support.focusinBubbles ) {
4020         jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
4021
4022                 // Attach a single capturing handler while someone wants focusin/focusout
4023                 var attaches = 0;
4024
4025                 jQuery.event.special[ fix ] = {
4026                         setup: function() {
4027                                 if ( attaches++ === 0 ) {
4028                                         document.addEventListener( orig, handler, true );
4029                                 }
4030                         },
4031                         teardown: function() {
4032                                 if ( --attaches === 0 ) {
4033                                         document.removeEventListener( orig, handler, true );
4034                                 }
4035                         }
4036                 };
4037
4038                 function handler( donor ) {
4039                         // Donor event is always a native one; fix it and switch its type.
4040                         // Let focusin/out handler cancel the donor focus/blur event.
4041                         var e = jQuery.event.fix( donor );
4042                         e.type = fix;
4043                         e.originalEvent = {};
4044                         jQuery.event.trigger( e, null, e.target );
4045                         if ( e.isDefaultPrevented() ) {
4046                                 donor.preventDefault();
4047                         }
4048                 }
4049         });
4050 }
4051
4052 jQuery.each(["bind", "one"], function( i, name ) {
4053         jQuery.fn[ name ] = function( type, data, fn ) {
4054                 var handler;
4055
4056                 // Handle object literals
4057                 if ( typeof type === "object" ) {
4058                         for ( var key in type ) {
4059                                 this[ name ](key, data, type[key], fn);
4060                         }
4061                         return this;
4062                 }
4063
4064                 if ( arguments.length === 2 || data === false ) {
4065                         fn = data;
4066                         data = undefined;
4067                 }
4068
4069                 if ( name === "one" ) {
4070                         handler = function( event ) {
4071                                 jQuery( this ).unbind( event, handler );
4072                                 return fn.apply( this, arguments );
4073                         };
4074                         handler.guid = fn.guid || jQuery.guid++;
4075                 } else {
4076                         handler = fn;
4077                 }
4078
4079                 if ( type === "unload" && name !== "one" ) {
4080                         this.one( type, data, fn );
4081
4082                 } else {
4083                         for ( var i = 0, l = this.length; i < l; i++ ) {
4084                                 jQuery.event.add( this[i], type, handler, data );
4085                         }
4086                 }
4087
4088                 return this;
4089         };
4090 });
4091
4092 jQuery.fn.extend({
4093         unbind: function( type, fn ) {
4094                 // Handle object literals
4095                 if ( typeof type === "object" && !type.preventDefault ) {
4096                         for ( var key in type ) {
4097                                 this.unbind(key, type[key]);
4098                         }
4099
4100                 } else {
4101                         for ( var i = 0, l = this.length; i < l; i++ ) {
4102                                 jQuery.event.remove( this[i], type, fn );
4103                         }
4104                 }
4105
4106                 return this;
4107         },
4108
4109         delegate: function( selector, types, data, fn ) {
4110                 return this.live( types, data, fn, selector );
4111         },
4112
4113         undelegate: function( selector, types, fn ) {
4114                 if ( arguments.length === 0 ) {
4115                         return this.unbind( "live" );
4116
4117                 } else {
4118                         return this.die( types, null, fn, selector );
4119                 }
4120         },
4121
4122         trigger: function( type, data ) {
4123                 return this.each(function() {
4124                         jQuery.event.trigger( type, data, this );
4125                 });
4126         },
4127
4128         triggerHandler: function( type, data ) {
4129                 if ( this[0] ) {
4130                         return jQuery.event.trigger( type, data, this[0], true );
4131                 }
4132         },
4133
4134         toggle: function( fn ) {
4135                 // Save reference to arguments for access in closure
4136                 var args = arguments,
4137                         guid = fn.guid || jQuery.guid++,
4138                         i = 0,
4139                         toggler = function( event ) {
4140                                 // Figure out which function to execute
4141                                 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
4142                                 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
4143
4144                                 // Make sure that clicks stop
4145                                 event.preventDefault();
4146
4147                                 // and execute the function
4148                                 return args[ lastToggle ].apply( this, arguments ) || false;
4149                         };
4150
4151                 // link all the functions, so any of them can unbind this click handler
4152                 toggler.guid = guid;
4153                 while ( i < args.length ) {
4154                         args[ i++ ].guid = guid;
4155                 }
4156
4157                 return this.click( toggler );
4158         },
4159
4160         hover: function( fnOver, fnOut ) {
4161                 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
4162         }
4163 });
4164
4165 var liveMap = {
4166         focus: "focusin",
4167         blur: "focusout",
4168         mouseenter: "mouseover",
4169         mouseleave: "mouseout"
4170 };
4171
4172 jQuery.each(["live", "die"], function( i, name ) {
4173         jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
4174                 var type, i = 0, match, namespaces, preType,
4175                         selector = origSelector || this.selector,
4176                         context = origSelector ? this : jQuery( this.context );
4177
4178                 if ( typeof types === "object" && !types.preventDefault ) {
4179                         for ( var key in types ) {
4180                                 context[ name ]( key, data, types[key], selector );
4181                         }
4182
4183                         return this;
4184                 }
4185
4186                 if ( name === "die" && !types &&
4187                                         origSelector && origSelector.charAt(0) === "." ) {
4188
4189                         context.unbind( origSelector );
4190
4191                         return this;
4192                 }
4193
4194                 if ( data === false || jQuery.isFunction( data ) ) {
4195                         fn = data || returnFalse;
4196                         data = undefined;
4197                 }
4198
4199                 types = (types || "").split(" ");
4200
4201                 while ( (type = types[ i++ ]) != null ) {
4202                         match = rnamespaces.exec( type );
4203                         namespaces = "";
4204
4205                         if ( match )  {
4206                                 namespaces = match[0];
4207                                 type = type.replace( rnamespaces, "" );
4208                         }
4209
4210                         if ( type === "hover" ) {
4211                                 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
4212                                 continue;
4213                         }
4214
4215                         preType = type;
4216
4217                         if ( liveMap[ type ] ) {
4218                                 types.push( liveMap[ type ] + namespaces );
4219                                 type = type + namespaces;
4220
4221                         } else {
4222                                 type = (liveMap[ type ] || type) + namespaces;
4223                         }
4224
4225                         if ( name === "live" ) {
4226                                 // bind live handler
4227                                 for ( var j = 0, l = context.length; j < l; j++ ) {
4228                                         jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
4229                                                 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
4230                                 }
4231
4232                         } else {
4233                                 // unbind live handler
4234                                 context.unbind( "live." + liveConvert( type, selector ), fn );
4235                         }
4236                 }
4237
4238                 return this;
4239         };
4240 });
4241
4242 function liveHandler( event ) {
4243         var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
4244                 elems = [],
4245                 selectors = [],
4246                 events = jQuery._data( this, "events" );
4247
4248         // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
4249         if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
4250                 return;
4251         }
4252
4253         if ( event.namespace ) {
4254                 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
4255         }
4256
4257         event.liveFired = this;
4258
4259         var live = events.live.slice(0);
4260
4261         for ( j = 0; j < live.length; j++ ) {
4262                 handleObj = live[j];
4263
4264                 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
4265                         selectors.push( handleObj.selector );
4266
4267                 } else {
4268                         live.splice( j--, 1 );
4269                 }
4270         }
4271
4272         match = jQuery( event.target ).closest( selectors, event.currentTarget );
4273
4274         for ( i = 0, l = match.length; i < l; i++ ) {
4275                 close = match[i];
4276
4277                 for ( j = 0; j < live.length; j++ ) {
4278                         handleObj = live[j];
4279
4280                         if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
4281                                 elem = close.elem;
4282                                 related = null;
4283
4284                                 // Those two events require additional checking
4285                                 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
4286                                         event.type = handleObj.preType;
4287                                         related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
4288
4289                                         // Make sure not to accidentally match a child element with the same selector
4290                                         if ( related && jQuery.contains( elem, related ) ) {
4291                                                 related = elem;
4292                                         }
4293                                 }
4294
4295                                 if ( !related || related !== elem ) {
4296                                         elems.push({ elem: elem, handleObj: handleObj, level: close.level });
4297                                 }
4298                         }
4299                 }
4300         }
4301
4302         for ( i = 0, l = elems.length; i < l; i++ ) {
4303                 match = elems[i];
4304
4305                 if ( maxLevel && match.level > maxLevel ) {
4306                         break;
4307                 }
4308
4309                 event.currentTarget = match.elem;
4310                 event.data = match.handleObj.data;
4311                 event.handleObj = match.handleObj;
4312
4313                 ret = match.handleObj.origHandler.apply( match.elem, arguments );
4314
4315                 if ( ret === false || event.isPropagationStopped() ) {
4316                         maxLevel = match.level;
4317
4318                         if ( ret === false ) {
4319                                 stop = false;
4320                         }
4321                         if ( event.isImmediatePropagationStopped() ) {
4322                                 break;
4323                         }
4324                 }
4325         }
4326
4327         return stop;
4328 }
4329
4330 function liveConvert( type, selector ) {
4331         return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
4332 }
4333
4334 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
4335         "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
4336         "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
4337
4338         // Handle event binding
4339         jQuery.fn[ name ] = function( data, fn ) {
4340                 if ( fn == null ) {
4341                         fn = data;
4342                         data = null;
4343                 }
4344
4345                 return arguments.length > 0 ?
4346                         this.bind( name, data, fn ) :
4347                         this.trigger( name );
4348         };
4349
4350         if ( jQuery.attrFn ) {
4351                 jQuery.attrFn[ name ] = true;
4352         }
4353 });
4354
4355
4356
4357 /*!
4358  * Sizzle CSS Selector Engine
4359  *  Copyright 2011, The Dojo Foundation
4360  *  Released under the MIT, BSD, and GPL Licenses.
4361  *  More information: http://sizzlejs.com/
4362  */
4363 (function(){
4364
4365 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
4366         done = 0,
4367         toString = Object.prototype.toString,
4368         hasDuplicate = false,
4369         baseHasDuplicate = true,
4370         rBackslash = /\\/g,
4371         rNonWord = /\W/;
4372
4373 // Here we check if the JavaScript engine is using some sort of
4374 // optimization where it does not always call our comparision
4375 // function. If that is the case, discard the hasDuplicate value.
4376 //   Thus far that includes Google Chrome.
4377 [0, 0].sort(function() {
4378         baseHasDuplicate = false;
4379         return 0;
4380 });
4381
4382 var Sizzle = function( selector, context, results, seed ) {
4383         results = results || [];
4384         context = context || document;
4385
4386         var origContext = context;
4387
4388         if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
4389                 return [];
4390         }
4391         
4392         if ( !selector || typeof selector !== "string" ) {
4393                 return results;
4394         }
4395
4396         var m, set, checkSet, extra, ret, cur, pop, i,
4397                 prune = true,
4398                 contextXML = Sizzle.isXML( context ),
4399                 parts = [],
4400                 soFar = selector;
4401         
4402         // Reset the position of the chunker regexp (start from head)
4403         do {
4404                 chunker.exec( "" );
4405                 m = chunker.exec( soFar );
4406
4407                 if ( m ) {
4408                         soFar = m[3];
4409                 
4410                         parts.push( m[1] );
4411                 
4412                         if ( m[2] ) {
4413                                 extra = m[3];
4414                                 break;
4415                         }
4416                 }
4417         } while ( m );
4418
4419         if ( parts.length > 1 && origPOS.exec( selector ) ) {
4420
4421                 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4422                         set = posProcess( parts[0] + parts[1], context );
4423
4424                 } else {
4425                         set = Expr.relative[ parts[0] ] ?
4426                                 [ context ] :
4427                                 Sizzle( parts.shift(), context );
4428
4429                         while ( parts.length ) {
4430                                 selector = parts.shift();
4431
4432                                 if ( Expr.relative[ selector ] ) {
4433                                         selector += parts.shift();
4434                                 }
4435                                 
4436                                 set = posProcess( selector, set );
4437                         }
4438                 }
4439
4440         } else {
4441                 // Take a shortcut and set the context if the root selector is an ID
4442                 // (but not if it'll be faster if the inner selector is an ID)
4443                 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4444                                 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4445
4446                         ret = Sizzle.find( parts.shift(), context, contextXML );
4447                         context = ret.expr ?
4448                                 Sizzle.filter( ret.expr, ret.set )[0] :
4449                                 ret.set[0];
4450                 }
4451
4452                 if ( context ) {
4453                         ret = seed ?
4454                                 { expr: parts.pop(), set: makeArray(seed) } :
4455                                 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4456
4457                         set = ret.expr ?
4458                                 Sizzle.filter( ret.expr, ret.set ) :
4459                                 ret.set;
4460
4461                         if ( parts.length > 0 ) {
4462                                 checkSet = makeArray( set );
4463
4464                         } else {
4465                                 prune = false;
4466                         }
4467
4468                         while ( parts.length ) {
4469                                 cur = parts.pop();
4470                                 pop = cur;
4471
4472                                 if ( !Expr.relative[ cur ] ) {
4473                                         cur = "";
4474                                 } else {
4475                                         pop = parts.pop();
4476                                 }
4477
4478                                 if ( pop == null ) {
4479                                         pop = context;
4480                                 }
4481
4482                                 Expr.relative[ cur ]( checkSet, pop, contextXML );
4483                         }
4484
4485                 } else {
4486                         checkSet = parts = [];
4487                 }
4488         }
4489
4490         if ( !checkSet ) {
4491                 checkSet = set;
4492         }
4493
4494         if ( !checkSet ) {
4495                 Sizzle.error( cur || selector );
4496         }
4497
4498         if ( toString.call(checkSet) === "[object Array]" ) {
4499                 if ( !prune ) {
4500                         results.push.apply( results, checkSet );
4501
4502                 } else if ( context && context.nodeType === 1 ) {
4503                         for ( i = 0; checkSet[i] != null; i++ ) {
4504                                 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
4505                                         results.push( set[i] );
4506                                 }
4507                         }
4508
4509                 } else {
4510                         for ( i = 0; checkSet[i] != null; i++ ) {
4511                                 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4512                                         results.push( set[i] );
4513                                 }
4514                         }
4515                 }
4516
4517         } else {
4518                 makeArray( checkSet, results );
4519         }
4520
4521         if ( extra ) {
4522                 Sizzle( extra, origContext, results, seed );
4523                 Sizzle.uniqueSort( results );
4524         }
4525
4526         return results;
4527 };
4528
4529 Sizzle.uniqueSort = function( results ) {
4530         if ( sortOrder ) {
4531                 hasDuplicate = baseHasDuplicate;
4532                 results.sort( sortOrder );
4533
4534                 if ( hasDuplicate ) {
4535                         for ( var i = 1; i < results.length; i++ ) {
4536                                 if ( results[i] === results[ i - 1 ] ) {
4537                                         results.splice( i--, 1 );
4538                                 }
4539                         }
4540                 }
4541         }
4542
4543         return results;
4544 };
4545
4546 Sizzle.matches = function( expr, set ) {
4547         return Sizzle( expr, null, null, set );
4548 };
4549
4550 Sizzle.matchesSelector = function( node, expr ) {
4551         return Sizzle( expr, null, null, [node] ).length > 0;
4552 };
4553
4554 Sizzle.find = function( expr, context, isXML ) {
4555         var set;
4556
4557         if ( !expr ) {
4558                 return [];
4559         }
4560
4561         for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4562                 var match,
4563                         type = Expr.order[i];
4564                 
4565                 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4566                         var left = match[1];
4567                         match.splice( 1, 1 );
4568
4569                         if ( left.substr( left.length - 1 ) !== "\\" ) {
4570                                 match[1] = (match[1] || "").replace( rBackslash, "" );
4571                                 set = Expr.find[ type ]( match, context, isXML );
4572
4573                                 if ( set != null ) {
4574                                         expr = expr.replace( Expr.match[ type ], "" );
4575                                         break;
4576                                 }
4577                         }
4578                 }
4579         }
4580
4581         if ( !set ) {
4582                 set = typeof context.getElementsByTagName !== "undefined" ?
4583                         context.getElementsByTagName( "*" ) :
4584                         [];
4585         }
4586
4587         return { set: set, expr: expr };
4588 };
4589
4590 Sizzle.filter = function( expr, set, inplace, not ) {
4591         var match, anyFound,
4592                 old = expr,
4593                 result = [],
4594                 curLoop = set,
4595                 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4596
4597         while ( expr && set.length ) {
4598                 for ( var type in Expr.filter ) {
4599                         if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4600                                 var found, item,
4601                                         filter = Expr.filter[ type ],
4602                                         left = match[1];
4603
4604                                 anyFound = false;
4605
4606                                 match.splice(1,1);
4607
4608                                 if ( left.substr( left.length - 1 ) === "\\" ) {
4609                                         continue;
4610                                 }
4611
4612                                 if ( curLoop === result ) {
4613                                         result = [];
4614                                 }
4615
4616                                 if ( Expr.preFilter[ type ] ) {
4617                                         match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4618
4619                                         if ( !match ) {
4620                                                 anyFound = found = true;
4621
4622                                         } else if ( match === true ) {
4623                                                 continue;
4624                                         }
4625                                 }
4626
4627                                 if ( match ) {
4628                                         for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4629                                                 if ( item ) {
4630                                                         found = filter( item, match, i, curLoop );
4631                                                         var pass = not ^ !!found;
4632
4633                                                         if ( inplace && found != null ) {
4634                                                                 if ( pass ) {
4635                                                                         anyFound = true;
4636
4637                                                                 } else {
4638                                                                         curLoop[i] = false;
4639                                                                 }
4640
4641                                                         } else if ( pass ) {
4642                                                                 result.push( item );
4643                                                                 anyFound = true;
4644                                                         }
4645                                                 }
4646                                         }
4647                                 }
4648
4649                                 if ( found !== undefined ) {
4650                                         if ( !inplace ) {
4651                                                 curLoop = result;
4652                                         }
4653
4654                                         expr = expr.replace( Expr.match[ type ], "" );
4655
4656                                         if ( !anyFound ) {
4657                                                 return [];
4658                                         }
4659
4660                                         break;
4661                                 }
4662                         }
4663                 }
4664
4665                 // Improper expression
4666                 if ( expr === old ) {
4667                         if ( anyFound == null ) {
4668                                 Sizzle.error( expr );
4669
4670                         } else {
4671                                 break;
4672                         }
4673                 }
4674
4675                 old = expr;
4676         }
4677
4678         return curLoop;
4679 };
4680
4681 Sizzle.error = function( msg ) {
4682         throw "Syntax error, unrecognized expression: " + msg;
4683 };
4684
4685 var Expr = Sizzle.selectors = {
4686         order: [ "ID", "NAME", "TAG" ],
4687
4688         match: {
4689                 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4690                 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4691                 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4692                 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4693                 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4694                 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4695                 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4696                 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4697         },
4698
4699         leftMatch: {},
4700
4701         attrMap: {
4702                 "class": "className",
4703                 "for": "htmlFor"
4704         },
4705
4706         attrHandle: {
4707                 href: function( elem ) {
4708                         return elem.getAttribute( "href" );
4709                 },
4710                 type: function( elem ) {
4711                         return elem.getAttribute( "type" );
4712                 }
4713         },
4714
4715         relative: {
4716                 "+": function(checkSet, part){
4717                         var isPartStr = typeof part === "string",
4718                                 isTag = isPartStr && !rNonWord.test( part ),
4719                                 isPartStrNotTag = isPartStr && !isTag;
4720
4721                         if ( isTag ) {
4722                                 part = part.toLowerCase();
4723                         }
4724
4725                         for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4726                                 if ( (elem = checkSet[i]) ) {
4727                                         while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4728
4729                                         checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4730                                                 elem || false :
4731                                                 elem === part;
4732                                 }
4733                         }
4734
4735                         if ( isPartStrNotTag ) {
4736                                 Sizzle.filter( part, checkSet, true );
4737                         }
4738                 },
4739
4740                 ">": function( checkSet, part ) {
4741                         var elem,
4742                                 isPartStr = typeof part === "string",
4743                                 i = 0,
4744                                 l = checkSet.length;
4745
4746                         if ( isPartStr && !rNonWord.test( part ) ) {
4747                                 part = part.toLowerCase();
4748
4749                                 for ( ; i < l; i++ ) {
4750                                         elem = checkSet[i];
4751
4752                                         if ( elem ) {
4753                                                 var parent = elem.parentNode;
4754                                                 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4755                                         }
4756                                 }
4757
4758                         } else {
4759                                 for ( ; i < l; i++ ) {
4760                                         elem = checkSet[i];
4761
4762                                         if ( elem ) {
4763                                                 checkSet[i] = isPartStr ?
4764                                                         elem.parentNode :
4765                                                         elem.parentNode === part;
4766                                         }
4767                                 }
4768
4769                                 if ( isPartStr ) {
4770                                         Sizzle.filter( part, checkSet, true );
4771                                 }
4772                         }
4773                 },
4774
4775                 "": function(checkSet, part, isXML){
4776                         var nodeCheck,
4777                                 doneName = done++,
4778                                 checkFn = dirCheck;
4779
4780                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4781                                 part = part.toLowerCase();
4782                                 nodeCheck = part;
4783                                 checkFn = dirNodeCheck;
4784                         }
4785
4786                         checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4787                 },
4788
4789                 "~": function( checkSet, part, isXML ) {
4790                         var nodeCheck,
4791                                 doneName = done++,
4792                                 checkFn = dirCheck;
4793
4794                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4795                                 part = part.toLowerCase();
4796                                 nodeCheck = part;
4797                                 checkFn = dirNodeCheck;
4798                         }
4799
4800                         checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4801                 }
4802         },
4803
4804         find: {
4805                 ID: function( match, context, isXML ) {
4806                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
4807                                 var m = context.getElementById(match[1]);
4808                                 // Check parentNode to catch when Blackberry 4.6 returns
4809                                 // nodes that are no longer in the document #6963
4810                                 return m && m.parentNode ? [m] : [];
4811                         }
4812                 },
4813
4814                 NAME: function( match, context ) {
4815                         if ( typeof context.getElementsByName !== "undefined" ) {
4816                                 var ret = [],
4817                                         results = context.getElementsByName( match[1] );
4818
4819                                 for ( var i = 0, l = results.length; i < l; i++ ) {
4820                                         if ( results[i].getAttribute("name") === match[1] ) {
4821                                                 ret.push( results[i] );
4822                                         }
4823                                 }
4824
4825                                 return ret.length === 0 ? null : ret;
4826                         }
4827                 },
4828
4829                 TAG: function( match, context ) {
4830                         if ( typeof context.getElementsByTagName !== "undefined" ) {
4831                                 return context.getElementsByTagName( match[1] );
4832                         }
4833                 }
4834         },
4835         preFilter: {
4836                 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4837                         match = " " + match[1].replace( rBackslash, "" ) + " ";
4838
4839                         if ( isXML ) {
4840                                 return match;
4841                         }
4842
4843                         for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4844                                 if ( elem ) {
4845                                         if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4846                                                 if ( !inplace ) {
4847                                                         result.push( elem );
4848                                                 }
4849
4850                                         } else if ( inplace ) {
4851                                                 curLoop[i] = false;
4852                                         }
4853                                 }
4854                         }
4855
4856                         return false;
4857                 },
4858
4859                 ID: function( match ) {
4860                         return match[1].replace( rBackslash, "" );
4861                 },
4862
4863                 TAG: function( match, curLoop ) {
4864                         return match[1].replace( rBackslash, "" ).toLowerCase();
4865                 },
4866
4867                 CHILD: function( match ) {
4868                         if ( match[1] === "nth" ) {
4869                                 if ( !match[2] ) {
4870                                         Sizzle.error( match[0] );
4871                                 }
4872
4873                                 match[2] = match[2].replace(/^\+|\s*/g, '');
4874
4875                                 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4876                                 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4877                                         match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4878                                         !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4879
4880                                 // calculate the numbers (first)n+(last) including if they are negative
4881                                 match[2] = (test[1] + (test[2] || 1)) - 0;
4882                                 match[3] = test[3] - 0;
4883                         }
4884                         else if ( match[2] ) {
4885                                 Sizzle.error( match[0] );
4886                         }
4887
4888                         // TODO: Move to normal caching system
4889                         match[0] = done++;
4890
4891                         return match;
4892                 },
4893
4894                 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4895                         var name = match[1] = match[1].replace( rBackslash, "" );
4896                         
4897                         if ( !isXML && Expr.attrMap[name] ) {
4898                                 match[1] = Expr.attrMap[name];
4899                         }
4900
4901                         // Handle if an un-quoted value was used
4902                         match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4903
4904                         if ( match[2] === "~=" ) {
4905                                 match[4] = " " + match[4] + " ";
4906                         }
4907
4908                         return match;
4909                 },
4910
4911                 PSEUDO: function( match, curLoop, inplace, result, not ) {
4912                         if ( match[1] === "not" ) {
4913                                 // If we're dealing with a complex expression, or a simple one
4914                                 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4915                                         match[3] = Sizzle(match[3], null, null, curLoop);
4916
4917                                 } else {
4918                                         var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4919
4920                                         if ( !inplace ) {
4921                                                 result.push.apply( result, ret );
4922                                         }
4923
4924                                         return false;
4925                                 }
4926
4927                         } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4928                                 return true;
4929                         }
4930                         
4931                         return match;
4932                 },
4933
4934                 POS: function( match ) {
4935                         match.unshift( true );
4936
4937                         return match;
4938                 }
4939         },
4940         
4941         filters: {
4942                 enabled: function( elem ) {
4943                         return elem.disabled === false && elem.type !== "hidden";
4944                 },
4945
4946                 disabled: function( elem ) {
4947                         return elem.disabled === true;
4948                 },
4949
4950                 checked: function( elem ) {
4951                         return elem.checked === true;
4952                 },
4953                 
4954                 selected: function( elem ) {
4955                         // Accessing this property makes selected-by-default
4956                         // options in Safari work properly
4957                         if ( elem.parentNode ) {
4958                                 elem.parentNode.selectedIndex;
4959                         }
4960                         
4961                         return elem.selected === true;
4962                 },
4963
4964                 parent: function( elem ) {
4965                         return !!elem.firstChild;
4966                 },
4967
4968                 empty: function( elem ) {
4969                         return !elem.firstChild;
4970                 },
4971
4972                 has: function( elem, i, match ) {
4973                         return !!Sizzle( match[3], elem ).length;
4974                 },
4975
4976                 header: function( elem ) {
4977                         return (/h\d/i).test( elem.nodeName );
4978                 },
4979
4980                 text: function( elem ) {
4981                         var attr = elem.getAttribute( "type" ), type = elem.type;
4982                         // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 
4983                         // use getAttribute instead to test this case
4984                         return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4985                 },
4986
4987                 radio: function( elem ) {
4988                         return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4989                 },
4990
4991                 checkbox: function( elem ) {
4992                         return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4993                 },
4994
4995                 file: function( elem ) {
4996                         return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4997                 },
4998
4999                 password: function( elem ) {
5000                         return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
5001                 },
5002
5003                 submit: function( elem ) {
5004                         var name = elem.nodeName.toLowerCase();
5005                         return (name === "input" || name === "button") && "submit" === elem.type;
5006                 },
5007
5008                 image: function( elem ) {
5009                         return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
5010                 },
5011
5012                 reset: function( elem ) {
5013                         return elem.nodeName.toLowerCase() === "input" && "reset" === elem.type;
5014                 },
5015
5016                 button: function( elem ) {
5017                         var name = elem.nodeName.toLowerCase();
5018                         return name === "input" && "button" === elem.type || name === "button";
5019                 },
5020
5021                 input: function( elem ) {
5022                         return (/input|select|textarea|button/i).test( elem.nodeName );
5023                 },
5024
5025                 focus: function( elem ) {
5026                         return elem === elem.ownerDocument.activeElement;
5027                 }
5028         },
5029         setFilters: {
5030                 first: function( elem, i ) {
5031                         return i === 0;
5032                 },
5033
5034                 last: function( elem, i, match, array ) {
5035                         return i === array.length - 1;
5036                 },
5037
5038                 even: function( elem, i ) {
5039                         return i % 2 === 0;
5040                 },
5041
5042                 odd: function( elem, i ) {
5043                         return i % 2 === 1;
5044                 },
5045
5046                 lt: function( elem, i, match ) {
5047                         return i < match[3] - 0;
5048                 },
5049
5050                 gt: function( elem, i, match ) {
5051                         return i > match[3] - 0;
5052                 },
5053
5054                 nth: function( elem, i, match ) {
5055                         return match[3] - 0 === i;
5056                 },
5057
5058                 eq: function( elem, i, match ) {
5059                         return match[3] - 0 === i;
5060                 }
5061         },
5062         filter: {
5063                 PSEUDO: function( elem, match, i, array ) {
5064                         var name = match[1],
5065                                 filter = Expr.filters[ name ];
5066
5067                         if ( filter ) {
5068                                 return filter( elem, i, match, array );
5069
5070                         } else if ( name === "contains" ) {
5071                                 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
5072
5073                         } else if ( name === "not" ) {
5074                                 var not = match[3];
5075
5076                                 for ( var j = 0, l = not.length; j < l; j++ ) {
5077                                         if ( not[j] === elem ) {
5078                                                 return false;
5079                                         }
5080                                 }
5081
5082                                 return true;
5083
5084                         } else {
5085                                 Sizzle.error( name );
5086                         }
5087                 },
5088
5089                 CHILD: function( elem, match ) {
5090                         var type = match[1],
5091                                 node = elem;
5092
5093                         switch ( type ) {
5094                                 case "only":
5095                                 case "first":
5096                                         while ( (node = node.previousSibling) )  {
5097                                                 if ( node.nodeType === 1 ) { 
5098                                                         return false; 
5099                                                 }
5100                                         }
5101
5102                                         if ( type === "first" ) { 
5103                                                 return true; 
5104                                         }
5105
5106                                         node = elem;
5107
5108                                 case "last":
5109                                         while ( (node = node.nextSibling) )      {
5110                                                 if ( node.nodeType === 1 ) { 
5111                                                         return false; 
5112                                                 }
5113                                         }
5114
5115                                         return true;
5116
5117                                 case "nth":
5118                                         var first = match[2],
5119                                                 last = match[3];
5120
5121                                         if ( first === 1 && last === 0 ) {
5122                                                 return true;
5123                                         }
5124                                         
5125                                         var doneName = match[0],
5126                                                 parent = elem.parentNode;
5127         
5128                                         if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
5129                                                 var count = 0;
5130                                                 
5131                                                 for ( node = parent.firstChild; node; node = node.nextSibling ) {
5132                                                         if ( node.nodeType === 1 ) {
5133                                                                 node.nodeIndex = ++count;
5134                                                         }
5135                                                 } 
5136
5137                                                 parent.sizcache = doneName;
5138                                         }
5139                                         
5140                                         var diff = elem.nodeIndex - last;
5141
5142                                         if ( first === 0 ) {
5143                                                 return diff === 0;
5144
5145                                         } else {
5146                                                 return ( diff % first === 0 && diff / first >= 0 );
5147                                         }
5148                         }
5149                 },
5150
5151                 ID: function( elem, match ) {
5152                         return elem.nodeType === 1 && elem.getAttribute("id") === match;
5153                 },
5154
5155                 TAG: function( elem, match ) {
5156                         return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
5157                 },
5158                 
5159                 CLASS: function( elem, match ) {
5160                         return (" " + (elem.className || elem.getAttribute("class")) + " ")
5161                                 .indexOf( match ) > -1;
5162                 },
5163
5164                 ATTR: function( elem, match ) {
5165                         var name = match[1],
5166                                 result = Expr.attrHandle[ name ] ?
5167                                         Expr.attrHandle[ name ]( elem ) :
5168                                         elem[ name ] != null ?
5169                                                 elem[ name ] :
5170                                                 elem.getAttribute( name ),
5171                                 value = result + "",
5172                                 type = match[2],
5173                                 check = match[4];
5174
5175                         return result == null ?
5176                                 type === "!=" :
5177                                 type === "=" ?
5178                                 value === check :
5179                                 type === "*=" ?
5180                                 value.indexOf(check) >= 0 :
5181                                 type === "~=" ?
5182                                 (" " + value + " ").indexOf(check) >= 0 :
5183                                 !check ?
5184                                 value && result !== false :
5185                                 type === "!=" ?
5186                                 value !== check :
5187                                 type === "^=" ?
5188                                 value.indexOf(check) === 0 :
5189                                 type === "$=" ?
5190                                 value.substr(value.length - check.length) === check :
5191                                 type === "|=" ?
5192                                 value === check || value.substr(0, check.length + 1) === check + "-" :
5193                                 false;
5194                 },
5195
5196                 POS: function( elem, match, i, array ) {
5197                         var name = match[2],
5198                                 filter = Expr.setFilters[ name ];
5199
5200                         if ( filter ) {
5201                                 return filter( elem, i, match, array );
5202                         }
5203                 }
5204         }
5205 };
5206
5207 var origPOS = Expr.match.POS,
5208         fescape = function(all, num){
5209                 return "\\" + (num - 0 + 1);
5210         };
5211
5212 for ( var type in Expr.match ) {
5213         Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
5214         Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
5215 }
5216
5217 var makeArray = function( array, results ) {
5218         array = Array.prototype.slice.call( array, 0 );
5219
5220         if ( results ) {
5221                 results.push.apply( results, array );
5222                 return results;
5223         }
5224         
5225         return array;
5226 };
5227
5228 // Perform a simple check to determine if the browser is capable of
5229 // converting a NodeList to an array using builtin methods.
5230 // Also verifies that the returned array holds DOM nodes
5231 // (which is not the case in the Blackberry browser)
5232 try {
5233         Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
5234
5235 // Provide a fallback method if it does not work
5236 } catch( e ) {
5237         makeArray = function( array, results ) {
5238                 var i = 0,
5239                         ret = results || [];
5240
5241                 if ( toString.call(array) === "[object Array]" ) {
5242                         Array.prototype.push.apply( ret, array );
5243
5244                 } else {
5245                         if ( typeof array.length === "number" ) {
5246                                 for ( var l = array.length; i < l; i++ ) {
5247                                         ret.push( array[i] );
5248                                 }
5249
5250                         } else {
5251                                 for ( ; array[i]; i++ ) {
5252                                         ret.push( array[i] );
5253                                 }
5254                         }
5255                 }
5256
5257                 return ret;
5258         };
5259 }
5260
5261 var sortOrder, siblingCheck;
5262
5263 if ( document.documentElement.compareDocumentPosition ) {
5264         sortOrder = function( a, b ) {
5265                 if ( a === b ) {
5266                         hasDuplicate = true;
5267                         return 0;
5268                 }
5269
5270                 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
5271                         return a.compareDocumentPosition ? -1 : 1;
5272                 }
5273
5274                 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
5275         };
5276
5277 } else {
5278         sortOrder = function( a, b ) {
5279                 var al, bl,
5280                         ap = [],
5281                         bp = [],
5282                         aup = a.parentNode,
5283                         bup = b.parentNode,
5284                         cur = aup;
5285
5286                 // The nodes are identical, we can exit early
5287                 if ( a === b ) {
5288                         hasDuplicate = true;
5289                         return 0;
5290
5291                 // If the nodes are siblings (or identical) we can do a quick check
5292                 } else if ( aup === bup ) {
5293                         return siblingCheck( a, b );
5294
5295                 // If no parents were found then the nodes are disconnected
5296                 } else if ( !aup ) {
5297                         return -1;
5298
5299                 } else if ( !bup ) {
5300                         return 1;
5301                 }
5302
5303                 // Otherwise they're somewhere else in the tree so we need
5304                 // to build up a full list of the parentNodes for comparison
5305                 while ( cur ) {
5306                         ap.unshift( cur );
5307                         cur = cur.parentNode;
5308                 }
5309
5310                 cur = bup;
5311
5312                 while ( cur ) {
5313                         bp.unshift( cur );
5314                         cur = cur.parentNode;
5315                 }
5316
5317                 al = ap.length;
5318                 bl = bp.length;
5319
5320                 // Start walking down the tree looking for a discrepancy
5321                 for ( var i = 0; i < al && i < bl; i++ ) {
5322                         if ( ap[i] !== bp[i] ) {
5323                                 return siblingCheck( ap[i], bp[i] );
5324                         }
5325                 }
5326
5327                 // We ended someplace up the tree so do a sibling check
5328                 return i === al ?
5329                         siblingCheck( a, bp[i], -1 ) :
5330                         siblingCheck( ap[i], b, 1 );
5331         };
5332
5333         siblingCheck = function( a, b, ret ) {
5334                 if ( a === b ) {
5335                         return ret;
5336                 }
5337
5338                 var cur = a.nextSibling;
5339
5340                 while ( cur ) {
5341                         if ( cur === b ) {
5342                                 return -1;
5343                         }
5344
5345                         cur = cur.nextSibling;
5346                 }
5347
5348                 return 1;
5349         };
5350 }
5351
5352 // Utility function for retreiving the text value of an array of DOM nodes
5353 Sizzle.getText = function( elems ) {
5354         var ret = "", elem;
5355
5356         for ( var i = 0; elems[i]; i++ ) {
5357                 elem = elems[i];
5358
5359                 // Get the text from text nodes and CDATA nodes
5360                 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
5361                         ret += elem.nodeValue;
5362
5363                 // Traverse everything else, except comment nodes
5364                 } else if ( elem.nodeType !== 8 ) {
5365                         ret += Sizzle.getText( elem.childNodes );
5366                 }
5367         }
5368
5369         return ret;
5370 };
5371
5372 // Check to see if the browser returns elements by name when
5373 // querying by getElementById (and provide a workaround)
5374 (function(){
5375         // We're going to inject a fake input element with a specified name
5376         var form = document.createElement("div"),
5377                 id = "script" + (new Date()).getTime(),
5378                 root = document.documentElement;
5379
5380         form.innerHTML = "<a name='" + id + "'/>";
5381
5382         // Inject it into the root element, check its status, and remove it quickly
5383         root.insertBefore( form, root.firstChild );
5384
5385         // The workaround has to do additional checks after a getElementById
5386         // Which slows things down for other browsers (hence the branching)
5387         if ( document.getElementById( id ) ) {
5388                 Expr.find.ID = function( match, context, isXML ) {
5389                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
5390                                 var m = context.getElementById(match[1]);
5391
5392                                 return m ?
5393                                         m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
5394                                                 [m] :
5395                                                 undefined :
5396                                         [];
5397                         }
5398                 };
5399
5400                 Expr.filter.ID = function( elem, match ) {
5401                         var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
5402
5403                         return elem.nodeType === 1 && node && node.nodeValue === match;
5404                 };
5405         }
5406
5407         root.removeChild( form );
5408
5409         // release memory in IE
5410         root = form = null;
5411 })();
5412
5413 (function(){
5414         // Check to see if the browser returns only elements
5415         // when doing getElementsByTagName("*")
5416
5417         // Create a fake element
5418         var div = document.createElement("div");
5419         div.appendChild( document.createComment("") );
5420
5421         // Make sure no comments are found
5422         if ( div.getElementsByTagName("*").length > 0 ) {
5423                 Expr.find.TAG = function( match, context ) {
5424                         var results = context.getElementsByTagName( match[1] );
5425
5426                         // Filter out possible comments
5427                         if ( match[1] === "*" ) {
5428                                 var tmp = [];
5429
5430                                 for ( var i = 0; results[i]; i++ ) {
5431                                         if ( results[i].nodeType === 1 ) {
5432                                                 tmp.push( results[i] );
5433                                         }
5434                                 }
5435
5436                                 results = tmp;
5437                         }
5438
5439                         return results;
5440                 };
5441         }
5442
5443         // Check to see if an attribute returns normalized href attributes
5444         div.innerHTML = "<a href='#'></a>";
5445
5446         if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
5447                         div.firstChild.getAttribute("href") !== "#" ) {
5448
5449                 Expr.attrHandle.href = function( elem ) {
5450                         return elem.getAttribute( "href", 2 );
5451                 };
5452         }
5453
5454         // release memory in IE
5455         div = null;
5456 })();
5457
5458 if ( document.querySelectorAll ) {
5459         (function(){
5460                 var oldSizzle = Sizzle,
5461                         div = document.createElement("div"),
5462                         id = "__sizzle__";
5463
5464                 div.innerHTML = "<p class='TEST'></p>";
5465
5466                 // Safari can't handle uppercase or unicode characters when
5467                 // in quirks mode.
5468                 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
5469                         return;
5470                 }
5471         
5472                 Sizzle = function( query, context, extra, seed ) {
5473                         context = context || document;
5474
5475                         // Only use querySelectorAll on non-XML documents
5476                         // (ID selectors don't work in non-HTML documents)
5477                         if ( !seed && !Sizzle.isXML(context) ) {
5478                                 // See if we find a selector to speed up
5479                                 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
5480                                 
5481                                 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
5482                                         // Speed-up: Sizzle("TAG")
5483                                         if ( match[1] ) {
5484                                                 return makeArray( context.getElementsByTagName( query ), extra );
5485                                         
5486                                         // Speed-up: Sizzle(".CLASS")
5487                                         } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
5488                                                 return makeArray( context.getElementsByClassName( match[2] ), extra );
5489                                         }
5490                                 }
5491                                 
5492                                 if ( context.nodeType === 9 ) {
5493                                         // Speed-up: Sizzle("body")
5494                                         // The body element only exists once, optimize finding it
5495                                         if ( query === "body" && context.body ) {
5496                                                 return makeArray( [ context.body ], extra );
5497                                                 
5498                                         // Speed-up: Sizzle("#ID")
5499                                         } else if ( match && match[3] ) {
5500                                                 var elem = context.getElementById( match[3] );
5501
5502                                                 // Check parentNode to catch when Blackberry 4.6 returns
5503                                                 // nodes that are no longer in the document #6963
5504                                                 if ( elem && elem.parentNode ) {
5505                                                         // Handle the case where IE and Opera return items
5506                                                         // by name instead of ID
5507                                                         if ( elem.id === match[3] ) {
5508                                                                 return makeArray( [ elem ], extra );
5509                                                         }
5510                                                         
5511                                                 } else {
5512                                                         return makeArray( [], extra );
5513                                                 }
5514                                         }
5515                                         
5516                                         try {
5517                                                 return makeArray( context.querySelectorAll(query), extra );
5518                                         } catch(qsaError) {}
5519
5520                                 // qSA works strangely on Element-rooted queries
5521                                 // We can work around this by specifying an extra ID on the root
5522                                 // and working up from there (Thanks to Andrew Dupont for the technique)
5523                                 // IE 8 doesn't work on object elements
5524                                 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5525                                         var oldContext = context,
5526                                                 old = context.getAttribute( "id" ),
5527                                                 nid = old || id,
5528                                                 hasParent = context.parentNode,
5529                                                 relativeHierarchySelector = /^\s*[+~]/.test( query );
5530
5531                                         if ( !old ) {
5532                                                 context.setAttribute( "id", nid );
5533                                         } else {
5534                                                 nid = nid.replace( /'/g, "\\$&" );
5535                                         }
5536                                         if ( relativeHierarchySelector && hasParent ) {
5537                                                 context = context.parentNode;
5538                                         }
5539
5540                                         try {
5541                                                 if ( !relativeHierarchySelector || hasParent ) {
5542                                                         return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
5543                                                 }
5544
5545                                         } catch(pseudoError) {
5546                                         } finally {
5547                                                 if ( !old ) {
5548                                                         oldContext.removeAttribute( "id" );
5549                                                 }
5550                                         }
5551                                 }
5552                         }
5553                 
5554                         return oldSizzle(query, context, extra, seed);
5555                 };
5556
5557                 for ( var prop in oldSizzle ) {
5558                         Sizzle[ prop ] = oldSizzle[ prop ];
5559                 }
5560
5561                 // release memory in IE
5562                 div = null;
5563         })();
5564 }
5565
5566 (function(){
5567         var html = document.documentElement,
5568                 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5569
5570         if ( matches ) {
5571                 // Check to see if it's possible to do matchesSelector
5572                 // on a disconnected node (IE 9 fails this)
5573                 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5574                         pseudoWorks = false;
5575
5576                 try {
5577                         // This should fail with an exception
5578                         // Gecko does not error, returns false instead
5579                         matches.call( document.documentElement, "[test!='']:sizzle" );
5580         
5581                 } catch( pseudoError ) {
5582                         pseudoWorks = true;
5583                 }
5584
5585                 Sizzle.matchesSelector = function( node, expr ) {
5586                         // Make sure that attribute selectors are quoted
5587                         expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5588
5589                         if ( !Sizzle.isXML( node ) ) {
5590                                 try { 
5591                                         if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5592                                                 var ret = matches.call( node, expr );
5593
5594                                                 // IE 9's matchesSelector returns false on disconnected nodes
5595                                                 if ( ret || !disconnectedMatch ||
5596                                                                 // As well, disconnected nodes are said to be in a document
5597                                                                 // fragment in IE 9, so check for that
5598                                                                 node.document && node.document.nodeType !== 11 ) {
5599                                                         return ret;
5600                                                 }
5601                                         }
5602                                 } catch(e) {}
5603                         }
5604
5605                         return Sizzle(expr, null, null, [node]).length > 0;
5606                 };
5607         }
5608 })();
5609
5610 (function(){
5611         var div = document.createElement("div");
5612
5613         div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5614
5615         // Opera can't find a second classname (in 9.6)
5616         // Also, make sure that getElementsByClassName actually exists
5617         if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5618                 return;
5619         }
5620
5621         // Safari caches class attributes, doesn't catch changes (in 3.2)
5622         div.lastChild.className = "e";
5623
5624         if ( div.getElementsByClassName("e").length === 1 ) {
5625                 return;
5626         }
5627         
5628         Expr.order.splice(1, 0, "CLASS");
5629         Expr.find.CLASS = function( match, context, isXML ) {
5630                 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5631                         return context.getElementsByClassName(match[1]);
5632                 }
5633         };
5634
5635         // release memory in IE
5636         div = null;
5637 })();
5638
5639 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5640         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5641                 var elem = checkSet[i];
5642
5643                 if ( elem ) {
5644                         var match = false;
5645
5646                         elem = elem[dir];
5647
5648                         while ( elem ) {
5649                                 if ( elem.sizcache === doneName ) {
5650                                         match = checkSet[elem.sizset];
5651                                         break;
5652                                 }
5653
5654                                 if ( elem.nodeType === 1 && !isXML ){
5655                                         elem.sizcache = doneName;
5656                                         elem.sizset = i;
5657                                 }
5658
5659                                 if ( elem.nodeName.toLowerCase() === cur ) {
5660                                         match = elem;
5661                                         break;
5662                                 }
5663
5664                                 elem = elem[dir];
5665                         }
5666
5667                         checkSet[i] = match;
5668                 }
5669         }
5670 }
5671
5672 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5673         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5674                 var elem = checkSet[i];
5675
5676                 if ( elem ) {
5677                         var match = false;
5678                         
5679                         elem = elem[dir];
5680
5681                         while ( elem ) {
5682                                 if ( elem.sizcache === doneName ) {
5683                                         match = checkSet[elem.sizset];
5684                                         break;
5685                                 }
5686
5687                                 if ( elem.nodeType === 1 ) {
5688                                         if ( !isXML ) {
5689                                                 elem.sizcache = doneName;
5690                                                 elem.sizset = i;
5691                                         }
5692
5693                                         if ( typeof cur !== "string" ) {
5694                                                 if ( elem === cur ) {
5695                                                         match = true;
5696                                                         break;
5697                                                 }
5698
5699                                         } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5700                                                 match = elem;
5701                                                 break;
5702                                         }
5703                                 }
5704
5705                                 elem = elem[dir];
5706                         }
5707
5708                         checkSet[i] = match;
5709                 }
5710         }
5711 }
5712
5713 if ( document.documentElement.contains ) {
5714         Sizzle.contains = function( a, b ) {
5715                 return a !== b && (a.contains ? a.contains(b) : true);
5716         };
5717
5718 } else if ( document.documentElement.compareDocumentPosition ) {
5719         Sizzle.contains = function( a, b ) {
5720                 return !!(a.compareDocumentPosition(b) & 16);
5721         };
5722
5723 } else {
5724         Sizzle.contains = function() {
5725                 return false;
5726         };
5727 }
5728
5729 Sizzle.isXML = function( elem ) {
5730         // documentElement is verified for cases where it doesn't yet exist
5731         // (such as loading iframes in IE - #4833) 
5732         var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5733
5734         return documentElement ? documentElement.nodeName !== "HTML" : false;
5735 };
5736
5737 var posProcess = function( selector, context ) {
5738         var match,
5739                 tmpSet = [],
5740                 later = "",
5741                 root = context.nodeType ? [context] : context;
5742
5743         // Position selectors must be done after the filter
5744         // And so must :not(positional) so we move all PSEUDOs to the end
5745         while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5746                 later += match[0];
5747                 selector = selector.replace( Expr.match.PSEUDO, "" );
5748         }
5749
5750         selector = Expr.relative[selector] ? selector + "*" : selector;
5751
5752         for ( var i = 0, l = root.length; i < l; i++ ) {
5753                 Sizzle( selector, root[i], tmpSet );
5754         }
5755
5756         return Sizzle.filter( later, tmpSet );
5757 };
5758
5759 // EXPOSE
5760 jQuery.find = Sizzle;
5761 jQuery.expr = Sizzle.selectors;
5762 jQuery.expr[":"] = jQuery.expr.filters;
5763 jQuery.unique = Sizzle.uniqueSort;
5764 jQuery.text = Sizzle.getText;
5765 jQuery.isXMLDoc = Sizzle.isXML;
5766 jQuery.contains = Sizzle.contains;
5767
5768
5769 })();
5770
5771
5772 var runtil = /Until$/,
5773         rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5774         // Note: This RegExp should be improved, or likely pulled from Sizzle
5775         rmultiselector = /,/,
5776         isSimple = /^.[^:#\[\.,]*$/,
5777         slice = Array.prototype.slice,
5778         POS = jQuery.expr.match.POS,
5779         // methods guaranteed to produce a unique set when starting from a unique set
5780         guaranteedUnique = {
5781                 children: true,
5782                 contents: true,
5783                 next: true,
5784                 prev: true
5785         };
5786
5787 jQuery.fn.extend({
5788         find: function( selector ) {
5789                 var self = this,
5790                         i, l;
5791
5792                 if ( typeof selector !== "string" ) {
5793                         return jQuery( selector ).filter(function() {
5794                                 for ( i = 0, l = self.length; i < l; i++ ) {
5795                                         if ( jQuery.contains( self[ i ], this ) ) {
5796                                                 return true;
5797                                         }
5798                                 }
5799                         });
5800                 }
5801
5802                 var ret = this.pushStack( "", "find", selector ),
5803                         length, n, r;
5804
5805                 for ( i = 0, l = this.length; i < l; i++ ) {
5806                         length = ret.length;
5807                         jQuery.find( selector, this[i], ret );
5808
5809                         if ( i > 0 ) {
5810                                 // Make sure that the results are unique
5811                                 for ( n = length; n < ret.length; n++ ) {
5812                                         for ( r = 0; r < length; r++ ) {
5813                                                 if ( ret[r] === ret[n] ) {
5814                                                         ret.splice(n--, 1);
5815                                                         break;
5816                                                 }
5817                                         }
5818                                 }
5819                         }
5820                 }
5821
5822                 return ret;
5823         },
5824
5825         has: function( target ) {
5826                 var targets = jQuery( target );
5827                 return this.filter(function() {
5828                         for ( var i = 0, l = targets.length; i < l; i++ ) {
5829                                 if ( jQuery.contains( this, targets[i] ) ) {
5830                                         return true;
5831                                 }
5832                         }
5833                 });
5834         },
5835
5836         not: function( selector ) {
5837                 return this.pushStack( winnow(this, selector, false), "not", selector);
5838         },
5839
5840         filter: function( selector ) {
5841                 return this.pushStack( winnow(this, selector, true), "filter", selector );
5842         },
5843
5844         is: function( selector ) {
5845                 return !!selector && ( typeof selector === "string" ?
5846                         jQuery.filter( selector, this ).length > 0 :
5847                         this.filter( selector ).length > 0 );
5848         },
5849
5850         closest: function( selectors, context ) {
5851                 var ret = [], i, l, cur = this[0];
5852                 
5853                 // Array
5854                 if ( jQuery.isArray( selectors ) ) {
5855                         var match, selector,
5856                                 matches = {},
5857                                 level = 1;
5858
5859                         if ( cur && selectors.length ) {
5860                                 for ( i = 0, l = selectors.length; i < l; i++ ) {
5861                                         selector = selectors[i];
5862
5863                                         if ( !matches[ selector ] ) {
5864                                                 matches[ selector ] = POS.test( selector ) ?
5865                                                         jQuery( selector, context || this.context ) :
5866                                                         selector;
5867                                         }
5868                                 }
5869
5870                                 while ( cur && cur.ownerDocument && cur !== context ) {
5871                                         for ( selector in matches ) {
5872                                                 match = matches[ selector ];
5873
5874                                                 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5875                                                         ret.push({ selector: selector, elem: cur, level: level });
5876                                                 }
5877                                         }
5878
5879                                         cur = cur.parentNode;
5880                                         level++;
5881                                 }
5882                         }
5883
5884                         return ret;
5885                 }
5886
5887                 // String
5888                 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5889                                 jQuery( selectors, context || this.context ) :
5890                                 0;
5891
5892                 for ( i = 0, l = this.length; i < l; i++ ) {
5893                         cur = this[i];
5894
5895                         while ( cur ) {
5896                                 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5897                                         ret.push( cur );
5898                                         break;
5899
5900                                 } else {
5901                                         cur = cur.parentNode;
5902                                         if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5903                                                 break;
5904                                         }
5905                                 }
5906                         }
5907                 }
5908
5909                 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5910
5911                 return this.pushStack( ret, "closest", selectors );
5912         },
5913
5914         // Determine the position of an element within
5915         // the matched set of elements
5916         index: function( elem ) {
5917                 if ( !elem || typeof elem === "string" ) {
5918                         return jQuery.inArray( this[0],
5919                                 // If it receives a string, the selector is used
5920                                 // If it receives nothing, the siblings are used
5921                                 elem ? jQuery( elem ) : this.parent().children() );
5922                 }
5923                 // Locate the position of the desired element
5924                 return jQuery.inArray(
5925                         // If it receives a jQuery object, the first element is used
5926                         elem.jquery ? elem[0] : elem, this );
5927         },
5928
5929         add: function( selector, context ) {
5930                 var set = typeof selector === "string" ?
5931                                 jQuery( selector, context ) :
5932                                 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5933                         all = jQuery.merge( this.get(), set );
5934
5935                 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5936                         all :
5937                         jQuery.unique( all ) );
5938         },
5939
5940         andSelf: function() {
5941                 return this.add( this.prevObject );
5942         }
5943 });
5944
5945 // A painfully simple check to see if an element is disconnected
5946 // from a document (should be improved, where feasible).
5947 function isDisconnected( node ) {
5948         return !node || !node.parentNode || node.parentNode.nodeType === 11;
5949 }
5950
5951 jQuery.each({
5952         parent: function( elem ) {
5953                 var parent = elem.parentNode;
5954                 return parent && parent.nodeType !== 11 ? parent : null;
5955         },
5956         parents: function( elem ) {
5957                 return jQuery.dir( elem, "parentNode" );
5958         },
5959         parentsUntil: function( elem, i, until ) {
5960                 return jQuery.dir( elem, "parentNode", until );
5961         },
5962         next: function( elem ) {
5963                 return jQuery.nth( elem, 2, "nextSibling" );
5964         },
5965         prev: function( elem ) {
5966                 return jQuery.nth( elem, 2, "previousSibling" );
5967         },
5968         nextAll: function( elem ) {
5969                 return jQuery.dir( elem, "nextSibling" );
5970         },
5971         prevAll: function( elem ) {
5972                 return jQuery.dir( elem, "previousSibling" );
5973         },
5974         nextUntil: function( elem, i, until ) {
5975                 return jQuery.dir( elem, "nextSibling", until );
5976         },
5977         prevUntil: function( elem, i, until ) {
5978                 return jQuery.dir( elem, "previousSibling", until );
5979         },
5980         siblings: function( elem ) {
5981                 return jQuery.sibling( elem.parentNode.firstChild, elem );
5982         },
5983         children: function( elem ) {
5984                 return jQuery.sibling( elem.firstChild );
5985         },
5986         contents: function( elem ) {
5987                 return jQuery.nodeName( elem, "iframe" ) ?
5988                         elem.contentDocument || elem.contentWindow.document :
5989                         jQuery.makeArray( elem.childNodes );
5990         }
5991 }, function( name, fn ) {
5992         jQuery.fn[ name ] = function( until, selector ) {
5993                 var ret = jQuery.map( this, fn, until ),
5994                         // The variable 'args' was introduced in
5995                         // https://github.com/jquery/jquery/commit/52a0238
5996                         // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5997                         // http://code.google.com/p/v8/issues/detail?id=1050
5998                         args = slice.call(arguments);
5999
6000                 if ( !runtil.test( name ) ) {
6001                         selector = until;
6002                 }
6003
6004                 if ( selector && typeof selector === "string" ) {
6005                         ret = jQuery.filter( selector, ret );
6006                 }
6007
6008                 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
6009
6010                 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
6011                         ret = ret.reverse();
6012                 }
6013
6014                 return this.pushStack( ret, name, args.join(",") );
6015         };
6016 });
6017
6018 jQuery.extend({
6019         filter: function( expr, elems, not ) {
6020                 if ( not ) {
6021                         expr = ":not(" + expr + ")";
6022                 }
6023
6024                 return elems.length === 1 ?
6025                         jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
6026                         jQuery.find.matches(expr, elems);
6027         },
6028
6029         dir: function( elem, dir, until ) {
6030                 var matched = [],
6031                         cur = elem[ dir ];
6032
6033                 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
6034                         if ( cur.nodeType === 1 ) {
6035                                 matched.push( cur );
6036                         }
6037                         cur = cur[dir];
6038                 }
6039                 return matched;
6040         },
6041
6042         nth: function( cur, result, dir, elem ) {
6043                 result = result || 1;
6044                 var num = 0;
6045
6046                 for ( ; cur; cur = cur[dir] ) {
6047                         if ( cur.nodeType === 1 && ++num === result ) {
6048                                 break;
6049                         }
6050                 }
6051
6052                 return cur;
6053         },
6054
6055         sibling: function( n, elem ) {
6056                 var r = [];
6057
6058                 for ( ; n; n = n.nextSibling ) {
6059                         if ( n.nodeType === 1 && n !== elem ) {
6060                                 r.push( n );
6061                         }
6062                 }
6063
6064                 return r;
6065         }
6066 });
6067
6068 // Implement the identical functionality for filter and not
6069 function winnow( elements, qualifier, keep ) {
6070
6071         // Can't pass null or undefined to indexOf in Firefox 4
6072         // Set to 0 to skip string check
6073         qualifier = qualifier || 0;
6074
6075         if ( jQuery.isFunction( qualifier ) ) {
6076                 return jQuery.grep(elements, function( elem, i ) {
6077                         var retVal = !!qualifier.call( elem, i, elem );
6078                         return retVal === keep;
6079                 });
6080
6081         } else if ( qualifier.nodeType ) {
6082                 return jQuery.grep(elements, function( elem, i ) {
6083                         return (elem === qualifier) === keep;
6084                 });
6085
6086         } else if ( typeof qualifier === "string" ) {
6087                 var filtered = jQuery.grep(elements, function( elem ) {
6088                         return elem.nodeType === 1;
6089                 });
6090
6091                 if ( isSimple.test( qualifier ) ) {
6092                         return jQuery.filter(qualifier, filtered, !keep);
6093                 } else {
6094                         qualifier = jQuery.filter( qualifier, filtered );
6095                 }
6096         }
6097
6098         return jQuery.grep(elements, function( elem, i ) {
6099                 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
6100         });
6101 }
6102
6103
6104
6105
6106 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
6107         rleadingWhitespace = /^\s+/,
6108         rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
6109         rtagName = /<([\w:]+)/,
6110         rtbody = /<tbody/i,
6111         rhtml = /<|&#?\w+;/,
6112         rnocache = /<(?:script|object|embed|option|style)/i,
6113         // checked="checked" or checked
6114         rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
6115         rscriptType = /\/(java|ecma)script/i,
6116         wrapMap = {
6117                 option: [ 1, "<select multiple='multiple'>", "</select>" ],
6118                 legend: [ 1, "<fieldset>", "</fieldset>" ],
6119                 thead: [ 1, "<table>", "</table>" ],
6120                 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
6121                 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
6122                 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
6123                 area: [ 1, "<map>", "</map>" ],
6124                 _default: [ 0, "", "" ]
6125         };
6126
6127 wrapMap.optgroup = wrapMap.option;
6128 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
6129 wrapMap.th = wrapMap.td;
6130
6131 // IE can't serialize <link> and <script> tags normally
6132 if ( !jQuery.support.htmlSerialize ) {
6133         wrapMap._default = [ 1, "div<div>", "</div>" ];
6134 }
6135
6136 jQuery.fn.extend({
6137         text: function( text ) {
6138                 if ( jQuery.isFunction(text) ) {
6139                         return this.each(function(i) {
6140                                 var self = jQuery( this );
6141
6142                                 self.text( text.call(this, i, self.text()) );
6143                         });
6144                 }
6145
6146                 if ( typeof text !== "object" && text !== undefined ) {
6147                         return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
6148                 }
6149
6150                 return jQuery.text( this );
6151         },
6152
6153         wrapAll: function( html ) {
6154                 if ( jQuery.isFunction( html ) ) {
6155                         return this.each(function(i) {
6156                                 jQuery(this).wrapAll( html.call(this, i) );
6157                         });
6158                 }
6159
6160                 if ( this[0] ) {
6161                         // The elements to wrap the target around
6162                         var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
6163
6164                         if ( this[0].parentNode ) {
6165                                 wrap.insertBefore( this[0] );
6166                         }
6167
6168                         wrap.map(function() {
6169                                 var elem = this;
6170
6171                                 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
6172                                         elem = elem.firstChild;
6173                                 }
6174
6175                                 return elem;
6176                         }).append( this );
6177                 }
6178
6179                 return this;
6180         },
6181
6182         wrapInner: function( html ) {
6183                 if ( jQuery.isFunction( html ) ) {
6184                         return this.each(function(i) {
6185                                 jQuery(this).wrapInner( html.call(this, i) );
6186                         });
6187                 }
6188
6189                 return this.each(function() {
6190                         var self = jQuery( this ),
6191                                 contents = self.contents();
6192
6193                         if ( contents.length ) {
6194                                 contents.wrapAll( html );
6195
6196                         } else {
6197                                 self.append( html );
6198                         }
6199                 });
6200         },
6201
6202         wrap: function( html ) {
6203                 return this.each(function() {
6204                         jQuery( this ).wrapAll( html );
6205                 });
6206         },
6207
6208         unwrap: function() {
6209                 return this.parent().each(function() {
6210                         if ( !jQuery.nodeName( this, "body" ) ) {
6211                                 jQuery( this ).replaceWith( this.childNodes );
6212                         }
6213                 }).end();
6214         },
6215
6216         append: function() {
6217                 return this.domManip(arguments, true, function( elem ) {
6218                         if ( this.nodeType === 1 ) {
6219                                 this.appendChild( elem );
6220                         }
6221                 });
6222         },
6223
6224         prepend: function() {
6225                 return this.domManip(arguments, true, function( elem ) {
6226                         if ( this.nodeType === 1 ) {
6227                                 this.insertBefore( elem, this.firstChild );
6228                         }
6229                 });
6230         },
6231
6232         before: function() {
6233                 if ( this[0] && this[0].parentNode ) {
6234                         return this.domManip(arguments, false, function( elem ) {
6235                                 this.parentNode.insertBefore( elem, this );
6236                         });
6237                 } else if ( arguments.length ) {
6238                         var set = jQuery(arguments[0]);
6239                         set.push.apply( set, this.toArray() );
6240                         return this.pushStack( set, "before", arguments );
6241                 }
6242         },
6243
6244         after: function() {
6245                 if ( this[0] && this[0].parentNode ) {
6246                         return this.domManip(arguments, false, function( elem ) {
6247                                 this.parentNode.insertBefore( elem, this.nextSibling );
6248                         });
6249                 } else if ( arguments.length ) {
6250                         var set = this.pushStack( this, "after", arguments );
6251                         set.push.apply( set, jQuery(arguments[0]).toArray() );
6252                         return set;
6253                 }
6254         },
6255
6256         // keepData is for internal use only--do not document
6257         remove: function( selector, keepData ) {
6258                 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
6259                         if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
6260                                 if ( !keepData && elem.nodeType === 1 ) {
6261                                         jQuery.cleanData( elem.getElementsByTagName("*") );
6262                                         jQuery.cleanData( [ elem ] );
6263                                 }
6264
6265                                 if ( elem.parentNode ) {
6266                                         elem.parentNode.removeChild( elem );
6267                                 }
6268                         }
6269                 }
6270
6271                 return this;
6272         },
6273
6274         empty: function() {
6275                 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
6276                         // Remove element nodes and prevent memory leaks
6277                         if ( elem.nodeType === 1 ) {
6278                                 jQuery.cleanData( elem.getElementsByTagName("*") );
6279                         }
6280
6281                         // Remove any remaining nodes
6282                         while ( elem.firstChild ) {
6283                                 elem.removeChild( elem.firstChild );
6284                         }
6285                 }
6286
6287                 return this;
6288         },
6289
6290         clone: function( dataAndEvents, deepDataAndEvents ) {
6291                 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6292                 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6293
6294                 return this.map( function () {
6295                         return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6296                 });
6297         },
6298
6299         html: function( value ) {
6300                 if ( value === undefined ) {
6301                         return this[0] && this[0].nodeType === 1 ?
6302                                 this[0].innerHTML.replace(rinlinejQuery, "") :
6303                                 null;
6304
6305                 // See if we can take a shortcut and just use innerHTML
6306                 } else if ( typeof value === "string" && !rnocache.test( value ) &&
6307                         (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
6308                         !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
6309
6310                         value = value.replace(rxhtmlTag, "<$1></$2>");
6311
6312                         try {
6313                                 for ( var i = 0, l = this.length; i < l; i++ ) {
6314                                         // Remove element nodes and prevent memory leaks
6315                                         if ( this[i].nodeType === 1 ) {
6316                                                 jQuery.cleanData( this[i].getElementsByTagName("*") );
6317                                                 this[i].innerHTML = value;
6318                                         }
6319                                 }
6320
6321                         // If using innerHTML throws an exception, use the fallback method
6322                         } catch(e) {
6323                                 this.empty().append( value );
6324                         }
6325
6326                 } else if ( jQuery.isFunction( value ) ) {
6327                         this.each(function(i){
6328                                 var self = jQuery( this );
6329
6330                                 self.html( value.call(this, i, self.html()) );
6331                         });
6332
6333                 } else {
6334                         this.empty().append( value );
6335                 }
6336
6337                 return this;
6338         },
6339
6340         replaceWith: function( value ) {
6341                 if ( this[0] && this[0].parentNode ) {
6342                         // Make sure that the elements are removed from the DOM before they are inserted
6343                         // this can help fix replacing a parent with child elements
6344                         if ( jQuery.isFunction( value ) ) {
6345                                 return this.each(function(i) {
6346                                         var self = jQuery(this), old = self.html();
6347                                         self.replaceWith( value.call( this, i, old ) );
6348                                 });
6349                         }
6350
6351                         if ( typeof value !== "string" ) {
6352                                 value = jQuery( value ).detach();
6353                         }
6354
6355                         return this.each(function() {
6356                                 var next = this.nextSibling,
6357                                         parent = this.parentNode;
6358
6359                                 jQuery( this ).remove();
6360
6361                                 if ( next ) {
6362                                         jQuery(next).before( value );
6363                                 } else {
6364                                         jQuery(parent).append( value );
6365                                 }
6366                         });
6367                 } else {
6368                         return this.length ?
6369                                 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
6370                                 this;
6371                 }
6372         },
6373
6374         detach: function( selector ) {
6375                 return this.remove( selector, true );
6376         },
6377
6378         domManip: function( args, table, callback ) {
6379                 var results, first, fragment, parent,
6380                         value = args[0],
6381                         scripts = [];
6382
6383                 // We can't cloneNode fragments that contain checked, in WebKit
6384                 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
6385                         return this.each(function() {
6386                                 jQuery(this).domManip( args, table, callback, true );
6387                         });
6388                 }
6389
6390                 if ( jQuery.isFunction(value) ) {
6391                         return this.each(function(i) {
6392                                 var self = jQuery(this);
6393                                 args[0] = value.call(this, i, table ? self.html() : undefined);
6394                                 self.domManip( args, table, callback );
6395                         });
6396                 }
6397
6398                 if ( this[0] ) {
6399                         parent = value && value.parentNode;
6400
6401                         // If we're in a fragment, just use that instead of building a new one
6402                         if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
6403                                 results = { fragment: parent };
6404
6405                         } else {
6406                                 results = jQuery.buildFragment( args, this, scripts );
6407                         }
6408
6409                         fragment = results.fragment;
6410
6411                         if ( fragment.childNodes.length === 1 ) {
6412                                 first = fragment = fragment.firstChild;
6413                         } else {
6414                                 first = fragment.firstChild;
6415                         }
6416
6417                         if ( first ) {
6418                                 table = table && jQuery.nodeName( first, "tr" );
6419
6420                                 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
6421                                         callback.call(
6422                                                 table ?
6423                                                         root(this[i], first) :
6424                                                         this[i],
6425                                                 // Make sure that we do not leak memory by inadvertently discarding
6426                                                 // the original fragment (which might have attached data) instead of
6427                                                 // using it; in addition, use the original fragment object for the last
6428                                                 // item instead of first because it can end up being emptied incorrectly
6429                                                 // in certain situations (Bug #8070).
6430                                                 // Fragments from the fragment cache must always be cloned and never used
6431                                                 // in place.
6432                                                 results.cacheable || (l > 1 && i < lastIndex) ?
6433                                                         jQuery.clone( fragment, true, true ) :
6434                                                         fragment
6435                                         );
6436                                 }
6437                         }
6438
6439                         if ( scripts.length ) {
6440                                 jQuery.each( scripts, evalScript );
6441                         }
6442                 }
6443
6444                 return this;
6445         }
6446 });
6447
6448 function root( elem, cur ) {
6449         return jQuery.nodeName(elem, "table") ?
6450                 (elem.getElementsByTagName("tbody")[0] ||
6451                 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
6452                 elem;
6453 }
6454
6455 function cloneCopyEvent( src, dest ) {
6456
6457         if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
6458                 return;
6459         }
6460
6461         var internalKey = jQuery.expando,
6462                 oldData = jQuery.data( src ),
6463                 curData = jQuery.data( dest, oldData );
6464
6465         // Switch to use the internal data object, if it exists, for the next
6466         // stage of data copying
6467         if ( (oldData = oldData[ internalKey ]) ) {
6468                 var events = oldData.events;
6469                                 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
6470
6471                 if ( events ) {
6472                         delete curData.handle;
6473                         curData.events = {};
6474
6475                         for ( var type in events ) {
6476                                 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
6477                                         jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
6478                                 }
6479                         }
6480                 }
6481         }
6482 }
6483
6484 function cloneFixAttributes( src, dest ) {
6485         var nodeName;
6486
6487         // We do not need to do anything for non-Elements
6488         if ( dest.nodeType !== 1 ) {
6489                 return;
6490         }
6491
6492         // clearAttributes removes the attributes, which we don't want,
6493         // but also removes the attachEvent events, which we *do* want
6494         if ( dest.clearAttributes ) {
6495                 dest.clearAttributes();
6496         }
6497
6498         // mergeAttributes, in contrast, only merges back on the
6499         // original attributes, not the events
6500         if ( dest.mergeAttributes ) {
6501                 dest.mergeAttributes( src );
6502         }
6503
6504         nodeName = dest.nodeName.toLowerCase();
6505
6506         // IE6-8 fail to clone children inside object elements that use
6507         // the proprietary classid attribute value (rather than the type
6508         // attribute) to identify the type of content to display
6509         if ( nodeName === "object" ) {
6510                 dest.outerHTML = src.outerHTML;
6511
6512         } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
6513                 // IE6-8 fails to persist the checked state of a cloned checkbox
6514                 // or radio button. Worse, IE6-7 fail to give the cloned element
6515                 // a checked appearance if the defaultChecked value isn't also set
6516                 if ( src.checked ) {
6517                         dest.defaultChecked = dest.checked = src.checked;
6518                 }
6519
6520                 // IE6-7 get confused and end up setting the value of a cloned
6521                 // checkbox/radio button to an empty string instead of "on"
6522                 if ( dest.value !== src.value ) {
6523                         dest.value = src.value;
6524                 }
6525
6526         // IE6-8 fails to return the selected option to the default selected
6527         // state when cloning options
6528         } else if ( nodeName === "option" ) {
6529                 dest.selected = src.defaultSelected;
6530
6531         // IE6-8 fails to set the defaultValue to the correct value when
6532         // cloning other types of input fields
6533         } else if ( nodeName === "input" || nodeName === "textarea" ) {
6534                 dest.defaultValue = src.defaultValue;
6535         }
6536
6537         // Event data gets referenced instead of copied if the expando
6538         // gets copied too
6539         dest.removeAttribute( jQuery.expando );
6540 }
6541
6542 jQuery.buildFragment = function( args, nodes, scripts ) {
6543         var fragment, cacheable, cacheresults,
6544                 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
6545
6546         // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
6547         // Cloning options loses the selected state, so don't cache them
6548         // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6549         // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6550         if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
6551                 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
6552
6553                 cacheable = true;
6554
6555                 cacheresults = jQuery.fragments[ args[0] ];
6556                 if ( cacheresults && cacheresults !== 1 ) {
6557                         fragment = cacheresults;
6558                 }
6559         }
6560
6561         if ( !fragment ) {
6562                 fragment = doc.createDocumentFragment();
6563                 jQuery.clean( args, doc, fragment, scripts );
6564         }
6565
6566         if ( cacheable ) {
6567                 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
6568         }
6569
6570         return { fragment: fragment, cacheable: cacheable };
6571 };
6572
6573 jQuery.fragments = {};
6574
6575 jQuery.each({
6576         appendTo: "append",
6577         prependTo: "prepend",
6578         insertBefore: "before",
6579         insertAfter: "after",
6580         replaceAll: "replaceWith"
6581 }, function( name, original ) {
6582         jQuery.fn[ name ] = function( selector ) {
6583                 var ret = [],
6584                         insert = jQuery( selector ),
6585                         parent = this.length === 1 && this[0].parentNode;
6586
6587                 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6588                         insert[ original ]( this[0] );
6589                         return this;
6590
6591                 } else {
6592                         for ( var i = 0, l = insert.length; i < l; i++ ) {
6593                                 var elems = (i > 0 ? this.clone(true) : this).get();
6594                                 jQuery( insert[i] )[ original ]( elems );
6595                                 ret = ret.concat( elems );
6596                         }
6597
6598                         return this.pushStack( ret, name, insert.selector );
6599                 }
6600         };
6601 });
6602
6603 function getAll( elem ) {
6604         if ( "getElementsByTagName" in elem ) {
6605                 return elem.getElementsByTagName( "*" );
6606         
6607         } else if ( "querySelectorAll" in elem ) {
6608                 return elem.querySelectorAll( "*" );
6609
6610         } else {
6611                 return [];
6612         }
6613 }
6614
6615 // Used in clean, fixes the defaultChecked property
6616 function fixDefaultChecked( elem ) {
6617         if ( elem.type === "checkbox" || elem.type === "radio" ) {
6618                 elem.defaultChecked = elem.checked;
6619         }
6620 }
6621 // Finds all inputs and passes them to fixDefaultChecked
6622 function findInputs( elem ) {
6623         if ( jQuery.nodeName( elem, "input" ) ) {
6624                 fixDefaultChecked( elem );
6625         } else if ( elem.getElementsByTagName ) {
6626                 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6627         }
6628 }
6629
6630 jQuery.extend({
6631         clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6632                 var clone = elem.cloneNode(true),
6633                                 srcElements,
6634                                 destElements,
6635                                 i;
6636
6637                 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6638                                 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6639                         // IE copies events bound via attachEvent when using cloneNode.
6640                         // Calling detachEvent on the clone will also remove the events
6641                         // from the original. In order to get around this, we use some
6642                         // proprietary methods to clear the events. Thanks to MooTools
6643                         // guys for this hotness.
6644
6645                         cloneFixAttributes( elem, clone );
6646
6647                         // Using Sizzle here is crazy slow, so we use getElementsByTagName
6648                         // instead
6649                         srcElements = getAll( elem );
6650                         destElements = getAll( clone );
6651
6652                         // Weird iteration because IE will replace the length property
6653                         // with an element if you are cloning the body and one of the
6654                         // elements on the page has a name or id of "length"
6655                         for ( i = 0; srcElements[i]; ++i ) {
6656                                 cloneFixAttributes( srcElements[i], destElements[i] );
6657                         }
6658                 }
6659
6660                 // Copy the events from the original to the clone
6661                 if ( dataAndEvents ) {
6662                         cloneCopyEvent( elem, clone );
6663
6664                         if ( deepDataAndEvents ) {
6665                                 srcElements = getAll( elem );
6666                                 destElements = getAll( clone );
6667
6668                                 for ( i = 0; srcElements[i]; ++i ) {
6669                                         cloneCopyEvent( srcElements[i], destElements[i] );
6670                                 }
6671                         }
6672                 }
6673
6674                 // Return the cloned set
6675                 return clone;
6676         },
6677
6678         clean: function( elems, context, fragment, scripts ) {
6679                 var checkScriptType;
6680
6681                 context = context || document;
6682
6683                 // !context.createElement fails in IE with an error but returns typeof 'object'
6684                 if ( typeof context.createElement === "undefined" ) {
6685                         context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6686                 }
6687
6688                 var ret = [];
6689
6690                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6691                         if ( typeof elem === "number" ) {
6692                                 elem += "";
6693                         }
6694
6695                         if ( !elem ) {
6696                                 continue;
6697                         }
6698
6699                         // Convert html string into DOM nodes
6700                         if ( typeof elem === "string" ) {
6701                                 if ( !rhtml.test( elem ) ) {
6702                                         elem = context.createTextNode( elem );
6703                                 } else {
6704                                         // Fix "XHTML"-style tags in all browsers
6705                                         elem = elem.replace(rxhtmlTag, "<$1></$2>");
6706
6707                                         // Trim whitespace, otherwise indexOf won't work as expected
6708                                         var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6709                                                 wrap = wrapMap[ tag ] || wrapMap._default,
6710                                                 depth = wrap[0],
6711                                                 div = context.createElement("div");
6712
6713                                         // Go to html and back, then peel off extra wrappers
6714                                         div.innerHTML = wrap[1] + elem + wrap[2];
6715
6716                                         // Move to the right depth
6717                                         while ( depth-- ) {
6718                                                 div = div.lastChild;
6719                                         }
6720
6721                                         // Remove IE's autoinserted <tbody> from table fragments
6722                                         if ( !jQuery.support.tbody ) {
6723
6724                                                 // String was a <table>, *may* have spurious <tbody>
6725                                                 var hasBody = rtbody.test(elem),
6726                                                         tbody = tag === "table" && !hasBody ?
6727                                                                 div.firstChild && div.firstChild.childNodes :
6728
6729                                                                 // String was a bare <thead> or <tfoot>
6730                                                                 wrap[1] === "<table>" && !hasBody ?
6731                                                                         div.childNodes :
6732                                                                         [];
6733
6734                                                 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
6735                                                         if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6736                                                                 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6737                                                         }
6738                                                 }
6739                                         }
6740
6741                                         // IE completely kills leading whitespace when innerHTML is used
6742                                         if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6743                                                 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6744                                         }
6745
6746                                         elem = div.childNodes;
6747                                 }
6748                         }
6749
6750                         // Resets defaultChecked for any radios and checkboxes
6751                         // about to be appended to the DOM in IE 6/7 (#8060)
6752                         var len;
6753                         if ( !jQuery.support.appendChecked ) {
6754                                 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6755                                         for ( i = 0; i < len; i++ ) {
6756                                                 findInputs( elem[i] );
6757                                         }
6758                                 } else {
6759                                         findInputs( elem );
6760                                 }
6761                         }
6762
6763                         if ( elem.nodeType ) {
6764                                 ret.push( elem );
6765                         } else {
6766                                 ret = jQuery.merge( ret, elem );
6767                         }
6768                 }
6769
6770                 if ( fragment ) {
6771                         checkScriptType = function( elem ) {
6772                                 return !elem.type || rscriptType.test( elem.type );
6773                         };
6774                         for ( i = 0; ret[i]; i++ ) {
6775                                 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6776                                         scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6777
6778                                 } else {
6779                                         if ( ret[i].nodeType === 1 ) {
6780                                                 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6781
6782                                                 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6783                                         }
6784                                         fragment.appendChild( ret[i] );
6785                                 }
6786                         }
6787                 }
6788
6789                 return ret;
6790         },
6791
6792         cleanData: function( elems ) {
6793                 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6794                         deleteExpando = jQuery.support.deleteExpando;
6795
6796                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6797                         if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6798                                 continue;
6799                         }
6800
6801                         id = elem[ jQuery.expando ];
6802
6803                         if ( id ) {
6804                                 data = cache[ id ] && cache[ id ][ internalKey ];
6805
6806                                 if ( data && data.events ) {
6807                                         for ( var type in data.events ) {
6808                                                 if ( special[ type ] ) {
6809                                                         jQuery.event.remove( elem, type );
6810
6811                                                 // This is a shortcut to avoid jQuery.event.remove's overhead
6812                                                 } else {
6813                                                         jQuery.removeEvent( elem, type, data.handle );
6814                                                 }
6815                                         }
6816
6817                                         // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6818                                         if ( data.handle ) {
6819                                                 data.handle.elem = null;
6820                                         }
6821                                 }
6822
6823                                 if ( deleteExpando ) {
6824                                         delete elem[ jQuery.expando ];
6825
6826                                 } else if ( elem.removeAttribute ) {
6827                                         elem.removeAttribute( jQuery.expando );
6828                                 }
6829
6830                                 delete cache[ id ];
6831                         }
6832                 }
6833         }
6834 });
6835
6836 function evalScript( i, elem ) {
6837         if ( elem.src ) {
6838                 jQuery.ajax({
6839                         url: elem.src,
6840                         async: false,
6841                         dataType: "script"
6842                 });
6843         } else {
6844                 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
6845         }
6846
6847         if ( elem.parentNode ) {
6848                 elem.parentNode.removeChild( elem );
6849         }
6850 }
6851
6852
6853
6854
6855 var ralpha = /alpha\([^)]*\)/i,
6856         ropacity = /opacity=([^)]*)/,
6857         rdashAlpha = /-([a-z])/ig,
6858         // fixed for IE9, see #8346
6859         rupper = /([A-Z]|^ms)/g,
6860         rnumpx = /^-?\d+(?:px)?$/i,
6861         rnum = /^-?\d/,
6862         rrelNum = /^[+\-]=/,
6863         rrelNumFilter = /[^+\-\.\de]+/g,
6864
6865         cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6866         cssWidth = [ "Left", "Right" ],
6867         cssHeight = [ "Top", "Bottom" ],
6868         curCSS,
6869
6870         getComputedStyle,
6871         currentStyle,
6872
6873         fcamelCase = function( all, letter ) {
6874                 return letter.toUpperCase();
6875         };
6876
6877 jQuery.fn.css = function( name, value ) {
6878         // Setting 'undefined' is a no-op
6879         if ( arguments.length === 2 && value === undefined ) {
6880                 return this;
6881         }
6882
6883         return jQuery.access( this, name, value, true, function( elem, name, value ) {
6884                 return value !== undefined ?
6885                         jQuery.style( elem, name, value ) :
6886                         jQuery.css( elem, name );
6887         });
6888 };
6889
6890 jQuery.extend({
6891         // Add in style property hooks for overriding the default
6892         // behavior of getting and setting a style property
6893         cssHooks: {
6894                 opacity: {
6895                         get: function( elem, computed ) {
6896                                 if ( computed ) {
6897                                         // We should always get a number back from opacity
6898                                         var ret = curCSS( elem, "opacity", "opacity" );
6899                                         return ret === "" ? "1" : ret;
6900
6901                                 } else {
6902                                         return elem.style.opacity;
6903                                 }
6904                         }
6905                 }
6906         },
6907
6908         // Exclude the following css properties to add px
6909         cssNumber: {
6910                 "zIndex": true,
6911                 "fontWeight": true,
6912                 "opacity": true,
6913                 "zoom": true,
6914                 "lineHeight": true,
6915                 "widows": true,
6916                 "orphans": true
6917         },
6918
6919         // Add in properties whose names you wish to fix before
6920         // setting or getting the value
6921         cssProps: {
6922                 // normalize float css property
6923                 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6924         },
6925
6926         // Get and set the style property on a DOM Node
6927         style: function( elem, name, value, extra ) {
6928                 // Don't set styles on text and comment nodes
6929                 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6930                         return;
6931                 }
6932
6933                 // Make sure that we're working with the right name
6934                 var ret, type, origName = jQuery.camelCase( name ),
6935                         style = elem.style, hooks = jQuery.cssHooks[ origName ];
6936
6937                 name = jQuery.cssProps[ origName ] || origName;
6938
6939                 // Check if we're setting a value
6940                 if ( value !== undefined ) {
6941                         type = typeof value;
6942
6943                         // Make sure that NaN and null values aren't set. See: #7116
6944                         if ( type === "number" && isNaN( value ) || value == null ) {
6945                                 return;
6946                         }
6947
6948                         // convert relative number strings (+= or -=) to relative numbers. #7345
6949                         if ( type === "string" && rrelNum.test( value ) ) {
6950                                 value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
6951                         }
6952
6953                         // If a number was passed in, add 'px' to the (except for certain CSS properties)
6954                         if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6955                                 value += "px";
6956                         }
6957
6958                         // If a hook was provided, use that value, otherwise just set the specified value
6959                         if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6960                                 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6961                                 // Fixes bug #5509
6962                                 try {
6963                                         style[ name ] = value;
6964                                 } catch(e) {}
6965                         }
6966
6967                 } else {
6968                         // If a hook was provided get the non-computed value from there
6969                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6970                                 return ret;
6971                         }
6972
6973                         // Otherwise just get the value from the style object
6974                         return style[ name ];
6975                 }
6976         },
6977
6978         css: function( elem, name, extra ) {
6979                 var ret, hooks;
6980
6981                 // Make sure that we're working with the right name
6982                 name = jQuery.camelCase( name );
6983                 hooks = jQuery.cssHooks[ name ];
6984                 name = jQuery.cssProps[ name ] || name;
6985
6986                 // cssFloat needs a special treatment
6987                 if ( name === "cssFloat" ) {
6988                         name = "float";
6989                 }
6990
6991                 // If a hook was provided get the computed value from there
6992                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6993                         return ret;
6994
6995                 // Otherwise, if a way to get the computed value exists, use that
6996                 } else if ( curCSS ) {
6997                         return curCSS( elem, name );
6998                 }
6999         },
7000
7001         // A method for quickly swapping in/out CSS properties to get correct calculations
7002         swap: function( elem, options, callback ) {
7003                 var old = {};
7004
7005                 // Remember the old values, and insert the new ones
7006                 for ( var name in options ) {
7007                         old[ name ] = elem.style[ name ];
7008                         elem.style[ name ] = options[ name ];
7009                 }
7010
7011                 callback.call( elem );
7012
7013                 // Revert the old values
7014                 for ( name in options ) {
7015                         elem.style[ name ] = old[ name ];
7016                 }
7017         },
7018
7019         camelCase: function( string ) {
7020                 return string.replace( rdashAlpha, fcamelCase );
7021         }
7022 });
7023
7024 // DEPRECATED, Use jQuery.css() instead
7025 jQuery.curCSS = jQuery.css;
7026
7027 jQuery.each(["height", "width"], function( i, name ) {
7028         jQuery.cssHooks[ name ] = {
7029                 get: function( elem, computed, extra ) {
7030                         var val;
7031
7032                         if ( computed ) {
7033                                 if ( elem.offsetWidth !== 0 ) {
7034                                         val = getWH( elem, name, extra );
7035
7036                                 } else {
7037                                         jQuery.swap( elem, cssShow, function() {
7038                                                 val = getWH( elem, name, extra );
7039                                         });
7040                                 }
7041
7042                                 if ( val <= 0 ) {
7043                                         val = curCSS( elem, name, name );
7044
7045                                         if ( val === "0px" && currentStyle ) {
7046                                                 val = currentStyle( elem, name, name );
7047                                         }
7048
7049                                         if ( val != null ) {
7050                                                 // Should return "auto" instead of 0, use 0 for
7051                                                 // temporary backwards-compat
7052                                                 return val === "" || val === "auto" ? "0px" : val;
7053                                         }
7054                                 }
7055
7056                                 if ( val < 0 || val == null ) {
7057                                         val = elem.style[ name ];
7058
7059                                         // Should return "auto" instead of 0, use 0 for
7060                                         // temporary backwards-compat
7061                                         return val === "" || val === "auto" ? "0px" : val;
7062                                 }
7063
7064                                 return typeof val === "string" ? val : val + "px";
7065                         }
7066                 },
7067
7068                 set: function( elem, value ) {
7069                         if ( rnumpx.test( value ) ) {
7070                                 // ignore negative width and height values #1599
7071                                 value = parseFloat(value);
7072
7073                                 if ( value >= 0 ) {
7074                                         return value + "px";
7075                                 }
7076
7077                         } else {
7078                                 return value;
7079                         }
7080                 }
7081         };
7082 });
7083
7084 if ( !jQuery.support.opacity ) {
7085         jQuery.cssHooks.opacity = {
7086                 get: function( elem, computed ) {
7087                         // IE uses filters for opacity
7088                         return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
7089                                 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
7090                                 computed ? "1" : "";
7091                 },
7092
7093                 set: function( elem, value ) {
7094                         var style = elem.style,
7095                                 currentStyle = elem.currentStyle;
7096
7097                         // IE has trouble with opacity if it does not have layout
7098                         // Force it by setting the zoom level
7099                         style.zoom = 1;
7100
7101                         // Set the alpha filter to set the opacity
7102                         var opacity = jQuery.isNaN( value ) ?
7103                                 "" :
7104                                 "alpha(opacity=" + value * 100 + ")",
7105                                 filter = currentStyle && currentStyle.filter || style.filter || "";
7106
7107                         style.filter = ralpha.test( filter ) ?
7108                                 filter.replace( ralpha, opacity ) :
7109                                 filter + " " + opacity;
7110                 }
7111         };
7112 }
7113
7114 jQuery(function() {
7115         // This hook cannot be added until DOM ready because the support test
7116         // for it is not run until after DOM ready
7117         if ( !jQuery.support.reliableMarginRight ) {
7118                 jQuery.cssHooks.marginRight = {
7119                         get: function( elem, computed ) {
7120                                 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
7121                                 // Work around by temporarily setting element display to inline-block
7122                                 var ret;
7123                                 jQuery.swap( elem, { "display": "inline-block" }, function() {
7124                                         if ( computed ) {
7125                                                 ret = curCSS( elem, "margin-right", "marginRight" );
7126                                         } else {
7127                                                 ret = elem.style.marginRight;
7128                                         }
7129                                 });
7130                                 return ret;
7131                         }
7132                 };
7133         }
7134 });
7135
7136 if ( document.defaultView && document.defaultView.getComputedStyle ) {
7137         getComputedStyle = function( elem, name ) {
7138                 var ret, defaultView, computedStyle;
7139
7140                 name = name.replace( rupper, "-$1" ).toLowerCase();
7141
7142                 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
7143                         return undefined;
7144                 }
7145
7146                 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
7147                         ret = computedStyle.getPropertyValue( name );
7148                         if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
7149                                 ret = jQuery.style( elem, name );
7150                         }
7151                 }
7152
7153                 return ret;
7154         };
7155 }
7156
7157 if ( document.documentElement.currentStyle ) {
7158         currentStyle = function( elem, name ) {
7159                 var left,
7160                         ret = elem.currentStyle && elem.currentStyle[ name ],
7161                         rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
7162                         style = elem.style;
7163
7164                 // From the awesome hack by Dean Edwards
7165                 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
7166
7167                 // If we're not dealing with a regular pixel number
7168                 // but a number that has a weird ending, we need to convert it to pixels
7169                 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
7170                         // Remember the original values
7171                         left = style.left;
7172
7173                         // Put in the new values to get a computed value out
7174                         if ( rsLeft ) {
7175                                 elem.runtimeStyle.left = elem.currentStyle.left;
7176                         }
7177                         style.left = name === "fontSize" ? "1em" : (ret || 0);
7178                         ret = style.pixelLeft + "px";
7179
7180                         // Revert the changed values
7181                         style.left = left;
7182                         if ( rsLeft ) {
7183                                 elem.runtimeStyle.left = rsLeft;
7184                         }
7185                 }
7186
7187                 return ret === "" ? "auto" : ret;
7188         };
7189 }
7190
7191 curCSS = getComputedStyle || currentStyle;
7192
7193 function getWH( elem, name, extra ) {
7194         var which = name === "width" ? cssWidth : cssHeight,
7195                 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
7196
7197         if ( extra === "border" ) {
7198                 return val;
7199         }
7200
7201         jQuery.each( which, function() {
7202                 if ( !extra ) {
7203                         val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
7204                 }
7205
7206                 if ( extra === "margin" ) {
7207                         val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
7208
7209                 } else {
7210                         val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
7211                 }
7212         });
7213
7214         return val;
7215 }
7216
7217 if ( jQuery.expr && jQuery.expr.filters ) {
7218         jQuery.expr.filters.hidden = function( elem ) {
7219                 var width = elem.offsetWidth,
7220                         height = elem.offsetHeight;
7221
7222                 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
7223         };
7224
7225         jQuery.expr.filters.visible = function( elem ) {
7226                 return !jQuery.expr.filters.hidden( elem );
7227         };
7228 }
7229
7230
7231
7232
7233 var r20 = /%20/g,
7234         rbracket = /\[\]$/,
7235         rCRLF = /\r?\n/g,
7236         rhash = /#.*$/,
7237         rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
7238         rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
7239         // #7653, #8125, #8152: local protocol detection
7240         rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
7241         rnoContent = /^(?:GET|HEAD)$/,
7242         rprotocol = /^\/\//,
7243         rquery = /\?/,
7244         rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
7245         rselectTextarea = /^(?:select|textarea)/i,
7246         rspacesAjax = /\s+/,
7247         rts = /([?&])_=[^&]*/,
7248         rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
7249
7250         // Keep a copy of the old load method
7251         _load = jQuery.fn.load,
7252
7253         /* Prefilters
7254          * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7255          * 2) These are called:
7256          *    - BEFORE asking for a transport
7257          *    - AFTER param serialization (s.data is a string if s.processData is true)
7258          * 3) key is the dataType
7259          * 4) the catchall symbol "*" can be used
7260          * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7261          */
7262         prefilters = {},
7263
7264         /* Transports bindings
7265          * 1) key is the dataType
7266          * 2) the catchall symbol "*" can be used
7267          * 3) selection will start with transport dataType and THEN go to "*" if needed
7268          */
7269         transports = {},
7270
7271         // Document location
7272         ajaxLocation,
7273
7274         // Document location segments
7275         ajaxLocParts;
7276
7277 // #8138, IE may throw an exception when accessing
7278 // a field from window.location if document.domain has been set
7279 try {
7280         ajaxLocation = location.href;
7281 } catch( e ) {
7282         // Use the href attribute of an A element
7283         // since IE will modify it given document.location
7284         ajaxLocation = document.createElement( "a" );
7285         ajaxLocation.href = "";
7286         ajaxLocation = ajaxLocation.href;
7287 }
7288
7289 // Segment location into parts
7290 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7291
7292 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7293 function addToPrefiltersOrTransports( structure ) {
7294
7295         // dataTypeExpression is optional and defaults to "*"
7296         return function( dataTypeExpression, func ) {
7297
7298                 if ( typeof dataTypeExpression !== "string" ) {
7299                         func = dataTypeExpression;
7300                         dataTypeExpression = "*";
7301                 }
7302
7303                 if ( jQuery.isFunction( func ) ) {
7304                         var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
7305                                 i = 0,
7306                                 length = dataTypes.length,
7307                                 dataType,
7308                                 list,
7309                                 placeBefore;
7310
7311                         // For each dataType in the dataTypeExpression
7312                         for(; i < length; i++ ) {
7313                                 dataType = dataTypes[ i ];
7314                                 // We control if we're asked to add before
7315                                 // any existing element
7316                                 placeBefore = /^\+/.test( dataType );
7317                                 if ( placeBefore ) {
7318                                         dataType = dataType.substr( 1 ) || "*";
7319                                 }
7320                                 list = structure[ dataType ] = structure[ dataType ] || [];
7321                                 // then we add to the structure accordingly
7322                                 list[ placeBefore ? "unshift" : "push" ]( func );
7323                         }
7324                 }
7325         };
7326 }
7327
7328 // Base inspection function for prefilters and transports
7329 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
7330                 dataType /* internal */, inspected /* internal */ ) {
7331
7332         dataType = dataType || options.dataTypes[ 0 ];
7333         inspected = inspected || {};
7334
7335         inspected[ dataType ] = true;
7336
7337         var list = structure[ dataType ],
7338                 i = 0,
7339                 length = list ? list.length : 0,
7340                 executeOnly = ( structure === prefilters ),
7341                 selection;
7342
7343         for(; i < length && ( executeOnly || !selection ); i++ ) {
7344                 selection = list[ i ]( options, originalOptions, jqXHR );
7345                 // If we got redirected to another dataType
7346                 // we try there if executing only and not done already
7347                 if ( typeof selection === "string" ) {
7348                         if ( !executeOnly || inspected[ selection ] ) {
7349                                 selection = undefined;
7350                         } else {
7351                                 options.dataTypes.unshift( selection );
7352                                 selection = inspectPrefiltersOrTransports(
7353                                                 structure, options, originalOptions, jqXHR, selection, inspected );
7354                         }
7355                 }
7356         }
7357         // If we're only executing or nothing was selected
7358         // we try the catchall dataType if not done already
7359         if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
7360                 selection = inspectPrefiltersOrTransports(
7361                                 structure, options, originalOptions, jqXHR, "*", inspected );
7362         }
7363         // unnecessary when only executing (prefilters)
7364         // but it'll be ignored by the caller in that case
7365         return selection;
7366 }
7367
7368 jQuery.fn.extend({
7369         load: function( url, params, callback ) {
7370                 if ( typeof url !== "string" && _load ) {
7371                         return _load.apply( this, arguments );
7372
7373                 // Don't do a request if no elements are being requested
7374                 } else if ( !this.length ) {
7375                         return this;
7376                 }
7377
7378                 var off = url.indexOf( " " );
7379                 if ( off >= 0 ) {
7380                         var selector = url.slice( off, url.length );
7381                         url = url.slice( 0, off );
7382                 }
7383
7384                 // Default to a GET request
7385                 var type = "GET";
7386
7387                 // If the second parameter was provided
7388                 if ( params ) {
7389                         // If it's a function
7390                         if ( jQuery.isFunction( params ) ) {
7391                                 // We assume that it's the callback
7392                                 callback = params;
7393                                 params = undefined;
7394
7395                         // Otherwise, build a param string
7396                         } else if ( typeof params === "object" ) {
7397                                 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
7398                                 type = "POST";
7399                         }
7400                 }
7401
7402                 var self = this;
7403
7404                 // Request the remote document
7405                 jQuery.ajax({
7406                         url: url,
7407                         type: type,
7408                         dataType: "html",
7409                         data: params,
7410                         // Complete callback (responseText is used internally)
7411                         complete: function( jqXHR, status, responseText ) {
7412                                 // Store the response as specified by the jqXHR object
7413                                 responseText = jqXHR.responseText;
7414                                 // If successful, inject the HTML into all the matched elements
7415                                 if ( jqXHR.isResolved() ) {
7416                                         // #4825: Get the actual response in case
7417                                         // a dataFilter is present in ajaxSettings
7418                                         jqXHR.done(function( r ) {
7419                                                 responseText = r;
7420                                         });
7421                                         // See if a selector was specified
7422                                         self.html( selector ?
7423                                                 // Create a dummy div to hold the results
7424                                                 jQuery("<div>")
7425                                                         // inject the contents of the document in, removing the scripts
7426                                                         // to avoid any 'Permission Denied' errors in IE
7427                                                         .append(responseText.replace(rscript, ""))
7428
7429                                                         // Locate the specified elements
7430                                                         .find(selector) :
7431
7432                                                 // If not, just inject the full result
7433                                                 responseText );
7434                                 }
7435
7436                                 if ( callback ) {
7437                                         self.each( callback, [ responseText, status, jqXHR ] );
7438                                 }
7439                         }
7440                 });
7441
7442                 return this;
7443         },
7444
7445         serialize: function() {
7446                 return jQuery.param( this.serializeArray() );
7447         },
7448
7449         serializeArray: function() {
7450                 return this.map(function(){
7451                         return this.elements ? jQuery.makeArray( this.elements ) : this;
7452                 })
7453                 .filter(function(){
7454                         return this.name && !this.disabled &&
7455                                 ( this.checked || rselectTextarea.test( this.nodeName ) ||
7456                                         rinput.test( this.type ) );
7457                 })
7458                 .map(function( i, elem ){
7459                         var val = jQuery( this ).val();
7460
7461                         return val == null ?
7462                                 null :
7463                                 jQuery.isArray( val ) ?
7464                                         jQuery.map( val, function( val, i ){
7465                                                 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7466                                         }) :
7467                                         { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
7468                 }).get();
7469         }
7470 });
7471
7472 // Attach a bunch of functions for handling common AJAX events
7473 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
7474         jQuery.fn[ o ] = function( f ){
7475                 return this.bind( o, f );
7476         };
7477 });
7478
7479 jQuery.each( [ "get", "post" ], function( i, method ) {
7480         jQuery[ method ] = function( url, data, callback, type ) {
7481                 // shift arguments if data argument was omitted
7482                 if ( jQuery.isFunction( data ) ) {
7483                         type = type || callback;
7484                         callback = data;
7485                         data = undefined;
7486                 }
7487
7488                 return jQuery.ajax({
7489                         type: method,
7490                         url: url,
7491                         data: data,
7492                         success: callback,
7493                         dataType: type
7494                 });
7495         };
7496 });
7497
7498 jQuery.extend({
7499
7500         getScript: function( url, callback ) {
7501                 return jQuery.get( url, undefined, callback, "script" );
7502         },
7503
7504         getJSON: function( url, data, callback ) {
7505                 return jQuery.get( url, data, callback, "json" );
7506         },
7507
7508         // Creates a full fledged settings object into target
7509         // with both ajaxSettings and settings fields.
7510         // If target is omitted, writes into ajaxSettings.
7511         ajaxSetup: function ( target, settings ) {
7512                 if ( !settings ) {
7513                         // Only one parameter, we extend ajaxSettings
7514                         settings = target;
7515                         target = jQuery.extend( true, jQuery.ajaxSettings, settings );
7516                 } else {
7517                         // target was provided, we extend into it
7518                         jQuery.extend( true, target, jQuery.ajaxSettings, settings );
7519                 }
7520                 // Flatten fields we don't want deep extended
7521                 for( var field in { context: 1, url: 1 } ) {
7522                         if ( field in settings ) {
7523                                 target[ field ] = settings[ field ];
7524                         } else if( field in jQuery.ajaxSettings ) {
7525                                 target[ field ] = jQuery.ajaxSettings[ field ];
7526                         }
7527                 }
7528                 return target;
7529         },
7530
7531         ajaxSettings: {
7532                 url: ajaxLocation,
7533                 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7534                 global: true,
7535                 type: "GET",
7536                 contentType: "application/x-www-form-urlencoded",
7537                 processData: true,
7538                 async: true,
7539                 /*
7540                 timeout: 0,
7541                 data: null,
7542                 dataType: null,
7543                 username: null,
7544                 password: null,
7545                 cache: null,
7546                 traditional: false,
7547                 headers: {},
7548                 */
7549
7550                 accepts: {
7551                         xml: "application/xml, text/xml",
7552                         html: "text/html",
7553                         text: "text/plain",
7554                         json: "application/json, text/javascript",
7555                         "*": "*/*"
7556                 },
7557
7558                 contents: {
7559                         xml: /xml/,
7560                         html: /html/,
7561                         json: /json/
7562                 },
7563
7564                 responseFields: {
7565                         xml: "responseXML",
7566                         text: "responseText"
7567                 },
7568
7569                 // List of data converters
7570                 // 1) key format is "source_type destination_type" (a single space in-between)
7571                 // 2) the catchall symbol "*" can be used for source_type
7572                 converters: {
7573
7574                         // Convert anything to text
7575                         "* text": window.String,
7576
7577                         // Text to html (true = no transformation)
7578                         "text html": true,
7579
7580                         // Evaluate text as a json expression
7581                         "text json": jQuery.parseJSON,
7582
7583                         // Parse text as xml
7584                         "text xml": jQuery.parseXML
7585                 }
7586         },
7587
7588         ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7589         ajaxTransport: addToPrefiltersOrTransports( transports ),
7590
7591         // Main method
7592         ajax: function( url, options ) {
7593
7594                 // If url is an object, simulate pre-1.5 signature
7595                 if ( typeof url === "object" ) {
7596                         options = url;
7597                         url = undefined;
7598                 }
7599
7600                 // Force options to be an object
7601                 options = options || {};
7602
7603                 var // Create the final options object
7604                         s = jQuery.ajaxSetup( {}, options ),
7605                         // Callbacks context
7606                         callbackContext = s.context || s,
7607                         // Context for global events
7608                         // It's the callbackContext if one was provided in the options
7609                         // and if it's a DOM node or a jQuery collection
7610                         globalEventContext = callbackContext !== s &&
7611                                 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7612                                                 jQuery( callbackContext ) : jQuery.event,
7613                         // Deferreds
7614                         deferred = jQuery.Deferred(),
7615                         completeDeferred = jQuery._Deferred(),
7616                         // Status-dependent callbacks
7617                         statusCode = s.statusCode || {},
7618                         // ifModified key
7619                         ifModifiedKey,
7620                         // Headers (they are sent all at once)
7621                         requestHeaders = {},
7622                         requestHeadersNames = {},
7623                         // Response headers
7624                         responseHeadersString,
7625                         responseHeaders,
7626                         // transport
7627                         transport,
7628                         // timeout handle
7629                         timeoutTimer,
7630                         // Cross-domain detection vars
7631                         parts,
7632                         // The jqXHR state
7633                         state = 0,
7634                         // To know if global events are to be dispatched
7635                         fireGlobals,
7636                         // Loop variable
7637                         i,
7638                         // Fake xhr
7639                         jqXHR = {
7640
7641                                 readyState: 0,
7642
7643                                 // Caches the header
7644                                 setRequestHeader: function( name, value ) {
7645                                         if ( !state ) {
7646                                                 var lname = name.toLowerCase();
7647                                                 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7648                                                 requestHeaders[ name ] = value;
7649                                         }
7650                                         return this;
7651                                 },
7652
7653                                 // Raw string
7654                                 getAllResponseHeaders: function() {
7655                                         return state === 2 ? responseHeadersString : null;
7656                                 },
7657
7658                                 // Builds headers hashtable if needed
7659                                 getResponseHeader: function( key ) {
7660                                         var match;
7661                                         if ( state === 2 ) {
7662                                                 if ( !responseHeaders ) {
7663                                                         responseHeaders = {};
7664                                                         while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7665                                                                 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7666                                                         }
7667                                                 }
7668                                                 match = responseHeaders[ key.toLowerCase() ];
7669                                         }
7670                                         return match === undefined ? null : match;
7671                                 },
7672
7673                                 // Overrides response content-type header
7674                                 overrideMimeType: function( type ) {
7675                                         if ( !state ) {
7676                                                 s.mimeType = type;
7677                                         }
7678                                         return this;
7679                                 },
7680
7681                                 // Cancel the request
7682                                 abort: function( statusText ) {
7683                                         statusText = statusText || "abort";
7684                                         if ( transport ) {
7685                                                 transport.abort( statusText );
7686                                         }
7687                                         done( 0, statusText );
7688                                         return this;
7689                                 }
7690                         };
7691
7692                 // Callback for when everything is done
7693                 // It is defined here because jslint complains if it is declared
7694                 // at the end of the function (which would be more logical and readable)
7695                 function done( status, statusText, responses, headers ) {
7696
7697                         // Called once
7698                         if ( state === 2 ) {
7699                                 return;
7700                         }
7701
7702                         // State is "done" now
7703                         state = 2;
7704
7705                         // Clear timeout if it exists
7706                         if ( timeoutTimer ) {
7707                                 clearTimeout( timeoutTimer );
7708                         }
7709
7710                         // Dereference transport for early garbage collection
7711                         // (no matter how long the jqXHR object will be used)
7712                         transport = undefined;
7713
7714                         // Cache response headers
7715                         responseHeadersString = headers || "";
7716
7717                         // Set readyState
7718                         jqXHR.readyState = status ? 4 : 0;
7719
7720                         var isSuccess,
7721                                 success,
7722                                 error,
7723                                 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7724                                 lastModified,
7725                                 etag;
7726
7727                         // If successful, handle type chaining
7728                         if ( status >= 200 && status < 300 || status === 304 ) {
7729
7730                                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7731                                 if ( s.ifModified ) {
7732
7733                                         if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7734                                                 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7735                                         }
7736                                         if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7737                                                 jQuery.etag[ ifModifiedKey ] = etag;
7738                                         }
7739                                 }
7740
7741                                 // If not modified
7742                                 if ( status === 304 ) {
7743
7744                                         statusText = "notmodified";
7745                                         isSuccess = true;
7746
7747                                 // If we have data
7748                                 } else {
7749
7750                                         try {
7751                                                 success = ajaxConvert( s, response );
7752                                                 statusText = "success";
7753                                                 isSuccess = true;
7754                                         } catch(e) {
7755                                                 // We have a parsererror
7756                                                 statusText = "parsererror";
7757                                                 error = e;
7758                                         }
7759                                 }
7760                         } else {
7761                                 // We extract error from statusText
7762                                 // then normalize statusText and status for non-aborts
7763                                 error = statusText;
7764                                 if( !statusText || status ) {
7765                                         statusText = "error";
7766                                         if ( status < 0 ) {
7767                                                 status = 0;
7768                                         }
7769                                 }
7770                         }
7771
7772                         // Set data for the fake xhr object
7773                         jqXHR.status = status;
7774                         jqXHR.statusText = statusText;
7775
7776                         // Success/Error
7777                         if ( isSuccess ) {
7778                                 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7779                         } else {
7780                                 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7781                         }
7782
7783                         // Status-dependent callbacks
7784                         jqXHR.statusCode( statusCode );
7785                         statusCode = undefined;
7786
7787                         if ( fireGlobals ) {
7788                                 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7789                                                 [ jqXHR, s, isSuccess ? success : error ] );
7790                         }
7791
7792                         // Complete
7793                         completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7794
7795                         if ( fireGlobals ) {
7796                                 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
7797                                 // Handle the global AJAX counter
7798                                 if ( !( --jQuery.active ) ) {
7799                                         jQuery.event.trigger( "ajaxStop" );
7800                                 }
7801                         }
7802                 }
7803
7804                 // Attach deferreds
7805                 deferred.promise( jqXHR );
7806                 jqXHR.success = jqXHR.done;
7807                 jqXHR.error = jqXHR.fail;
7808                 jqXHR.complete = completeDeferred.done;
7809
7810                 // Status-dependent callbacks
7811                 jqXHR.statusCode = function( map ) {
7812                         if ( map ) {
7813                                 var tmp;
7814                                 if ( state < 2 ) {
7815                                         for( tmp in map ) {
7816                                                 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7817                                         }
7818                                 } else {
7819                                         tmp = map[ jqXHR.status ];
7820                                         jqXHR.then( tmp, tmp );
7821                                 }
7822                         }
7823                         return this;
7824                 };
7825
7826                 // Remove hash character (#7531: and string promotion)
7827                 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7828                 // We also use the url parameter if available
7829                 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7830
7831                 // Extract dataTypes list
7832                 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7833
7834                 // Determine if a cross-domain request is in order
7835                 if ( s.crossDomain == null ) {
7836                         parts = rurl.exec( s.url.toLowerCase() );
7837                         s.crossDomain = !!( parts &&
7838                                 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7839                                         ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7840                                                 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7841                         );
7842                 }
7843
7844                 // Convert data if not already a string
7845                 if ( s.data && s.processData && typeof s.data !== "string" ) {
7846                         s.data = jQuery.param( s.data, s.traditional );
7847                 }
7848
7849                 // Apply prefilters
7850                 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7851
7852                 // If request was aborted inside a prefiler, stop there
7853                 if ( state === 2 ) {
7854                         return false;
7855                 }
7856
7857                 // We can fire global events as of now if asked to
7858                 fireGlobals = s.global;
7859
7860                 // Uppercase the type
7861                 s.type = s.type.toUpperCase();
7862
7863                 // Determine if request has content
7864                 s.hasContent = !rnoContent.test( s.type );
7865
7866                 // Watch for a new set of requests
7867                 if ( fireGlobals && jQuery.active++ === 0 ) {
7868                         jQuery.event.trigger( "ajaxStart" );
7869                 }
7870
7871                 // More options handling for requests with no content
7872                 if ( !s.hasContent ) {
7873
7874                         // If data is available, append data to url
7875                         if ( s.data ) {
7876                                 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7877                         }
7878
7879                         // Get ifModifiedKey before adding the anti-cache parameter
7880                         ifModifiedKey = s.url;
7881
7882                         // Add anti-cache in url if needed
7883                         if ( s.cache === false ) {
7884
7885                                 var ts = jQuery.now(),
7886                                         // try replacing _= if it is there
7887                                         ret = s.url.replace( rts, "$1_=" + ts );
7888
7889                                 // if nothing was replaced, add timestamp to the end
7890                                 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7891                         }
7892                 }
7893
7894                 // Set the correct header, if data is being sent
7895                 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7896                         jqXHR.setRequestHeader( "Content-Type", s.contentType );
7897                 }
7898
7899                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7900                 if ( s.ifModified ) {
7901                         ifModifiedKey = ifModifiedKey || s.url;
7902                         if ( jQuery.lastModified[ ifModifiedKey ] ) {
7903                                 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7904                         }
7905                         if ( jQuery.etag[ ifModifiedKey ] ) {
7906                                 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7907                         }
7908                 }
7909
7910                 // Set the Accepts header for the server, depending on the dataType
7911                 jqXHR.setRequestHeader(
7912                         "Accept",
7913                         s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7914                                 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
7915                                 s.accepts[ "*" ]
7916                 );
7917
7918                 // Check for headers option
7919                 for ( i in s.headers ) {
7920                         jqXHR.setRequestHeader( i, s.headers[ i ] );
7921                 }
7922
7923                 // Allow custom headers/mimetypes and early abort
7924                 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7925                                 // Abort if not done already
7926                                 jqXHR.abort();
7927                                 return false;
7928
7929                 }
7930
7931                 // Install callbacks on deferreds
7932                 for ( i in { success: 1, error: 1, complete: 1 } ) {
7933                         jqXHR[ i ]( s[ i ] );
7934                 }
7935
7936                 // Get transport
7937                 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7938
7939                 // If no transport, we auto-abort
7940                 if ( !transport ) {
7941                         done( -1, "No Transport" );
7942                 } else {
7943                         jqXHR.readyState = 1;
7944                         // Send global event
7945                         if ( fireGlobals ) {
7946                                 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7947                         }
7948                         // Timeout
7949                         if ( s.async && s.timeout > 0 ) {
7950                                 timeoutTimer = setTimeout( function(){
7951                                         jqXHR.abort( "timeout" );
7952                                 }, s.timeout );
7953                         }
7954
7955                         try {
7956                                 state = 1;
7957                                 transport.send( requestHeaders, done );
7958                         } catch (e) {
7959                                 // Propagate exception as error if not done
7960                                 if ( status < 2 ) {
7961                                         done( -1, e );
7962                                 // Simply rethrow otherwise
7963                                 } else {
7964                                         jQuery.error( e );
7965                                 }
7966                         }
7967                 }
7968
7969                 return jqXHR;
7970         },
7971
7972         // Serialize an array of form elements or a set of
7973         // key/values into a query string
7974         param: function( a, traditional ) {
7975                 var s = [],
7976                         add = function( key, value ) {
7977                                 // If value is a function, invoke it and return its value
7978                                 value = jQuery.isFunction( value ) ? value() : value;
7979                                 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7980                         };
7981
7982                 // Set traditional to true for jQuery <= 1.3.2 behavior.
7983                 if ( traditional === undefined ) {
7984                         traditional = jQuery.ajaxSettings.traditional;
7985                 }
7986
7987                 // If an array was passed in, assume that it is an array of form elements.
7988                 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7989                         // Serialize the form elements
7990                         jQuery.each( a, function() {
7991                                 add( this.name, this.value );
7992                         });
7993
7994                 } else {
7995                         // If traditional, encode the "old" way (the way 1.3.2 or older
7996                         // did it), otherwise encode params recursively.
7997                         for ( var prefix in a ) {
7998                                 buildParams( prefix, a[ prefix ], traditional, add );
7999                         }
8000                 }
8001
8002                 // Return the resulting serialization
8003                 return s.join( "&" ).replace( r20, "+" );
8004         }
8005 });
8006
8007 function buildParams( prefix, obj, traditional, add ) {
8008         if ( jQuery.isArray( obj ) ) {
8009                 // Serialize array item.
8010                 jQuery.each( obj, function( i, v ) {
8011                         if ( traditional || rbracket.test( prefix ) ) {
8012                                 // Treat each array item as a scalar.
8013                                 add( prefix, v );
8014
8015                         } else {
8016                                 // If array item is non-scalar (array or object), encode its
8017                                 // numeric index to resolve deserialization ambiguity issues.
8018                                 // Note that rack (as of 1.0.0) can't currently deserialize
8019                                 // nested arrays properly, and attempting to do so may cause
8020                                 // a server error. Possible fixes are to modify rack's
8021                                 // deserialization algorithm or to provide an option or flag
8022                                 // to force array serialization to be shallow.
8023                                 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
8024                         }
8025                 });
8026
8027         } else if ( !traditional && obj != null && typeof obj === "object" ) {
8028                 // Serialize object item.
8029                 for ( var name in obj ) {
8030                         buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8031                 }
8032
8033         } else {
8034                 // Serialize scalar item.
8035                 add( prefix, obj );
8036         }
8037 }
8038
8039 // This is still on the jQuery object... for now
8040 // Want to move this to jQuery.ajax some day
8041 jQuery.extend({
8042
8043         // Counter for holding the number of active queries
8044         active: 0,
8045
8046         // Last-Modified header cache for next request
8047         lastModified: {},
8048         etag: {}
8049
8050 });
8051
8052 /* Handles responses to an ajax request:
8053  * - sets all responseXXX fields accordingly
8054  * - finds the right dataType (mediates between content-type and expected dataType)
8055  * - returns the corresponding response
8056  */
8057 function ajaxHandleResponses( s, jqXHR, responses ) {
8058
8059         var contents = s.contents,
8060                 dataTypes = s.dataTypes,
8061                 responseFields = s.responseFields,
8062                 ct,
8063                 type,
8064                 finalDataType,
8065                 firstDataType;
8066
8067         // Fill responseXXX fields
8068         for( type in responseFields ) {
8069                 if ( type in responses ) {
8070                         jqXHR[ responseFields[type] ] = responses[ type ];
8071                 }
8072         }
8073
8074         // Remove auto dataType and get content-type in the process
8075         while( dataTypes[ 0 ] === "*" ) {
8076                 dataTypes.shift();
8077                 if ( ct === undefined ) {
8078                         ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
8079                 }
8080         }
8081
8082         // Check if we're dealing with a known content-type
8083         if ( ct ) {
8084                 for ( type in contents ) {
8085                         if ( contents[ type ] && contents[ type ].test( ct ) ) {
8086                                 dataTypes.unshift( type );
8087                                 break;
8088                         }
8089                 }
8090         }
8091
8092         // Check to see if we have a response for the expected dataType
8093         if ( dataTypes[ 0 ] in responses ) {
8094                 finalDataType = dataTypes[ 0 ];
8095         } else {
8096                 // Try convertible dataTypes
8097                 for ( type in responses ) {
8098                         if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
8099                                 finalDataType = type;
8100                                 break;
8101                         }
8102                         if ( !firstDataType ) {
8103                                 firstDataType = type;
8104                         }
8105                 }
8106                 // Or just use first one
8107                 finalDataType = finalDataType || firstDataType;
8108         }
8109
8110         // If we found a dataType
8111         // We add the dataType to the list if needed
8112         // and return the corresponding response
8113         if ( finalDataType ) {
8114                 if ( finalDataType !== dataTypes[ 0 ] ) {
8115                         dataTypes.unshift( finalDataType );
8116                 }
8117                 return responses[ finalDataType ];
8118         }
8119 }
8120
8121 // Chain conversions given the request and the original response
8122 function ajaxConvert( s, response ) {
8123
8124         // Apply the dataFilter if provided
8125         if ( s.dataFilter ) {
8126                 response = s.dataFilter( response, s.dataType );
8127         }
8128
8129         var dataTypes = s.dataTypes,
8130                 converters = {},
8131                 i,
8132                 key,
8133                 length = dataTypes.length,
8134                 tmp,
8135                 // Current and previous dataTypes
8136                 current = dataTypes[ 0 ],
8137                 prev,
8138                 // Conversion expression
8139                 conversion,
8140                 // Conversion function
8141                 conv,
8142                 // Conversion functions (transitive conversion)
8143                 conv1,
8144                 conv2;
8145
8146         // For each dataType in the chain
8147         for( i = 1; i < length; i++ ) {
8148
8149                 // Create converters map
8150                 // with lowercased keys
8151                 if ( i === 1 ) {
8152                         for( key in s.converters ) {
8153                                 if( typeof key === "string" ) {
8154                                         converters[ key.toLowerCase() ] = s.converters[ key ];
8155                                 }
8156                         }
8157                 }
8158
8159                 // Get the dataTypes
8160                 prev = current;
8161                 current = dataTypes[ i ];
8162
8163                 // If current is auto dataType, update it to prev
8164                 if( current === "*" ) {
8165                         current = prev;
8166                 // If no auto and dataTypes are actually different
8167                 } else if ( prev !== "*" && prev !== current ) {
8168
8169                         // Get the converter
8170                         conversion = prev + " " + current;
8171                         conv = converters[ conversion ] || converters[ "* " + current ];
8172
8173                         // If there is no direct converter, search transitively
8174                         if ( !conv ) {
8175                                 conv2 = undefined;
8176                                 for( conv1 in converters ) {
8177                                         tmp = conv1.split( " " );
8178                                         if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
8179                                                 conv2 = converters[ tmp[1] + " " + current ];
8180                                                 if ( conv2 ) {
8181                                                         conv1 = converters[ conv1 ];
8182                                                         if ( conv1 === true ) {
8183                                                                 conv = conv2;
8184                                                         } else if ( conv2 === true ) {
8185                                                                 conv = conv1;
8186                                                         }
8187                                                         break;
8188                                                 }
8189                                         }
8190                                 }
8191                         }
8192                         // If we found no converter, dispatch an error
8193                         if ( !( conv || conv2 ) ) {
8194                                 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
8195                         }
8196                         // If found converter is not an equivalence
8197                         if ( conv !== true ) {
8198                                 // Convert with 1 or 2 converters accordingly
8199                                 response = conv ? conv( response ) : conv2( conv1(response) );
8200                         }
8201                 }
8202         }
8203         return response;
8204 }
8205
8206
8207
8208
8209 var jsc = jQuery.now(),
8210         jsre = /(\=)\?(&|$)|\?\?/i;
8211
8212 // Default jsonp settings
8213 jQuery.ajaxSetup({
8214         jsonp: "callback",
8215         jsonpCallback: function() {
8216                 return jQuery.expando + "_" + ( jsc++ );
8217         }
8218 });
8219
8220 // Detect, normalize options and install callbacks for jsonp requests
8221 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8222
8223         var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
8224                 ( typeof s.data === "string" );
8225
8226         if ( s.dataTypes[ 0 ] === "jsonp" ||
8227                 s.jsonp !== false && ( jsre.test( s.url ) ||
8228                                 inspectData && jsre.test( s.data ) ) ) {
8229
8230                 var responseContainer,
8231                         jsonpCallback = s.jsonpCallback =
8232                                 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
8233                         previous = window[ jsonpCallback ],
8234                         url = s.url,
8235                         data = s.data,
8236                         replace = "$1" + jsonpCallback + "$2";
8237
8238                 if ( s.jsonp !== false ) {
8239                         url = url.replace( jsre, replace );
8240                         if ( s.url === url ) {
8241                                 if ( inspectData ) {
8242                                         data = data.replace( jsre, replace );
8243                                 }
8244                                 if ( s.data === data ) {
8245                                         // Add callback manually
8246                                         url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
8247                                 }
8248                         }
8249                 }
8250
8251                 s.url = url;
8252                 s.data = data;
8253
8254                 // Install callback
8255                 window[ jsonpCallback ] = function( response ) {
8256                         responseContainer = [ response ];
8257                 };
8258
8259                 // Clean-up function
8260                 jqXHR.always(function() {
8261                         // Set callback back to previous value
8262                         window[ jsonpCallback ] = previous;
8263                         // Call if it was a function and we have a response
8264                         if ( responseContainer && jQuery.isFunction( previous ) ) {
8265                                 window[ jsonpCallback ]( responseContainer[ 0 ] );
8266                         }
8267                 });
8268
8269                 // Use data converter to retrieve json after script execution
8270                 s.converters["script json"] = function() {
8271                         if ( !responseContainer ) {
8272                                 jQuery.error( jsonpCallback + " was not called" );
8273                         }
8274                         return responseContainer[ 0 ];
8275                 };
8276
8277                 // force json dataType
8278                 s.dataTypes[ 0 ] = "json";
8279
8280                 // Delegate to script
8281                 return "script";
8282         }
8283 });
8284
8285
8286
8287
8288 // Install script dataType
8289 jQuery.ajaxSetup({
8290         accepts: {
8291                 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8292         },
8293         contents: {
8294                 script: /javascript|ecmascript/
8295         },
8296         converters: {
8297                 "text script": function( text ) {
8298                         jQuery.globalEval( text );
8299                         return text;
8300                 }
8301         }
8302 });
8303
8304 // Handle cache's special case and global
8305 jQuery.ajaxPrefilter( "script", function( s ) {
8306         if ( s.cache === undefined ) {
8307                 s.cache = false;
8308         }
8309         if ( s.crossDomain ) {
8310                 s.type = "GET";
8311                 s.global = false;
8312         }
8313 });
8314
8315 // Bind script tag hack transport
8316 jQuery.ajaxTransport( "script", function(s) {
8317
8318         // This transport only deals with cross domain requests
8319         if ( s.crossDomain ) {
8320
8321                 var script,
8322                         head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
8323
8324                 return {
8325
8326                         send: function( _, callback ) {
8327
8328                                 script = document.createElement( "script" );
8329
8330                                 script.async = "async";
8331
8332                                 if ( s.scriptCharset ) {
8333                                         script.charset = s.scriptCharset;
8334                                 }
8335
8336                                 script.src = s.url;
8337
8338                                 // Attach handlers for all browsers
8339                                 script.onload = script.onreadystatechange = function( _, isAbort ) {
8340
8341                                         if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
8342
8343                                                 // Handle memory leak in IE
8344                                                 script.onload = script.onreadystatechange = null;
8345
8346                                                 // Remove the script
8347                                                 if ( head && script.parentNode ) {
8348                                                         head.removeChild( script );
8349                                                 }
8350
8351                                                 // Dereference the script
8352                                                 script = undefined;
8353
8354                                                 // Callback if not abort
8355                                                 if ( !isAbort ) {
8356                                                         callback( 200, "success" );
8357                                                 }
8358                                         }
8359                                 };
8360                                 // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
8361                                 // This arises when a base node is used (#2709 and #4378).
8362                                 head.insertBefore( script, head.firstChild );
8363                         },
8364
8365                         abort: function() {
8366                                 if ( script ) {
8367                                         script.onload( 0, 1 );
8368                                 }
8369                         }
8370                 };
8371         }
8372 });
8373
8374
8375
8376
8377 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
8378         xhrOnUnloadAbort = window.ActiveXObject ? function() {
8379                 // Abort all pending requests
8380                 for ( var key in xhrCallbacks ) {
8381                         xhrCallbacks[ key ]( 0, 1 );
8382                 }
8383         } : false,
8384         xhrId = 0,
8385         xhrCallbacks;
8386
8387 // Functions to create xhrs
8388 function createStandardXHR() {
8389         try {
8390                 return new window.XMLHttpRequest();
8391         } catch( e ) {}
8392 }
8393
8394 function createActiveXHR() {
8395         try {
8396                 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
8397         } catch( e ) {}
8398 }
8399
8400 // Create the request object
8401 // (This is still attached to ajaxSettings for backward compatibility)
8402 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
8403         /* Microsoft failed to properly
8404          * implement the XMLHttpRequest in IE7 (can't request local files),
8405          * so we use the ActiveXObject when it is available
8406          * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
8407          * we need a fallback.
8408          */
8409         function() {
8410                 return !this.isLocal && createStandardXHR() || createActiveXHR();
8411         } :
8412         // For all other browsers, use the standard XMLHttpRequest object
8413         createStandardXHR;
8414
8415 // Determine support properties
8416 (function( xhr ) {
8417         jQuery.extend( jQuery.support, {
8418                 ajax: !!xhr,
8419                 cors: !!xhr && ( "withCredentials" in xhr )
8420         });
8421 })( jQuery.ajaxSettings.xhr() );
8422
8423 // Create transport if the browser can provide an xhr
8424 if ( jQuery.support.ajax ) {
8425
8426         jQuery.ajaxTransport(function( s ) {
8427                 // Cross domain only allowed if supported through XMLHttpRequest
8428                 if ( !s.crossDomain || jQuery.support.cors ) {
8429
8430                         var callback;
8431
8432                         return {
8433                                 send: function( headers, complete ) {
8434
8435                                         // Get a new xhr
8436                                         var xhr = s.xhr(),
8437                                                 handle,
8438                                                 i;
8439
8440                                         // Open the socket
8441                                         // Passing null username, generates a login popup on Opera (#2865)
8442                                         if ( s.username ) {
8443                                                 xhr.open( s.type, s.url, s.async, s.username, s.password );
8444                                         } else {
8445                                                 xhr.open( s.type, s.url, s.async );
8446                                         }
8447
8448                                         // Apply custom fields if provided
8449                                         if ( s.xhrFields ) {
8450                                                 for ( i in s.xhrFields ) {
8451                                                         xhr[ i ] = s.xhrFields[ i ];
8452                                                 }
8453                                         }
8454
8455                                         // Override mime type if needed
8456                                         if ( s.mimeType && xhr.overrideMimeType ) {
8457                                                 xhr.overrideMimeType( s.mimeType );
8458                                         }
8459
8460                                         // X-Requested-With header
8461                                         // For cross-domain requests, seeing as conditions for a preflight are
8462                                         // akin to a jigsaw puzzle, we simply never set it to be sure.
8463                                         // (it can always be set on a per-request basis or even using ajaxSetup)
8464                                         // For same-domain requests, won't change header if already provided.
8465                                         if ( !s.crossDomain && !headers["X-Requested-With"] ) {
8466                                                 headers[ "X-Requested-With" ] = "XMLHttpRequest";
8467                                         }
8468
8469                                         // Need an extra try/catch for cross domain requests in Firefox 3
8470                                         try {
8471                                                 for ( i in headers ) {
8472                                                         xhr.setRequestHeader( i, headers[ i ] );
8473                                                 }
8474                                         } catch( _ ) {}
8475
8476                                         // Do send the request
8477                                         // This may raise an exception which is actually
8478                                         // handled in jQuery.ajax (so no try/catch here)
8479                                         xhr.send( ( s.hasContent && s.data ) || null );
8480
8481                                         // Listener
8482                                         callback = function( _, isAbort ) {
8483
8484                                                 var status,
8485                                                         statusText,
8486                                                         responseHeaders,
8487                                                         responses,
8488                                                         xml;
8489
8490                                                 // Firefox throws exceptions when accessing properties
8491                                                 // of an xhr when a network error occured
8492                                                 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
8493                                                 try {
8494
8495                                                         // Was never called and is aborted or complete
8496                                                         if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
8497
8498                                                                 // Only called once
8499                                                                 callback = undefined;
8500
8501                                                                 // Do not keep as active anymore
8502                                                                 if ( handle ) {
8503                                                                         xhr.onreadystatechange = jQuery.noop;
8504                                                                         if ( xhrOnUnloadAbort ) {
8505                                                                                 delete xhrCallbacks[ handle ];
8506                                                                         }
8507                                                                 }
8508
8509                                                                 // If it's an abort
8510                                                                 if ( isAbort ) {
8511                                                                         // Abort it manually if needed
8512                                                                         if ( xhr.readyState !== 4 ) {
8513                                                                                 xhr.abort();
8514                                                                         }
8515                                                                 } else {
8516                                                                         status = xhr.status;
8517                                                                         responseHeaders = xhr.getAllResponseHeaders();
8518                                                                         responses = {};
8519                                                                         xml = xhr.responseXML;
8520
8521                                                                         // Construct response list
8522                                                                         if ( xml && xml.documentElement /* #4958 */ ) {
8523                                                                                 responses.xml = xml;
8524                                                                         }
8525                                                                         responses.text = xhr.responseText;
8526
8527                                                                         // Firefox throws an exception when accessing
8528                                                                         // statusText for faulty cross-domain requests
8529                                                                         try {
8530                                                                                 statusText = xhr.statusText;
8531                                                                         } catch( e ) {
8532                                                                                 // We normalize with Webkit giving an empty statusText
8533                                                                                 statusText = "";
8534                                                                         }
8535
8536                                                                         // Filter status for non standard behaviors
8537
8538                                                                         // If the request is local and we have data: assume a success
8539                                                                         // (success with no data won't get notified, that's the best we
8540                                                                         // can do given current implementations)
8541                                                                         if ( !status && s.isLocal && !s.crossDomain ) {
8542                                                                                 status = responses.text ? 200 : 404;
8543                                                                         // IE - #1450: sometimes returns 1223 when it should be 204
8544                                                                         } else if ( status === 1223 ) {
8545                                                                                 status = 204;
8546                                                                         }
8547                                                                 }
8548                                                         }
8549                                                 } catch( firefoxAccessException ) {
8550                                                         if ( !isAbort ) {
8551                                                                 complete( -1, firefoxAccessException );
8552                                                         }
8553                                                 }
8554
8555                                                 // Call complete if needed
8556                                                 if ( responses ) {
8557                                                         complete( status, statusText, responses, responseHeaders );
8558                                                 }
8559                                         };
8560
8561                                         // if we're in sync mode or it's in cache
8562                                         // and has been retrieved directly (IE6 & IE7)
8563                                         // we need to manually fire the callback
8564                                         if ( !s.async || xhr.readyState === 4 ) {
8565                                                 callback();
8566                                         } else {
8567                                                 handle = ++xhrId;
8568                                                 if ( xhrOnUnloadAbort ) {
8569                                                         // Create the active xhrs callbacks list if needed
8570                                                         // and attach the unload handler
8571                                                         if ( !xhrCallbacks ) {
8572                                                                 xhrCallbacks = {};
8573                                                                 jQuery( window ).unload( xhrOnUnloadAbort );
8574                                                         }
8575                                                         // Add to list of active xhrs callbacks
8576                                                         xhrCallbacks[ handle ] = callback;
8577                                                 }
8578                                                 xhr.onreadystatechange = callback;
8579                                         }
8580                                 },
8581
8582                                 abort: function() {
8583                                         if ( callback ) {
8584                                                 callback(0,1);
8585                                         }
8586                                 }
8587                         };
8588                 }
8589         });
8590 }
8591
8592
8593
8594
8595 var elemdisplay = {},
8596         iframe, iframeDoc,
8597         rfxtypes = /^(?:toggle|show|hide)$/,
8598         rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8599         timerId,
8600         fxAttrs = [
8601                 // height animations
8602                 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8603                 // width animations
8604                 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8605                 // opacity animations
8606                 [ "opacity" ]
8607         ],
8608         fxNow,
8609         requestAnimationFrame = window.webkitRequestAnimationFrame ||
8610             window.mozRequestAnimationFrame ||
8611             window.oRequestAnimationFrame;
8612
8613 jQuery.fn.extend({
8614         show: function( speed, easing, callback ) {
8615                 var elem, display;
8616
8617                 if ( speed || speed === 0 ) {
8618                         return this.animate( genFx("show", 3), speed, easing, callback);
8619
8620                 } else {
8621                         for ( var i = 0, j = this.length; i < j; i++ ) {
8622                                 elem = this[i];
8623
8624                                 if ( elem.style ) {
8625                                         display = elem.style.display;
8626
8627                                         // Reset the inline display of this element to learn if it is
8628                                         // being hidden by cascaded rules or not
8629                                         if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8630                                                 display = elem.style.display = "";
8631                                         }
8632
8633                                         // Set elements which have been overridden with display: none
8634                                         // in a stylesheet to whatever the default browser style is
8635                                         // for such an element
8636                                         if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
8637                                                 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
8638                                         }
8639                                 }
8640                         }
8641
8642                         // Set the display of most of the elements in a second loop
8643                         // to avoid the constant reflow
8644                         for ( i = 0; i < j; i++ ) {
8645                                 elem = this[i];
8646
8647                                 if ( elem.style ) {
8648                                         display = elem.style.display;
8649
8650                                         if ( display === "" || display === "none" ) {
8651                                                 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8652                                         }
8653                                 }
8654                         }
8655
8656                         return this;
8657                 }
8658         },
8659
8660         hide: function( speed, easing, callback ) {
8661                 if ( speed || speed === 0 ) {
8662                         return this.animate( genFx("hide", 3), speed, easing, callback);
8663
8664                 } else {
8665                         for ( var i = 0, j = this.length; i < j; i++ ) {
8666                                 if ( this[i].style ) {
8667                                         var display = jQuery.css( this[i], "display" );
8668
8669                                         if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8670                                                 jQuery._data( this[i], "olddisplay", display );
8671                                         }
8672                                 }
8673                         }
8674
8675                         // Set the display of the elements in a second loop
8676                         // to avoid the constant reflow
8677                         for ( i = 0; i < j; i++ ) {
8678                                 if ( this[i].style ) {
8679                                         this[i].style.display = "none";
8680                                 }
8681                         }
8682
8683                         return this;
8684                 }
8685         },
8686
8687         // Save the old toggle function
8688         _toggle: jQuery.fn.toggle,
8689
8690         toggle: function( fn, fn2, callback ) {
8691                 var bool = typeof fn === "boolean";
8692
8693                 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8694                         this._toggle.apply( this, arguments );
8695
8696                 } else if ( fn == null || bool ) {
8697                         this.each(function() {
8698                                 var state = bool ? fn : jQuery(this).is(":hidden");
8699                                 jQuery(this)[ state ? "show" : "hide" ]();
8700                         });
8701
8702                 } else {
8703                         this.animate(genFx("toggle", 3), fn, fn2, callback);
8704                 }
8705
8706                 return this;
8707         },
8708
8709         fadeTo: function( speed, to, easing, callback ) {
8710                 return this.filter(":hidden").css("opacity", 0).show().end()
8711                                         .animate({opacity: to}, speed, easing, callback);
8712         },
8713
8714         animate: function( prop, speed, easing, callback ) {
8715                 var optall = jQuery.speed(speed, easing, callback);
8716
8717                 if ( jQuery.isEmptyObject( prop ) ) {
8718                         return this.each( optall.complete, [ false ] );
8719                 }
8720
8721                 return this[ optall.queue === false ? "each" : "queue" ](function() {
8722                         // XXX 'this' does not always have a nodeName when running the
8723                         // test suite
8724
8725                         if ( optall.queue === false ) {
8726                                 jQuery._mark( this );
8727                         }
8728
8729                         var opt = jQuery.extend({}, optall),
8730                                 isElement = this.nodeType === 1,
8731                                 hidden = isElement && jQuery(this).is(":hidden"),
8732                                 name, val, p,
8733                                 display, e,
8734                                 parts, start, end, unit;
8735
8736                         // will store per property easing and be used to determine when an animation is complete
8737                         opt.animatedProperties = {};
8738
8739                         for ( p in prop ) {
8740
8741                                 // property name normalization
8742                                 name = jQuery.camelCase( p );
8743                                 if ( p !== name ) {
8744                                         prop[ name ] = prop[ p ];
8745                                         delete prop[ p ];
8746                                 }
8747
8748                                 val = prop[name];
8749
8750                                 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8751                                         return opt.complete.call(this);
8752                                 }
8753
8754                                 if ( isElement && ( name === "height" || name === "width" ) ) {
8755                                         // Make sure that nothing sneaks out
8756                                         // Record all 3 overflow attributes because IE does not
8757                                         // change the overflow attribute when overflowX and
8758                                         // overflowY are set to the same value
8759                                         opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8760
8761                                         // Set display property to inline-block for height/width
8762                                         // animations on inline elements that are having width/height
8763                                         // animated
8764                                         if ( jQuery.css( this, "display" ) === "inline" &&
8765                                                         jQuery.css( this, "float" ) === "none" ) {
8766                                                 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8767                                                         this.style.display = "inline-block";
8768
8769                                                 } else {
8770                                                         display = defaultDisplay(this.nodeName);
8771
8772                                                         // inline-level elements accept inline-block;
8773                                                         // block-level elements need to be inline with layout
8774                                                         if ( display === "inline" ) {
8775                                                                 this.style.display = "inline-block";
8776
8777                                                         } else {
8778                                                                 this.style.display = "inline";
8779                                                                 this.style.zoom = 1;
8780                                                         }
8781                                                 }
8782                                         }
8783                                 }
8784
8785                                 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8786                                 opt.animatedProperties[name] = jQuery.isArray( val ) ?
8787                                         val[1]:
8788                                         opt.specialEasing && opt.specialEasing[name] || opt.easing || 'swing';
8789                         }
8790
8791                         if ( opt.overflow != null ) {
8792                                 this.style.overflow = "hidden";
8793                         }
8794
8795                         for ( p in prop ) {
8796                                 e = new jQuery.fx( this, opt, p );
8797
8798                                 val = prop[p];
8799
8800                                 if ( rfxtypes.test(val) ) {
8801                                         e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8802
8803                                 } else {
8804                                         parts = rfxnum.exec(val);
8805                                         start = e.cur();
8806
8807                                         if ( parts ) {
8808                                                 end = parseFloat( parts[2] );
8809                                                 unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" );
8810
8811                                                 // We need to compute starting value
8812                                                 if ( unit !== "px" ) {
8813                                                         jQuery.style( this, p, (end || 1) + unit);
8814                                                         start = ((end || 1) / e.cur()) * start;
8815                                                         jQuery.style( this, p, start + unit);
8816                                                 }
8817
8818                                                 // If a +=/-= token was provided, we're doing a relative animation
8819                                                 if ( parts[1] ) {
8820                                                         end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
8821                                                 }
8822
8823                                                 e.custom( start, end, unit );
8824
8825                                         } else {
8826                                                 e.custom( start, val, "" );
8827                                         }
8828                                 }
8829                         }
8830
8831                         // For JS strict compliance
8832                         return true;
8833                 });
8834         },
8835
8836         stop: function( clearQueue, gotoEnd ) {
8837                 if ( clearQueue ) {
8838                         this.queue([]);
8839                 }
8840
8841                 this.each(function() {
8842                         var timers = jQuery.timers,
8843                                 i = timers.length;
8844                         // clear marker counters if we know they won't be
8845                         if ( !gotoEnd ) {
8846                                 jQuery._unmark( true, this );
8847                         }
8848                         // go in reverse order so anything added to the queue during the loop is ignored
8849                         while ( i-- ) {
8850                                 if ( timers[i].elem === this ) {
8851                                         if (gotoEnd) {
8852                                                 // force the next step to be the last
8853                                                 timers[i](true);
8854                                         }
8855
8856                                         timers.splice(i, 1);
8857                                 }
8858                         }
8859                 });
8860
8861                 // start the next in the queue if the last step wasn't forced
8862                 if ( !gotoEnd ) {
8863                         this.dequeue();
8864                 }
8865
8866                 return this;
8867         }
8868
8869 });
8870
8871 // Animations created synchronously will run synchronously
8872 function createFxNow() {
8873         setTimeout( clearFxNow, 0 );
8874         return ( fxNow = jQuery.now() );
8875 }
8876
8877 function clearFxNow() {
8878         fxNow = undefined;
8879 }
8880
8881 // Generate parameters to create a standard animation
8882 function genFx( type, num ) {
8883         var obj = {};
8884
8885         jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8886                 obj[ this ] = type;
8887         });
8888
8889         return obj;
8890 }
8891
8892 // Generate shortcuts for custom animations
8893 jQuery.each({
8894         slideDown: genFx("show", 1),
8895         slideUp: genFx("hide", 1),
8896         slideToggle: genFx("toggle", 1),
8897         fadeIn: { opacity: "show" },
8898         fadeOut: { opacity: "hide" },
8899         fadeToggle: { opacity: "toggle" }
8900 }, function( name, props ) {
8901         jQuery.fn[ name ] = function( speed, easing, callback ) {
8902                 return this.animate( props, speed, easing, callback );
8903         };
8904 });
8905
8906 jQuery.extend({
8907         speed: function( speed, easing, fn ) {
8908                 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8909                         complete: fn || !fn && easing ||
8910                                 jQuery.isFunction( speed ) && speed,
8911                         duration: speed,
8912                         easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8913                 };
8914
8915                 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8916                         opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8917
8918                 // Queueing
8919                 opt.old = opt.complete;
8920                 opt.complete = function( noUnmark ) {
8921                         if ( opt.queue !== false ) {
8922                                 jQuery.dequeue( this );
8923                         } else if ( noUnmark !== false ) {
8924                                 jQuery._unmark( this );
8925                         }
8926
8927                         if ( jQuery.isFunction( opt.old ) ) {
8928                                 opt.old.call( this );
8929                         }
8930                 };
8931
8932                 return opt;
8933         },
8934
8935         easing: {
8936                 linear: function( p, n, firstNum, diff ) {
8937                         return firstNum + diff * p;
8938                 },
8939                 swing: function( p, n, firstNum, diff ) {
8940                         return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8941                 }
8942         },
8943
8944         timers: [],
8945
8946         fx: function( elem, options, prop ) {
8947                 this.options = options;
8948                 this.elem = elem;
8949                 this.prop = prop;
8950
8951                 options.orig = options.orig || {};
8952         }
8953
8954 });
8955
8956 jQuery.fx.prototype = {
8957         // Simple function for setting a style value
8958         update: function() {
8959                 if ( this.options.step ) {
8960                         this.options.step.call( this.elem, this.now, this );
8961                 }
8962
8963                 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8964         },
8965
8966         // Get the current size
8967         cur: function() {
8968                 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8969                         return this.elem[ this.prop ];
8970                 }
8971
8972                 var parsed,
8973                         r = jQuery.css( this.elem, this.prop );
8974                 // Empty strings, null, undefined and "auto" are converted to 0,
8975                 // complex values such as "rotate(1rad)" are returned as is,
8976                 // simple values such as "10px" are parsed to Float.
8977                 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8978         },
8979
8980         // Start an animation from one number to another
8981         custom: function( from, to, unit ) {
8982                 var self = this,
8983                         fx = jQuery.fx,
8984                         raf;
8985
8986                 this.startTime = fxNow || createFxNow();
8987                 this.start = from;
8988                 this.end = to;
8989                 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8990                 this.now = this.start;
8991                 this.pos = this.state = 0;
8992
8993                 function t( gotoEnd ) {
8994                         return self.step(gotoEnd);
8995                 }
8996
8997                 t.elem = this.elem;
8998
8999                 if ( t() && jQuery.timers.push(t) && !timerId ) {
9000                         // Use requestAnimationFrame instead of setInterval if available
9001                         if ( requestAnimationFrame ) {
9002                                 timerId = 1;
9003                                 raf = function() {
9004                                         // When timerId gets set to null at any point, this stops
9005                                         if ( timerId ) {
9006                                                 requestAnimationFrame( raf );
9007                                                 fx.tick();
9008                                         }
9009                                 };
9010                                 requestAnimationFrame( raf );
9011                         } else {
9012                                 timerId = setInterval( fx.tick, fx.interval );
9013                         }
9014                 }
9015         },
9016
9017         // Simple 'show' function
9018         show: function() {
9019                 // Remember where we started, so that we can go back to it later
9020                 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
9021                 this.options.show = true;
9022
9023                 // Begin the animation
9024                 // Make sure that we start at a small width/height to avoid any
9025                 // flash of content
9026                 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
9027
9028                 // Start by showing the element
9029                 jQuery( this.elem ).show();
9030         },
9031
9032         // Simple 'hide' function
9033         hide: function() {
9034                 // Remember where we started, so that we can go back to it later
9035                 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
9036                 this.options.hide = true;
9037
9038                 // Begin the animation
9039                 this.custom(this.cur(), 0);
9040         },
9041
9042         // Each step of an animation
9043         step: function( gotoEnd ) {
9044                 var t = fxNow || createFxNow(),
9045                         done = true,
9046                         elem = this.elem,
9047                         options = this.options,
9048                         i, n;
9049
9050                 if ( gotoEnd || t >= options.duration + this.startTime ) {
9051                         this.now = this.end;
9052                         this.pos = this.state = 1;
9053                         this.update();
9054
9055                         options.animatedProperties[ this.prop ] = true;
9056
9057                         for ( i in options.animatedProperties ) {
9058                                 if ( options.animatedProperties[i] !== true ) {
9059                                         done = false;
9060                                 }
9061                         }
9062
9063                         if ( done ) {
9064                                 // Reset the overflow
9065                                 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
9066
9067                                         jQuery.each( [ "", "X", "Y" ], function (index, value) {
9068                                                 elem.style[ "overflow" + value ] = options.overflow[index];
9069                                         });
9070                                 }
9071
9072                                 // Hide the element if the "hide" operation was done
9073                                 if ( options.hide ) {
9074                                         jQuery(elem).hide();
9075                                 }
9076
9077                                 // Reset the properties, if the item has been hidden or shown
9078                                 if ( options.hide || options.show ) {
9079                                         for ( var p in options.animatedProperties ) {
9080                                                 jQuery.style( elem, p, options.orig[p] );
9081                                         }
9082                                 }
9083
9084                                 // Execute the complete function
9085                                 options.complete.call( elem );
9086                         }
9087
9088                         return false;
9089
9090                 } else {
9091                         // classical easing cannot be used with an Infinity duration
9092                         if ( options.duration == Infinity ) {
9093                                 this.now = t;
9094                         } else {
9095                                 n = t - this.startTime;
9096
9097                                 this.state = n / options.duration;
9098                                 // Perform the easing function, defaults to swing
9099                                 this.pos = jQuery.easing[options.animatedProperties[this.prop]](this.state, n, 0, 1, options.duration);
9100                                 this.now = this.start + ((this.end - this.start) * this.pos);
9101                         }
9102                         // Perform the next step of the animation
9103                         this.update();
9104                 }
9105
9106                 return true;
9107         }
9108 };
9109
9110 jQuery.extend( jQuery.fx, {
9111         tick: function() {
9112                 var timers = jQuery.timers,
9113                         i = timers.length;
9114                 while ( i-- ) {
9115                         if ( !timers[i]() ) {
9116                                 timers.splice(i, 1);
9117                         }
9118                 }
9119
9120                 if ( !timers.length ) {
9121                         jQuery.fx.stop();
9122                 }
9123         },
9124
9125         interval: 13,
9126
9127         stop: function() {
9128                 clearInterval( timerId );
9129                 timerId = null;
9130         },
9131
9132         speeds: {
9133                 slow: 600,
9134                 fast: 200,
9135                 // Default speed
9136                 _default: 400
9137         },
9138
9139         step: {
9140                 opacity: function( fx ) {
9141                         jQuery.style( fx.elem, "opacity", fx.now );
9142                 },
9143
9144                 _default: function( fx ) {
9145                         if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
9146                                 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
9147                         } else {
9148                                 fx.elem[ fx.prop ] = fx.now;
9149                         }
9150                 }
9151         }
9152 });
9153
9154 if ( jQuery.expr && jQuery.expr.filters ) {
9155         jQuery.expr.filters.animated = function( elem ) {
9156                 return jQuery.grep(jQuery.timers, function( fn ) {
9157                         return elem === fn.elem;
9158                 }).length;
9159         };
9160 }
9161
9162 // Try to restore the default display value of an element
9163 function defaultDisplay( nodeName ) {
9164
9165         if ( !elemdisplay[ nodeName ] ) {
9166
9167                 var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
9168                         display = elem.css( "display" );
9169
9170                 elem.remove();
9171
9172                 // If the simple way fails,
9173                 // get element's real default display by attaching it to a temp iframe
9174                 if ( display === "none" || display === "" ) {
9175                         // No iframe to use yet, so create it
9176                         if ( !iframe ) {
9177                                 iframe = document.createElement( "iframe" );
9178                                 iframe.frameBorder = iframe.width = iframe.height = 0;
9179                         }
9180
9181                         document.body.appendChild( iframe );
9182
9183                         // Create a cacheable copy of the iframe document on first call.
9184                         // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
9185                         // document to it, Webkit & Firefox won't allow reusing the iframe document
9186                         if ( !iframeDoc || !iframe.createElement ) {
9187                                 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
9188                                 iframeDoc.write( "<!doctype><html><body></body></html>" );
9189                         }
9190
9191                         elem = iframeDoc.createElement( nodeName );
9192
9193                         iframeDoc.body.appendChild( elem );
9194
9195                         display = jQuery.css( elem, "display" );
9196
9197                         document.body.removeChild( iframe );
9198                 }
9199
9200                 // Store the correct default display
9201                 elemdisplay[ nodeName ] = display;
9202         }
9203
9204         return elemdisplay[ nodeName ];
9205 }
9206
9207
9208
9209
9210 var rtable = /^t(?:able|d|h)$/i,
9211         rroot = /^(?:body|html)$/i;
9212
9213 if ( "getBoundingClientRect" in document.documentElement ) {
9214         jQuery.fn.offset = function( options ) {
9215                 var elem = this[0], box;
9216
9217                 if ( options ) {
9218                         return this.each(function( i ) {
9219                                 jQuery.offset.setOffset( this, options, i );
9220                         });
9221                 }
9222
9223                 if ( !elem || !elem.ownerDocument ) {
9224                         return null;
9225                 }
9226
9227                 if ( elem === elem.ownerDocument.body ) {
9228                         return jQuery.offset.bodyOffset( elem );
9229                 }
9230
9231                 try {
9232                         box = elem.getBoundingClientRect();
9233                 } catch(e) {}
9234
9235                 var doc = elem.ownerDocument,
9236                         docElem = doc.documentElement;
9237
9238                 // Make sure we're not dealing with a disconnected DOM node
9239                 if ( !box || !jQuery.contains( docElem, elem ) ) {
9240                         return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
9241                 }
9242
9243                 var body = doc.body,
9244                         win = getWindow(doc),
9245                         clientTop  = docElem.clientTop  || body.clientTop  || 0,
9246                         clientLeft = docElem.clientLeft || body.clientLeft || 0,
9247                         scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
9248                         scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
9249                         top  = box.top  + scrollTop  - clientTop,
9250                         left = box.left + scrollLeft - clientLeft;
9251
9252                 return { top: top, left: left };
9253         };
9254
9255 } else {
9256         jQuery.fn.offset = function( options ) {
9257                 var elem = this[0];
9258
9259                 if ( options ) {
9260                         return this.each(function( i ) {
9261                                 jQuery.offset.setOffset( this, options, i );
9262                         });
9263                 }
9264
9265                 if ( !elem || !elem.ownerDocument ) {
9266                         return null;
9267                 }
9268
9269                 if ( elem === elem.ownerDocument.body ) {
9270                         return jQuery.offset.bodyOffset( elem );
9271                 }
9272
9273                 jQuery.offset.initialize();
9274
9275                 var computedStyle,
9276                         offsetParent = elem.offsetParent,
9277                         prevOffsetParent = elem,
9278                         doc = elem.ownerDocument,
9279                         docElem = doc.documentElement,
9280                         body = doc.body,
9281                         defaultView = doc.defaultView,
9282                         prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
9283                         top = elem.offsetTop,
9284                         left = elem.offsetLeft;
9285
9286                 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
9287                         if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
9288                                 break;
9289                         }
9290
9291                         computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
9292                         top  -= elem.scrollTop;
9293                         left -= elem.scrollLeft;
9294
9295                         if ( elem === offsetParent ) {
9296                                 top  += elem.offsetTop;
9297                                 left += elem.offsetLeft;
9298
9299                                 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
9300                                         top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
9301                                         left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9302                                 }
9303
9304                                 prevOffsetParent = offsetParent;
9305                                 offsetParent = elem.offsetParent;
9306                         }
9307
9308                         if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
9309                                 top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
9310                                 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
9311                         }
9312
9313                         prevComputedStyle = computedStyle;
9314                 }
9315
9316                 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
9317                         top  += body.offsetTop;
9318                         left += body.offsetLeft;
9319                 }
9320
9321                 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
9322                         top  += Math.max( docElem.scrollTop, body.scrollTop );
9323                         left += Math.max( docElem.scrollLeft, body.scrollLeft );
9324                 }
9325
9326                 return { top: top, left: left };
9327         };
9328 }
9329
9330 jQuery.offset = {
9331         initialize: function() {
9332                 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
9333                         html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
9334
9335                 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
9336
9337                 container.innerHTML = html;
9338                 body.insertBefore( container, body.firstChild );
9339                 innerDiv = container.firstChild;
9340                 checkDiv = innerDiv.firstChild;
9341                 td = innerDiv.nextSibling.firstChild.firstChild;
9342
9343                 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
9344                 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
9345
9346                 checkDiv.style.position = "fixed";
9347                 checkDiv.style.top = "20px";
9348
9349                 // safari subtracts parent border width here which is 5px
9350                 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
9351                 checkDiv.style.position = checkDiv.style.top = "";
9352
9353                 innerDiv.style.overflow = "hidden";
9354                 innerDiv.style.position = "relative";
9355
9356                 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
9357
9358                 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
9359
9360                 body.removeChild( container );
9361                 jQuery.offset.initialize = jQuery.noop;
9362         },
9363
9364         bodyOffset: function( body ) {
9365                 var top = body.offsetTop,
9366                         left = body.offsetLeft;
9367
9368                 jQuery.offset.initialize();
9369
9370                 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
9371                         top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
9372                         left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
9373                 }
9374
9375                 return { top: top, left: left };
9376         },
9377
9378         setOffset: function( elem, options, i ) {
9379                 var position = jQuery.css( elem, "position" );
9380
9381                 // set position first, in-case top/left are set even on static elem
9382                 if ( position === "static" ) {
9383                         elem.style.position = "relative";
9384                 }
9385
9386                 var curElem = jQuery( elem ),
9387                         curOffset = curElem.offset(),
9388                         curCSSTop = jQuery.css( elem, "top" ),
9389                         curCSSLeft = jQuery.css( elem, "left" ),
9390                         calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
9391                         props = {}, curPosition = {}, curTop, curLeft;
9392
9393                 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
9394                 if ( calculatePosition ) {
9395                         curPosition = curElem.position();
9396                         curTop = curPosition.top;
9397                         curLeft = curPosition.left;
9398                 } else {
9399                         curTop = parseFloat( curCSSTop ) || 0;
9400                         curLeft = parseFloat( curCSSLeft ) || 0;
9401                 }
9402
9403                 if ( jQuery.isFunction( options ) ) {
9404                         options = options.call( elem, i, curOffset );
9405                 }
9406
9407                 if (options.top != null) {
9408                         props.top = (options.top - curOffset.top) + curTop;
9409                 }
9410                 if (options.left != null) {
9411                         props.left = (options.left - curOffset.left) + curLeft;
9412                 }
9413
9414                 if ( "using" in options ) {
9415                         options.using.call( elem, props );
9416                 } else {
9417                         curElem.css( props );
9418                 }
9419         }
9420 };
9421
9422
9423 jQuery.fn.extend({
9424         position: function() {
9425                 if ( !this[0] ) {
9426                         return null;
9427                 }
9428
9429                 var elem = this[0],
9430
9431                 // Get *real* offsetParent
9432                 offsetParent = this.offsetParent(),
9433
9434                 // Get correct offsets
9435                 offset       = this.offset(),
9436                 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
9437
9438                 // Subtract element margins
9439                 // note: when an element has margin: auto the offsetLeft and marginLeft
9440                 // are the same in Safari causing offset.left to incorrectly be 0
9441                 offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
9442                 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
9443
9444                 // Add offsetParent borders
9445                 parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
9446                 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
9447
9448                 // Subtract the two offsets
9449                 return {
9450                         top:  offset.top  - parentOffset.top,
9451                         left: offset.left - parentOffset.left
9452                 };
9453         },
9454
9455         offsetParent: function() {
9456                 return this.map(function() {
9457                         var offsetParent = this.offsetParent || document.body;
9458                         while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
9459                                 offsetParent = offsetParent.offsetParent;
9460                         }
9461                         return offsetParent;
9462                 });
9463         }
9464 });
9465
9466
9467 // Create scrollLeft and scrollTop methods
9468 jQuery.each( ["Left", "Top"], function( i, name ) {
9469         var method = "scroll" + name;
9470
9471         jQuery.fn[ method ] = function( val ) {
9472                 var elem, win;
9473
9474                 if ( val === undefined ) {
9475                         elem = this[ 0 ];
9476
9477                         if ( !elem ) {
9478                                 return null;
9479                         }
9480
9481                         win = getWindow( elem );
9482
9483                         // Return the scroll offset
9484                         return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
9485                                 jQuery.support.boxModel && win.document.documentElement[ method ] ||
9486                                         win.document.body[ method ] :
9487                                 elem[ method ];
9488                 }
9489
9490                 // Set the scroll offset
9491                 return this.each(function() {
9492                         win = getWindow( this );
9493
9494                         if ( win ) {
9495                                 win.scrollTo(
9496                                         !i ? val : jQuery( win ).scrollLeft(),
9497                                          i ? val : jQuery( win ).scrollTop()
9498                                 );
9499
9500                         } else {
9501                                 this[ method ] = val;
9502                         }
9503                 });
9504         };
9505 });
9506
9507 function getWindow( elem ) {
9508         return jQuery.isWindow( elem ) ?
9509                 elem :
9510                 elem.nodeType === 9 ?
9511                         elem.defaultView || elem.parentWindow :
9512                         false;
9513 }
9514
9515
9516
9517
9518 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
9519 jQuery.each([ "Height", "Width" ], function( i, name ) {
9520
9521         var type = name.toLowerCase();
9522
9523         // innerHeight and innerWidth
9524         jQuery.fn["inner" + name] = function() {
9525                 return this[0] ?
9526                         parseFloat( jQuery.css( this[0], type, "padding" ) ) :
9527                         null;
9528         };
9529
9530         // outerHeight and outerWidth
9531         jQuery.fn["outer" + name] = function( margin ) {
9532                 return this[0] ?
9533                         parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
9534                         null;
9535         };
9536
9537         jQuery.fn[ type ] = function( size ) {
9538                 // Get window width or height
9539                 var elem = this[0];
9540                 if ( !elem ) {
9541                         return size == null ? null : this;
9542                 }
9543
9544                 if ( jQuery.isFunction( size ) ) {
9545                         return this.each(function( i ) {
9546                                 var self = jQuery( this );
9547                                 self[ type ]( size.call( this, i, self[ type ]() ) );
9548                         });
9549                 }
9550
9551                 if ( jQuery.isWindow( elem ) ) {
9552                         // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
9553                         // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9554                         var docElemProp = elem.document.documentElement[ "client" + name ];
9555                         return elem.document.compatMode === "CSS1Compat" && docElemProp ||
9556                                 elem.document.body[ "client" + name ] || docElemProp;
9557
9558                 // Get document width or height
9559                 } else if ( elem.nodeType === 9 ) {
9560                         // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9561                         return Math.max(
9562                                 elem.documentElement["client" + name],
9563                                 elem.body["scroll" + name], elem.documentElement["scroll" + name],
9564                                 elem.body["offset" + name], elem.documentElement["offset" + name]
9565                         );
9566
9567                 // Get or set width or height on the element
9568                 } else if ( size === undefined ) {
9569                         var orig = jQuery.css( elem, type ),
9570                                 ret = parseFloat( orig );
9571
9572                         return jQuery.isNaN( ret ) ? orig : ret;
9573
9574                 // Set the width or height on the element (default to pixels if value is unitless)
9575                 } else {
9576                         return this.css( type, typeof size === "string" ? size : size + "px" );
9577                 }
9578         };
9579
9580 });
9581
9582
9583 window.jQuery = window.$ = jQuery;
9584 })(window);
9585 /*!
9586  * jQuery UI 1.8.12
9587  *
9588  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
9589  * licensed under MIT 
9590  * http://jquery.org/license
9591  *
9592  * http://docs.jquery.com/UI
9593  */
9594 (function( $, undefined ) {
9595
9596 // prevent duplicate loading
9597 // this is only a problem because we proxy existing functions
9598 // and we don't want to double proxy them
9599 $.ui = $.ui || {};
9600 if ( $.ui.version ) {
9601         return;
9602 }
9603
9604 $.extend( $.ui, {
9605         version: "1.8.12",
9606
9607         keyCode: {
9608                 ALT: 18,
9609                 BACKSPACE: 8,
9610                 CAPS_LOCK: 20,
9611                 COMMA: 188,
9612                 COMMAND: 91,
9613                 COMMAND_LEFT: 91, // COMMAND
9614                 COMMAND_RIGHT: 93,
9615                 CONTROL: 17,
9616                 DELETE: 46,
9617                 DOWN: 40,
9618                 END: 35,
9619                 ENTER: 13,
9620                 ESCAPE: 27,
9621                 HOME: 36,
9622                 INSERT: 45,
9623                 LEFT: 37,
9624                 MENU: 93, // COMMAND_RIGHT
9625                 NUMPAD_ADD: 107,
9626                 NUMPAD_DECIMAL: 110,
9627                 NUMPAD_DIVIDE: 111,
9628                 NUMPAD_ENTER: 108,
9629                 NUMPAD_MULTIPLY: 106,
9630                 NUMPAD_SUBTRACT: 109,
9631                 PAGE_DOWN: 34,
9632                 PAGE_UP: 33,
9633                 PERIOD: 190,
9634                 RIGHT: 39,
9635                 SHIFT: 16,
9636                 SPACE: 32,
9637                 TAB: 9,
9638                 UP: 38,
9639                 WINDOWS: 91 // COMMAND
9640         }
9641 });
9642
9643 // plugins
9644 $.fn.extend({
9645         _focus: $.fn.focus,
9646         focus: function( delay, fn ) {
9647                 return typeof delay === "number" ?
9648                         this.each(function() {
9649                                 var elem = this;
9650                                 setTimeout(function() {
9651                                         $( elem ).focus();
9652                                         if ( fn ) {
9653                                                 fn.call( elem );
9654                                         }
9655                                 }, delay );
9656                         }) :
9657                         this._focus.apply( this, arguments );
9658         },
9659
9660         scrollParent: function() {
9661                 var scrollParent;
9662                 if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
9663                         scrollParent = this.parents().filter(function() {
9664                                 return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
9665                         }).eq(0);
9666                 } else {
9667                         scrollParent = this.parents().filter(function() {
9668                                 return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
9669                         }).eq(0);
9670                 }
9671
9672                 return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
9673         },
9674
9675         zIndex: function( zIndex ) {
9676                 if ( zIndex !== undefined ) {
9677                         return this.css( "zIndex", zIndex );
9678                 }
9679
9680                 if ( this.length ) {
9681                         var elem = $( this[ 0 ] ), position, value;
9682                         while ( elem.length && elem[ 0 ] !== document ) {
9683                                 // Ignore z-index if position is set to a value where z-index is ignored by the browser
9684                                 // This makes behavior of this function consistent across browsers
9685                                 // WebKit always returns auto if the element is positioned
9686                                 position = elem.css( "position" );
9687                                 if ( position === "absolute" || position === "relative" || position === "fixed" ) {
9688                                         // IE returns 0 when zIndex is not specified
9689                                         // other browsers return a string
9690                                         // we ignore the case of nested elements with an explicit value of 0
9691                                         // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
9692                                         value = parseInt( elem.css( "zIndex" ), 10 );
9693                                         if ( !isNaN( value ) && value !== 0 ) {
9694                                                 return value;
9695                                         }
9696                                 }
9697                                 elem = elem.parent();
9698                         }
9699                 }
9700
9701                 return 0;
9702         },
9703
9704         disableSelection: function() {
9705                 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
9706                         ".ui-disableSelection", function( event ) {
9707                                 event.preventDefault();
9708                         });
9709         },
9710
9711         enableSelection: function() {
9712                 return this.unbind( ".ui-disableSelection" );
9713         }
9714 });
9715
9716 $.each( [ "Width", "Height" ], function( i, name ) {
9717         var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
9718                 type = name.toLowerCase(),
9719                 orig = {
9720                         innerWidth: $.fn.innerWidth,
9721                         innerHeight: $.fn.innerHeight,
9722                         outerWidth: $.fn.outerWidth,
9723                         outerHeight: $.fn.outerHeight
9724                 };
9725
9726         function reduce( elem, size, border, margin ) {
9727                 $.each( side, function() {
9728                         size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
9729                         if ( border ) {
9730                                 size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
9731                         }
9732                         if ( margin ) {
9733                                 size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
9734                         }
9735                 });
9736                 return size;
9737         }
9738
9739         $.fn[ "inner" + name ] = function( size ) {
9740                 if ( size === undefined ) {
9741                         return orig[ "inner" + name ].call( this );
9742                 }
9743
9744                 return this.each(function() {
9745                         $( this ).css( type, reduce( this, size ) + "px" );
9746                 });
9747         };
9748
9749         $.fn[ "outer" + name] = function( size, margin ) {
9750                 if ( typeof size !== "number" ) {
9751                         return orig[ "outer" + name ].call( this, size );
9752                 }
9753
9754                 return this.each(function() {
9755                         $( this).css( type, reduce( this, size, true, margin ) + "px" );
9756                 });
9757         };
9758 });
9759
9760 // selectors
9761 function visible( element ) {
9762         return !$( element ).parents().andSelf().filter(function() {
9763                 return $.curCSS( this, "visibility" ) === "hidden" ||
9764                         $.expr.filters.hidden( this );
9765         }).length;
9766 }
9767
9768 $.extend( $.expr[ ":" ], {
9769         data: function( elem, i, match ) {
9770                 return !!$.data( elem, match[ 3 ] );
9771         },
9772
9773         focusable: function( element ) {
9774                 var nodeName = element.nodeName.toLowerCase(),
9775                         tabIndex = $.attr( element, "tabindex" );
9776                 if ( "area" === nodeName ) {
9777                         var map = element.parentNode,
9778                                 mapName = map.name,
9779                                 img;
9780                         if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
9781                                 return false;
9782                         }
9783                         img = $( "img[usemap=#" + mapName + "]" )[0];
9784                         return !!img && visible( img );
9785                 }
9786                 return ( /input|select|textarea|button|object/.test( nodeName )
9787                         ? !element.disabled
9788                         : "a" == nodeName
9789                                 ? element.href || !isNaN( tabIndex )
9790                                 : !isNaN( tabIndex ))
9791                         // the element and all of its ancestors must be visible
9792                         && visible( element );
9793         },
9794
9795         tabbable: function( element ) {
9796                 var tabIndex = $.attr( element, "tabindex" );
9797                 return ( isNaN( tabIndex ) || tabIndex >= 0 ) && $( element ).is( ":focusable" );
9798         }
9799 });
9800
9801 // support
9802 $(function() {
9803         var body = document.body,
9804                 div = body.appendChild( div = document.createElement( "div" ) );
9805
9806         $.extend( div.style, {
9807                 minHeight: "100px",
9808                 height: "auto",
9809                 padding: 0,
9810                 borderWidth: 0
9811         });
9812
9813         $.support.minHeight = div.offsetHeight === 100;
9814         $.support.selectstart = "onselectstart" in div;
9815
9816         // set display to none to avoid a layout bug in IE
9817         // http://dev.jquery.com/ticket/4014
9818         body.removeChild( div ).style.display = "none";
9819 });
9820
9821
9822
9823
9824
9825 // deprecated
9826 $.extend( $.ui, {
9827         // $.ui.plugin is deprecated.  Use the proxy pattern instead.
9828         plugin: {
9829                 add: function( module, option, set ) {
9830                         var proto = $.ui[ module ].prototype;
9831                         for ( var i in set ) {
9832                                 proto.plugins[ i ] = proto.plugins[ i ] || [];
9833                                 proto.plugins[ i ].push( [ option, set[ i ] ] );
9834                         }
9835                 },
9836                 call: function( instance, name, args ) {
9837                         var set = instance.plugins[ name ];
9838                         if ( !set || !instance.element[ 0 ].parentNode ) {
9839                                 return;
9840                         }
9841         
9842                         for ( var i = 0; i < set.length; i++ ) {
9843                                 if ( instance.options[ set[ i ][ 0 ] ] ) {
9844                                         set[ i ][ 1 ].apply( instance.element, args );
9845                                 }
9846                         }
9847                 }
9848         },
9849         
9850         // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
9851         contains: function( a, b ) {
9852                 return document.compareDocumentPosition ?
9853                         a.compareDocumentPosition( b ) & 16 :
9854                         a !== b && a.contains( b );
9855         },
9856         
9857         // only used by resizable
9858         hasScroll: function( el, a ) {
9859         
9860                 //If overflow is hidden, the element might have extra content, but the user wants to hide it
9861                 if ( $( el ).css( "overflow" ) === "hidden") {
9862                         return false;
9863                 }
9864         
9865                 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
9866                         has = false;
9867         
9868                 if ( el[ scroll ] > 0 ) {
9869                         return true;
9870                 }
9871         
9872                 // TODO: determine which cases actually cause this to happen
9873                 // if the element doesn't have the scroll set, see if it's possible to
9874                 // set the scroll
9875                 el[ scroll ] = 1;
9876                 has = ( el[ scroll ] > 0 );
9877                 el[ scroll ] = 0;
9878                 return has;
9879         },
9880         
9881         // these are odd functions, fix the API or move into individual plugins
9882         isOverAxis: function( x, reference, size ) {
9883                 //Determines when x coordinate is over "b" element axis
9884                 return ( x > reference ) && ( x < ( reference + size ) );
9885         },
9886         isOver: function( y, x, top, left, height, width ) {
9887                 //Determines when x, y coordinates is over "b" element
9888                 return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
9889         }
9890 });
9891
9892 })( jQuery );
9893 /*!
9894  * jQuery UI Widget 1.8.12
9895  *
9896  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
9897  * Dual licensed under the MIT or GPL Version 2 licenses.
9898  * http://jquery.org/license
9899  *
9900  * http://docs.jquery.com/UI/Widget
9901  */
9902 (function( $, undefined ) {
9903
9904 // jQuery 1.4+
9905 if ( $.cleanData ) {
9906         var _cleanData = $.cleanData;
9907         $.cleanData = function( elems ) {
9908                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
9909                         $( elem ).triggerHandler( "remove" );
9910                 }
9911                 _cleanData( elems );
9912         };
9913 } else {
9914         var _remove = $.fn.remove;
9915         $.fn.remove = function( selector, keepData ) {
9916                 return this.each(function() {
9917                         if ( !keepData ) {
9918                                 if ( !selector || $.filter( selector, [ this ] ).length ) {
9919                                         $( "*", this ).add( [ this ] ).each(function() {
9920                                                 $( this ).triggerHandler( "remove" );
9921                                         });
9922                                 }
9923                         }
9924                         return _remove.call( $(this), selector, keepData );
9925                 });
9926         };
9927 }
9928
9929 $.widget = function( name, base, prototype ) {
9930         var namespace = name.split( "." )[ 0 ],
9931                 fullName;
9932         name = name.split( "." )[ 1 ];
9933         fullName = namespace + "-" + name;
9934
9935         if ( !prototype ) {
9936                 prototype = base;
9937                 base = $.Widget;
9938         }
9939
9940         // create selector for plugin
9941         $.expr[ ":" ][ fullName ] = function( elem ) {
9942                 return !!$.data( elem, name );
9943         };
9944
9945         $[ namespace ] = $[ namespace ] || {};
9946         $[ namespace ][ name ] = function( options, element ) {
9947                 // allow instantiation without initializing for simple inheritance
9948                 if ( arguments.length ) {
9949                         this._createWidget( options, element );
9950                 }
9951         };
9952
9953         var basePrototype = new base();
9954         // we need to make the options hash a property directly on the new instance
9955         // otherwise we'll modify the options hash on the prototype that we're
9956         // inheriting from
9957 //      $.each( basePrototype, function( key, val ) {
9958 //              if ( $.isPlainObject(val) ) {
9959 //                      basePrototype[ key ] = $.extend( {}, val );
9960 //              }
9961 //      });
9962         basePrototype.options = $.extend( true, {}, basePrototype.options );
9963         $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
9964                 namespace: namespace,
9965                 widgetName: name,
9966                 widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
9967                 widgetBaseClass: fullName
9968         }, prototype );
9969
9970         $.widget.bridge( name, $[ namespace ][ name ] );
9971 };
9972
9973 $.widget.bridge = function( name, object ) {
9974         $.fn[ name ] = function( options ) {
9975                 var isMethodCall = typeof options === "string",
9976                         args = Array.prototype.slice.call( arguments, 1 ),
9977                         returnValue = this;
9978
9979                 // allow multiple hashes to be passed on init
9980                 options = !isMethodCall && args.length ?
9981                         $.extend.apply( null, [ true, options ].concat(args) ) :
9982                         options;
9983
9984                 // prevent calls to internal methods
9985                 if ( isMethodCall && options.charAt( 0 ) === "_" ) {
9986                         return returnValue;
9987                 }
9988
9989                 if ( isMethodCall ) {
9990                         this.each(function() {
9991                                 var instance = $.data( this, name ),
9992                                         methodValue = instance && $.isFunction( instance[options] ) ?
9993                                                 instance[ options ].apply( instance, args ) :
9994                                                 instance;
9995                                 // TODO: add this back in 1.9 and use $.error() (see #5972)
9996 //                              if ( !instance ) {
9997 //                                      throw "cannot call methods on " + name + " prior to initialization; " +
9998 //                                              "attempted to call method '" + options + "'";
9999 //                              }
10000 //                              if ( !$.isFunction( instance[options] ) ) {
10001 //                                      throw "no such method '" + options + "' for " + name + " widget instance";
10002 //                              }
10003 //                              var methodValue = instance[ options ].apply( instance, args );
10004                                 if ( methodValue !== instance && methodValue !== undefined ) {
10005                                         returnValue = methodValue;
10006                                         return false;
10007                                 }
10008                         });
10009                 } else {
10010                         this.each(function() {
10011                                 var instance = $.data( this, name );
10012                                 if ( instance ) {
10013                                         instance.option( options || {} )._init();
10014                                 } else {
10015                                         $.data( this, name, new object( options, this ) );
10016                                 }
10017                         });
10018                 }
10019
10020                 return returnValue;
10021         };
10022 };
10023
10024 $.Widget = function( options, element ) {
10025         // allow instantiation without initializing for simple inheritance
10026         if ( arguments.length ) {
10027                 this._createWidget( options, element );
10028         }
10029 };
10030
10031 $.Widget.prototype = {
10032         widgetName: "widget",
10033         widgetEventPrefix: "",
10034         options: {
10035                 disabled: false
10036         },
10037         _createWidget: function( options, element ) {
10038                 // $.widget.bridge stores the plugin instance, but we do it anyway
10039                 // so that it's stored even before the _create function runs
10040                 $.data( element, this.widgetName, this );
10041                 this.element = $( element );
10042                 this.options = $.extend( true, {},
10043                         this.options,
10044                         this._getCreateOptions(),
10045                         options );
10046
10047                 var self = this;
10048                 this.element.bind( "remove." + this.widgetName, function() {
10049                         self.destroy();
10050                 });
10051
10052                 this._create();
10053                 this._trigger( "create" );
10054                 this._init();
10055         },
10056         _getCreateOptions: function() {
10057                 return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
10058         },
10059         _create: function() {},
10060         _init: function() {},
10061
10062         destroy: function() {
10063                 this.element
10064                         .unbind( "." + this.widgetName )
10065                         .removeData( this.widgetName );
10066                 this.widget()
10067                         .unbind( "." + this.widgetName )
10068                         .removeAttr( "aria-disabled" )
10069                         .removeClass(
10070                                 this.widgetBaseClass + "-disabled " +
10071                                 "ui-state-disabled" );
10072         },
10073
10074         widget: function() {
10075                 return this.element;
10076         },
10077
10078         option: function( key, value ) {
10079                 var options = key;
10080
10081                 if ( arguments.length === 0 ) {
10082                         // don't return a reference to the internal hash
10083                         return $.extend( {}, this.options );
10084                 }
10085
10086                 if  (typeof key === "string" ) {
10087                         if ( value === undefined ) {
10088                                 return this.options[ key ];
10089                         }
10090                         options = {};
10091                         options[ key ] = value;
10092                 }
10093
10094                 this._setOptions( options );
10095
10096                 return this;
10097         },
10098         _setOptions: function( options ) {
10099                 var self = this;
10100                 $.each( options, function( key, value ) {
10101                         self._setOption( key, value );
10102                 });
10103
10104                 return this;
10105         },
10106         _setOption: function( key, value ) {
10107                 this.options[ key ] = value;
10108
10109                 if ( key === "disabled" ) {
10110                         this.widget()
10111                                 [ value ? "addClass" : "removeClass"](
10112                                         this.widgetBaseClass + "-disabled" + " " +
10113                                         "ui-state-disabled" )
10114                                 .attr( "aria-disabled", value );
10115                 }
10116
10117                 return this;
10118         },
10119
10120         enable: function() {
10121                 return this._setOption( "disabled", false );
10122         },
10123         disable: function() {
10124                 return this._setOption( "disabled", true );
10125         },
10126
10127         _trigger: function( type, event, data ) {
10128                 var callback = this.options[ type ];
10129
10130                 event = $.Event( event );
10131                 event.type = ( type === this.widgetEventPrefix ?
10132                         type :
10133                         this.widgetEventPrefix + type ).toLowerCase();
10134                 data = data || {};
10135
10136                 // copy original event properties over to the new event
10137                 // this would happen if we could call $.event.fix instead of $.Event
10138                 // but we don't have a way to force an event to be fixed multiple times
10139                 if ( event.originalEvent ) {
10140                         for ( var i = $.event.props.length, prop; i; ) {
10141                                 prop = $.event.props[ --i ];
10142                                 event[ prop ] = event.originalEvent[ prop ];
10143                         }
10144                 }
10145
10146                 this.element.trigger( event, data );
10147
10148                 return !( $.isFunction(callback) &&
10149                         callback.call( this.element[0], event, data ) === false ||
10150                         event.isDefaultPrevented() );
10151         }
10152 };
10153
10154 })( jQuery );
10155 /*!
10156  * jQuery UI Mouse 1.8.12
10157  *
10158  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10159  * Dual licensed under the MIT or GPL Version 2 licenses.
10160  * http://jquery.org/license
10161  *
10162  * http://docs.jquery.com/UI/Mouse
10163  *
10164  * Depends:
10165  *      jquery.ui.widget.js
10166  */
10167 (function( $, undefined ) {
10168
10169 $.widget("ui.mouse", {
10170         options: {
10171                 cancel: ':input,option',
10172                 distance: 1,
10173                 delay: 0
10174         },
10175         _mouseInit: function() {
10176                 var self = this;
10177
10178                 this.element
10179                         .bind('mousedown.'+this.widgetName, function(event) {
10180                                 return self._mouseDown(event);
10181                         })
10182                         .bind('click.'+this.widgetName, function(event) {
10183                                 if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
10184                                     $.removeData(event.target, self.widgetName + '.preventClickEvent');
10185                                         event.stopImmediatePropagation();
10186                                         return false;
10187                                 }
10188                         });
10189
10190                 this.started = false;
10191         },
10192
10193         // TODO: make sure destroying one instance of mouse doesn't mess with
10194         // other instances of mouse
10195         _mouseDestroy: function() {
10196                 this.element.unbind('.'+this.widgetName);
10197         },
10198
10199         _mouseDown: function(event) {
10200                 // don't let more than one widget handle mouseStart
10201                 // TODO: figure out why we have to use originalEvent
10202                 event.originalEvent = event.originalEvent || {};
10203                 if (event.originalEvent.mouseHandled) { return; }
10204
10205                 // we may have missed mouseup (out of window)
10206                 (this._mouseStarted && this._mouseUp(event));
10207
10208                 this._mouseDownEvent = event;
10209
10210                 var self = this,
10211                         btnIsLeft = (event.which == 1),
10212                         elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
10213                 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
10214                         return true;
10215                 }
10216
10217                 this.mouseDelayMet = !this.options.delay;
10218                 if (!this.mouseDelayMet) {
10219                         this._mouseDelayTimer = setTimeout(function() {
10220                                 self.mouseDelayMet = true;
10221                         }, this.options.delay);
10222                 }
10223
10224                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
10225                         this._mouseStarted = (this._mouseStart(event) !== false);
10226                         if (!this._mouseStarted) {
10227                                 event.preventDefault();
10228                                 return true;
10229                         }
10230                 }
10231
10232                 // Click event may never have fired (Gecko & Opera)
10233                 if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
10234                         $.removeData(event.target, this.widgetName + '.preventClickEvent');
10235                 }
10236
10237                 // these delegates are required to keep context
10238                 this._mouseMoveDelegate = function(event) {
10239                         return self._mouseMove(event);
10240                 };
10241                 this._mouseUpDelegate = function(event) {
10242                         return self._mouseUp(event);
10243                 };
10244                 $(document)
10245                         .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
10246                         .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
10247
10248                 event.preventDefault();
10249                 event.originalEvent.mouseHandled = true;
10250                 return true;
10251         },
10252
10253         _mouseMove: function(event) {
10254                 // IE mouseup check - mouseup happened when mouse was out of window
10255                 if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
10256                         return this._mouseUp(event);
10257                 }
10258
10259                 if (this._mouseStarted) {
10260                         this._mouseDrag(event);
10261                         return event.preventDefault();
10262                 }
10263
10264                 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
10265                         this._mouseStarted =
10266                                 (this._mouseStart(this._mouseDownEvent, event) !== false);
10267                         (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
10268                 }
10269
10270                 return !this._mouseStarted;
10271         },
10272
10273         _mouseUp: function(event) {
10274                 $(document)
10275                         .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
10276                         .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
10277
10278                 if (this._mouseStarted) {
10279                         this._mouseStarted = false;
10280
10281                         if (event.target == this._mouseDownEvent.target) {
10282                             $.data(event.target, this.widgetName + '.preventClickEvent', true);
10283                         }
10284
10285                         this._mouseStop(event);
10286                 }
10287
10288                 return false;
10289         },
10290
10291         _mouseDistanceMet: function(event) {
10292                 return (Math.max(
10293                                 Math.abs(this._mouseDownEvent.pageX - event.pageX),
10294                                 Math.abs(this._mouseDownEvent.pageY - event.pageY)
10295                         ) >= this.options.distance
10296                 );
10297         },
10298
10299         _mouseDelayMet: function(event) {
10300                 return this.mouseDelayMet;
10301         },
10302
10303         // These are placeholder methods, to be overriden by extending plugin
10304         _mouseStart: function(event) {},
10305         _mouseDrag: function(event) {},
10306         _mouseStop: function(event) {},
10307         _mouseCapture: function(event) { return true; }
10308 });
10309
10310 })(jQuery);
10311 /*
10312  * jQuery UI Draggable 1.8.12
10313  *
10314  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10315  * Dual licensed under the MIT or GPL Version 2 licenses.
10316  * http://jquery.org/license
10317  *
10318  * http://docs.jquery.com/UI/Draggables
10319  *
10320  * Depends:
10321  *      jquery.ui.core.js
10322  *      jquery.ui.mouse.js
10323  *      jquery.ui.widget.js
10324  */
10325 (function( $, undefined ) {
10326
10327 $.widget("ui.draggable", $.ui.mouse, {
10328         widgetEventPrefix: "drag",
10329         options: {
10330                 addClasses: true,
10331                 appendTo: "parent",
10332                 axis: false,
10333                 connectToSortable: false,
10334                 containment: false,
10335                 cursor: "auto",
10336                 cursorAt: false,
10337                 grid: false,
10338                 handle: false,
10339                 helper: "original",
10340                 iframeFix: false,
10341                 opacity: false,
10342                 refreshPositions: false,
10343                 revert: false,
10344                 revertDuration: 500,
10345                 scope: "default",
10346                 scroll: true,
10347                 scrollSensitivity: 20,
10348                 scrollSpeed: 20,
10349                 snap: false,
10350                 snapMode: "both",
10351                 snapTolerance: 20,
10352                 stack: false,
10353                 zIndex: false
10354         },
10355         _create: function() {
10356
10357                 if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
10358                         this.element[0].style.position = 'relative';
10359
10360                 (this.options.addClasses && this.element.addClass("ui-draggable"));
10361                 (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
10362
10363                 this._mouseInit();
10364
10365         },
10366
10367         destroy: function() {
10368                 if(!this.element.data('draggable')) return;
10369                 this.element
10370                         .removeData("draggable")
10371                         .unbind(".draggable")
10372                         .removeClass("ui-draggable"
10373                                 + " ui-draggable-dragging"
10374                                 + " ui-draggable-disabled");
10375                 this._mouseDestroy();
10376
10377                 return this;
10378         },
10379
10380         _mouseCapture: function(event) {
10381
10382                 var o = this.options;
10383
10384                 // among others, prevent a drag on a resizable-handle
10385                 if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
10386                         return false;
10387
10388                 //Quit if we're not on a valid handle
10389                 this.handle = this._getHandle(event);
10390                 if (!this.handle)
10391                         return false;
10392
10393                 return true;
10394
10395         },
10396
10397         _mouseStart: function(event) {
10398
10399                 var o = this.options;
10400
10401                 //Create and append the visible helper
10402                 this.helper = this._createHelper(event);
10403
10404                 //Cache the helper size
10405                 this._cacheHelperProportions();
10406
10407                 //If ddmanager is used for droppables, set the global draggable
10408                 if($.ui.ddmanager)
10409                         $.ui.ddmanager.current = this;
10410
10411                 /*
10412                  * - Position generation -
10413                  * This block generates everything position related - it's the core of draggables.
10414                  */
10415
10416                 //Cache the margins of the original element
10417                 this._cacheMargins();
10418
10419                 //Store the helper's css position
10420                 this.cssPosition = this.helper.css("position");
10421                 this.scrollParent = this.helper.scrollParent();
10422
10423                 //The element's absolute position on the page minus margins
10424                 this.offset = this.positionAbs = this.element.offset();
10425                 this.offset = {
10426                         top: this.offset.top - this.margins.top,
10427                         left: this.offset.left - this.margins.left
10428                 };
10429
10430                 $.extend(this.offset, {
10431                         click: { //Where the click happened, relative to the element
10432                                 left: event.pageX - this.offset.left,
10433                                 top: event.pageY - this.offset.top
10434                         },
10435                         parent: this._getParentOffset(),
10436                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
10437                 });
10438
10439                 //Generate the original position
10440                 this.originalPosition = this.position = this._generatePosition(event);
10441                 this.originalPageX = event.pageX;
10442                 this.originalPageY = event.pageY;
10443
10444                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
10445                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
10446
10447                 //Set a containment if given in the options
10448                 if(o.containment)
10449                         this._setContainment();
10450
10451                 //Trigger event + callbacks
10452                 if(this._trigger("start", event) === false) {
10453                         this._clear();
10454                         return false;
10455                 }
10456
10457                 //Recache the helper size
10458                 this._cacheHelperProportions();
10459
10460                 //Prepare the droppable offsets
10461                 if ($.ui.ddmanager && !o.dropBehaviour)
10462                         $.ui.ddmanager.prepareOffsets(this, event);
10463
10464                 this.helper.addClass("ui-draggable-dragging");
10465                 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
10466                 return true;
10467         },
10468
10469         _mouseDrag: function(event, noPropagation) {
10470
10471                 //Compute the helpers position
10472                 this.position = this._generatePosition(event);
10473                 this.positionAbs = this._convertPositionTo("absolute");
10474
10475                 //Call plugins and callbacks and use the resulting position if something is returned
10476                 if (!noPropagation) {
10477                         var ui = this._uiHash();
10478                         if(this._trigger('drag', event, ui) === false) {
10479                                 this._mouseUp({});
10480                                 return false;
10481                         }
10482                         this.position = ui.position;
10483                 }
10484
10485                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
10486                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
10487                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
10488
10489                 return false;
10490         },
10491
10492         _mouseStop: function(event) {
10493
10494                 //If we are using droppables, inform the manager about the drop
10495                 var dropped = false;
10496                 if ($.ui.ddmanager && !this.options.dropBehaviour)
10497                         dropped = $.ui.ddmanager.drop(this, event);
10498
10499                 //if a drop comes from outside (a sortable)
10500                 if(this.dropped) {
10501                         dropped = this.dropped;
10502                         this.dropped = false;
10503                 }
10504                 
10505                 //if the original element is removed, don't bother to continue if helper is set to "original"
10506                 if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
10507                         return false;
10508
10509                 if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
10510                         var self = this;
10511                         $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
10512                                 if(self._trigger("stop", event) !== false) {
10513                                         self._clear();
10514                                 }
10515                         });
10516                 } else {
10517                         if(this._trigger("stop", event) !== false) {
10518                                 this._clear();
10519                         }
10520                 }
10521
10522                 return false;
10523         },
10524         
10525         cancel: function() {
10526                 
10527                 if(this.helper.is(".ui-draggable-dragging")) {
10528                         this._mouseUp({});
10529                 } else {
10530                         this._clear();
10531                 }
10532                 
10533                 return this;
10534                 
10535         },
10536
10537         _getHandle: function(event) {
10538
10539                 var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
10540                 $(this.options.handle, this.element)
10541                         .find("*")
10542                         .andSelf()
10543                         .each(function() {
10544                                 if(this == event.target) handle = true;
10545                         });
10546
10547                 return handle;
10548
10549         },
10550
10551         _createHelper: function(event) {
10552
10553                 var o = this.options;
10554                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
10555
10556                 if(!helper.parents('body').length)
10557                         helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
10558
10559                 if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
10560                         helper.css("position", "absolute");
10561
10562                 return helper;
10563
10564         },
10565
10566         _adjustOffsetFromHelper: function(obj) {
10567                 if (typeof obj == 'string') {
10568                         obj = obj.split(' ');
10569                 }
10570                 if ($.isArray(obj)) {
10571                         obj = {left: +obj[0], top: +obj[1] || 0};
10572                 }
10573                 if ('left' in obj) {
10574                         this.offset.click.left = obj.left + this.margins.left;
10575                 }
10576                 if ('right' in obj) {
10577                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
10578                 }
10579                 if ('top' in obj) {
10580                         this.offset.click.top = obj.top + this.margins.top;
10581                 }
10582                 if ('bottom' in obj) {
10583                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
10584                 }
10585         },
10586
10587         _getParentOffset: function() {
10588
10589                 //Get the offsetParent and cache its position
10590                 this.offsetParent = this.helper.offsetParent();
10591                 var po = this.offsetParent.offset();
10592
10593                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
10594                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
10595                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
10596                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
10597                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
10598                         po.left += this.scrollParent.scrollLeft();
10599                         po.top += this.scrollParent.scrollTop();
10600                 }
10601
10602                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
10603                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
10604                         po = { top: 0, left: 0 };
10605
10606                 return {
10607                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
10608                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
10609                 };
10610
10611         },
10612
10613         _getRelativeOffset: function() {
10614
10615                 if(this.cssPosition == "relative") {
10616                         var p = this.element.position();
10617                         return {
10618                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
10619                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
10620                         };
10621                 } else {
10622                         return { top: 0, left: 0 };
10623                 }
10624
10625         },
10626
10627         _cacheMargins: function() {
10628                 this.margins = {
10629                         left: (parseInt(this.element.css("marginLeft"),10) || 0),
10630                         top: (parseInt(this.element.css("marginTop"),10) || 0),
10631                         right: (parseInt(this.element.css("marginRight"),10) || 0),
10632                         bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
10633                 };
10634         },
10635
10636         _cacheHelperProportions: function() {
10637                 this.helperProportions = {
10638                         width: this.helper.outerWidth(),
10639                         height: this.helper.outerHeight()
10640                 };
10641         },
10642
10643         _setContainment: function() {
10644
10645                 var o = this.options;
10646                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
10647                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
10648                         (o.containment == 'document' ? 0 : $(window).scrollLeft()) - this.offset.relative.left - this.offset.parent.left,
10649                         (o.containment == 'document' ? 0 : $(window).scrollTop()) - this.offset.relative.top - this.offset.parent.top,
10650                         (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
10651                         (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
10652                 ];
10653
10654                 if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
10655                         var ce = $(o.containment)[0]; if(!ce) return;
10656                         var co = $(o.containment).offset();
10657                         var over = ($(ce).css("overflow") != 'hidden');
10658
10659                         this.containment = [
10660                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
10661                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
10662                                 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
10663                                 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
10664                         ];
10665                 } else if(o.containment.constructor == Array) {
10666                         this.containment = o.containment;
10667                 }
10668
10669         },
10670
10671         _convertPositionTo: function(d, pos) {
10672
10673                 if(!pos) pos = this.position;
10674                 var mod = d == "absolute" ? 1 : -1;
10675                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
10676
10677                 return {
10678                         top: (
10679                                 pos.top                                                                                                                                 // The absolute mouse position
10680                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
10681                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
10682                                 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
10683                         ),
10684                         left: (
10685                                 pos.left                                                                                                                                // The absolute mouse position
10686                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
10687                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
10688                                 - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
10689                         )
10690                 };
10691
10692         },
10693
10694         _generatePosition: function(event) {
10695
10696                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
10697                 var pageX = event.pageX;
10698                 var pageY = event.pageY;
10699
10700                 /*
10701                  * - Position constraining -
10702                  * Constrain the position to a mix of grid, containment.
10703                  */
10704
10705                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
10706
10707                         if(this.containment) {
10708                                 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
10709                                 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
10710                                 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
10711                                 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
10712                         }
10713
10714                         if(o.grid) {
10715                                 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
10716                                 pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
10717
10718                                 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
10719                                 pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
10720                         }
10721
10722                 }
10723
10724                 return {
10725                         top: (
10726                                 pageY                                                                                                                           // The absolute mouse position
10727                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
10728                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
10729                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
10730                                 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
10731                         ),
10732                         left: (
10733                                 pageX                                                                                                                           // The absolute mouse position
10734                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
10735                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
10736                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
10737                                 + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
10738                         )
10739                 };
10740
10741         },
10742
10743         _clear: function() {
10744                 this.helper.removeClass("ui-draggable-dragging");
10745                 if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
10746                 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
10747                 this.helper = null;
10748                 this.cancelHelperRemoval = false;
10749         },
10750
10751         // From now on bulk stuff - mainly helpers
10752
10753         _trigger: function(type, event, ui) {
10754                 ui = ui || this._uiHash();
10755                 $.ui.plugin.call(this, type, [event, ui]);
10756                 if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
10757                 return $.Widget.prototype._trigger.call(this, type, event, ui);
10758         },
10759
10760         plugins: {},
10761
10762         _uiHash: function(event) {
10763                 return {
10764                         helper: this.helper,
10765                         position: this.position,
10766                         originalPosition: this.originalPosition,
10767                         offset: this.positionAbs
10768                 };
10769         }
10770
10771 });
10772
10773 $.extend($.ui.draggable, {
10774         version: "1.8.12"
10775 });
10776
10777 $.ui.plugin.add("draggable", "connectToSortable", {
10778         start: function(event, ui) {
10779
10780                 var inst = $(this).data("draggable"), o = inst.options,
10781                         uiSortable = $.extend({}, ui, { item: inst.element });
10782                 inst.sortables = [];
10783                 $(o.connectToSortable).each(function() {
10784                         var sortable = $.data(this, 'sortable');
10785                         if (sortable && !sortable.options.disabled) {
10786                                 inst.sortables.push({
10787                                         instance: sortable,
10788                                         shouldRevert: sortable.options.revert
10789                                 });
10790                                 sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
10791                                 sortable._trigger("activate", event, uiSortable);
10792                         }
10793                 });
10794
10795         },
10796         stop: function(event, ui) {
10797
10798                 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
10799                 var inst = $(this).data("draggable"),
10800                         uiSortable = $.extend({}, ui, { item: inst.element });
10801
10802                 $.each(inst.sortables, function() {
10803                         if(this.instance.isOver) {
10804
10805                                 this.instance.isOver = 0;
10806
10807                                 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
10808                                 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
10809
10810                                 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
10811                                 if(this.shouldRevert) this.instance.options.revert = true;
10812
10813                                 //Trigger the stop of the sortable
10814                                 this.instance._mouseStop(event);
10815
10816                                 this.instance.options.helper = this.instance.options._helper;
10817
10818                                 //If the helper has been the original item, restore properties in the sortable
10819                                 if(inst.options.helper == 'original')
10820                                         this.instance.currentItem.css({ top: 'auto', left: 'auto' });
10821
10822                         } else {
10823                                 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
10824                                 this.instance._trigger("deactivate", event, uiSortable);
10825                         }
10826
10827                 });
10828
10829         },
10830         drag: function(event, ui) {
10831
10832                 var inst = $(this).data("draggable"), self = this;
10833
10834                 var checkPos = function(o) {
10835                         var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
10836                         var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
10837                         var itemHeight = o.height, itemWidth = o.width;
10838                         var itemTop = o.top, itemLeft = o.left;
10839
10840                         return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
10841                 };
10842
10843                 $.each(inst.sortables, function(i) {
10844                         
10845                         //Copy over some variables to allow calling the sortable's native _intersectsWith
10846                         this.instance.positionAbs = inst.positionAbs;
10847                         this.instance.helperProportions = inst.helperProportions;
10848                         this.instance.offset.click = inst.offset.click;
10849                         
10850                         if(this.instance._intersectsWith(this.instance.containerCache)) {
10851
10852                                 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
10853                                 if(!this.instance.isOver) {
10854
10855                                         this.instance.isOver = 1;
10856                                         //Now we fake the start of dragging for the sortable instance,
10857                                         //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
10858                                         //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
10859                                         this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
10860                                         this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
10861                                         this.instance.options.helper = function() { return ui.helper[0]; };
10862
10863                                         event.target = this.instance.currentItem[0];
10864                                         this.instance._mouseCapture(event, true);
10865                                         this.instance._mouseStart(event, true, true);
10866
10867                                         //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
10868                                         this.instance.offset.click.top = inst.offset.click.top;
10869                                         this.instance.offset.click.left = inst.offset.click.left;
10870                                         this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
10871                                         this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
10872
10873                                         inst._trigger("toSortable", event);
10874                                         inst.dropped = this.instance.element; //draggable revert needs that
10875                                         //hack so receive/update callbacks work (mostly)
10876                                         inst.currentItem = inst.element;
10877                                         this.instance.fromOutside = inst;
10878
10879                                 }
10880
10881                                 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
10882                                 if(this.instance.currentItem) this.instance._mouseDrag(event);
10883
10884                         } else {
10885
10886                                 //If it doesn't intersect with the sortable, and it intersected before,
10887                                 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
10888                                 if(this.instance.isOver) {
10889
10890                                         this.instance.isOver = 0;
10891                                         this.instance.cancelHelperRemoval = true;
10892                                         
10893                                         //Prevent reverting on this forced stop
10894                                         this.instance.options.revert = false;
10895                                         
10896                                         // The out event needs to be triggered independently
10897                                         this.instance._trigger('out', event, this.instance._uiHash(this.instance));
10898                                         
10899                                         this.instance._mouseStop(event, true);
10900                                         this.instance.options.helper = this.instance.options._helper;
10901
10902                                         //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
10903                                         this.instance.currentItem.remove();
10904                                         if(this.instance.placeholder) this.instance.placeholder.remove();
10905
10906                                         inst._trigger("fromSortable", event);
10907                                         inst.dropped = false; //draggable revert needs that
10908                                 }
10909
10910                         };
10911
10912                 });
10913
10914         }
10915 });
10916
10917 $.ui.plugin.add("draggable", "cursor", {
10918         start: function(event, ui) {
10919                 var t = $('body'), o = $(this).data('draggable').options;
10920                 if (t.css("cursor")) o._cursor = t.css("cursor");
10921                 t.css("cursor", o.cursor);
10922         },
10923         stop: function(event, ui) {
10924                 var o = $(this).data('draggable').options;
10925                 if (o._cursor) $('body').css("cursor", o._cursor);
10926         }
10927 });
10928
10929 $.ui.plugin.add("draggable", "iframeFix", {
10930         start: function(event, ui) {
10931                 var o = $(this).data('draggable').options;
10932                 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
10933                         $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
10934                         .css({
10935                                 width: this.offsetWidth+"px", height: this.offsetHeight+"px",
10936                                 position: "absolute", opacity: "0.001", zIndex: 1000
10937                         })
10938                         .css($(this).offset())
10939                         .appendTo("body");
10940                 });
10941         },
10942         stop: function(event, ui) {
10943                 $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
10944         }
10945 });
10946
10947 $.ui.plugin.add("draggable", "opacity", {
10948         start: function(event, ui) {
10949                 var t = $(ui.helper), o = $(this).data('draggable').options;
10950                 if(t.css("opacity")) o._opacity = t.css("opacity");
10951                 t.css('opacity', o.opacity);
10952         },
10953         stop: function(event, ui) {
10954                 var o = $(this).data('draggable').options;
10955                 if(o._opacity) $(ui.helper).css('opacity', o._opacity);
10956         }
10957 });
10958
10959 $.ui.plugin.add("draggable", "scroll", {
10960         start: function(event, ui) {
10961                 var i = $(this).data("draggable");
10962                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
10963         },
10964         drag: function(event, ui) {
10965
10966                 var i = $(this).data("draggable"), o = i.options, scrolled = false;
10967
10968                 if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
10969
10970                         if(!o.axis || o.axis != 'x') {
10971                                 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
10972                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
10973                                 else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
10974                                         i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
10975                         }
10976
10977                         if(!o.axis || o.axis != 'y') {
10978                                 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
10979                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
10980                                 else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
10981                                         i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
10982                         }
10983
10984                 } else {
10985
10986                         if(!o.axis || o.axis != 'x') {
10987                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
10988                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
10989                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
10990                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
10991                         }
10992
10993                         if(!o.axis || o.axis != 'y') {
10994                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
10995                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
10996                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
10997                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
10998                         }
10999
11000                 }
11001
11002                 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
11003                         $.ui.ddmanager.prepareOffsets(i, event);
11004
11005         }
11006 });
11007
11008 $.ui.plugin.add("draggable", "snap", {
11009         start: function(event, ui) {
11010
11011                 var i = $(this).data("draggable"), o = i.options;
11012                 i.snapElements = [];
11013
11014                 $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
11015                         var $t = $(this); var $o = $t.offset();
11016                         if(this != i.element[0]) i.snapElements.push({
11017                                 item: this,
11018                                 width: $t.outerWidth(), height: $t.outerHeight(),
11019                                 top: $o.top, left: $o.left
11020                         });
11021                 });
11022
11023         },
11024         drag: function(event, ui) {
11025
11026                 var inst = $(this).data("draggable"), o = inst.options;
11027                 var d = o.snapTolerance;
11028
11029                 var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
11030                         y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
11031
11032                 for (var i = inst.snapElements.length - 1; i >= 0; i--){
11033
11034                         var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
11035                                 t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
11036
11037                         //Yes, I know, this is insane ;)
11038                         if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
11039                                 if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
11040                                 inst.snapElements[i].snapping = false;
11041                                 continue;
11042                         }
11043
11044                         if(o.snapMode != 'inner') {
11045                                 var ts = Math.abs(t - y2) <= d;
11046                                 var bs = Math.abs(b - y1) <= d;
11047                                 var ls = Math.abs(l - x2) <= d;
11048                                 var rs = Math.abs(r - x1) <= d;
11049                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
11050                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
11051                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
11052                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
11053                         }
11054
11055                         var first = (ts || bs || ls || rs);
11056
11057                         if(o.snapMode != 'outer') {
11058                                 var ts = Math.abs(t - y1) <= d;
11059                                 var bs = Math.abs(b - y2) <= d;
11060                                 var ls = Math.abs(l - x1) <= d;
11061                                 var rs = Math.abs(r - x2) <= d;
11062                                 if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
11063                                 if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
11064                                 if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
11065                                 if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
11066                         }
11067
11068                         if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
11069                                 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
11070                         inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
11071
11072                 };
11073
11074         }
11075 });
11076
11077 $.ui.plugin.add("draggable", "stack", {
11078         start: function(event, ui) {
11079
11080                 var o = $(this).data("draggable").options;
11081
11082                 var group = $.makeArray($(o.stack)).sort(function(a,b) {
11083                         return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
11084                 });
11085                 if (!group.length) { return; }
11086                 
11087                 var min = parseInt(group[0].style.zIndex) || 0;
11088                 $(group).each(function(i) {
11089                         this.style.zIndex = min + i;
11090                 });
11091
11092                 this[0].style.zIndex = min + group.length;
11093
11094         }
11095 });
11096
11097 $.ui.plugin.add("draggable", "zIndex", {
11098         start: function(event, ui) {
11099                 var t = $(ui.helper), o = $(this).data("draggable").options;
11100                 if(t.css("zIndex")) o._zIndex = t.css("zIndex");
11101                 t.css('zIndex', o.zIndex);
11102         },
11103         stop: function(event, ui) {
11104                 var o = $(this).data("draggable").options;
11105                 if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
11106         }
11107 });
11108
11109 })(jQuery);
11110 /*
11111  * jQuery UI Droppable 1.8.12
11112  *
11113  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11114  * Dual licensed under the MIT or GPL Version 2 licenses.
11115  * http://jquery.org/license
11116  *
11117  * http://docs.jquery.com/UI/Droppables
11118  *
11119  * Depends:
11120  *      jquery.ui.core.js
11121  *      jquery.ui.widget.js
11122  *      jquery.ui.mouse.js
11123  *      jquery.ui.draggable.js
11124  */
11125 (function( $, undefined ) {
11126
11127 $.widget("ui.droppable", {
11128         widgetEventPrefix: "drop",
11129         options: {
11130                 accept: '*',
11131                 activeClass: false,
11132                 addClasses: true,
11133                 greedy: false,
11134                 hoverClass: false,
11135                 scope: 'default',
11136                 tolerance: 'intersect'
11137         },
11138         _create: function() {
11139
11140                 var o = this.options, accept = o.accept;
11141                 this.isover = 0; this.isout = 1;
11142
11143                 this.accept = $.isFunction(accept) ? accept : function(d) {
11144                         return d.is(accept);
11145                 };
11146
11147                 //Store the droppable's proportions
11148                 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
11149
11150                 // Add the reference and positions to the manager
11151                 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
11152                 $.ui.ddmanager.droppables[o.scope].push(this);
11153
11154                 (o.addClasses && this.element.addClass("ui-droppable"));
11155
11156         },
11157
11158         destroy: function() {
11159                 var drop = $.ui.ddmanager.droppables[this.options.scope];
11160                 for ( var i = 0; i < drop.length; i++ )
11161                         if ( drop[i] == this )
11162                                 drop.splice(i, 1);
11163
11164                 this.element
11165                         .removeClass("ui-droppable ui-droppable-disabled")
11166                         .removeData("droppable")
11167                         .unbind(".droppable");
11168
11169                 return this;
11170         },
11171
11172         _setOption: function(key, value) {
11173
11174                 if(key == 'accept') {
11175                         this.accept = $.isFunction(value) ? value : function(d) {
11176                                 return d.is(value);
11177                         };
11178                 }
11179                 $.Widget.prototype._setOption.apply(this, arguments);
11180         },
11181
11182         _activate: function(event) {
11183                 var draggable = $.ui.ddmanager.current;
11184                 if(this.options.activeClass) this.element.addClass(this.options.activeClass);
11185                 (draggable && this._trigger('activate', event, this.ui(draggable)));
11186         },
11187
11188         _deactivate: function(event) {
11189                 var draggable = $.ui.ddmanager.current;
11190                 if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
11191                 (draggable && this._trigger('deactivate', event, this.ui(draggable)));
11192         },
11193
11194         _over: function(event) {
11195
11196                 var draggable = $.ui.ddmanager.current;
11197                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
11198
11199                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
11200                         if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
11201                         this._trigger('over', event, this.ui(draggable));
11202                 }
11203
11204         },
11205
11206         _out: function(event) {
11207
11208                 var draggable = $.ui.ddmanager.current;
11209                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
11210
11211                 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
11212                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
11213                         this._trigger('out', event, this.ui(draggable));
11214                 }
11215
11216         },
11217
11218         _drop: function(event,custom) {
11219
11220                 var draggable = custom || $.ui.ddmanager.current;
11221                 if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
11222
11223                 var childrenIntersection = false;
11224                 this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
11225                         var inst = $.data(this, 'droppable');
11226                         if(
11227                                 inst.options.greedy
11228                                 && !inst.options.disabled
11229                                 && inst.options.scope == draggable.options.scope
11230                                 && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
11231                                 && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
11232                         ) { childrenIntersection = true; return false; }
11233                 });
11234                 if(childrenIntersection) return false;
11235
11236                 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
11237                         if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
11238                         if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
11239                         this._trigger('drop', event, this.ui(draggable));
11240                         return this.element;
11241                 }
11242
11243                 return false;
11244
11245         },
11246
11247         ui: function(c) {
11248                 return {
11249                         draggable: (c.currentItem || c.element),
11250                         helper: c.helper,
11251                         position: c.position,
11252                         offset: c.positionAbs
11253                 };
11254         }
11255
11256 });
11257
11258 $.extend($.ui.droppable, {
11259         version: "1.8.12"
11260 });
11261
11262 $.ui.intersect = function(draggable, droppable, toleranceMode) {
11263
11264         if (!droppable.offset) return false;
11265
11266         var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
11267                 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
11268         var l = droppable.offset.left, r = l + droppable.proportions.width,
11269                 t = droppable.offset.top, b = t + droppable.proportions.height;
11270
11271         switch (toleranceMode) {
11272                 case 'fit':
11273                         return (l <= x1 && x2 <= r
11274                                 && t <= y1 && y2 <= b);
11275                         break;
11276                 case 'intersect':
11277                         return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
11278                                 && x2 - (draggable.helperProportions.width / 2) < r // Left Half
11279                                 && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
11280                                 && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
11281                         break;
11282                 case 'pointer':
11283                         var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
11284                                 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
11285                                 isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
11286                         return isOver;
11287                         break;
11288                 case 'touch':
11289                         return (
11290                                         (y1 >= t && y1 <= b) || // Top edge touching
11291                                         (y2 >= t && y2 <= b) || // Bottom edge touching
11292                                         (y1 < t && y2 > b)              // Surrounded vertically
11293                                 ) && (
11294                                         (x1 >= l && x1 <= r) || // Left edge touching
11295                                         (x2 >= l && x2 <= r) || // Right edge touching
11296                                         (x1 < l && x2 > r)              // Surrounded horizontally
11297                                 );
11298                         break;
11299                 default:
11300                         return false;
11301                         break;
11302                 }
11303
11304 };
11305
11306 /*
11307         This manager tracks offsets of draggables and droppables
11308 */
11309 $.ui.ddmanager = {
11310         current: null,
11311         droppables: { 'default': [] },
11312         prepareOffsets: function(t, event) {
11313
11314                 var m = $.ui.ddmanager.droppables[t.options.scope] || [];
11315                 var type = event ? event.type : null; // workaround for #2317
11316                 var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
11317
11318                 droppablesLoop: for (var i = 0; i < m.length; i++) {
11319
11320                         if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue;   //No disabled and non-accepted
11321                         for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
11322                         m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue;                                                                       //If the element is not visible, continue
11323
11324                         if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
11325
11326                         m[i].offset = m[i].element.offset();
11327                         m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
11328
11329                 }
11330
11331         },
11332         drop: function(draggable, event) {
11333
11334                 var dropped = false;
11335                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
11336
11337                         if(!this.options) return;
11338                         if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
11339                                 dropped = dropped || this._drop.call(this, event);
11340
11341                         if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
11342                                 this.isout = 1; this.isover = 0;
11343                                 this._deactivate.call(this, event);
11344                         }
11345
11346                 });
11347                 return dropped;
11348
11349         },
11350         drag: function(draggable, event) {
11351
11352                 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
11353                 if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
11354
11355                 //Run through all droppables and check their positions based on specific tolerance options
11356                 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
11357
11358                         if(this.options.disabled || this.greedyChild || !this.visible) return;
11359                         var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
11360
11361                         var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
11362                         if(!c) return;
11363
11364                         var parentInstance;
11365                         if (this.options.greedy) {
11366                                 var parent = this.element.parents(':data(droppable):eq(0)');
11367                                 if (parent.length) {
11368                                         parentInstance = $.data(parent[0], 'droppable');
11369                                         parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
11370                                 }
11371                         }
11372
11373                         // we just moved into a greedy child
11374                         if (parentInstance && c == 'isover') {
11375                                 parentInstance['isover'] = 0;
11376                                 parentInstance['isout'] = 1;
11377                                 parentInstance._out.call(parentInstance, event);
11378                         }
11379
11380                         this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
11381                         this[c == "isover" ? "_over" : "_out"].call(this, event);
11382
11383                         // we just moved out of a greedy child
11384                         if (parentInstance && c == 'isout') {
11385                                 parentInstance['isout'] = 0;
11386                                 parentInstance['isover'] = 1;
11387                                 parentInstance._over.call(parentInstance, event);
11388                         }
11389                 });
11390
11391         }
11392 };
11393
11394 })(jQuery);
11395 /*
11396  * jQuery UI Resizable 1.8.12
11397  *
11398  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11399  * Dual licensed under the MIT or GPL Version 2 licenses.
11400  * http://jquery.org/license
11401  *
11402  * http://docs.jquery.com/UI/Resizables
11403  *
11404  * Depends:
11405  *      jquery.ui.core.js
11406  *      jquery.ui.mouse.js
11407  *      jquery.ui.widget.js
11408  */
11409 (function( $, undefined ) {
11410
11411 $.widget("ui.resizable", $.ui.mouse, {
11412         widgetEventPrefix: "resize",
11413         options: {
11414                 alsoResize: false,
11415                 animate: false,
11416                 animateDuration: "slow",
11417                 animateEasing: "swing",
11418                 aspectRatio: false,
11419                 autoHide: false,
11420                 containment: false,
11421                 ghost: false,
11422                 grid: false,
11423                 handles: "e,s,se",
11424                 helper: false,
11425                 maxHeight: null,
11426                 maxWidth: null,
11427                 minHeight: 10,
11428                 minWidth: 10,
11429                 zIndex: 1000
11430         },
11431         _create: function() {
11432
11433                 var self = this, o = this.options;
11434                 this.element.addClass("ui-resizable");
11435
11436                 $.extend(this, {
11437                         _aspectRatio: !!(o.aspectRatio),
11438                         aspectRatio: o.aspectRatio,
11439                         originalElement: this.element,
11440                         _proportionallyResizeElements: [],
11441                         _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
11442                 });
11443
11444                 //Wrap the element if it cannot hold child nodes
11445                 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
11446
11447                         //Opera fix for relative positioning
11448                         if (/relative/.test(this.element.css('position')) && $.browser.opera)
11449                                 this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
11450
11451                         //Create a wrapper element and set the wrapper to the new current internal element
11452                         this.element.wrap(
11453                                 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
11454                                         position: this.element.css('position'),
11455                                         width: this.element.outerWidth(),
11456                                         height: this.element.outerHeight(),
11457                                         top: this.element.css('top'),
11458                                         left: this.element.css('left')
11459                                 })
11460                         );
11461
11462                         //Overwrite the original this.element
11463                         this.element = this.element.parent().data(
11464                                 "resizable", this.element.data('resizable')
11465                         );
11466
11467                         this.elementIsWrapper = true;
11468
11469                         //Move margins to the wrapper
11470                         this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
11471                         this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
11472
11473                         //Prevent Safari textarea resize
11474                         this.originalResizeStyle = this.originalElement.css('resize');
11475                         this.originalElement.css('resize', 'none');
11476
11477                         //Push the actual element to our proportionallyResize internal array
11478                         this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
11479
11480                         // avoid IE jump (hard set the margin)
11481                         this.originalElement.css({ margin: this.originalElement.css('margin') });
11482
11483                         // fix handlers offset
11484                         this._proportionallyResize();
11485
11486                 }
11487
11488                 this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
11489                 if(this.handles.constructor == String) {
11490
11491                         if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
11492                         var n = this.handles.split(","); this.handles = {};
11493
11494                         for(var i = 0; i < n.length; i++) {
11495
11496                                 var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
11497                                 var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
11498
11499                                 // increase zIndex of sw, se, ne, nw axis
11500                                 //TODO : this modifies original option
11501                                 if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
11502
11503                                 //TODO : What's going on here?
11504                                 if ('se' == handle) {
11505                                         axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
11506                                 };
11507
11508                                 //Insert into internal handles object and append to element
11509                                 this.handles[handle] = '.ui-resizable-'+handle;
11510                                 this.element.append(axis);
11511                         }
11512
11513                 }
11514
11515                 this._renderAxis = function(target) {
11516
11517                         target = target || this.element;
11518
11519                         for(var i in this.handles) {
11520
11521                                 if(this.handles[i].constructor == String)
11522                                         this.handles[i] = $(this.handles[i], this.element).show();
11523
11524                                 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
11525                                 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
11526
11527                                         var axis = $(this.handles[i], this.element), padWrapper = 0;
11528
11529                                         //Checking the correct pad and border
11530                                         padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
11531
11532                                         //The padding type i have to apply...
11533                                         var padPos = [ 'padding',
11534                                                 /ne|nw|n/.test(i) ? 'Top' :
11535                                                 /se|sw|s/.test(i) ? 'Bottom' :
11536                                                 /^e$/.test(i) ? 'Right' : 'Left' ].join("");
11537
11538                                         target.css(padPos, padWrapper);
11539
11540                                         this._proportionallyResize();
11541
11542                                 }
11543
11544                                 //TODO: What's that good for? There's not anything to be executed left
11545                                 if(!$(this.handles[i]).length)
11546                                         continue;
11547
11548                         }
11549                 };
11550
11551                 //TODO: make renderAxis a prototype function
11552                 this._renderAxis(this.element);
11553
11554                 this._handles = $('.ui-resizable-handle', this.element)
11555                         .disableSelection();
11556
11557                 //Matching axis name
11558                 this._handles.mouseover(function() {
11559                         if (!self.resizing) {
11560                                 if (this.className)
11561                                         var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
11562                                 //Axis, default = se
11563                                 self.axis = axis && axis[1] ? axis[1] : 'se';
11564                         }
11565                 });
11566
11567                 //If we want to auto hide the elements
11568                 if (o.autoHide) {
11569                         this._handles.hide();
11570                         $(this.element)
11571                                 .addClass("ui-resizable-autohide")
11572                                 .hover(function() {
11573                                         $(this).removeClass("ui-resizable-autohide");
11574                                         self._handles.show();
11575                                 },
11576                                 function(){
11577                                         if (!self.resizing) {
11578                                                 $(this).addClass("ui-resizable-autohide");
11579                                                 self._handles.hide();
11580                                         }
11581                                 });
11582                 }
11583
11584                 //Initialize the mouse interaction
11585                 this._mouseInit();
11586
11587         },
11588
11589         destroy: function() {
11590
11591                 this._mouseDestroy();
11592
11593                 var _destroy = function(exp) {
11594                         $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
11595                                 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
11596                 };
11597
11598                 //TODO: Unwrap at same DOM position
11599                 if (this.elementIsWrapper) {
11600                         _destroy(this.element);
11601                         var wrapper = this.element;
11602                         wrapper.after(
11603                                 this.originalElement.css({
11604                                         position: wrapper.css('position'),
11605                                         width: wrapper.outerWidth(),
11606                                         height: wrapper.outerHeight(),
11607                                         top: wrapper.css('top'),
11608                                         left: wrapper.css('left')
11609                                 })
11610                         ).remove();
11611                 }
11612
11613                 this.originalElement.css('resize', this.originalResizeStyle);
11614                 _destroy(this.originalElement);
11615
11616                 return this;
11617         },
11618
11619         _mouseCapture: function(event) {
11620                 var handle = false;
11621                 for (var i in this.handles) {
11622                         if ($(this.handles[i])[0] == event.target) {
11623                                 handle = true;
11624                         }
11625                 }
11626
11627                 return !this.options.disabled && handle;
11628         },
11629
11630         _mouseStart: function(event) {
11631
11632                 var o = this.options, iniPos = this.element.position(), el = this.element;
11633
11634                 this.resizing = true;
11635                 this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
11636
11637                 // bugfix for http://dev.jquery.com/ticket/1749
11638                 if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
11639                         el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
11640                 }
11641
11642                 //Opera fixing relative position
11643                 if ($.browser.opera && (/relative/).test(el.css('position')))
11644                         el.css({ position: 'relative', top: 'auto', left: 'auto' });
11645
11646                 this._renderProxy();
11647
11648                 var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
11649
11650                 if (o.containment) {
11651                         curleft += $(o.containment).scrollLeft() || 0;
11652                         curtop += $(o.containment).scrollTop() || 0;
11653                 }
11654
11655                 //Store needed variables
11656                 this.offset = this.helper.offset();
11657                 this.position = { left: curleft, top: curtop };
11658                 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
11659                 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
11660                 this.originalPosition = { left: curleft, top: curtop };
11661                 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
11662                 this.originalMousePosition = { left: event.pageX, top: event.pageY };
11663
11664                 //Aspect Ratio
11665                 this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
11666
11667             var cursor = $('.ui-resizable-' + this.axis).css('cursor');
11668             $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
11669
11670                 el.addClass("ui-resizable-resizing");
11671                 this._propagate("start", event);
11672                 return true;
11673         },
11674
11675         _mouseDrag: function(event) {
11676
11677                 //Increase performance, avoid regex
11678                 var el = this.helper, o = this.options, props = {},
11679                         self = this, smp = this.originalMousePosition, a = this.axis;
11680
11681                 var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
11682                 var trigger = this._change[a];
11683                 if (!trigger) return false;
11684
11685                 // Calculate the attrs that will be change
11686                 var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
11687
11688                 if (this._aspectRatio || event.shiftKey)
11689                         data = this._updateRatio(data, event);
11690
11691                 data = this._respectSize(data, event);
11692
11693                 // plugins callbacks need to be called first
11694                 this._propagate("resize", event);
11695
11696                 el.css({
11697                         top: this.position.top + "px", left: this.position.left + "px",
11698                         width: this.size.width + "px", height: this.size.height + "px"
11699                 });
11700
11701                 if (!this._helper && this._proportionallyResizeElements.length)
11702                         this._proportionallyResize();
11703
11704                 this._updateCache(data);
11705
11706                 // calling the user callback at the end
11707                 this._trigger('resize', event, this.ui());
11708
11709                 return false;
11710         },
11711
11712         _mouseStop: function(event) {
11713
11714                 this.resizing = false;
11715                 var o = this.options, self = this;
11716
11717                 if(this._helper) {
11718                         var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
11719                                 soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
11720                                 soffsetw = ista ? 0 : self.sizeDiff.width;
11721
11722                         var s = { width: (self.helper.width()  - soffsetw), height: (self.helper.height() - soffseth) },
11723                                 left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
11724                                 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
11725
11726                         if (!o.animate)
11727                                 this.element.css($.extend(s, { top: top, left: left }));
11728
11729                         self.helper.height(self.size.height);
11730                         self.helper.width(self.size.width);
11731
11732                         if (this._helper && !o.animate) this._proportionallyResize();
11733                 }
11734
11735                 $('body').css('cursor', 'auto');
11736
11737                 this.element.removeClass("ui-resizable-resizing");
11738
11739                 this._propagate("stop", event);
11740
11741                 if (this._helper) this.helper.remove();
11742                 return false;
11743
11744         },
11745
11746         _updateCache: function(data) {
11747                 var o = this.options;
11748                 this.offset = this.helper.offset();
11749                 if (isNumber(data.left)) this.position.left = data.left;
11750                 if (isNumber(data.top)) this.position.top = data.top;
11751                 if (isNumber(data.height)) this.size.height = data.height;
11752                 if (isNumber(data.width)) this.size.width = data.width;
11753         },
11754
11755         _updateRatio: function(data, event) {
11756
11757                 var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
11758
11759                 if (data.height) data.width = (csize.height * this.aspectRatio);
11760                 else if (data.width) data.height = (csize.width / this.aspectRatio);
11761
11762                 if (a == 'sw') {
11763                         data.left = cpos.left + (csize.width - data.width);
11764                         data.top = null;
11765                 }
11766                 if (a == 'nw') {
11767                         data.top = cpos.top + (csize.height - data.height);
11768                         data.left = cpos.left + (csize.width - data.width);
11769                 }
11770
11771                 return data;
11772         },
11773
11774         _respectSize: function(data, event) {
11775
11776                 var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
11777                                 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
11778                                         isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
11779
11780                 if (isminw) data.width = o.minWidth;
11781                 if (isminh) data.height = o.minHeight;
11782                 if (ismaxw) data.width = o.maxWidth;
11783                 if (ismaxh) data.height = o.maxHeight;
11784
11785                 var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
11786                 var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
11787
11788                 if (isminw && cw) data.left = dw - o.minWidth;
11789                 if (ismaxw && cw) data.left = dw - o.maxWidth;
11790                 if (isminh && ch)       data.top = dh - o.minHeight;
11791                 if (ismaxh && ch)       data.top = dh - o.maxHeight;
11792
11793                 // fixing jump error on top/left - bug #2330
11794                 var isNotwh = !data.width && !data.height;
11795                 if (isNotwh && !data.left && data.top) data.top = null;
11796                 else if (isNotwh && !data.top && data.left) data.left = null;
11797
11798                 return data;
11799         },
11800
11801         _proportionallyResize: function() {
11802
11803                 var o = this.options;
11804                 if (!this._proportionallyResizeElements.length) return;
11805                 var element = this.helper || this.element;
11806
11807                 for (var i=0; i < this._proportionallyResizeElements.length; i++) {
11808
11809                         var prel = this._proportionallyResizeElements[i];
11810
11811                         if (!this.borderDif) {
11812                                 var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
11813                                         p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
11814
11815                                 this.borderDif = $.map(b, function(v, i) {
11816                                         var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
11817                                         return border + padding;
11818                                 });
11819                         }
11820
11821                         if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
11822                                 continue;
11823
11824                         prel.css({
11825                                 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
11826                                 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
11827                         });
11828
11829                 };
11830
11831         },
11832
11833         _renderProxy: function() {
11834
11835                 var el = this.element, o = this.options;
11836                 this.elementOffset = el.offset();
11837
11838                 if(this._helper) {
11839
11840                         this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
11841
11842                         // fix ie6 offset TODO: This seems broken
11843                         var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
11844                         pxyoffset = ( ie6 ? 2 : -1 );
11845
11846                         this.helper.addClass(this._helper).css({
11847                                 width: this.element.outerWidth() + pxyoffset,
11848                                 height: this.element.outerHeight() + pxyoffset,
11849                                 position: 'absolute',
11850                                 left: this.elementOffset.left - ie6offset +'px',
11851                                 top: this.elementOffset.top - ie6offset +'px',
11852                                 zIndex: ++o.zIndex //TODO: Don't modify option
11853                         });
11854
11855                         this.helper
11856                                 .appendTo("body")
11857                                 .disableSelection();
11858
11859                 } else {
11860                         this.helper = this.element;
11861                 }
11862
11863         },
11864
11865         _change: {
11866                 e: function(event, dx, dy) {
11867                         return { width: this.originalSize.width + dx };
11868                 },
11869                 w: function(event, dx, dy) {
11870                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
11871                         return { left: sp.left + dx, width: cs.width - dx };
11872                 },
11873                 n: function(event, dx, dy) {
11874                         var o = this.options, cs = this.originalSize, sp = this.originalPosition;
11875                         return { top: sp.top + dy, height: cs.height - dy };
11876                 },
11877                 s: function(event, dx, dy) {
11878                         return { height: this.originalSize.height + dy };
11879                 },
11880                 se: function(event, dx, dy) {
11881                         return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
11882                 },
11883                 sw: function(event, dx, dy) {
11884                         return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
11885                 },
11886                 ne: function(event, dx, dy) {
11887                         return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
11888                 },
11889                 nw: function(event, dx, dy) {
11890                         return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
11891                 }
11892         },
11893
11894         _propagate: function(n, event) {
11895                 $.ui.plugin.call(this, n, [event, this.ui()]);
11896                 (n != "resize" && this._trigger(n, event, this.ui()));
11897         },
11898
11899         plugins: {},
11900
11901         ui: function() {
11902                 return {
11903                         originalElement: this.originalElement,
11904                         element: this.element,
11905                         helper: this.helper,
11906                         position: this.position,
11907                         size: this.size,
11908                         originalSize: this.originalSize,
11909                         originalPosition: this.originalPosition
11910                 };
11911         }
11912
11913 });
11914
11915 $.extend($.ui.resizable, {
11916         version: "1.8.12"
11917 });
11918
11919 /*
11920  * Resizable Extensions
11921  */
11922
11923 $.ui.plugin.add("resizable", "alsoResize", {
11924
11925         start: function (event, ui) {
11926                 var self = $(this).data("resizable"), o = self.options;
11927
11928                 var _store = function (exp) {
11929                         $(exp).each(function() {
11930                                 var el = $(this);
11931                                 el.data("resizable-alsoresize", {
11932                                         width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
11933                                         left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
11934                                         position: el.css('position') // to reset Opera on stop()
11935                                 });
11936                         });
11937                 };
11938
11939                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
11940                         if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
11941                         else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
11942                 }else{
11943                         _store(o.alsoResize);
11944                 }
11945         },
11946
11947         resize: function (event, ui) {
11948                 var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
11949
11950                 var delta = {
11951                         height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
11952                         top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
11953                 },
11954
11955                 _alsoResize = function (exp, c) {
11956                         $(exp).each(function() {
11957                                 var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, 
11958                                         css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
11959
11960                                 $.each(css, function (i, prop) {
11961                                         var sum = (start[prop]||0) + (delta[prop]||0);
11962                                         if (sum && sum >= 0)
11963                                                 style[prop] = sum || null;
11964                                 });
11965
11966                                 // Opera fixing relative position
11967                                 if ($.browser.opera && /relative/.test(el.css('position'))) {
11968                                         self._revertToRelativePosition = true;
11969                                         el.css({ position: 'absolute', top: 'auto', left: 'auto' });
11970                                 }
11971
11972                                 el.css(style);
11973                         });
11974                 };
11975
11976                 if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
11977                         $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
11978                 }else{
11979                         _alsoResize(o.alsoResize);
11980                 }
11981         },
11982
11983         stop: function (event, ui) {
11984                 var self = $(this).data("resizable"), o = self.options;
11985
11986                 var _reset = function (exp) {
11987                         $(exp).each(function() {
11988                                 var el = $(this);
11989                                 // reset position for Opera - no need to verify it was changed
11990                                 el.css({ position: el.data("resizable-alsoresize").position });
11991                         });
11992                 };
11993
11994                 if (self._revertToRelativePosition) {
11995                         self._revertToRelativePosition = false;
11996                         if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
11997                                 $.each(o.alsoResize, function (exp) { _reset(exp); });
11998                         }else{
11999                                 _reset(o.alsoResize);
12000                         }
12001                 }
12002
12003                 $(this).removeData("resizable-alsoresize");
12004         }
12005 });
12006
12007 $.ui.plugin.add("resizable", "animate", {
12008
12009         stop: function(event, ui) {
12010                 var self = $(this).data("resizable"), o = self.options;
12011
12012                 var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
12013                                         soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
12014                                                 soffsetw = ista ? 0 : self.sizeDiff.width;
12015
12016                 var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
12017                                         left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
12018                                                 top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
12019
12020                 self.element.animate(
12021                         $.extend(style, top && left ? { top: top, left: left } : {}), {
12022                                 duration: o.animateDuration,
12023                                 easing: o.animateEasing,
12024                                 step: function() {
12025
12026                                         var data = {
12027                                                 width: parseInt(self.element.css('width'), 10),
12028                                                 height: parseInt(self.element.css('height'), 10),
12029                                                 top: parseInt(self.element.css('top'), 10),
12030                                                 left: parseInt(self.element.css('left'), 10)
12031                                         };
12032
12033                                         if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
12034
12035                                         // propagating resize, and updating values for each animation step
12036                                         self._updateCache(data);
12037                                         self._propagate("resize", event);
12038
12039                                 }
12040                         }
12041                 );
12042         }
12043
12044 });
12045
12046 $.ui.plugin.add("resizable", "containment", {
12047
12048         start: function(event, ui) {
12049                 var self = $(this).data("resizable"), o = self.options, el = self.element;
12050                 var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
12051                 if (!ce) return;
12052
12053                 self.containerElement = $(ce);
12054
12055                 if (/document/.test(oc) || oc == document) {
12056                         self.containerOffset = { left: 0, top: 0 };
12057                         self.containerPosition = { left: 0, top: 0 };
12058
12059                         self.parentData = {
12060                                 element: $(document), left: 0, top: 0,
12061                                 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
12062                         };
12063                 }
12064
12065                 // i'm a node, so compute top, left, right, bottom
12066                 else {
12067                         var element = $(ce), p = [];
12068                         $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
12069
12070                         self.containerOffset = element.offset();
12071                         self.containerPosition = element.position();
12072                         self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
12073
12074                         var co = self.containerOffset, ch = self.containerSize.height,  cw = self.containerSize.width,
12075                                                 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
12076
12077                         self.parentData = {
12078                                 element: ce, left: co.left, top: co.top, width: width, height: height
12079                         };
12080                 }
12081         },
12082
12083         resize: function(event, ui) {
12084                 var self = $(this).data("resizable"), o = self.options,
12085                                 ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
12086                                 pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
12087
12088                 if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
12089
12090                 if (cp.left < (self._helper ? co.left : 0)) {
12091                         self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
12092                         if (pRatio) self.size.height = self.size.width / o.aspectRatio;
12093                         self.position.left = o.helper ? co.left : 0;
12094                 }
12095
12096                 if (cp.top < (self._helper ? co.top : 0)) {
12097                         self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
12098                         if (pRatio) self.size.width = self.size.height * o.aspectRatio;
12099                         self.position.top = self._helper ? co.top : 0;
12100                 }
12101
12102                 self.offset.left = self.parentData.left+self.position.left;
12103                 self.offset.top = self.parentData.top+self.position.top;
12104
12105                 var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
12106                                         hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
12107
12108                 var isParent = self.containerElement.get(0) == self.element.parent().get(0),
12109                     isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
12110
12111                 if(isParent && isOffsetRelative) woset -= self.parentData.left;
12112
12113                 if (woset + self.size.width >= self.parentData.width) {
12114                         self.size.width = self.parentData.width - woset;
12115                         if (pRatio) self.size.height = self.size.width / self.aspectRatio;
12116                 }
12117
12118                 if (hoset + self.size.height >= self.parentData.height) {
12119                         self.size.height = self.parentData.height - hoset;
12120                         if (pRatio) self.size.width = self.size.height * self.aspectRatio;
12121                 }
12122         },
12123
12124         stop: function(event, ui){
12125                 var self = $(this).data("resizable"), o = self.options, cp = self.position,
12126                                 co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
12127
12128                 var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
12129
12130                 if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
12131                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
12132
12133                 if (self._helper && !o.animate && (/static/).test(ce.css('position')))
12134                         $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
12135
12136         }
12137 });
12138
12139 $.ui.plugin.add("resizable", "ghost", {
12140
12141         start: function(event, ui) {
12142
12143                 var self = $(this).data("resizable"), o = self.options, cs = self.size;
12144
12145                 self.ghost = self.originalElement.clone();
12146                 self.ghost
12147                         .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
12148                         .addClass('ui-resizable-ghost')
12149                         .addClass(typeof o.ghost == 'string' ? o.ghost : '');
12150
12151                 self.ghost.appendTo(self.helper);
12152
12153         },
12154
12155         resize: function(event, ui){
12156                 var self = $(this).data("resizable"), o = self.options;
12157                 if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
12158         },
12159
12160         stop: function(event, ui){
12161                 var self = $(this).data("resizable"), o = self.options;
12162                 if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
12163         }
12164
12165 });
12166
12167 $.ui.plugin.add("resizable", "grid", {
12168
12169         resize: function(event, ui) {
12170                 var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
12171                 o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
12172                 var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
12173
12174                 if (/^(se|s|e)$/.test(a)) {
12175                         self.size.width = os.width + ox;
12176                         self.size.height = os.height + oy;
12177                 }
12178                 else if (/^(ne)$/.test(a)) {
12179                         self.size.width = os.width + ox;
12180                         self.size.height = os.height + oy;
12181                         self.position.top = op.top - oy;
12182                 }
12183                 else if (/^(sw)$/.test(a)) {
12184                         self.size.width = os.width + ox;
12185                         self.size.height = os.height + oy;
12186                         self.position.left = op.left - ox;
12187                 }
12188                 else {
12189                         self.size.width = os.width + ox;
12190                         self.size.height = os.height + oy;
12191                         self.position.top = op.top - oy;
12192                         self.position.left = op.left - ox;
12193                 }
12194         }
12195
12196 });
12197
12198 var num = function(v) {
12199         return parseInt(v, 10) || 0;
12200 };
12201
12202 var isNumber = function(value) {
12203         return !isNaN(parseInt(value, 10));
12204 };
12205
12206 })(jQuery);
12207 /*
12208  * jQuery UI Selectable 1.8.12
12209  *
12210  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
12211  * Dual licensed under the MIT or GPL Version 2 licenses.
12212  * http://jquery.org/license
12213  *
12214  * http://docs.jquery.com/UI/Selectables
12215  *
12216  * Depends:
12217  *      jquery.ui.core.js
12218  *      jquery.ui.mouse.js
12219  *      jquery.ui.widget.js
12220  */
12221 (function( $, undefined ) {
12222
12223 $.widget("ui.selectable", $.ui.mouse, {
12224         options: {
12225                 appendTo: 'body',
12226                 autoRefresh: true,
12227                 distance: 0,
12228                 filter: '*',
12229                 tolerance: 'touch'
12230         },
12231         _create: function() {
12232                 var self = this;
12233
12234                 this.element.addClass("ui-selectable");
12235
12236                 this.dragged = false;
12237
12238                 // cache selectee children based on filter
12239                 var selectees;
12240                 this.refresh = function() {
12241                         selectees = $(self.options.filter, self.element[0]);
12242                         selectees.each(function() {
12243                                 var $this = $(this);
12244                                 var pos = $this.offset();
12245                                 $.data(this, "selectable-item", {
12246                                         element: this,
12247                                         $element: $this,
12248                                         left: pos.left,
12249                                         top: pos.top,
12250                                         right: pos.left + $this.outerWidth(),
12251                                         bottom: pos.top + $this.outerHeight(),
12252                                         startselected: false,
12253                                         selected: $this.hasClass('ui-selected'),
12254                                         selecting: $this.hasClass('ui-selecting'),
12255                                         unselecting: $this.hasClass('ui-unselecting')
12256                                 });
12257                         });
12258                 };
12259                 this.refresh();
12260
12261                 this.selectees = selectees.addClass("ui-selectee");
12262
12263                 this._mouseInit();
12264
12265                 this.helper = $("<div class='ui-selectable-helper'></div>");
12266         },
12267
12268         destroy: function() {
12269                 this.selectees
12270                         .removeClass("ui-selectee")
12271                         .removeData("selectable-item");
12272                 this.element
12273                         .removeClass("ui-selectable ui-selectable-disabled")
12274                         .removeData("selectable")
12275                         .unbind(".selectable");
12276                 this._mouseDestroy();
12277
12278                 return this;
12279         },
12280
12281         _mouseStart: function(event) {
12282                 var self = this;
12283
12284                 this.opos = [event.pageX, event.pageY];
12285
12286                 if (this.options.disabled)
12287                         return;
12288
12289                 var options = this.options;
12290
12291                 this.selectees = $(options.filter, this.element[0]);
12292
12293                 this._trigger("start", event);
12294
12295                 $(options.appendTo).append(this.helper);
12296                 // position helper (lasso)
12297                 this.helper.css({
12298                         "left": event.clientX,
12299                         "top": event.clientY,
12300                         "width": 0,
12301                         "height": 0
12302                 });
12303
12304                 if (options.autoRefresh) {
12305                         this.refresh();
12306                 }
12307
12308                 this.selectees.filter('.ui-selected').each(function() {
12309                         var selectee = $.data(this, "selectable-item");
12310                         selectee.startselected = true;
12311                         if (!event.metaKey) {
12312                                 selectee.$element.removeClass('ui-selected');
12313                                 selectee.selected = false;
12314                                 selectee.$element.addClass('ui-unselecting');
12315                                 selectee.unselecting = true;
12316                                 // selectable UNSELECTING callback
12317                                 self._trigger("unselecting", event, {
12318                                         unselecting: selectee.element
12319                                 });
12320                         }
12321                 });
12322
12323                 $(event.target).parents().andSelf().each(function() {
12324                         var selectee = $.data(this, "selectable-item");
12325                         if (selectee) {
12326                                 var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
12327                                 selectee.$element
12328                                         .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
12329                                         .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
12330                                 selectee.unselecting = !doSelect;
12331                                 selectee.selecting = doSelect;
12332                                 selectee.selected = doSelect;
12333                                 // selectable (UN)SELECTING callback
12334                                 if (doSelect) {
12335                                         self._trigger("selecting", event, {
12336                                                 selecting: selectee.element
12337                                         });
12338                                 } else {
12339                                         self._trigger("unselecting", event, {
12340                                                 unselecting: selectee.element
12341                                         });
12342                                 }
12343                                 return false;
12344                         }
12345                 });
12346
12347         },
12348
12349         _mouseDrag: function(event) {
12350                 var self = this;
12351                 this.dragged = true;
12352
12353                 if (this.options.disabled)
12354                         return;
12355
12356                 var options = this.options;
12357
12358                 var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
12359                 if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
12360                 if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
12361                 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
12362
12363                 this.selectees.each(function() {
12364                         var selectee = $.data(this, "selectable-item");
12365                         //prevent helper from being selected if appendTo: selectable
12366                         if (!selectee || selectee.element == self.element[0])
12367                                 return;
12368                         var hit = false;
12369                         if (options.tolerance == 'touch') {
12370                                 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
12371                         } else if (options.tolerance == 'fit') {
12372                                 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
12373                         }
12374
12375                         if (hit) {
12376                                 // SELECT
12377                                 if (selectee.selected) {
12378                                         selectee.$element.removeClass('ui-selected');
12379                                         selectee.selected = false;
12380                                 }
12381                                 if (selectee.unselecting) {
12382                                         selectee.$element.removeClass('ui-unselecting');
12383                                         selectee.unselecting = false;
12384                                 }
12385                                 if (!selectee.selecting) {
12386                                         selectee.$element.addClass('ui-selecting');
12387                                         selectee.selecting = true;
12388                                         // selectable SELECTING callback
12389                                         self._trigger("selecting", event, {
12390                                                 selecting: selectee.element
12391                                         });
12392                                 }
12393                         } else {
12394                                 // UNSELECT
12395                                 if (selectee.selecting) {
12396                                         if (event.metaKey && selectee.startselected) {
12397                                                 selectee.$element.removeClass('ui-selecting');
12398                                                 selectee.selecting = false;
12399                                                 selectee.$element.addClass('ui-selected');
12400                                                 selectee.selected = true;
12401                                         } else {
12402                                                 selectee.$element.removeClass('ui-selecting');
12403                                                 selectee.selecting = false;
12404                                                 if (selectee.startselected) {
12405                                                         selectee.$element.addClass('ui-unselecting');
12406                                                         selectee.unselecting = true;
12407                                                 }
12408                                                 // selectable UNSELECTING callback
12409                                                 self._trigger("unselecting", event, {
12410                                                         unselecting: selectee.element
12411                                                 });
12412                                         }
12413                                 }
12414                                 if (selectee.selected) {
12415                                         if (!event.metaKey && !selectee.startselected) {
12416                                                 selectee.$element.removeClass('ui-selected');
12417                                                 selectee.selected = false;
12418
12419                                                 selectee.$element.addClass('ui-unselecting');
12420                                                 selectee.unselecting = true;
12421                                                 // selectable UNSELECTING callback
12422                                                 self._trigger("unselecting", event, {
12423                                                         unselecting: selectee.element
12424                                                 });
12425                                         }
12426                                 }
12427                         }
12428                 });
12429
12430                 return false;
12431         },
12432
12433         _mouseStop: function(event) {
12434                 var self = this;
12435
12436                 this.dragged = false;
12437
12438                 var options = this.options;
12439
12440                 $('.ui-unselecting', this.element[0]).each(function() {
12441                         var selectee = $.data(this, "selectable-item");
12442                         selectee.$element.removeClass('ui-unselecting');
12443                         selectee.unselecting = false;
12444                         selectee.startselected = false;
12445                         self._trigger("unselected", event, {
12446                                 unselected: selectee.element
12447                         });
12448                 });
12449                 $('.ui-selecting', this.element[0]).each(function() {
12450                         var selectee = $.data(this, "selectable-item");
12451                         selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
12452                         selectee.selecting = false;
12453                         selectee.selected = true;
12454                         selectee.startselected = true;
12455                         self._trigger("selected", event, {
12456                                 selected: selectee.element
12457                         });
12458                 });
12459                 this._trigger("stop", event);
12460
12461                 this.helper.remove();
12462
12463                 return false;
12464         }
12465
12466 });
12467
12468 $.extend($.ui.selectable, {
12469         version: "1.8.12"
12470 });
12471
12472 })(jQuery);
12473 /*
12474  * jQuery UI Sortable 1.8.12
12475  *
12476  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
12477  * Dual licensed under the MIT or GPL Version 2 licenses.
12478  * http://jquery.org/license
12479  *
12480  * http://docs.jquery.com/UI/Sortables
12481  *
12482  * Depends:
12483  *      jquery.ui.core.js
12484  *      jquery.ui.mouse.js
12485  *      jquery.ui.widget.js
12486  */
12487 (function( $, undefined ) {
12488
12489 $.widget("ui.sortable", $.ui.mouse, {
12490         widgetEventPrefix: "sort",
12491         options: {
12492                 appendTo: "parent",
12493                 axis: false,
12494                 connectWith: false,
12495                 containment: false,
12496                 cursor: 'auto',
12497                 cursorAt: false,
12498                 dropOnEmpty: true,
12499                 forcePlaceholderSize: false,
12500                 forceHelperSize: false,
12501                 grid: false,
12502                 handle: false,
12503                 helper: "original",
12504                 items: '> *',
12505                 opacity: false,
12506                 placeholder: false,
12507                 revert: false,
12508                 scroll: true,
12509                 scrollSensitivity: 20,
12510                 scrollSpeed: 20,
12511                 scope: "default",
12512                 tolerance: "intersect",
12513                 zIndex: 1000
12514         },
12515         _create: function() {
12516
12517                 var o = this.options;
12518                 this.containerCache = {};
12519                 this.element.addClass("ui-sortable");
12520
12521                 //Get the items
12522                 this.refresh();
12523
12524                 //Let's determine if the items are being displayed horizontally
12525                 this.floating = this.items.length ? (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
12526
12527                 //Let's determine the parent's offset
12528                 this.offset = this.element.offset();
12529
12530                 //Initialize mouse events for interaction
12531                 this._mouseInit();
12532
12533         },
12534
12535         destroy: function() {
12536                 this.element
12537                         .removeClass("ui-sortable ui-sortable-disabled")
12538                         .removeData("sortable")
12539                         .unbind(".sortable");
12540                 this._mouseDestroy();
12541
12542                 for ( var i = this.items.length - 1; i >= 0; i-- )
12543                         this.items[i].item.removeData("sortable-item");
12544
12545                 return this;
12546         },
12547
12548         _setOption: function(key, value){
12549                 if ( key === "disabled" ) {
12550                         this.options[ key ] = value;
12551         
12552                         this.widget()
12553                                 [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
12554                 } else {
12555                         // Don't call widget base _setOption for disable as it adds ui-state-disabled class
12556                         $.Widget.prototype._setOption.apply(this, arguments);
12557                 }
12558         },
12559
12560         _mouseCapture: function(event, overrideHandle) {
12561
12562                 if (this.reverting) {
12563                         return false;
12564                 }
12565
12566                 if(this.options.disabled || this.options.type == 'static') return false;
12567
12568                 //We have to refresh the items data once first
12569                 this._refreshItems(event);
12570
12571                 //Find out if the clicked node (or one of its parents) is a actual item in this.items
12572                 var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
12573                         if($.data(this, 'sortable-item') == self) {
12574                                 currentItem = $(this);
12575                                 return false;
12576                         }
12577                 });
12578                 if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
12579
12580                 if(!currentItem) return false;
12581                 if(this.options.handle && !overrideHandle) {
12582                         var validHandle = false;
12583
12584                         $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
12585                         if(!validHandle) return false;
12586                 }
12587
12588                 this.currentItem = currentItem;
12589                 this._removeCurrentsFromItems();
12590                 return true;
12591
12592         },
12593
12594         _mouseStart: function(event, overrideHandle, noActivation) {
12595
12596                 var o = this.options, self = this;
12597                 this.currentContainer = this;
12598
12599                 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
12600                 this.refreshPositions();
12601
12602                 //Create and append the visible helper
12603                 this.helper = this._createHelper(event);
12604
12605                 //Cache the helper size
12606                 this._cacheHelperProportions();
12607
12608                 /*
12609                  * - Position generation -
12610                  * This block generates everything position related - it's the core of draggables.
12611                  */
12612
12613                 //Cache the margins of the original element
12614                 this._cacheMargins();
12615
12616                 //Get the next scrolling parent
12617                 this.scrollParent = this.helper.scrollParent();
12618
12619                 //The element's absolute position on the page minus margins
12620                 this.offset = this.currentItem.offset();
12621                 this.offset = {
12622                         top: this.offset.top - this.margins.top,
12623                         left: this.offset.left - this.margins.left
12624                 };
12625
12626                 // Only after we got the offset, we can change the helper's position to absolute
12627                 // TODO: Still need to figure out a way to make relative sorting possible
12628                 this.helper.css("position", "absolute");
12629                 this.cssPosition = this.helper.css("position");
12630
12631                 $.extend(this.offset, {
12632                         click: { //Where the click happened, relative to the element
12633                                 left: event.pageX - this.offset.left,
12634                                 top: event.pageY - this.offset.top
12635                         },
12636                         parent: this._getParentOffset(),
12637                         relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
12638                 });
12639
12640                 //Generate the original position
12641                 this.originalPosition = this._generatePosition(event);
12642                 this.originalPageX = event.pageX;
12643                 this.originalPageY = event.pageY;
12644
12645                 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
12646                 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
12647
12648                 //Cache the former DOM position
12649                 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
12650
12651                 //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
12652                 if(this.helper[0] != this.currentItem[0]) {
12653                         this.currentItem.hide();
12654                 }
12655
12656                 //Create the placeholder
12657                 this._createPlaceholder();
12658
12659                 //Set a containment if given in the options
12660                 if(o.containment)
12661                         this._setContainment();
12662
12663                 if(o.cursor) { // cursor option
12664                         if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
12665                         $('body').css("cursor", o.cursor);
12666                 }
12667
12668                 if(o.opacity) { // opacity option
12669                         if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
12670                         this.helper.css("opacity", o.opacity);
12671                 }
12672
12673                 if(o.zIndex) { // zIndex option
12674                         if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
12675                         this.helper.css("zIndex", o.zIndex);
12676                 }
12677
12678                 //Prepare scrolling
12679                 if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
12680                         this.overflowOffset = this.scrollParent.offset();
12681
12682                 //Call callbacks
12683                 this._trigger("start", event, this._uiHash());
12684
12685                 //Recache the helper size
12686                 if(!this._preserveHelperProportions)
12687                         this._cacheHelperProportions();
12688
12689
12690                 //Post 'activate' events to possible containers
12691                 if(!noActivation) {
12692                          for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
12693                 }
12694
12695                 //Prepare possible droppables
12696                 if($.ui.ddmanager)
12697                         $.ui.ddmanager.current = this;
12698
12699                 if ($.ui.ddmanager && !o.dropBehaviour)
12700                         $.ui.ddmanager.prepareOffsets(this, event);
12701
12702                 this.dragging = true;
12703
12704                 this.helper.addClass("ui-sortable-helper");
12705                 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
12706                 return true;
12707
12708         },
12709
12710         _mouseDrag: function(event) {
12711
12712                 //Compute the helpers position
12713                 this.position = this._generatePosition(event);
12714                 this.positionAbs = this._convertPositionTo("absolute");
12715
12716                 if (!this.lastPositionAbs) {
12717                         this.lastPositionAbs = this.positionAbs;
12718                 }
12719
12720                 //Do scrolling
12721                 if(this.options.scroll) {
12722                         var o = this.options, scrolled = false;
12723                         if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
12724
12725                                 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
12726                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
12727                                 else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
12728                                         this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
12729
12730                                 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
12731                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
12732                                 else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
12733                                         this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
12734
12735                         } else {
12736
12737                                 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
12738                                         scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
12739                                 else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
12740                                         scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
12741
12742                                 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
12743                                         scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
12744                                 else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
12745                                         scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
12746
12747                         }
12748
12749                         if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
12750                                 $.ui.ddmanager.prepareOffsets(this, event);
12751                 }
12752
12753                 //Regenerate the absolute position used for position checks
12754                 this.positionAbs = this._convertPositionTo("absolute");
12755
12756                 //Set the helper position
12757                 if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
12758                 if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
12759
12760                 //Rearrange
12761                 for (var i = this.items.length - 1; i >= 0; i--) {
12762
12763                         //Cache variables and intersection, continue if no intersection
12764                         var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
12765                         if (!intersection) continue;
12766
12767                         if(itemElement != this.currentItem[0] //cannot intersect with itself
12768                                 &&      this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
12769                                 &&      !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
12770                                 && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
12771                                 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
12772                         ) {
12773
12774                                 this.direction = intersection == 1 ? "down" : "up";
12775
12776                                 if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
12777                                         this._rearrange(event, item);
12778                                 } else {
12779                                         break;
12780                                 }
12781
12782                                 this._trigger("change", event, this._uiHash());
12783                                 break;
12784                         }
12785                 }
12786
12787                 //Post events to containers
12788                 this._contactContainers(event);
12789
12790                 //Interconnect with droppables
12791                 if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
12792
12793                 //Call callbacks
12794                 this._trigger('sort', event, this._uiHash());
12795
12796                 this.lastPositionAbs = this.positionAbs;
12797                 return false;
12798
12799         },
12800
12801         _mouseStop: function(event, noPropagation) {
12802
12803                 if(!event) return;
12804
12805                 //If we are using droppables, inform the manager about the drop
12806                 if ($.ui.ddmanager && !this.options.dropBehaviour)
12807                         $.ui.ddmanager.drop(this, event);
12808
12809                 if(this.options.revert) {
12810                         var self = this;
12811                         var cur = self.placeholder.offset();
12812
12813                         self.reverting = true;
12814
12815                         $(this.helper).animate({
12816                                 left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
12817                                 top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
12818                         }, parseInt(this.options.revert, 10) || 500, function() {
12819                                 self._clear(event);
12820                         });
12821                 } else {
12822                         this._clear(event, noPropagation);
12823                 }
12824
12825                 return false;
12826
12827         },
12828
12829         cancel: function() {
12830
12831                 var self = this;
12832
12833                 if(this.dragging) {
12834
12835                         this._mouseUp({ target: null });
12836
12837                         if(this.options.helper == "original")
12838                                 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
12839                         else
12840                                 this.currentItem.show();
12841
12842                         //Post deactivating events to containers
12843                         for (var i = this.containers.length - 1; i >= 0; i--){
12844                                 this.containers[i]._trigger("deactivate", null, self._uiHash(this));
12845                                 if(this.containers[i].containerCache.over) {
12846                                         this.containers[i]._trigger("out", null, self._uiHash(this));
12847                                         this.containers[i].containerCache.over = 0;
12848                                 }
12849                         }
12850
12851                 }
12852
12853                 if (this.placeholder) {
12854                         //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
12855                         if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
12856                         if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
12857
12858                         $.extend(this, {
12859                                 helper: null,
12860                                 dragging: false,
12861                                 reverting: false,
12862                                 _noFinalSort: null
12863                         });
12864
12865                         if(this.domPosition.prev) {
12866                                 $(this.domPosition.prev).after(this.currentItem);
12867                         } else {
12868                                 $(this.domPosition.parent).prepend(this.currentItem);
12869                         }
12870                 }
12871
12872                 return this;
12873
12874         },
12875
12876         serialize: function(o) {
12877
12878                 var items = this._getItemsAsjQuery(o && o.connected);
12879                 var str = []; o = o || {};
12880
12881                 $(items).each(function() {
12882                         var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
12883                         if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
12884                 });
12885
12886                 if(!str.length && o.key) {
12887                         str.push(o.key + '=');
12888                 }
12889
12890                 return str.join('&');
12891
12892         },
12893
12894         toArray: function(o) {
12895
12896                 var items = this._getItemsAsjQuery(o && o.connected);
12897                 var ret = []; o = o || {};
12898
12899                 items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
12900                 return ret;
12901
12902         },
12903
12904         /* Be careful with the following core functions */
12905         _intersectsWith: function(item) {
12906
12907                 var x1 = this.positionAbs.left,
12908                         x2 = x1 + this.helperProportions.width,
12909                         y1 = this.positionAbs.top,
12910                         y2 = y1 + this.helperProportions.height;
12911
12912                 var l = item.left,
12913                         r = l + item.width,
12914                         t = item.top,
12915                         b = t + item.height;
12916
12917                 var dyClick = this.offset.click.top,
12918                         dxClick = this.offset.click.left;
12919
12920                 var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
12921
12922                 if(        this.options.tolerance == "pointer"
12923                         || this.options.forcePointerForContainers
12924                         || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
12925                 ) {
12926                         return isOverElement;
12927                 } else {
12928
12929                         return (l < x1 + (this.helperProportions.width / 2) // Right Half
12930                                 && x2 - (this.helperProportions.width / 2) < r // Left Half
12931                                 && t < y1 + (this.helperProportions.height / 2) // Bottom Half
12932                                 && y2 - (this.helperProportions.height / 2) < b ); // Top Half
12933
12934                 }
12935         },
12936
12937         _intersectsWithPointer: function(item) {
12938
12939                 var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
12940                         isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
12941                         isOverElement = isOverElementHeight && isOverElementWidth,
12942                         verticalDirection = this._getDragVerticalDirection(),
12943                         horizontalDirection = this._getDragHorizontalDirection();
12944
12945                 if (!isOverElement)
12946                         return false;
12947
12948                 return this.floating ?
12949                         ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
12950                         : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
12951
12952         },
12953
12954         _intersectsWithSides: function(item) {
12955
12956                 var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
12957                         isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
12958                         verticalDirection = this._getDragVerticalDirection(),
12959                         horizontalDirection = this._getDragHorizontalDirection();
12960
12961                 if (this.floating && horizontalDirection) {
12962                         return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
12963                 } else {
12964                         return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
12965                 }
12966
12967         },
12968
12969         _getDragVerticalDirection: function() {
12970                 var delta = this.positionAbs.top - this.lastPositionAbs.top;
12971                 return delta != 0 && (delta > 0 ? "down" : "up");
12972         },
12973
12974         _getDragHorizontalDirection: function() {
12975                 var delta = this.positionAbs.left - this.lastPositionAbs.left;
12976                 return delta != 0 && (delta > 0 ? "right" : "left");
12977         },
12978
12979         refresh: function(event) {
12980                 this._refreshItems(event);
12981                 this.refreshPositions();
12982                 return this;
12983         },
12984
12985         _connectWith: function() {
12986                 var options = this.options;
12987                 return options.connectWith.constructor == String
12988                         ? [options.connectWith]
12989                         : options.connectWith;
12990         },
12991         
12992         _getItemsAsjQuery: function(connected) {
12993
12994                 var self = this;
12995                 var items = [];
12996                 var queries = [];
12997                 var connectWith = this._connectWith();
12998
12999                 if(connectWith && connected) {
13000                         for (var i = connectWith.length - 1; i >= 0; i--){
13001                                 var cur = $(connectWith[i]);
13002                                 for (var j = cur.length - 1; j >= 0; j--){
13003                                         var inst = $.data(cur[j], 'sortable');
13004                                         if(inst && inst != this && !inst.options.disabled) {
13005                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
13006                                         }
13007                                 };
13008                         };
13009                 }
13010
13011                 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
13012
13013                 for (var i = queries.length - 1; i >= 0; i--){
13014                         queries[i][0].each(function() {
13015                                 items.push(this);
13016                         });
13017                 };
13018
13019                 return $(items);
13020
13021         },
13022
13023         _removeCurrentsFromItems: function() {
13024
13025                 var list = this.currentItem.find(":data(sortable-item)");
13026
13027                 for (var i=0; i < this.items.length; i++) {
13028
13029                         for (var j=0; j < list.length; j++) {
13030                                 if(list[j] == this.items[i].item[0])
13031                                         this.items.splice(i,1);
13032                         };
13033
13034                 };
13035
13036         },
13037
13038         _refreshItems: function(event) {
13039
13040                 this.items = [];
13041                 this.containers = [this];
13042                 var items = this.items;
13043                 var self = this;
13044                 var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
13045                 var connectWith = this._connectWith();
13046
13047                 if(connectWith) {
13048                         for (var i = connectWith.length - 1; i >= 0; i--){
13049                                 var cur = $(connectWith[i]);
13050                                 for (var j = cur.length - 1; j >= 0; j--){
13051                                         var inst = $.data(cur[j], 'sortable');
13052                                         if(inst && inst != this && !inst.options.disabled) {
13053                                                 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
13054                                                 this.containers.push(inst);
13055                                         }
13056                                 };
13057                         };
13058                 }
13059
13060                 for (var i = queries.length - 1; i >= 0; i--) {
13061                         var targetData = queries[i][1];
13062                         var _queries = queries[i][0];
13063
13064                         for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
13065                                 var item = $(_queries[j]);
13066
13067                                 item.data('sortable-item', targetData); // Data for target checking (mouse manager)
13068
13069                                 items.push({
13070                                         item: item,
13071                                         instance: targetData,
13072                                         width: 0, height: 0,
13073                                         left: 0, top: 0
13074                                 });
13075                         };
13076                 };
13077
13078         },
13079
13080         refreshPositions: function(fast) {
13081
13082                 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
13083                 if(this.offsetParent && this.helper) {
13084                         this.offset.parent = this._getParentOffset();
13085                 }
13086
13087                 for (var i = this.items.length - 1; i >= 0; i--){
13088                         var item = this.items[i];
13089
13090                         //We ignore calculating positions of all connected containers when we're not over them
13091                         if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
13092                                 continue;
13093
13094                         var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
13095
13096                         if (!fast) {
13097                                 item.width = t.outerWidth();
13098                                 item.height = t.outerHeight();
13099                         }
13100
13101                         var p = t.offset();
13102                         item.left = p.left;
13103                         item.top = p.top;
13104                 };
13105
13106                 if(this.options.custom && this.options.custom.refreshContainers) {
13107                         this.options.custom.refreshContainers.call(this);
13108                 } else {
13109                         for (var i = this.containers.length - 1; i >= 0; i--){
13110                                 var p = this.containers[i].element.offset();
13111                                 this.containers[i].containerCache.left = p.left;
13112                                 this.containers[i].containerCache.top = p.top;
13113                                 this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
13114                                 this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
13115                         };
13116                 }
13117
13118                 return this;
13119         },
13120
13121         _createPlaceholder: function(that) {
13122
13123                 var self = that || this, o = self.options;
13124
13125                 if(!o.placeholder || o.placeholder.constructor == String) {
13126                         var className = o.placeholder;
13127                         o.placeholder = {
13128                                 element: function() {
13129
13130                                         var el = $(document.createElement(self.currentItem[0].nodeName))
13131                                                 .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
13132                                                 .removeClass("ui-sortable-helper")[0];
13133
13134                                         if(!className)
13135                                                 el.style.visibility = "hidden";
13136
13137                                         return el;
13138                                 },
13139                                 update: function(container, p) {
13140
13141                                         // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
13142                                         // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
13143                                         if(className && !o.forcePlaceholderSize) return;
13144
13145                                         //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
13146                                         if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
13147                                         if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
13148                                 }
13149                         };
13150                 }
13151
13152                 //Create the placeholder
13153                 self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
13154
13155                 //Append it after the actual current item
13156                 self.currentItem.after(self.placeholder);
13157
13158                 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
13159                 o.placeholder.update(self, self.placeholder);
13160
13161         },
13162
13163         _contactContainers: function(event) {
13164                 
13165                 // get innermost container that intersects with item 
13166                 var innermostContainer = null, innermostIndex = null;           
13167                 
13168                 
13169                 for (var i = this.containers.length - 1; i >= 0; i--){
13170
13171                         // never consider a container that's located within the item itself 
13172                         if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
13173                                 continue;
13174
13175                         if(this._intersectsWith(this.containers[i].containerCache)) {
13176
13177                                 // if we've already found a container and it's more "inner" than this, then continue 
13178                                 if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
13179                                         continue;
13180
13181                                 innermostContainer = this.containers[i]; 
13182                                 innermostIndex = i;
13183                                         
13184                         } else {
13185                                 // container doesn't intersect. trigger "out" event if necessary 
13186                                 if(this.containers[i].containerCache.over) {
13187                                         this.containers[i]._trigger("out", event, this._uiHash(this));
13188                                         this.containers[i].containerCache.over = 0;
13189                                 }
13190                         }
13191
13192                 }
13193                 
13194                 // if no intersecting containers found, return 
13195                 if(!innermostContainer) return; 
13196
13197                 // move the item into the container if it's not there already
13198                 if(this.containers.length === 1) {
13199                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
13200                         this.containers[innermostIndex].containerCache.over = 1;
13201                 } else if(this.currentContainer != this.containers[innermostIndex]) { 
13202
13203                         //When entering a new container, we will find the item with the least distance and append our item near it 
13204                         var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; 
13205                         for (var j = this.items.length - 1; j >= 0; j--) { 
13206                                 if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; 
13207                                 var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; 
13208                                 if(Math.abs(cur - base) < dist) { 
13209                                         dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; 
13210                                 } 
13211                         } 
13212
13213                         if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled 
13214                                 return; 
13215
13216                         this.currentContainer = this.containers[innermostIndex]; 
13217                         itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); 
13218                         this._trigger("change", event, this._uiHash()); 
13219                         this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); 
13220
13221                         //Update the placeholder 
13222                         this.options.placeholder.update(this.currentContainer, this.placeholder); 
13223                 
13224                         this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); 
13225                         this.containers[innermostIndex].containerCache.over = 1;
13226                 } 
13227         
13228                 
13229         },
13230
13231         _createHelper: function(event) {
13232
13233                 var o = this.options;
13234                 var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
13235
13236                 if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
13237                         $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
13238
13239                 if(helper[0] == this.currentItem[0])
13240                         this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
13241
13242                 if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
13243                 if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
13244
13245                 return helper;
13246
13247         },
13248
13249         _adjustOffsetFromHelper: function(obj) {
13250                 if (typeof obj == 'string') {
13251                         obj = obj.split(' ');
13252                 }
13253                 if ($.isArray(obj)) {
13254                         obj = {left: +obj[0], top: +obj[1] || 0};
13255                 }
13256                 if ('left' in obj) {
13257                         this.offset.click.left = obj.left + this.margins.left;
13258                 }
13259                 if ('right' in obj) {
13260                         this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
13261                 }
13262                 if ('top' in obj) {
13263                         this.offset.click.top = obj.top + this.margins.top;
13264                 }
13265                 if ('bottom' in obj) {
13266                         this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
13267                 }
13268         },
13269
13270         _getParentOffset: function() {
13271
13272
13273                 //Get the offsetParent and cache its position
13274                 this.offsetParent = this.helper.offsetParent();
13275                 var po = this.offsetParent.offset();
13276
13277                 // This is a special case where we need to modify a offset calculated on start, since the following happened:
13278                 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
13279                 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
13280                 //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
13281                 if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
13282                         po.left += this.scrollParent.scrollLeft();
13283                         po.top += this.scrollParent.scrollTop();
13284                 }
13285
13286                 if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
13287                 || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
13288                         po = { top: 0, left: 0 };
13289
13290                 return {
13291                         top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
13292                         left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
13293                 };
13294
13295         },
13296
13297         _getRelativeOffset: function() {
13298
13299                 if(this.cssPosition == "relative") {
13300                         var p = this.currentItem.position();
13301                         return {
13302                                 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
13303                                 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
13304                         };
13305                 } else {
13306                         return { top: 0, left: 0 };
13307                 }
13308
13309         },
13310
13311         _cacheMargins: function() {
13312                 this.margins = {
13313                         left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
13314                         top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
13315                 };
13316         },
13317
13318         _cacheHelperProportions: function() {
13319                 this.helperProportions = {
13320                         width: this.helper.outerWidth(),
13321                         height: this.helper.outerHeight()
13322                 };
13323         },
13324
13325         _setContainment: function() {
13326
13327                 var o = this.options;
13328                 if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
13329                 if(o.containment == 'document' || o.containment == 'window') this.containment = [
13330                         0 - this.offset.relative.left - this.offset.parent.left,
13331                         0 - this.offset.relative.top - this.offset.parent.top,
13332                         $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
13333                         ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
13334                 ];
13335
13336                 if(!(/^(document|window|parent)$/).test(o.containment)) {
13337                         var ce = $(o.containment)[0];
13338                         var co = $(o.containment).offset();
13339                         var over = ($(ce).css("overflow") != 'hidden');
13340
13341                         this.containment = [
13342                                 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
13343                                 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
13344                                 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
13345                                 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
13346                         ];
13347                 }
13348
13349         },
13350
13351         _convertPositionTo: function(d, pos) {
13352
13353                 if(!pos) pos = this.position;
13354                 var mod = d == "absolute" ? 1 : -1;
13355                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
13356
13357                 return {
13358                         top: (
13359                                 pos.top                                                                                                                                 // The absolute mouse position
13360                                 + this.offset.relative.top * mod                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
13361                                 + this.offset.parent.top * mod                                                                                  // The offsetParent's offset without borders (offset + border)
13362                                 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
13363                         ),
13364                         left: (
13365                                 pos.left                                                                                                                                // The absolute mouse position
13366                                 + this.offset.relative.left * mod                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
13367                                 + this.offset.parent.left * mod                                                                                 // The offsetParent's offset without borders (offset + border)
13368                                 - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
13369                         )
13370                 };
13371
13372         },
13373
13374         _generatePosition: function(event) {
13375
13376                 var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
13377
13378                 // This is another very weird special case that only happens for relative elements:
13379                 // 1. If the css position is relative
13380                 // 2. and the scroll parent is the document or similar to the offset parent
13381                 // we have to refresh the relative offset during the scroll so there are no jumps
13382                 if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
13383                         this.offset.relative = this._getRelativeOffset();
13384                 }
13385
13386                 var pageX = event.pageX;
13387                 var pageY = event.pageY;
13388
13389                 /*
13390                  * - Position constraining -
13391                  * Constrain the position to a mix of grid, containment.
13392                  */
13393
13394                 if(this.originalPosition) { //If we are not dragging yet, we won't check for options
13395
13396                         if(this.containment) {
13397                                 if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
13398                                 if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
13399                                 if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
13400                                 if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
13401                         }
13402
13403                         if(o.grid) {
13404                                 var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
13405                                 pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
13406
13407                                 var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
13408                                 pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
13409                         }
13410
13411                 }
13412
13413                 return {
13414                         top: (
13415                                 pageY                                                                                                                           // The absolute mouse position
13416                                 - this.offset.click.top                                                                                                 // Click offset (relative to the element)
13417                                 - this.offset.relative.top                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
13418                                 - this.offset.parent.top                                                                                                // The offsetParent's offset without borders (offset + border)
13419                                 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
13420                         ),
13421                         left: (
13422                                 pageX                                                                                                                           // The absolute mouse position
13423                                 - this.offset.click.left                                                                                                // Click offset (relative to the element)
13424                                 - this.offset.relative.left                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
13425                                 - this.offset.parent.left                                                                                               // The offsetParent's offset without borders (offset + border)
13426                                 + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
13427                         )
13428                 };
13429
13430         },
13431
13432         _rearrange: function(event, i, a, hardRefresh) {
13433
13434                 a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
13435
13436                 //Various things done here to improve the performance:
13437                 // 1. we create a setTimeout, that calls refreshPositions
13438                 // 2. on the instance, we have a counter variable, that get's higher after every append
13439                 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
13440                 // 4. this lets only the last addition to the timeout stack through
13441                 this.counter = this.counter ? ++this.counter : 1;
13442                 var self = this, counter = this.counter;
13443
13444                 window.setTimeout(function() {
13445                         if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
13446                 },0);
13447
13448         },
13449
13450         _clear: function(event, noPropagation) {
13451
13452                 this.reverting = false;
13453                 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
13454                 // everything else normalized again
13455                 var delayedTriggers = [], self = this;
13456
13457                 // We first have to update the dom position of the actual currentItem
13458                 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
13459                 if(!this._noFinalSort && this.currentItem[0].parentNode) this.placeholder.before(this.currentItem);
13460                 this._noFinalSort = null;
13461
13462                 if(this.helper[0] == this.currentItem[0]) {
13463                         for(var i in this._storedCSS) {
13464                                 if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
13465                         }
13466                         this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
13467                 } else {
13468                         this.currentItem.show();
13469                 }
13470
13471                 if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
13472                 if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
13473                 if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
13474                         if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
13475                         for (var i = this.containers.length - 1; i >= 0; i--){
13476                                 if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
13477                                         delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
13478                                         delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
13479                                 }
13480                         };
13481                 };
13482
13483                 //Post events to containers
13484                 for (var i = this.containers.length - 1; i >= 0; i--){
13485                         if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
13486                         if(this.containers[i].containerCache.over) {
13487                                 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
13488                                 this.containers[i].containerCache.over = 0;
13489                         }
13490                 }
13491
13492                 //Do what was originally in plugins
13493                 if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
13494                 if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
13495                 if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
13496
13497                 this.dragging = false;
13498                 if(this.cancelHelperRemoval) {
13499                         if(!noPropagation) {
13500                                 this._trigger("beforeStop", event, this._uiHash());
13501                                 for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
13502                                 this._trigger("stop", event, this._uiHash());
13503                         }
13504                         return false;
13505                 }
13506
13507                 if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
13508
13509                 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
13510                 this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
13511
13512                 if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
13513
13514                 if(!noPropagation) {
13515                         for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
13516                         this._trigger("stop", event, this._uiHash());
13517                 }
13518
13519                 this.fromOutside = false;
13520                 return true;
13521
13522         },
13523
13524         _trigger: function() {
13525                 if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
13526                         this.cancel();
13527                 }
13528         },
13529
13530         _uiHash: function(inst) {
13531                 var self = inst || this;
13532                 return {
13533                         helper: self.helper,
13534                         placeholder: self.placeholder || $([]),
13535                         position: self.position,
13536                         originalPosition: self.originalPosition,
13537                         offset: self.positionAbs,
13538                         item: self.currentItem,
13539                         sender: inst ? inst.element : null
13540                 };
13541         }
13542
13543 });
13544
13545 $.extend($.ui.sortable, {
13546         version: "1.8.12"
13547 });
13548
13549 })(jQuery);
13550 /*
13551  * jQuery UI Effects 1.8.12
13552  *
13553  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
13554  * Dual licensed under the MIT or GPL Version 2 licenses.
13555  * http://jquery.org/license
13556  *
13557  * http://docs.jquery.com/UI/Effects/
13558  */
13559 ;jQuery.effects || (function($, undefined) {
13560
13561 $.effects = {};
13562
13563
13564
13565 /******************************************************************************/
13566 /****************************** COLOR ANIMATIONS ******************************/
13567 /******************************************************************************/
13568
13569 // override the animation for color styles
13570 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
13571         'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
13572 function(i, attr) {
13573         $.fx.step[attr] = function(fx) {
13574                 if (!fx.colorInit) {
13575                         fx.start = getColor(fx.elem, attr);
13576                         fx.end = getRGB(fx.end);
13577                         fx.colorInit = true;
13578                 }
13579
13580                 fx.elem.style[attr] = 'rgb(' +
13581                         Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
13582                         Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
13583                         Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
13584         };
13585 });
13586
13587 // Color Conversion functions from highlightFade
13588 // By Blair Mitchelmore
13589 // http://jquery.offput.ca/highlightFade/
13590
13591 // Parse strings looking for color tuples [255,255,255]
13592 function getRGB(color) {
13593                 var result;
13594
13595                 // Check if we're already dealing with an array of colors
13596                 if ( color && color.constructor == Array && color.length == 3 )
13597                                 return color;
13598
13599                 // Look for rgb(num,num,num)
13600                 if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
13601                                 return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
13602
13603                 // Look for rgb(num%,num%,num%)
13604                 if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
13605                                 return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
13606
13607                 // Look for #a0b1c2
13608                 if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
13609                                 return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
13610
13611                 // Look for #fff
13612                 if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
13613                                 return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
13614
13615                 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
13616                 if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
13617                                 return colors['transparent'];
13618
13619                 // Otherwise, we're most likely dealing with a named color
13620                 return colors[$.trim(color).toLowerCase()];
13621 }
13622
13623 function getColor(elem, attr) {
13624                 var color;
13625
13626                 do {
13627                                 color = $.curCSS(elem, attr);
13628
13629                                 // Keep going until we find an element that has color, or we hit the body
13630                                 if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
13631                                                 break;
13632
13633                                 attr = "backgroundColor";
13634                 } while ( elem = elem.parentNode );
13635
13636                 return getRGB(color);
13637 };
13638
13639 // Some named colors to work with
13640 // From Interface by Stefan Petre
13641 // http://interface.eyecon.ro/
13642
13643 var colors = {
13644         aqua:[0,255,255],
13645         azure:[240,255,255],
13646         beige:[245,245,220],
13647         black:[0,0,0],
13648         blue:[0,0,255],
13649         brown:[165,42,42],
13650         cyan:[0,255,255],
13651         darkblue:[0,0,139],
13652         darkcyan:[0,139,139],
13653         darkgrey:[169,169,169],
13654         darkgreen:[0,100,0],
13655         darkkhaki:[189,183,107],
13656         darkmagenta:[139,0,139],
13657         darkolivegreen:[85,107,47],
13658         darkorange:[255,140,0],
13659         darkorchid:[153,50,204],
13660         darkred:[139,0,0],
13661         darksalmon:[233,150,122],
13662         darkviolet:[148,0,211],
13663         fuchsia:[255,0,255],
13664         gold:[255,215,0],
13665         green:[0,128,0],
13666         indigo:[75,0,130],
13667         khaki:[240,230,140],
13668         lightblue:[173,216,230],
13669         lightcyan:[224,255,255],
13670         lightgreen:[144,238,144],
13671         lightgrey:[211,211,211],
13672         lightpink:[255,182,193],
13673         lightyellow:[255,255,224],
13674         lime:[0,255,0],
13675         magenta:[255,0,255],
13676         maroon:[128,0,0],
13677         navy:[0,0,128],
13678         olive:[128,128,0],
13679         orange:[255,165,0],
13680         pink:[255,192,203],
13681         purple:[128,0,128],
13682         violet:[128,0,128],
13683         red:[255,0,0],
13684         silver:[192,192,192],
13685         white:[255,255,255],
13686         yellow:[255,255,0],
13687         transparent: [255,255,255]
13688 };
13689
13690
13691
13692 /******************************************************************************/
13693 /****************************** CLASS ANIMATIONS ******************************/
13694 /******************************************************************************/
13695
13696 var classAnimationActions = ['add', 'remove', 'toggle'],
13697         shorthandStyles = {
13698                 border: 1,
13699                 borderBottom: 1,
13700                 borderColor: 1,
13701                 borderLeft: 1,
13702                 borderRight: 1,
13703                 borderTop: 1,
13704                 borderWidth: 1,
13705                 margin: 1,
13706                 padding: 1
13707         };
13708
13709 function getElementStyles() {
13710         var style = document.defaultView
13711                         ? document.defaultView.getComputedStyle(this, null)
13712                         : this.currentStyle,
13713                 newStyle = {},
13714                 key,
13715                 camelCase;
13716
13717         // webkit enumerates style porperties
13718         if (style && style.length && style[0] && style[style[0]]) {
13719                 var len = style.length;
13720                 while (len--) {
13721                         key = style[len];
13722                         if (typeof style[key] == 'string') {
13723                                 camelCase = key.replace(/\-(\w)/g, function(all, letter){
13724                                         return letter.toUpperCase();
13725                                 });
13726                                 newStyle[camelCase] = style[key];
13727                         }
13728                 }
13729         } else {
13730                 for (key in style) {
13731                         if (typeof style[key] === 'string') {
13732                                 newStyle[key] = style[key];
13733                         }
13734                 }
13735         }
13736         
13737         return newStyle;
13738 }
13739
13740 function filterStyles(styles) {
13741         var name, value;
13742         for (name in styles) {
13743                 value = styles[name];
13744                 if (
13745                         // ignore null and undefined values
13746                         value == null ||
13747                         // ignore functions (when does this occur?)
13748                         $.isFunction(value) ||
13749                         // shorthand styles that need to be expanded
13750                         name in shorthandStyles ||
13751                         // ignore scrollbars (break in IE)
13752                         (/scrollbar/).test(name) ||
13753
13754                         // only colors or values that can be converted to numbers
13755                         (!(/color/i).test(name) && isNaN(parseFloat(value)))
13756                 ) {
13757                         delete styles[name];
13758                 }
13759         }
13760         
13761         return styles;
13762 }
13763
13764 function styleDifference(oldStyle, newStyle) {
13765         var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
13766                 name;
13767
13768         for (name in newStyle) {
13769                 if (oldStyle[name] != newStyle[name]) {
13770                         diff[name] = newStyle[name];
13771                 }
13772         }
13773
13774         return diff;
13775 }
13776
13777 $.effects.animateClass = function(value, duration, easing, callback) {
13778         if ($.isFunction(easing)) {
13779                 callback = easing;
13780                 easing = null;
13781         }
13782
13783         return this.queue('fx', function() {
13784                 var that = $(this),
13785                         originalStyleAttr = that.attr('style') || ' ',
13786                         originalStyle = filterStyles(getElementStyles.call(this)),
13787                         newStyle,
13788                         className = that.attr('className');
13789
13790                 $.each(classAnimationActions, function(i, action) {
13791                         if (value[action]) {
13792                                 that[action + 'Class'](value[action]);
13793                         }
13794                 });
13795                 newStyle = filterStyles(getElementStyles.call(this));
13796                 that.attr('className', className);
13797
13798                 that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() {
13799                         $.each(classAnimationActions, function(i, action) {
13800                                 if (value[action]) { that[action + 'Class'](value[action]); }
13801                         });
13802                         // work around bug in IE by clearing the cssText before setting it
13803                         if (typeof that.attr('style') == 'object') {
13804                                 that.attr('style').cssText = '';
13805                                 that.attr('style').cssText = originalStyleAttr;
13806                         } else {
13807                                 that.attr('style', originalStyleAttr);
13808                         }
13809                         if (callback) { callback.apply(this, arguments); }
13810                 });
13811
13812                 // $.animate adds a function to the end of the queue
13813                 // but we want it at the front
13814                 var queue = $.queue(this),
13815                         anim = queue.splice(queue.length - 1, 1)[0];
13816                 queue.splice(1, 0, anim);
13817                 $.dequeue(this);
13818         });
13819 };
13820
13821 $.fn.extend({
13822         _addClass: $.fn.addClass,
13823         addClass: function(classNames, speed, easing, callback) {
13824                 return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
13825         },
13826
13827         _removeClass: $.fn.removeClass,
13828         removeClass: function(classNames,speed,easing,callback) {
13829                 return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
13830         },
13831
13832         _toggleClass: $.fn.toggleClass,
13833         toggleClass: function(classNames, force, speed, easing, callback) {
13834                 if ( typeof force == "boolean" || force === undefined ) {
13835                         if ( !speed ) {
13836                                 // without speed parameter;
13837                                 return this._toggleClass(classNames, force);
13838                         } else {
13839                                 return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
13840                         }
13841                 } else {
13842                         // without switch parameter;
13843                         return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
13844                 }
13845         },
13846
13847         switchClass: function(remove,add,speed,easing,callback) {
13848                 return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
13849         }
13850 });
13851
13852
13853
13854 /******************************************************************************/
13855 /*********************************** EFFECTS **********************************/
13856 /******************************************************************************/
13857
13858 $.extend($.effects, {
13859         version: "1.8.12",
13860
13861         // Saves a set of properties in a data storage
13862         save: function(element, set) {
13863                 for(var i=0; i < set.length; i++) {
13864                         if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
13865                 }
13866         },
13867
13868         // Restores a set of previously saved properties from a data storage
13869         restore: function(element, set) {
13870                 for(var i=0; i < set.length; i++) {
13871                         if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
13872                 }
13873         },
13874
13875         setMode: function(el, mode) {
13876                 if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
13877                 return mode;
13878         },
13879
13880         getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
13881                 // this should be a little more flexible in the future to handle a string & hash
13882                 var y, x;
13883                 switch (origin[0]) {
13884                         case 'top': y = 0; break;
13885                         case 'middle': y = 0.5; break;
13886                         case 'bottom': y = 1; break;
13887                         default: y = origin[0] / original.height;
13888                 };
13889                 switch (origin[1]) {
13890                         case 'left': x = 0; break;
13891                         case 'center': x = 0.5; break;
13892                         case 'right': x = 1; break;
13893                         default: x = origin[1] / original.width;
13894                 };
13895                 return {x: x, y: y};
13896         },
13897
13898         // Wraps the element around a wrapper that copies position properties
13899         createWrapper: function(element) {
13900
13901                 // if the element is already wrapped, return it
13902                 if (element.parent().is('.ui-effects-wrapper')) {
13903                         return element.parent();
13904                 }
13905
13906                 // wrap the element
13907                 var props = {
13908                                 width: element.outerWidth(true),
13909                                 height: element.outerHeight(true),
13910                                 'float': element.css('float')
13911                         },
13912                         wrapper = $('<div></div>')
13913                                 .addClass('ui-effects-wrapper')
13914                                 .css({
13915                                         fontSize: '100%',
13916                                         background: 'transparent',
13917                                         border: 'none',
13918                                         margin: 0,
13919                                         padding: 0
13920                                 });
13921
13922                 element.wrap(wrapper);
13923                 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
13924
13925                 // transfer positioning properties to the wrapper
13926                 if (element.css('position') == 'static') {
13927                         wrapper.css({ position: 'relative' });
13928                         element.css({ position: 'relative' });
13929                 } else {
13930                         $.extend(props, {
13931                                 position: element.css('position'),
13932                                 zIndex: element.css('z-index')
13933                         });
13934                         $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
13935                                 props[pos] = element.css(pos);
13936                                 if (isNaN(parseInt(props[pos], 10))) {
13937                                         props[pos] = 'auto';
13938                                 }
13939                         });
13940                         element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
13941                 }
13942
13943                 return wrapper.css(props).show();
13944         },
13945
13946         removeWrapper: function(element) {
13947                 if (element.parent().is('.ui-effects-wrapper'))
13948                         return element.parent().replaceWith(element);
13949                 return element;
13950         },
13951
13952         setTransition: function(element, list, factor, value) {
13953                 value = value || {};
13954                 $.each(list, function(i, x){
13955                         unit = element.cssUnit(x);
13956                         if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
13957                 });
13958                 return value;
13959         }
13960 });
13961
13962
13963 function _normalizeArguments(effect, options, speed, callback) {
13964         // shift params for method overloading
13965         if (typeof effect == 'object') {
13966                 callback = options;
13967                 speed = null;
13968                 options = effect;
13969                 effect = options.effect;
13970         }
13971         if ($.isFunction(options)) {
13972                 callback = options;
13973                 speed = null;
13974                 options = {};
13975         }
13976         if (typeof options == 'number' || $.fx.speeds[options]) {
13977                 callback = speed;
13978                 speed = options;
13979                 options = {};
13980         }
13981         if ($.isFunction(speed)) {
13982                 callback = speed;
13983                 speed = null;
13984         }
13985
13986         options = options || {};
13987
13988         speed = speed || options.duration;
13989         speed = $.fx.off ? 0 : typeof speed == 'number'
13990                 ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
13991
13992         callback = callback || options.complete;
13993
13994         return [effect, options, speed, callback];
13995 }
13996
13997 function standardSpeed( speed ) {
13998         // valid standard speeds
13999         if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
14000                 return true;
14001         }
14002         
14003         // invalid strings - treat as "normal" speed
14004         if ( typeof speed === "string" && !$.effects[ speed ] ) {
14005                 return true;
14006         }
14007         
14008         return false;
14009 }
14010
14011 $.fn.extend({
14012         effect: function(effect, options, speed, callback) {
14013                 var args = _normalizeArguments.apply(this, arguments),
14014                         // TODO: make effects take actual parameters instead of a hash
14015                         args2 = {
14016                                 options: args[1],
14017                                 duration: args[2],
14018                                 callback: args[3]
14019                         },
14020                         mode = args2.options.mode,
14021                         effectMethod = $.effects[effect];
14022                 
14023                 if ( $.fx.off || !effectMethod ) {
14024                         // delegate to the original method (e.g., .show()) if possible
14025                         if ( mode ) {
14026                                 return this[ mode ]( args2.duration, args2.callback );
14027                         } else {
14028                                 return this.each(function() {
14029                                         if ( args2.callback ) {
14030                                                 args2.callback.call( this );
14031                                         }
14032                                 });
14033                         }
14034                 }
14035                 
14036                 return effectMethod.call(this, args2);
14037         },
14038
14039         _show: $.fn.show,
14040         show: function(speed) {
14041                 if ( standardSpeed( speed ) ) {
14042                         return this._show.apply(this, arguments);
14043                 } else {
14044                         var args = _normalizeArguments.apply(this, arguments);
14045                         args[1].mode = 'show';
14046                         return this.effect.apply(this, args);
14047                 }
14048         },
14049
14050         _hide: $.fn.hide,
14051         hide: function(speed) {
14052                 if ( standardSpeed( speed ) ) {
14053                         return this._hide.apply(this, arguments);
14054                 } else {
14055                         var args = _normalizeArguments.apply(this, arguments);
14056                         args[1].mode = 'hide';
14057                         return this.effect.apply(this, args);
14058                 }
14059         },
14060
14061         // jQuery core overloads toggle and creates _toggle
14062         __toggle: $.fn.toggle,
14063         toggle: function(speed) {
14064                 if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
14065                         return this.__toggle.apply(this, arguments);
14066                 } else {
14067                         var args = _normalizeArguments.apply(this, arguments);
14068                         args[1].mode = 'toggle';
14069                         return this.effect.apply(this, args);
14070                 }
14071         },
14072
14073         // helper functions
14074         cssUnit: function(key) {
14075                 var style = this.css(key), val = [];
14076                 $.each( ['em','px','%','pt'], function(i, unit){
14077                         if(style.indexOf(unit) > 0)
14078                                 val = [parseFloat(style), unit];
14079                 });
14080                 return val;
14081         }
14082 });
14083
14084
14085
14086 /******************************************************************************/
14087 /*********************************** EASING ***********************************/
14088 /******************************************************************************/
14089
14090 /*
14091  * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
14092  *
14093  * Uses the built in easing capabilities added In jQuery 1.1
14094  * to offer multiple easing options
14095  *
14096  * TERMS OF USE - jQuery Easing
14097  *
14098  * Open source under the BSD License.
14099  *
14100  * Copyright 2008 George McGinley Smith
14101  * All rights reserved.
14102  *
14103  * Redistribution and use in source and binary forms, with or without modification,
14104  * are permitted provided that the following conditions are met:
14105  *
14106  * Redistributions of source code must retain the above copyright notice, this list of
14107  * conditions and the following disclaimer.
14108  * Redistributions in binary form must reproduce the above copyright notice, this list
14109  * of conditions and the following disclaimer in the documentation and/or other materials
14110  * provided with the distribution.
14111  *
14112  * Neither the name of the author nor the names of contributors may be used to endorse
14113  * or promote products derived from this software without specific prior written permission.
14114  *
14115  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
14116  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14117  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
14118  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14119  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
14120  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
14121  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
14122  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
14123  * OF THE POSSIBILITY OF SUCH DAMAGE.
14124  *
14125 */
14126
14127 // t: current time, b: begInnIng value, c: change In value, d: duration
14128 $.easing.jswing = $.easing.swing;
14129
14130 $.extend($.easing,
14131 {
14132         def: 'easeOutQuad',
14133         swing: function (x, t, b, c, d) {
14134                 //alert($.easing.default);
14135                 return $.easing[$.easing.def](x, t, b, c, d);
14136         },
14137         easeInQuad: function (x, t, b, c, d) {
14138                 return c*(t/=d)*t + b;
14139         },
14140         easeOutQuad: function (x, t, b, c, d) {
14141                 return -c *(t/=d)*(t-2) + b;
14142         },
14143         easeInOutQuad: function (x, t, b, c, d) {
14144                 if ((t/=d/2) < 1) return c/2*t*t + b;
14145                 return -c/2 * ((--t)*(t-2) - 1) + b;
14146         },
14147         easeInCubic: function (x, t, b, c, d) {
14148                 return c*(t/=d)*t*t + b;
14149         },
14150         easeOutCubic: function (x, t, b, c, d) {
14151                 return c*((t=t/d-1)*t*t + 1) + b;
14152         },
14153         easeInOutCubic: function (x, t, b, c, d) {
14154                 if ((t/=d/2) < 1) return c/2*t*t*t + b;
14155                 return c/2*((t-=2)*t*t + 2) + b;
14156         },
14157         easeInQuart: function (x, t, b, c, d) {
14158                 return c*(t/=d)*t*t*t + b;
14159         },
14160         easeOutQuart: function (x, t, b, c, d) {
14161                 return -c * ((t=t/d-1)*t*t*t - 1) + b;
14162         },
14163         easeInOutQuart: function (x, t, b, c, d) {
14164                 if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
14165                 return -c/2 * ((t-=2)*t*t*t - 2) + b;
14166         },
14167         easeInQuint: function (x, t, b, c, d) {
14168                 return c*(t/=d)*t*t*t*t + b;
14169         },
14170         easeOutQuint: function (x, t, b, c, d) {
14171                 return c*((t=t/d-1)*t*t*t*t + 1) + b;
14172         },
14173         easeInOutQuint: function (x, t, b, c, d) {
14174                 if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
14175                 return c/2*((t-=2)*t*t*t*t + 2) + b;
14176         },
14177         easeInSine: function (x, t, b, c, d) {
14178                 return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
14179         },
14180         easeOutSine: function (x, t, b, c, d) {
14181                 return c * Math.sin(t/d * (Math.PI/2)) + b;
14182         },
14183         easeInOutSine: function (x, t, b, c, d) {
14184                 return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
14185         },
14186         easeInExpo: function (x, t, b, c, d) {
14187                 return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
14188         },
14189         easeOutExpo: function (x, t, b, c, d) {
14190                 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
14191         },
14192         easeInOutExpo: function (x, t, b, c, d) {
14193                 if (t==0) return b;
14194                 if (t==d) return b+c;
14195                 if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
14196                 return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
14197         },
14198         easeInCirc: function (x, t, b, c, d) {
14199                 return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
14200         },
14201         easeOutCirc: function (x, t, b, c, d) {
14202                 return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
14203         },
14204         easeInOutCirc: function (x, t, b, c, d) {
14205                 if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
14206                 return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
14207         },
14208         easeInElastic: function (x, t, b, c, d) {
14209                 var s=1.70158;var p=0;var a=c;
14210                 if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
14211                 if (a < Math.abs(c)) { a=c; var s=p/4; }
14212                 else var s = p/(2*Math.PI) * Math.asin (c/a);
14213                 return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
14214         },
14215         easeOutElastic: function (x, t, b, c, d) {
14216                 var s=1.70158;var p=0;var a=c;
14217                 if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
14218                 if (a < Math.abs(c)) { a=c; var s=p/4; }
14219                 else var s = p/(2*Math.PI) * Math.asin (c/a);
14220                 return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
14221         },
14222         easeInOutElastic: function (x, t, b, c, d) {
14223                 var s=1.70158;var p=0;var a=c;
14224                 if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
14225                 if (a < Math.abs(c)) { a=c; var s=p/4; }
14226                 else var s = p/(2*Math.PI) * Math.asin (c/a);
14227                 if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
14228                 return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
14229         },
14230         easeInBack: function (x, t, b, c, d, s) {
14231                 if (s == undefined) s = 1.70158;
14232                 return c*(t/=d)*t*((s+1)*t - s) + b;
14233         },
14234         easeOutBack: function (x, t, b, c, d, s) {
14235                 if (s == undefined) s = 1.70158;
14236                 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
14237         },
14238         easeInOutBack: function (x, t, b, c, d, s) {
14239                 if (s == undefined) s = 1.70158;
14240                 if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
14241                 return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
14242         },
14243         easeInBounce: function (x, t, b, c, d) {
14244                 return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
14245         },
14246         easeOutBounce: function (x, t, b, c, d) {
14247                 if ((t/=d) < (1/2.75)) {
14248                         return c*(7.5625*t*t) + b;
14249                 } else if (t < (2/2.75)) {
14250                         return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
14251                 } else if (t < (2.5/2.75)) {
14252                         return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
14253                 } else {
14254                         return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
14255                 }
14256         },
14257         easeInOutBounce: function (x, t, b, c, d) {
14258                 if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
14259                 return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
14260         }
14261 });
14262
14263 /*
14264  *
14265  * TERMS OF USE - EASING EQUATIONS
14266  *
14267  * Open source under the BSD License.
14268  *
14269  * Copyright 2001 Robert Penner
14270  * All rights reserved.
14271  *
14272  * Redistribution and use in source and binary forms, with or without modification,
14273  * are permitted provided that the following conditions are met:
14274  *
14275  * Redistributions of source code must retain the above copyright notice, this list of
14276  * conditions and the following disclaimer.
14277  * Redistributions in binary form must reproduce the above copyright notice, this list
14278  * of conditions and the following disclaimer in the documentation and/or other materials
14279  * provided with the distribution.
14280  *
14281  * Neither the name of the author nor the names of contributors may be used to endorse
14282  * or promote products derived from this software without specific prior written permission.
14283  *
14284  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
14285  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14286  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
14287  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14288  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
14289  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
14290  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
14291  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
14292  * OF THE POSSIBILITY OF SUCH DAMAGE.
14293  *
14294  */
14295
14296 })(jQuery);
14297 /*
14298  * jQuery UI Effects Blind 1.8.12
14299  *
14300  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14301  * Dual licensed under the MIT or GPL Version 2 licenses.
14302  * http://jquery.org/license
14303  *
14304  * http://docs.jquery.com/UI/Effects/Blind
14305  *
14306  * Depends:
14307  *      jquery.effects.core.js
14308  */
14309 (function( $, undefined ) {
14310
14311 $.effects.blind = function(o) {
14312
14313         return this.queue(function() {
14314
14315                 // Create element
14316                 var el = $(this), props = ['position','top','bottom','left','right'];
14317
14318                 // Set options
14319                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
14320                 var direction = o.options.direction || 'vertical'; // Default direction
14321
14322                 // Adjust
14323                 $.effects.save(el, props); el.show(); // Save & Show
14324                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
14325                 var ref = (direction == 'vertical') ? 'height' : 'width';
14326                 var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
14327                 if(mode == 'show') wrapper.css(ref, 0); // Shift
14328
14329                 // Animation
14330                 var animation = {};
14331                 animation[ref] = mode == 'show' ? distance : 0;
14332
14333                 // Animate
14334                 wrapper.animate(animation, o.duration, o.options.easing, function() {
14335                         if(mode == 'hide') el.hide(); // Hide
14336                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14337                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
14338                         el.dequeue();
14339                 });
14340
14341         });
14342
14343 };
14344
14345 })(jQuery);
14346 /*
14347  * jQuery UI Effects Bounce 1.8.12
14348  *
14349  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14350  * Dual licensed under the MIT or GPL Version 2 licenses.
14351  * http://jquery.org/license
14352  *
14353  * http://docs.jquery.com/UI/Effects/Bounce
14354  *
14355  * Depends:
14356  *      jquery.effects.core.js
14357  */
14358 (function( $, undefined ) {
14359
14360 $.effects.bounce = function(o) {
14361
14362         return this.queue(function() {
14363
14364                 // Create element
14365                 var el = $(this), props = ['position','top','bottom','left','right'];
14366
14367                 // Set options
14368                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
14369                 var direction = o.options.direction || 'up'; // Default direction
14370                 var distance = o.options.distance || 20; // Default distance
14371                 var times = o.options.times || 5; // Default # of times
14372                 var speed = o.duration || 250; // Default speed per bounce
14373                 if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
14374
14375                 // Adjust
14376                 $.effects.save(el, props); el.show(); // Save & Show
14377                 $.effects.createWrapper(el); // Create Wrapper
14378                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
14379                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
14380                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
14381                 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
14382                 if (mode == 'hide') distance = distance / (times * 2);
14383                 if (mode != 'hide') times--;
14384
14385                 // Animate
14386                 if (mode == 'show') { // Show Bounce
14387                         var animation = {opacity: 1};
14388                         animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
14389                         el.animate(animation, speed / 2, o.options.easing);
14390                         distance = distance / 2;
14391                         times--;
14392                 };
14393                 for (var i = 0; i < times; i++) { // Bounces
14394                         var animation1 = {}, animation2 = {};
14395                         animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
14396                         animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
14397                         el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
14398                         distance = (mode == 'hide') ? distance * 2 : distance / 2;
14399                 };
14400                 if (mode == 'hide') { // Last Bounce
14401                         var animation = {opacity: 0};
14402                         animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
14403                         el.animate(animation, speed / 2, o.options.easing, function(){
14404                                 el.hide(); // Hide
14405                                 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14406                                 if(o.callback) o.callback.apply(this, arguments); // Callback
14407                         });
14408                 } else {
14409                         var animation1 = {}, animation2 = {};
14410                         animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
14411                         animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
14412                         el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
14413                                 $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14414                                 if(o.callback) o.callback.apply(this, arguments); // Callback
14415                         });
14416                 };
14417                 el.queue('fx', function() { el.dequeue(); });
14418                 el.dequeue();
14419         });
14420
14421 };
14422
14423 })(jQuery);
14424 /*
14425  * jQuery UI Effects Clip 1.8.12
14426  *
14427  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14428  * Dual licensed under the MIT or GPL Version 2 licenses.
14429  * http://jquery.org/license
14430  *
14431  * http://docs.jquery.com/UI/Effects/Clip
14432  *
14433  * Depends:
14434  *      jquery.effects.core.js
14435  */
14436 (function( $, undefined ) {
14437
14438 $.effects.clip = function(o) {
14439
14440         return this.queue(function() {
14441
14442                 // Create element
14443                 var el = $(this), props = ['position','top','bottom','left','right','height','width'];
14444
14445                 // Set options
14446                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
14447                 var direction = o.options.direction || 'vertical'; // Default direction
14448
14449                 // Adjust
14450                 $.effects.save(el, props); el.show(); // Save & Show
14451                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
14452                 var animate = el[0].tagName == 'IMG' ? wrapper : el;
14453                 var ref = {
14454                         size: (direction == 'vertical') ? 'height' : 'width',
14455                         position: (direction == 'vertical') ? 'top' : 'left'
14456                 };
14457                 var distance = (direction == 'vertical') ? animate.height() : animate.width();
14458                 if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
14459
14460                 // Animation
14461                 var animation = {};
14462                 animation[ref.size] = mode == 'show' ? distance : 0;
14463                 animation[ref.position] = mode == 'show' ? 0 : distance / 2;
14464
14465                 // Animate
14466                 animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
14467                         if(mode == 'hide') el.hide(); // Hide
14468                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14469                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
14470                         el.dequeue();
14471                 }});
14472
14473         });
14474
14475 };
14476
14477 })(jQuery);
14478 /*
14479  * jQuery UI Effects Drop 1.8.12
14480  *
14481  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14482  * Dual licensed under the MIT or GPL Version 2 licenses.
14483  * http://jquery.org/license
14484  *
14485  * http://docs.jquery.com/UI/Effects/Drop
14486  *
14487  * Depends:
14488  *      jquery.effects.core.js
14489  */
14490 (function( $, undefined ) {
14491
14492 $.effects.drop = function(o) {
14493
14494         return this.queue(function() {
14495
14496                 // Create element
14497                 var el = $(this), props = ['position','top','bottom','left','right','opacity'];
14498
14499                 // Set options
14500                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
14501                 var direction = o.options.direction || 'left'; // Default Direction
14502
14503                 // Adjust
14504                 $.effects.save(el, props); el.show(); // Save & Show
14505                 $.effects.createWrapper(el); // Create Wrapper
14506                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
14507                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
14508                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
14509                 if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
14510
14511                 // Animation
14512                 var animation = {opacity: mode == 'show' ? 1 : 0};
14513                 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
14514
14515                 // Animate
14516                 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
14517                         if(mode == 'hide') el.hide(); // Hide
14518                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14519                         if(o.callback) o.callback.apply(this, arguments); // Callback
14520                         el.dequeue();
14521                 }});
14522
14523         });
14524
14525 };
14526
14527 })(jQuery);
14528 /*
14529  * jQuery UI Effects Explode 1.8.12
14530  *
14531  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14532  * Dual licensed under the MIT or GPL Version 2 licenses.
14533  * http://jquery.org/license
14534  *
14535  * http://docs.jquery.com/UI/Effects/Explode
14536  *
14537  * Depends:
14538  *      jquery.effects.core.js
14539  */
14540 (function( $, undefined ) {
14541
14542 $.effects.explode = function(o) {
14543
14544         return this.queue(function() {
14545
14546         var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
14547         var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
14548
14549         o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
14550         var el = $(this).show().css('visibility', 'hidden');
14551         var offset = el.offset();
14552
14553         //Substract the margins - not fixing the problem yet.
14554         offset.top -= parseInt(el.css("marginTop"),10) || 0;
14555         offset.left -= parseInt(el.css("marginLeft"),10) || 0;
14556
14557         var width = el.outerWidth(true);
14558         var height = el.outerHeight(true);
14559
14560         for(var i=0;i<rows;i++) { // =
14561                 for(var j=0;j<cells;j++) { // ||
14562                         el
14563                                 .clone()
14564                                 .appendTo('body')
14565                                 .wrap('<div></div>')
14566                                 .css({
14567                                         position: 'absolute',
14568                                         visibility: 'visible',
14569                                         left: -j*(width/cells),
14570                                         top: -i*(height/rows)
14571                                 })
14572                                 .parent()
14573                                 .addClass('ui-effects-explode')
14574                                 .css({
14575                                         position: 'absolute',
14576                                         overflow: 'hidden',
14577                                         width: width/cells,
14578                                         height: height/rows,
14579                                         left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
14580                                         top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
14581                                         opacity: o.options.mode == 'show' ? 0 : 1
14582                                 }).animate({
14583                                         left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
14584                                         top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
14585                                         opacity: o.options.mode == 'show' ? 1 : 0
14586                                 }, o.duration || 500);
14587                 }
14588         }
14589
14590         // Set a timeout, to call the callback approx. when the other animations have finished
14591         setTimeout(function() {
14592
14593                 o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
14594                                 if(o.callback) o.callback.apply(el[0]); // Callback
14595                                 el.dequeue();
14596
14597                                 $('div.ui-effects-explode').remove();
14598
14599         }, o.duration || 500);
14600
14601
14602         });
14603
14604 };
14605
14606 })(jQuery);
14607 /*
14608  * jQuery UI Effects Fade 1.8.12
14609  *
14610  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14611  * Dual licensed under the MIT or GPL Version 2 licenses.
14612  * http://jquery.org/license
14613  *
14614  * http://docs.jquery.com/UI/Effects/Fade
14615  *
14616  * Depends:
14617  *      jquery.effects.core.js
14618  */
14619 (function( $, undefined ) {
14620
14621 $.effects.fade = function(o) {
14622         return this.queue(function() {
14623                 var elem = $(this),
14624                         mode = $.effects.setMode(elem, o.options.mode || 'hide');
14625
14626                 elem.animate({ opacity: mode }, {
14627                         queue: false,
14628                         duration: o.duration,
14629                         easing: o.options.easing,
14630                         complete: function() {
14631                                 (o.callback && o.callback.apply(this, arguments));
14632                                 elem.dequeue();
14633                         }
14634                 });
14635         });
14636 };
14637
14638 })(jQuery);
14639 /*
14640  * jQuery UI Effects Fold 1.8.12
14641  *
14642  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14643  * Dual licensed under the MIT or GPL Version 2 licenses.
14644  * http://jquery.org/license
14645  *
14646  * http://docs.jquery.com/UI/Effects/Fold
14647  *
14648  * Depends:
14649  *      jquery.effects.core.js
14650  */
14651 (function( $, undefined ) {
14652
14653 $.effects.fold = function(o) {
14654
14655         return this.queue(function() {
14656
14657                 // Create element
14658                 var el = $(this), props = ['position','top','bottom','left','right'];
14659
14660                 // Set options
14661                 var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
14662                 var size = o.options.size || 15; // Default fold size
14663                 var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
14664                 var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
14665
14666                 // Adjust
14667                 $.effects.save(el, props); el.show(); // Save & Show
14668                 var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
14669                 var widthFirst = ((mode == 'show') != horizFirst);
14670                 var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
14671                 var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
14672                 var percent = /([0-9]+)%/.exec(size);
14673                 if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
14674                 if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
14675
14676                 // Animation
14677                 var animation1 = {}, animation2 = {};
14678                 animation1[ref[0]] = mode == 'show' ? distance[0] : size;
14679                 animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
14680
14681                 // Animate
14682                 wrapper.animate(animation1, duration, o.options.easing)
14683                 .animate(animation2, duration, o.options.easing, function() {
14684                         if(mode == 'hide') el.hide(); // Hide
14685                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
14686                         if(o.callback) o.callback.apply(el[0], arguments); // Callback
14687                         el.dequeue();
14688                 });
14689
14690         });
14691
14692 };
14693
14694 })(jQuery);
14695 /*
14696  * jQuery UI Effects Highlight 1.8.12
14697  *
14698  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14699  * Dual licensed under the MIT or GPL Version 2 licenses.
14700  * http://jquery.org/license
14701  *
14702  * http://docs.jquery.com/UI/Effects/Highlight
14703  *
14704  * Depends:
14705  *      jquery.effects.core.js
14706  */
14707 (function( $, undefined ) {
14708
14709 $.effects.highlight = function(o) {
14710         return this.queue(function() {
14711                 var elem = $(this),
14712                         props = ['backgroundImage', 'backgroundColor', 'opacity'],
14713                         mode = $.effects.setMode(elem, o.options.mode || 'show'),
14714                         animation = {
14715                                 backgroundColor: elem.css('backgroundColor')
14716                         };
14717
14718                 if (mode == 'hide') {
14719                         animation.opacity = 0;
14720                 }
14721
14722                 $.effects.save(elem, props);
14723                 elem
14724                         .show()
14725                         .css({
14726                                 backgroundImage: 'none',
14727                                 backgroundColor: o.options.color || '#ffff99'
14728                         })
14729                         .animate(animation, {
14730                                 queue: false,
14731                                 duration: o.duration,
14732                                 easing: o.options.easing,
14733                                 complete: function() {
14734                                         (mode == 'hide' && elem.hide());
14735                                         $.effects.restore(elem, props);
14736                                         (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
14737                                         (o.callback && o.callback.apply(this, arguments));
14738                                         elem.dequeue();
14739                                 }
14740                         });
14741         });
14742 };
14743
14744 })(jQuery);
14745 /*
14746  * jQuery UI Effects Pulsate 1.8.12
14747  *
14748  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14749  * Dual licensed under the MIT or GPL Version 2 licenses.
14750  * http://jquery.org/license
14751  *
14752  * http://docs.jquery.com/UI/Effects/Pulsate
14753  *
14754  * Depends:
14755  *      jquery.effects.core.js
14756  */
14757 (function( $, undefined ) {
14758
14759 $.effects.pulsate = function(o) {
14760         return this.queue(function() {
14761                 var elem = $(this),
14762                         mode = $.effects.setMode(elem, o.options.mode || 'show');
14763                         times = ((o.options.times || 5) * 2) - 1;
14764                         duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
14765                         isVisible = elem.is(':visible'),
14766                         animateTo = 0;
14767
14768                 if (!isVisible) {
14769                         elem.css('opacity', 0).show();
14770                         animateTo = 1;
14771                 }
14772
14773                 if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
14774                         times--;
14775                 }
14776
14777                 for (var i = 0; i < times; i++) {
14778                         elem.animate({ opacity: animateTo }, duration, o.options.easing);
14779                         animateTo = (animateTo + 1) % 2;
14780                 }
14781
14782                 elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
14783                         if (animateTo == 0) {
14784                                 elem.hide();
14785                         }
14786                         (o.callback && o.callback.apply(this, arguments));
14787                 });
14788
14789                 elem
14790                         .queue('fx', function() { elem.dequeue(); })
14791                         .dequeue();
14792         });
14793 };
14794
14795 })(jQuery);
14796 /*
14797  * jQuery UI Effects Scale 1.8.12
14798  *
14799  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14800  * Dual licensed under the MIT or GPL Version 2 licenses.
14801  * http://jquery.org/license
14802  *
14803  * http://docs.jquery.com/UI/Effects/Scale
14804  *
14805  * Depends:
14806  *      jquery.effects.core.js
14807  */
14808 (function( $, undefined ) {
14809
14810 $.effects.puff = function(o) {
14811         return this.queue(function() {
14812                 var elem = $(this),
14813                         mode = $.effects.setMode(elem, o.options.mode || 'hide'),
14814                         percent = parseInt(o.options.percent, 10) || 150,
14815                         factor = percent / 100,
14816                         original = { height: elem.height(), width: elem.width() };
14817
14818                 $.extend(o.options, {
14819                         fade: true,
14820                         mode: mode,
14821                         percent: mode == 'hide' ? percent : 100,
14822                         from: mode == 'hide'
14823                                 ? original
14824                                 : {
14825                                         height: original.height * factor,
14826                                         width: original.width * factor
14827                                 }
14828                 });
14829
14830                 elem.effect('scale', o.options, o.duration, o.callback);
14831                 elem.dequeue();
14832         });
14833 };
14834
14835 $.effects.scale = function(o) {
14836
14837         return this.queue(function() {
14838
14839                 // Create element
14840                 var el = $(this);
14841
14842                 // Set options
14843                 var options = $.extend(true, {}, o.options);
14844                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
14845                 var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
14846                 var direction = o.options.direction || 'both'; // Set default axis
14847                 var origin = o.options.origin; // The origin of the scaling
14848                 if (mode != 'effect') { // Set default origin and restore for show/hide
14849                         options.origin = origin || ['middle','center'];
14850                         options.restore = true;
14851                 }
14852                 var original = {height: el.height(), width: el.width()}; // Save original
14853                 el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
14854
14855                 // Adjust
14856                 var factor = { // Set scaling factor
14857                         y: direction != 'horizontal' ? (percent / 100) : 1,
14858                         x: direction != 'vertical' ? (percent / 100) : 1
14859                 };
14860                 el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
14861
14862                 if (o.options.fade) { // Fade option to support puff
14863                         if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
14864                         if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
14865                 };
14866
14867                 // Animation
14868                 options.from = el.from; options.to = el.to; options.mode = mode;
14869
14870                 // Animate
14871                 el.effect('size', options, o.duration, o.callback);
14872                 el.dequeue();
14873         });
14874
14875 };
14876
14877 $.effects.size = function(o) {
14878
14879         return this.queue(function() {
14880
14881                 // Create element
14882                 var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
14883                 var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
14884                 var props2 = ['width','height','overflow']; // Copy for children
14885                 var cProps = ['fontSize'];
14886                 var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
14887                 var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
14888
14889                 // Set options
14890                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
14891                 var restore = o.options.restore || false; // Default restore
14892                 var scale = o.options.scale || 'both'; // Default scale mode
14893                 var origin = o.options.origin; // The origin of the sizing
14894                 var original = {height: el.height(), width: el.width()}; // Save original
14895                 el.from = o.options.from || original; // Default from state
14896                 el.to = o.options.to || original; // Default to state
14897                 // Adjust
14898                 if (origin) { // Calculate baseline shifts
14899                         var baseline = $.effects.getBaseline(origin, original);
14900                         el.from.top = (original.height - el.from.height) * baseline.y;
14901                         el.from.left = (original.width - el.from.width) * baseline.x;
14902                         el.to.top = (original.height - el.to.height) * baseline.y;
14903                         el.to.left = (original.width - el.to.width) * baseline.x;
14904                 };
14905                 var factor = { // Set scaling factor
14906                         from: {y: el.from.height / original.height, x: el.from.width / original.width},
14907                         to: {y: el.to.height / original.height, x: el.to.width / original.width}
14908                 };
14909                 if (scale == 'box' || scale == 'both') { // Scale the css box
14910                         if (factor.from.y != factor.to.y) { // Vertical props scaling
14911                                 props = props.concat(vProps);
14912                                 el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
14913                                 el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
14914                         };
14915                         if (factor.from.x != factor.to.x) { // Horizontal props scaling
14916                                 props = props.concat(hProps);
14917                                 el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
14918                                 el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
14919                         };
14920                 };
14921                 if (scale == 'content' || scale == 'both') { // Scale the content
14922                         if (factor.from.y != factor.to.y) { // Vertical props scaling
14923                                 props = props.concat(cProps);
14924                                 el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
14925                                 el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
14926                         };
14927                 };
14928                 $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
14929                 $.effects.createWrapper(el); // Create Wrapper
14930                 el.css('overflow','hidden').css(el.from); // Shift
14931
14932                 // Animate
14933                 if (scale == 'content' || scale == 'both') { // Scale the children
14934                         vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
14935                         hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
14936                         props2 = props.concat(vProps).concat(hProps); // Concat
14937                         el.find("*[width]").each(function(){
14938                                 child = $(this);
14939                                 if (restore) $.effects.save(child, props2);
14940                                 var c_original = {height: child.height(), width: child.width()}; // Save original
14941                                 child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
14942                                 child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
14943                                 if (factor.from.y != factor.to.y) { // Vertical props scaling
14944                                         child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
14945                                         child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
14946                                 };
14947                                 if (factor.from.x != factor.to.x) { // Horizontal props scaling
14948                                         child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
14949                                         child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
14950                                 };
14951                                 child.css(child.from); // Shift children
14952                                 child.animate(child.to, o.duration, o.options.easing, function(){
14953                                         if (restore) $.effects.restore(child, props2); // Restore children
14954                                 }); // Animate children
14955                         });
14956                 };
14957
14958                 // Animate
14959                 el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
14960                         if (el.to.opacity === 0) {
14961                                 el.css('opacity', el.from.opacity);
14962                         }
14963                         if(mode == 'hide') el.hide(); // Hide
14964                         $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
14965                         if(o.callback) o.callback.apply(this, arguments); // Callback
14966                         el.dequeue();
14967                 }});
14968
14969         });
14970
14971 };
14972
14973 })(jQuery);
14974 /*
14975  * jQuery UI Effects Shake 1.8.12
14976  *
14977  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
14978  * Dual licensed under the MIT or GPL Version 2 licenses.
14979  * http://jquery.org/license
14980  *
14981  * http://docs.jquery.com/UI/Effects/Shake
14982  *
14983  * Depends:
14984  *      jquery.effects.core.js
14985  */
14986 (function( $, undefined ) {
14987
14988 $.effects.shake = function(o) {
14989
14990         return this.queue(function() {
14991
14992                 // Create element
14993                 var el = $(this), props = ['position','top','bottom','left','right'];
14994
14995                 // Set options
14996                 var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
14997                 var direction = o.options.direction || 'left'; // Default direction
14998                 var distance = o.options.distance || 20; // Default distance
14999                 var times = o.options.times || 3; // Default # of times
15000                 var speed = o.duration || o.options.duration || 140; // Default speed per shake
15001
15002                 // Adjust
15003                 $.effects.save(el, props); el.show(); // Save & Show
15004                 $.effects.createWrapper(el); // Create Wrapper
15005                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
15006                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
15007
15008                 // Animation
15009                 var animation = {}, animation1 = {}, animation2 = {};
15010                 animation[ref] = (motion == 'pos' ? '-=' : '+=')  + distance;
15011                 animation1[ref] = (motion == 'pos' ? '+=' : '-=')  + distance * 2;
15012                 animation2[ref] = (motion == 'pos' ? '-=' : '+=')  + distance * 2;
15013
15014                 // Animate
15015                 el.animate(animation, speed, o.options.easing);
15016                 for (var i = 1; i < times; i++) { // Shakes
15017                         el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
15018                 };
15019                 el.animate(animation1, speed, o.options.easing).
15020                 animate(animation, speed / 2, o.options.easing, function(){ // Last shake
15021                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
15022                         if(o.callback) o.callback.apply(this, arguments); // Callback
15023                 });
15024                 el.queue('fx', function() { el.dequeue(); });
15025                 el.dequeue();
15026         });
15027
15028 };
15029
15030 })(jQuery);
15031 /*
15032  * jQuery UI Effects Slide 1.8.12
15033  *
15034  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
15035  * Dual licensed under the MIT or GPL Version 2 licenses.
15036  * http://jquery.org/license
15037  *
15038  * http://docs.jquery.com/UI/Effects/Slide
15039  *
15040  * Depends:
15041  *      jquery.effects.core.js
15042  */
15043 (function( $, undefined ) {
15044
15045 $.effects.slide = function(o) {
15046
15047         return this.queue(function() {
15048
15049                 // Create element
15050                 var el = $(this), props = ['position','top','bottom','left','right'];
15051
15052                 // Set options
15053                 var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
15054                 var direction = o.options.direction || 'left'; // Default Direction
15055
15056                 // Adjust
15057                 $.effects.save(el, props); el.show(); // Save & Show
15058                 $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
15059                 var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
15060                 var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
15061                 var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
15062                 if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
15063
15064                 // Animation
15065                 var animation = {};
15066                 animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
15067
15068                 // Animate
15069                 el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
15070                         if(mode == 'hide') el.hide(); // Hide
15071                         $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
15072                         if(o.callback) o.callback.apply(this, arguments); // Callback
15073                         el.dequeue();
15074                 }});
15075
15076         });
15077
15078 };
15079
15080 })(jQuery);
15081 /*
15082  * jQuery UI Effects Transfer 1.8.12
15083  *
15084  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
15085  * Dual licensed under the MIT or GPL Version 2 licenses.
15086  * http://jquery.org/license
15087  *
15088  * http://docs.jquery.com/UI/Effects/Transfer
15089  *
15090  * Depends:
15091  *      jquery.effects.core.js
15092  */
15093 (function( $, undefined ) {
15094
15095 $.effects.transfer = function(o) {
15096         return this.queue(function() {
15097                 var elem = $(this),
15098                         target = $(o.options.to),
15099                         endPosition = target.offset(),
15100                         animation = {
15101                                 top: endPosition.top,
15102                                 left: endPosition.left,
15103                                 height: target.innerHeight(),
15104                                 width: target.innerWidth()
15105                         },
15106                         startPosition = elem.offset(),
15107                         transfer = $('<div class="ui-effects-transfer"></div>')
15108                                 .appendTo(document.body)
15109                                 .addClass(o.options.className)
15110                                 .css({
15111                                         top: startPosition.top,
15112                                         left: startPosition.left,
15113                                         height: elem.innerHeight(),
15114                                         width: elem.innerWidth(),
15115                                         position: 'absolute'
15116                                 })
15117                                 .animate(animation, o.duration, o.options.easing, function() {
15118                                         transfer.remove();
15119                                         (o.callback && o.callback.apply(elem[0], arguments));
15120                                         elem.dequeue();
15121                                 });
15122         });
15123 };
15124
15125 })(jQuery);
15126 /*
15127  * jQuery UI Accordion 1.8.12
15128  *
15129  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
15130  * Dual licensed under the MIT or GPL Version 2 licenses.
15131  * http://jquery.org/license
15132  *
15133  * http://docs.jquery.com/UI/Accordion
15134  *
15135  * Depends:
15136  *      jquery.ui.core.js
15137  *      jquery.ui.widget.js
15138  */
15139 (function( $, undefined ) {
15140
15141 $.widget( "ui.accordion", {
15142         options: {
15143                 active: 0,
15144                 animated: "slide",
15145                 autoHeight: true,
15146                 clearStyle: false,
15147                 collapsible: false,
15148                 event: "click",
15149                 fillSpace: false,
15150                 header: "> li > :first-child,> :not(li):even",
15151                 icons: {
15152                         header: "ui-icon-triangle-1-e",
15153                         headerSelected: "ui-icon-triangle-1-s"
15154                 },
15155                 navigation: false,
15156                 navigationFilter: function() {
15157                         return this.href.toLowerCase() === location.href.toLowerCase();
15158                 }
15159         },
15160
15161         _create: function() {
15162                 var self = this,
15163                         options = self.options;
15164
15165                 self.running = 0;
15166
15167                 self.element
15168                         .addClass( "ui-accordion ui-widget ui-helper-reset" )
15169                         // in lack of child-selectors in CSS
15170                         // we need to mark top-LIs in a UL-accordion for some IE-fix
15171                         .children( "li" )
15172                                 .addClass( "ui-accordion-li-fix" );
15173
15174                 self.headers = self.element.find( options.header )
15175                         .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
15176                         .bind( "mouseenter.accordion", function() {
15177                                 if ( options.disabled ) {
15178                                         return;
15179                                 }
15180                                 $( this ).addClass( "ui-state-hover" );
15181                         })
15182                         .bind( "mouseleave.accordion", function() {
15183                                 if ( options.disabled ) {
15184                                         return;
15185                                 }
15186                                 $( this ).removeClass( "ui-state-hover" );
15187                         })
15188                         .bind( "focus.accordion", function() {
15189                                 if ( options.disabled ) {
15190                                         return;
15191                                 }
15192                                 $( this ).addClass( "ui-state-focus" );
15193                         })
15194                         .bind( "blur.accordion", function() {
15195                                 if ( options.disabled ) {
15196                                         return;
15197                                 }
15198                                 $( this ).removeClass( "ui-state-focus" );
15199                         });
15200
15201                 self.headers.next()
15202                         .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
15203
15204                 if ( options.navigation ) {
15205                         var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
15206                         if ( current.length ) {
15207                                 var header = current.closest( ".ui-accordion-header" );
15208                                 if ( header.length ) {
15209                                         // anchor within header
15210                                         self.active = header;
15211                                 } else {
15212                                         // anchor within content
15213                                         self.active = current.closest( ".ui-accordion-content" ).prev();
15214                                 }
15215                         }
15216                 }
15217
15218                 self.active = self._findActive( self.active || options.active )
15219                         .addClass( "ui-state-default ui-state-active" )
15220                         .toggleClass( "ui-corner-all" )
15221                         .toggleClass( "ui-corner-top" );
15222                 self.active.next().addClass( "ui-accordion-content-active" );
15223
15224                 self._createIcons();
15225                 self.resize();
15226                 
15227                 // ARIA
15228                 self.element.attr( "role", "tablist" );
15229
15230                 self.headers
15231                         .attr( "role", "tab" )
15232                         .bind( "keydown.accordion", function( event ) {
15233                                 return self._keydown( event );
15234                         })
15235                         .next()
15236                                 .attr( "role", "tabpanel" );
15237
15238                 self.headers
15239                         .not( self.active || "" )
15240                         .attr({
15241                                 "aria-expanded": "false",
15242                                 "aria-selected": "false",
15243                                 tabIndex: -1
15244                         })
15245                         .next()
15246                                 .hide();
15247
15248                 // make sure at least one header is in the tab order
15249                 if ( !self.active.length ) {
15250                         self.headers.eq( 0 ).attr( "tabIndex", 0 );
15251                 } else {
15252                         self.active
15253                                 .attr({
15254                                         "aria-expanded": "true",
15255                                         "aria-selected": "true",
15256                                         tabIndex: 0
15257                                 });
15258                 }
15259
15260                 // only need links in tab order for Safari
15261                 if ( !$.browser.safari ) {
15262                         self.headers.find( "a" ).attr( "tabIndex", -1 );
15263                 }
15264
15265                 if ( options.event ) {
15266                         self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
15267                                 self._clickHandler.call( self, event, this );
15268                                 event.preventDefault();
15269                         });
15270                 }
15271         },
15272
15273         _createIcons: function() {
15274                 var options = this.options;
15275                 if ( options.icons ) {
15276                         $( "<span></span>" )
15277                                 .addClass( "ui-icon " + options.icons.header )
15278                                 .prependTo( this.headers );
15279                         this.active.children( ".ui-icon" )
15280                                 .toggleClass(options.icons.header)
15281                                 .toggleClass(options.icons.headerSelected);
15282                         this.element.addClass( "ui-accordion-icons" );
15283                 }
15284         },
15285
15286         _destroyIcons: function() {
15287                 this.headers.children( ".ui-icon" ).remove();
15288                 this.element.removeClass( "ui-accordion-icons" );
15289         },
15290
15291         destroy: function() {
15292                 var options = this.options;
15293
15294                 this.element
15295                         .removeClass( "ui-accordion ui-widget ui-helper-reset" )
15296                         .removeAttr( "role" );
15297
15298                 this.headers
15299                         .unbind( ".accordion" )
15300                         .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
15301                         .removeAttr( "role" )
15302                         .removeAttr( "aria-expanded" )
15303                         .removeAttr( "aria-selected" )
15304                         .removeAttr( "tabIndex" );
15305
15306                 this.headers.find( "a" ).removeAttr( "tabIndex" );
15307                 this._destroyIcons();
15308                 var contents = this.headers.next()
15309                         .css( "display", "" )
15310                         .removeAttr( "role" )
15311                         .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
15312                 if ( options.autoHeight || options.fillHeight ) {
15313                         contents.css( "height", "" );
15314                 }
15315
15316                 return $.Widget.prototype.destroy.call( this );
15317         },
15318
15319         _setOption: function( key, value ) {
15320                 $.Widget.prototype._setOption.apply( this, arguments );
15321                         
15322                 if ( key == "active" ) {
15323                         this.activate( value );
15324                 }
15325                 if ( key == "icons" ) {
15326                         this._destroyIcons();
15327                         if ( value ) {
15328                                 this._createIcons();
15329                         }
15330                 }
15331                 // #5332 - opacity doesn't cascade to positioned elements in IE
15332                 // so we need to add the disabled class to the headers and panels
15333                 if ( key == "disabled" ) {
15334                         this.headers.add(this.headers.next())
15335                                 [ value ? "addClass" : "removeClass" ](
15336                                         "ui-accordion-disabled ui-state-disabled" );
15337                 }
15338         },
15339
15340         _keydown: function( event ) {
15341                 if ( this.options.disabled || event.altKey || event.ctrlKey ) {
15342                         return;
15343                 }
15344
15345                 var keyCode = $.ui.keyCode,
15346                         length = this.headers.length,
15347                         currentIndex = this.headers.index( event.target ),
15348                         toFocus = false;
15349
15350                 switch ( event.keyCode ) {
15351                         case keyCode.RIGHT:
15352                         case keyCode.DOWN:
15353                                 toFocus = this.headers[ ( currentIndex + 1 ) % length ];
15354                                 break;
15355                         case keyCode.LEFT:
15356                         case keyCode.UP:
15357                                 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
15358                                 break;
15359                         case keyCode.SPACE:
15360                         case keyCode.ENTER:
15361                                 this._clickHandler( { target: event.target }, event.target );
15362                                 event.preventDefault();
15363                 }
15364
15365                 if ( toFocus ) {
15366                         $( event.target ).attr( "tabIndex", -1 );
15367                         $( toFocus ).attr( "tabIndex", 0 );
15368                         toFocus.focus();
15369                         return false;
15370                 }
15371
15372                 return true;
15373         },
15374
15375         resize: function() {
15376                 var options = this.options,
15377                         maxHeight;
15378
15379                 if ( options.fillSpace ) {
15380                         if ( $.browser.msie ) {
15381                                 var defOverflow = this.element.parent().css( "overflow" );
15382                                 this.element.parent().css( "overflow", "hidden");
15383                         }
15384                         maxHeight = this.element.parent().height();
15385                         if ($.browser.msie) {
15386                                 this.element.parent().css( "overflow", defOverflow );
15387                         }
15388
15389                         this.headers.each(function() {
15390                                 maxHeight -= $( this ).outerHeight( true );
15391                         });
15392
15393                         this.headers.next()
15394                                 .each(function() {
15395                                         $( this ).height( Math.max( 0, maxHeight -
15396                                                 $( this ).innerHeight() + $( this ).height() ) );
15397                                 })
15398                                 .css( "overflow", "auto" );
15399                 } else if ( options.autoHeight ) {
15400                         maxHeight = 0;
15401                         this.headers.next()
15402                                 .each(function() {
15403                                         maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
15404                                 })
15405                                 .height( maxHeight );
15406                 }
15407
15408                 return this;
15409         },
15410
15411         activate: function( index ) {
15412                 // TODO this gets called on init, changing the option without an explicit call for that
15413                 this.options.active = index;
15414                 // call clickHandler with custom event
15415                 var active = this._findActive( index )[ 0 ];
15416                 this._clickHandler( { target: active }, active );
15417
15418                 return this;
15419         },
15420
15421         _findActive: function( selector ) {
15422                 return selector
15423                         ? typeof selector === "number"
15424                                 ? this.headers.filter( ":eq(" + selector + ")" )
15425                                 : this.headers.not( this.headers.not( selector ) )
15426                         : selector === false
15427                                 ? $( [] )
15428                                 : this.headers.filter( ":eq(0)" );
15429         },
15430
15431         // TODO isn't event.target enough? why the separate target argument?
15432         _clickHandler: function( event, target ) {
15433                 var options = this.options;
15434                 if ( options.disabled ) {
15435                         return;
15436                 }
15437
15438                 // called only when using activate(false) to close all parts programmatically
15439                 if ( !event.target ) {
15440                         if ( !options.collapsible ) {
15441                                 return;
15442                         }
15443                         this.active
15444                                 .removeClass( "ui-state-active ui-corner-top" )
15445                                 .addClass( "ui-state-default ui-corner-all" )
15446                                 .children( ".ui-icon" )
15447                                         .removeClass( options.icons.headerSelected )
15448                                         .addClass( options.icons.header );
15449                         this.active.next().addClass( "ui-accordion-content-active" );
15450                         var toHide = this.active.next(),
15451                                 data = {
15452                                         options: options,
15453                                         newHeader: $( [] ),
15454                                         oldHeader: options.active,
15455                                         newContent: $( [] ),
15456                                         oldContent: toHide
15457                                 },
15458                                 toShow = ( this.active = $( [] ) );
15459                         this._toggle( toShow, toHide, data );
15460                         return;
15461                 }
15462
15463                 // get the click target
15464                 var clicked = $( event.currentTarget || target ),
15465                         clickedIsActive = clicked[0] === this.active[0];
15466
15467                 // TODO the option is changed, is that correct?
15468                 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
15469                 options.active = options.collapsible && clickedIsActive ?
15470                         false :
15471                         this.headers.index( clicked );
15472
15473                 // if animations are still active, or the active header is the target, ignore click
15474                 if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
15475                         return;
15476                 }
15477
15478                 // find elements to show and hide
15479                 var active = this.active,
15480                         toShow = clicked.next(),
15481                         toHide = this.active.next(),
15482                         data = {
15483                                 options: options,
15484                                 newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
15485                                 oldHeader: this.active,
15486                                 newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
15487                                 oldContent: toHide
15488                         },
15489                         down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
15490
15491                 // when the call to ._toggle() comes after the class changes
15492                 // it causes a very odd bug in IE 8 (see #6720)
15493                 this.active = clickedIsActive ? $([]) : clicked;
15494                 this._toggle( toShow, toHide, data, clickedIsActive, down );
15495
15496                 // switch classes
15497                 active
15498                         .removeClass( "ui-state-active ui-corner-top" )
15499                         .addClass( "ui-state-default ui-corner-all" )
15500                         .children( ".ui-icon" )
15501                                 .removeClass( options.icons.headerSelected )
15502                                 .addClass( options.icons.header );
15503                 if ( !clickedIsActive ) {
15504                         clicked
15505                                 .removeClass( "ui-state-default ui-corner-all" )
15506                                 .addClass( "ui-state-active ui-corner-top" )
15507                                 .children( ".ui-icon" )
15508                                         .removeClass( options.icons.header )
15509                                         .addClass( options.icons.headerSelected );
15510                         clicked
15511                                 .next()
15512                                 .addClass( "ui-accordion-content-active" );
15513                 }
15514
15515                 return;
15516         },
15517
15518         _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
15519                 var self = this,
15520                         options = self.options;
15521
15522                 self.toShow = toShow;
15523                 self.toHide = toHide;
15524                 self.data = data;
15525
15526                 var complete = function() {
15527                         if ( !self ) {
15528                                 return;
15529                         }
15530                         return self._completed.apply( self, arguments );
15531                 };
15532
15533                 // trigger changestart event
15534                 self._trigger( "changestart", null, self.data );
15535
15536                 // count elements to animate
15537                 self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
15538
15539                 if ( options.animated ) {
15540                         var animOptions = {};
15541
15542                         if ( options.collapsible && clickedIsActive ) {
15543                                 animOptions = {
15544                                         toShow: $( [] ),
15545                                         toHide: toHide,
15546                                         complete: complete,
15547                                         down: down,
15548                                         autoHeight: options.autoHeight || options.fillSpace
15549                                 };
15550                         } else {
15551                                 animOptions = {
15552                                         toShow: toShow,
15553                                         toHide: toHide,
15554                                         complete: complete,
15555                                         down: down,
15556                                         autoHeight: options.autoHeight || options.fillSpace
15557                                 };
15558                         }
15559
15560                         if ( !options.proxied ) {
15561                                 options.proxied = options.animated;
15562                         }
15563
15564                         if ( !options.proxiedDuration ) {
15565                                 options.proxiedDuration = options.duration;
15566                         }
15567
15568                         options.animated = $.isFunction( options.proxied ) ?
15569                                 options.proxied( animOptions ) :
15570                                 options.proxied;
15571
15572                         options.duration = $.isFunction( options.proxiedDuration ) ?
15573                                 options.proxiedDuration( animOptions ) :
15574                                 options.proxiedDuration;
15575
15576                         var animations = $.ui.accordion.animations,
15577                                 duration = options.duration,
15578                                 easing = options.animated;
15579
15580                         if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
15581                                 easing = "slide";
15582                         }
15583                         if ( !animations[ easing ] ) {
15584                                 animations[ easing ] = function( options ) {
15585                                         this.slide( options, {
15586                                                 easing: easing,
15587                                                 duration: duration || 700
15588                                         });
15589                                 };
15590                         }
15591
15592                         animations[ easing ]( animOptions );
15593                 } else {
15594                         if ( options.collapsible && clickedIsActive ) {
15595                                 toShow.toggle();
15596                         } else {
15597                                 toHide.hide();
15598                                 toShow.show();
15599                         }
15600
15601                         complete( true );
15602                 }
15603
15604                 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
15605                 toHide.prev()
15606                         .attr({
15607                                 "aria-expanded": "false",
15608                                 "aria-selected": "false",
15609                                 tabIndex: -1
15610                         })
15611                         .blur();
15612                 toShow.prev()
15613                         .attr({
15614                                 "aria-expanded": "true",
15615                                 "aria-selected": "true",
15616                                 tabIndex: 0
15617                         })
15618                         .focus();
15619         },
15620
15621         _completed: function( cancel ) {
15622                 this.running = cancel ? 0 : --this.running;
15623                 if ( this.running ) {
15624                         return;
15625                 }
15626
15627                 if ( this.options.clearStyle ) {
15628                         this.toShow.add( this.toHide ).css({
15629                                 height: "",
15630                                 overflow: ""
15631                         });
15632                 }
15633
15634                 // other classes are removed before the animation; this one needs to stay until completed
15635                 this.toHide.removeClass( "ui-accordion-content-active" );
15636                 // Work around for rendering bug in IE (#5421)
15637                 if ( this.toHide.length ) {
15638                         this.toHide.parent()[0].className = this.toHide.parent()[0].className;
15639                 }
15640
15641                 this._trigger( "change", null, this.data );
15642         }
15643 });
15644
15645 $.extend( $.ui.accordion, {
15646         version: "1.8.12",
15647         animations: {
15648                 slide: function( options, additions ) {
15649                         options = $.extend({
15650                                 easing: "swing",
15651                                 duration: 300
15652                         }, options, additions );
15653                         if ( !options.toHide.size() ) {
15654                                 options.toShow.animate({
15655                                         height: "show",
15656                                         paddingTop: "show",
15657                                         paddingBottom: "show"
15658                                 }, options );
15659                                 return;
15660                         }
15661                         if ( !options.toShow.size() ) {
15662                                 options.toHide.animate({
15663                                         height: "hide",
15664                                         paddingTop: "hide",
15665                                         paddingBottom: "hide"
15666                                 }, options );
15667                                 return;
15668                         }
15669                         var overflow = options.toShow.css( "overflow" ),
15670                                 percentDone = 0,
15671                                 showProps = {},
15672                                 hideProps = {},
15673                                 fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
15674                                 originalWidth;
15675                         // fix width before calculating height of hidden element
15676                         var s = options.toShow;
15677                         originalWidth = s[0].style.width;
15678                         s.width( parseInt( s.parent().width(), 10 )
15679                                 - parseInt( s.css( "paddingLeft" ), 10 )
15680                                 - parseInt( s.css( "paddingRight" ), 10 )
15681                                 - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
15682                                 - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
15683
15684                         $.each( fxAttrs, function( i, prop ) {
15685                                 hideProps[ prop ] = "hide";
15686
15687                                 var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
15688                                 showProps[ prop ] = {
15689                                         value: parts[ 1 ],
15690                                         unit: parts[ 2 ] || "px"
15691                                 };
15692                         });
15693                         options.toShow.css({ height: 0, overflow: "hidden" }).show();
15694                         options.toHide
15695                                 .filter( ":hidden" )
15696                                         .each( options.complete )
15697                                 .end()
15698                                 .filter( ":visible" )
15699                                 .animate( hideProps, {
15700                                 step: function( now, settings ) {
15701                                         // only calculate the percent when animating height
15702                                         // IE gets very inconsistent results when animating elements
15703                                         // with small values, which is common for padding
15704                                         if ( settings.prop == "height" ) {
15705                                                 percentDone = ( settings.end - settings.start === 0 ) ? 0 :
15706                                                         ( settings.now - settings.start ) / ( settings.end - settings.start );
15707                                         }
15708
15709                                         options.toShow[ 0 ].style[ settings.prop ] =
15710                                                 ( percentDone * showProps[ settings.prop ].value )
15711                                                 + showProps[ settings.prop ].unit;
15712                                 },
15713                                 duration: options.duration,
15714                                 easing: options.easing,
15715                                 complete: function() {
15716                                         if ( !options.autoHeight ) {
15717                                                 options.toShow.css( "height", "" );
15718                                         }
15719                                         options.toShow.css({
15720                                                 width: originalWidth,
15721                                                 overflow: overflow
15722                                         });
15723                                         options.complete();
15724                                 }
15725                         });
15726                 },
15727                 bounceslide: function( options ) {
15728                         this.slide( options, {
15729                                 easing: options.down ? "easeOutBounce" : "swing",
15730                                 duration: options.down ? 1000 : 200
15731                         });
15732                 }
15733         }
15734 });
15735
15736 })( jQuery );
15737 /*
15738  * jQuery UI Autocomplete 1.8.12
15739  *
15740  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
15741  * Dual licensed under the MIT or GPL Version 2 licenses.
15742  * http://jquery.org/license
15743  *
15744  * http://docs.jquery.com/UI/Autocomplete
15745  *
15746  * Depends:
15747  *      jquery.ui.core.js
15748  *      jquery.ui.widget.js
15749  *      jquery.ui.position.js
15750  */
15751 (function( $, undefined ) {
15752
15753 // used to prevent race conditions with remote data sources
15754 var requestIndex = 0;
15755
15756 $.widget( "ui.autocomplete", {
15757         options: {
15758                 appendTo: "body",
15759                 autoFocus: false,
15760                 delay: 300,
15761                 minLength: 1,
15762                 position: {
15763                         my: "left top",
15764                         at: "left bottom",
15765                         collision: "none"
15766                 },
15767                 source: null
15768         },
15769
15770         pending: 0,
15771
15772         _create: function() {
15773                 var self = this,
15774                         doc = this.element[ 0 ].ownerDocument,
15775                         suppressKeyPress;
15776
15777                 this.element
15778                         .addClass( "ui-autocomplete-input" )
15779                         .attr( "autocomplete", "off" )
15780                         // TODO verify these actually work as intended
15781                         .attr({
15782                                 role: "textbox",
15783                                 "aria-autocomplete": "list",
15784                                 "aria-haspopup": "true"
15785                         })
15786                         .bind( "keydown.autocomplete", function( event ) {
15787                                 if ( self.options.disabled || self.element.attr( "readonly" ) ) {
15788                                         return;
15789                                 }
15790
15791                                 suppressKeyPress = false;
15792                                 var keyCode = $.ui.keyCode;
15793                                 switch( event.keyCode ) {
15794                                 case keyCode.PAGE_UP:
15795                                         self._move( "previousPage", event );
15796                                         break;
15797                                 case keyCode.PAGE_DOWN:
15798                                         self._move( "nextPage", event );
15799                                         break;
15800                                 case keyCode.UP:
15801                                         self._move( "previous", event );
15802                                         // prevent moving cursor to beginning of text field in some browsers
15803                                         event.preventDefault();
15804                                         break;
15805                                 case keyCode.DOWN:
15806                                         self._move( "next", event );
15807                                         // prevent moving cursor to end of text field in some browsers
15808                                         event.preventDefault();
15809                                         break;
15810                                 case keyCode.ENTER:
15811                                 case keyCode.NUMPAD_ENTER:
15812                                         // when menu is open and has focus
15813                                         if ( self.menu.active ) {
15814                                                 // #6055 - Opera still allows the keypress to occur
15815                                                 // which causes forms to submit
15816                                                 suppressKeyPress = true;
15817                                                 event.preventDefault();
15818                                         }
15819                                         //passthrough - ENTER and TAB both select the current element
15820                                 case keyCode.TAB:
15821                                         if ( !self.menu.active ) {
15822                                                 return;
15823                                         }
15824                                         self.menu.select( event );
15825                                         break;
15826                                 case keyCode.ESCAPE:
15827                                         self.element.val( self.term );
15828                                         self.close( event );
15829                                         break;
15830                                 default:
15831                                         // keypress is triggered before the input value is changed
15832                                         clearTimeout( self.searching );
15833                                         self.searching = setTimeout(function() {
15834                                                 // only search if the value has changed
15835                                                 if ( self.term != self.element.val() ) {
15836                                                         self.selectedItem = null;
15837                                                         self.search( null, event );
15838                                                 }
15839                                         }, self.options.delay );
15840                                         break;
15841                                 }
15842                         })
15843                         .bind( "keypress.autocomplete", function( event ) {
15844                                 if ( suppressKeyPress ) {
15845                                         suppressKeyPress = false;
15846                                         event.preventDefault();
15847                                 }
15848                         })
15849                         .bind( "focus.autocomplete", function() {
15850                                 if ( self.options.disabled ) {
15851                                         return;
15852                                 }
15853
15854                                 self.selectedItem = null;
15855                                 self.previous = self.element.val();
15856                         })
15857                         .bind( "blur.autocomplete", function( event ) {
15858                                 if ( self.options.disabled ) {
15859                                         return;
15860                                 }
15861
15862                                 clearTimeout( self.searching );
15863                                 // clicks on the menu (or a button to trigger a search) will cause a blur event
15864                                 self.closing = setTimeout(function() {
15865                                         self.close( event );
15866                                         self._change( event );
15867                                 }, 150 );
15868                         });
15869                 this._initSource();
15870                 this.response = function() {
15871                         return self._response.apply( self, arguments );
15872                 };
15873                 this.menu = $( "<ul></ul>" )
15874                         .addClass( "ui-autocomplete" )
15875                         .appendTo( $( this.options.appendTo || "body", doc )[0] )
15876                         // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
15877                         .mousedown(function( event ) {
15878                                 // clicking on the scrollbar causes focus to shift to the body
15879                                 // but we can't detect a mouseup or a click immediately afterward
15880                                 // so we have to track the next mousedown and close the menu if
15881                                 // the user clicks somewhere outside of the autocomplete
15882                                 var menuElement = self.menu.element[ 0 ];
15883                                 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
15884                                         setTimeout(function() {
15885                                                 $( document ).one( 'mousedown', function( event ) {
15886                                                         if ( event.target !== self.element[ 0 ] &&
15887                                                                 event.target !== menuElement &&
15888                                                                 !$.ui.contains( menuElement, event.target ) ) {
15889                                                                 self.close();
15890                                                         }
15891                                                 });
15892                                         }, 1 );
15893                                 }
15894
15895                                 // use another timeout to make sure the blur-event-handler on the input was already triggered
15896                                 setTimeout(function() {
15897                                         clearTimeout( self.closing );
15898                                 }, 13);
15899                         })
15900                         .menu({
15901                                 focus: function( event, ui ) {
15902                                         var item = ui.item.data( "item.autocomplete" );
15903                                         if ( false !== self._trigger( "focus", event, { item: item } ) ) {
15904                                                 // use value to match what will end up in the input, if it was a key event
15905                                                 if ( /^key/.test(event.originalEvent.type) ) {
15906                                                         self.element.val( item.value );
15907                                                 }
15908                                         }
15909                                 },
15910                                 selected: function( event, ui ) {
15911                                         var item = ui.item.data( "item.autocomplete" ),
15912                                                 previous = self.previous;
15913
15914                                         // only trigger when focus was lost (click on menu)
15915                                         if ( self.element[0] !== doc.activeElement ) {
15916                                                 self.element.focus();
15917                                                 self.previous = previous;
15918                                                 // #6109 - IE triggers two focus events and the second
15919                                                 // is asynchronous, so we need to reset the previous
15920                                                 // term synchronously and asynchronously :-(
15921                                                 setTimeout(function() {
15922                                                         self.previous = previous;
15923                                                         self.selectedItem = item;
15924                                                 }, 1);
15925                                         }
15926
15927                                         if ( false !== self._trigger( "select", event, { item: item } ) ) {
15928                                                 self.element.val( item.value );
15929                                         }
15930                                         // reset the term after the select event
15931                                         // this allows custom select handling to work properly
15932                                         self.term = self.element.val();
15933
15934                                         self.close( event );
15935                                         self.selectedItem = item;
15936                                 },
15937                                 blur: function( event, ui ) {
15938                                         // don't set the value of the text field if it's already correct
15939                                         // this prevents moving the cursor unnecessarily
15940                                         if ( self.menu.element.is(":visible") &&
15941                                                 ( self.element.val() !== self.term ) ) {
15942                                                 self.element.val( self.term );
15943                                         }
15944                                 }
15945                         })
15946                         .zIndex( this.element.zIndex() + 1 )
15947                         // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
15948                         .css({ top: 0, left: 0 })
15949                         .hide()
15950                         .data( "menu" );
15951                 if ( $.fn.bgiframe ) {
15952                          this.menu.element.bgiframe();
15953                 }
15954         },
15955
15956         destroy: function() {
15957                 this.element
15958                         .removeClass( "ui-autocomplete-input" )
15959                         .removeAttr( "autocomplete" )
15960                         .removeAttr( "role" )
15961                         .removeAttr( "aria-autocomplete" )
15962                         .removeAttr( "aria-haspopup" );
15963                 this.menu.element.remove();
15964                 $.Widget.prototype.destroy.call( this );
15965         },
15966
15967         _setOption: function( key, value ) {
15968                 $.Widget.prototype._setOption.apply( this, arguments );
15969                 if ( key === "source" ) {
15970                         this._initSource();
15971                 }
15972                 if ( key === "appendTo" ) {
15973                         this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
15974                 }
15975                 if ( key === "disabled" && value && this.xhr ) {
15976                         this.xhr.abort();
15977                 }
15978         },
15979
15980         _initSource: function() {
15981                 var self = this,
15982                         array,
15983                         url;
15984                 if ( $.isArray(this.options.source) ) {
15985                         array = this.options.source;
15986                         this.source = function( request, response ) {
15987                                 response( $.ui.autocomplete.filter(array, request.term) );
15988                         };
15989                 } else if ( typeof this.options.source === "string" ) {
15990                         url = this.options.source;
15991                         this.source = function( request, response ) {
15992                                 if ( self.xhr ) {
15993                                         self.xhr.abort();
15994                                 }
15995                                 self.xhr = $.ajax({
15996                                         url: url,
15997                                         data: request,
15998                                         dataType: "json",
15999                                         autocompleteRequest: ++requestIndex,
16000                                         success: function( data, status ) {
16001                                                 if ( this.autocompleteRequest === requestIndex ) {
16002                                                         response( data );
16003                                                 }
16004                                         },
16005                                         error: function() {
16006                                                 if ( this.autocompleteRequest === requestIndex ) {
16007                                                         response( [] );
16008                                                 }
16009                                         }
16010                                 });
16011                         };
16012                 } else {
16013                         this.source = this.options.source;
16014                 }
16015         },
16016
16017         search: function( value, event ) {
16018                 value = value != null ? value : this.element.val();
16019
16020                 // always save the actual value, not the one passed as an argument
16021                 this.term = this.element.val();
16022
16023                 if ( value.length < this.options.minLength ) {
16024                         return this.close( event );
16025                 }
16026
16027                 clearTimeout( this.closing );
16028                 if ( this._trigger( "search", event ) === false ) {
16029                         return;
16030                 }
16031
16032                 return this._search( value );
16033         },
16034
16035         _search: function( value ) {
16036                 this.pending++;
16037                 this.element.addClass( "ui-autocomplete-loading" );
16038
16039                 this.source( { term: value }, this.response );
16040         },
16041
16042         _response: function( content ) {
16043                 if ( !this.options.disabled && content && content.length ) {
16044                         content = this._normalize( content );
16045                         this._suggest( content );
16046                         this._trigger( "open" );
16047                 } else {
16048                         this.close();
16049                 }
16050                 this.pending--;
16051                 if ( !this.pending ) {
16052                         this.element.removeClass( "ui-autocomplete-loading" );
16053                 }
16054         },
16055
16056         close: function( event ) {
16057                 clearTimeout( this.closing );
16058                 if ( this.menu.element.is(":visible") ) {
16059                         this.menu.element.hide();
16060                         this.menu.deactivate();
16061                         this._trigger( "close", event );
16062                 }
16063         },
16064         
16065         _change: function( event ) {
16066                 if ( this.previous !== this.element.val() ) {
16067                         this._trigger( "change", event, { item: this.selectedItem } );
16068                 }
16069         },
16070
16071         _normalize: function( items ) {
16072                 // assume all items have the right format when the first item is complete
16073                 if ( items.length && items[0].label && items[0].value ) {
16074                         return items;
16075                 }
16076                 return $.map( items, function(item) {
16077                         if ( typeof item === "string" ) {
16078                                 return {
16079                                         label: item,
16080                                         value: item
16081                                 };
16082                         }
16083                         return $.extend({
16084                                 label: item.label || item.value,
16085                                 value: item.value || item.label
16086                         }, item );
16087                 });
16088         },
16089
16090         _suggest: function( items ) {
16091                 var ul = this.menu.element
16092                         .empty()
16093                         .zIndex( this.element.zIndex() + 1 );
16094                 this._renderMenu( ul, items );
16095                 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
16096                 this.menu.deactivate();
16097                 this.menu.refresh();
16098
16099                 // size and position menu
16100                 ul.show();
16101                 this._resizeMenu();
16102                 ul.position( $.extend({
16103                         of: this.element
16104                 }, this.options.position ));
16105
16106                 if ( this.options.autoFocus ) {
16107                         this.menu.next( new $.Event("mouseover") );
16108                 }
16109         },
16110
16111         _resizeMenu: function() {
16112                 var ul = this.menu.element;
16113                 ul.outerWidth( Math.max(
16114                         ul.width( "" ).outerWidth(),
16115                         this.element.outerWidth()
16116                 ) );
16117         },
16118
16119         _renderMenu: function( ul, items ) {
16120                 var self = this;
16121                 $.each( items, function( index, item ) {
16122                         self._renderItem( ul, item );
16123                 });
16124         },
16125
16126         _renderItem: function( ul, item) {
16127                 return $( "<li></li>" )
16128                         .data( "item.autocomplete", item )
16129                         .append( $( "<a></a>" ).text( item.label ) )
16130                         .appendTo( ul );
16131         },
16132
16133         _move: function( direction, event ) {
16134                 if ( !this.menu.element.is(":visible") ) {
16135                         this.search( null, event );
16136                         return;
16137                 }
16138                 if ( this.menu.first() && /^previous/.test(direction) ||
16139                                 this.menu.last() && /^next/.test(direction) ) {
16140                         this.element.val( this.term );
16141                         this.menu.deactivate();
16142                         return;
16143                 }
16144                 this.menu[ direction ]( event );
16145         },
16146
16147         widget: function() {
16148                 return this.menu.element;
16149         }
16150 });
16151
16152 $.extend( $.ui.autocomplete, {
16153         escapeRegex: function( value ) {
16154                 return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
16155         },
16156         filter: function(array, term) {
16157                 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
16158                 return $.grep( array, function(value) {
16159                         return matcher.test( value.label || value.value || value );
16160                 });
16161         }
16162 });
16163
16164 }( jQuery ));
16165
16166 /*
16167  * jQuery UI Menu (not officially released)
16168  * 
16169  * This widget isn't yet finished and the API is subject to change. We plan to finish
16170  * it for the next release. You're welcome to give it a try anyway and give us feedback,
16171  * as long as you're okay with migrating your code later on. We can help with that, too.
16172  *
16173  * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
16174  * Dual licensed under the MIT or GPL Version 2 licenses.
16175  * http://jquery.org/license
16176  *
16177  * http://docs.jquery.com/UI/Menu
16178  *
16179  * Depends:
16180  *      jquery.ui.core.js
16181  *  jquery.ui.widget.js
16182  */
16183 (function($) {
16184
16185 $.widget("ui.menu", {
16186         _create: function() {
16187                 var self = this;
16188                 this.element
16189                         .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
16190                         .attr({
16191                                 role: "listbox",
16192                                 "aria-activedescendant": "ui-active-menuitem"
16193                         })
16194                         .click(function( event ) {
16195                                 if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
16196                                         return;
16197                                 }
16198                                 // temporary
16199                                 event.preventDefault();
16200                                 self.select( event );
16201                         });
16202                 this.refresh();
16203         },
16204         
16205         refresh: function() {
16206                 var self = this;
16207
16208                 // don't refresh list items that are already adapted
16209                 var items = this.element.children("li:not(.ui-menu-item):has(a)")
16210                         .addClass("ui-menu-item")
16211                         .attr("role", "menuitem");
16212                 
16213                 items.children("a")
16214                         .addClass("ui-corner-all")
16215                         .attr("tabindex", -1)
16216                         // mouseenter doesn't work with event delegation
16217                         .mouseenter(function( event ) {
16218                                 self.activate( event, $(this).parent() );
16219                         })
16220                         .mouseleave(function() {
16221                                 self.deactivate();
16222                         });
16223         },
16224
16225         activate: function( event, item ) {
16226                 this.deactivate();
16227                 if (this.hasScroll()) {
16228                         var offset = item.offset().top - this.element.offset().top,
16229                                 scroll = this.element.attr("scrollTop"),
16230                                 elementHeight = this.element.height();
16231                         if (offset < 0) {
16232                                 this.element.attr("scrollTop", scroll + offset);
16233                         } else if (offset >= elementHeight) {
16234                                 this.element.attr("scrollTop", scroll + offset - elementHeight + item.height());
16235                         }
16236                 }
16237                 this.active = item.eq(0)
16238                         .children("a")
16239                                 .addClass("ui-state-hover")
16240                                 .attr("id", "ui-active-menuitem")
16241                         .end();
16242                 this._trigger("focus", event, { item: item });
16243         },
16244
16245         deactivate: function() {
16246                 if (!this.active) { return; }
16247
16248                 this.active.children("a")
16249                         .removeClass("ui-state-hover")
16250                         .removeAttr("id");
16251                 this._trigger("blur");
16252                 this.active = null;
16253         },
16254
16255         next: function(event) {
16256                 this.move("next", ".ui-menu-item:first", event);
16257         },
16258
16259         previous: function(event) {
16260                 this.move("prev", ".ui-menu-item:last", event);
16261         },
16262
16263         first: function() {
16264                 return this.active && !this.active.prevAll(".ui-menu-item").length;
16265         },
16266
16267         last: function() {
16268                 return this.active && !this.active.nextAll(".ui-menu-item").length;
16269         },
16270
16271         move: function(direction, edge, event) {
16272                 if (!this.active) {
16273                         this.activate(event, this.element.children(edge));
16274                         return;
16275                 }
16276                 var next = this.active[direction + "All"](".ui-menu-item").eq(0);
16277                 if (next.length) {
16278                         this.activate(event, next);
16279                 } else {
16280                         this.activate(event, this.element.children(edge));
16281                 }
16282         },
16283
16284         // TODO merge with previousPage
16285         nextPage: function(event) {
16286                 if (this.hasScroll()) {
16287                         // TODO merge with no-scroll-else
16288                         if (!this.active || this.last()) {
16289                                 this.activate(event, this.element.children(".ui-menu-item:first"));
16290                                 return;
16291                         }
16292                         var base = this.active.offset().top,
16293                                 height = this.element.height(),
16294                                 result = this.element.children(".ui-menu-item").filter(function() {
16295                                         var close = $(this).offset().top - base - height + $(this).height();
16296                                         // TODO improve approximation
16297                                         return close < 10 && close > -10;
16298                                 });
16299
16300                         // TODO try to catch this earlier when scrollTop indicates the last page anyway
16301                         if (!result.length) {
16302                                 result = this.element.children(".ui-menu-item:last");
16303                         }
16304                         this.activate(event, result);
16305                 } else {
16306                         this.activate(event, this.element.children(".ui-menu-item")
16307                                 .filter(!this.active || this.last() ? ":first" : ":last"));
16308                 }
16309         },
16310
16311         // TODO merge with nextPage
16312         previousPage: function(event) {
16313                 if (this.hasScroll()) {
16314                         // TODO merge with no-scroll-else
16315                         if (!this.active || this.first()) {
16316                                 this.activate(event, this.element.children(".ui-menu-item:last"));
16317                                 return;
16318                         }
16319
16320                         var base = this.active.offset().top,
16321                                 height = this.element.height();
16322                                 result = this.element.children(".ui-menu-item").filter(function() {
16323                                         var close = $(this).offset().top - base + height - $(this).height();
16324                                         // TODO improve approximation
16325                                         return close < 10 && close > -10;
16326                                 });
16327
16328                         // TODO try to catch this earlier when scrollTop indicates the last page anyway
16329                         if (!result.length) {
16330                                 result = this.element.children(".ui-menu-item:first");
16331                         }
16332                         this.activate(event, result);
16333                 } else {
16334                         this.activate(event, this.element.children(".ui-menu-item")
16335                                 .filter(!this.active || this.first() ? ":last" : ":first"));
16336                 }
16337         },
16338
16339         hasScroll: function() {
16340                 return this.element.height() < this.element.attr("scrollHeight");
16341         },
16342
16343         select: function( event ) {
16344                 this._trigger("selected", event, { item: this.active });
16345         }
16346 });
16347
16348 }(jQuery));
16349 /*
16350  * jQuery UI Button 1.8.12
16351  *
16352  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
16353  * Dual licensed under the MIT or GPL Version 2 licenses.
16354  * http://jquery.org/license
16355  *
16356  * http://docs.jquery.com/UI/Button
16357  *
16358  * Depends:
16359  *      jquery.ui.core.js
16360  *      jquery.ui.widget.js
16361  */
16362 (function( $, undefined ) {
16363
16364 var lastActive,
16365         baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
16366         stateClasses = "ui-state-hover ui-state-active ",
16367         typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
16368         formResetHandler = function( event ) {
16369                 $( ":ui-button", event.target.form ).each(function() {
16370                         var inst = $( this ).data( "button" );
16371                         setTimeout(function() {
16372                                 inst.refresh();
16373                         }, 1 );
16374                 });
16375         },
16376         radioGroup = function( radio ) {
16377                 var name = radio.name,
16378                         form = radio.form,
16379                         radios = $( [] );
16380                 if ( name ) {
16381                         if ( form ) {
16382                                 radios = $( form ).find( "[name='" + name + "']" );
16383                         } else {
16384                                 radios = $( "[name='" + name + "']", radio.ownerDocument )
16385                                         .filter(function() {
16386                                                 return !this.form;
16387                                         });
16388                         }
16389                 }
16390                 return radios;
16391         };
16392
16393 $.widget( "ui.button", {
16394         options: {
16395                 disabled: null,
16396                 text: true,
16397                 label: null,
16398                 icons: {
16399                         primary: null,
16400                         secondary: null
16401                 }
16402         },
16403         _create: function() {
16404                 this.element.closest( "form" )
16405                         .unbind( "reset.button" )
16406                         .bind( "reset.button", formResetHandler );
16407
16408                 if ( typeof this.options.disabled !== "boolean" ) {
16409                         this.options.disabled = this.element.attr( "disabled" );
16410                 }
16411
16412                 this._determineButtonType();
16413                 this.hasTitle = !!this.buttonElement.attr( "title" );
16414
16415                 var self = this,
16416                         options = this.options,
16417                         toggleButton = this.type === "checkbox" || this.type === "radio",
16418                         hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
16419                         focusClass = "ui-state-focus";
16420
16421                 if ( options.label === null ) {
16422                         options.label = this.buttonElement.html();
16423                 }
16424
16425                 if ( this.element.is( ":disabled" ) ) {
16426                         options.disabled = true;
16427                 }
16428
16429                 this.buttonElement
16430                         .addClass( baseClasses )
16431                         .attr( "role", "button" )
16432                         .bind( "mouseenter.button", function() {
16433                                 if ( options.disabled ) {
16434                                         return;
16435                                 }
16436                                 $( this ).addClass( "ui-state-hover" );
16437                                 if ( this === lastActive ) {
16438                                         $( this ).addClass( "ui-state-active" );
16439                                 }
16440                         })
16441                         .bind( "mouseleave.button", function() {
16442                                 if ( options.disabled ) {
16443                                         return;
16444                                 }
16445                                 $( this ).removeClass( hoverClass );
16446                         })
16447                         .bind( "focus.button", function() {
16448                                 // no need to check disabled, focus won't be triggered anyway
16449                                 $( this ).addClass( focusClass );
16450                         })
16451                         .bind( "blur.button", function() {
16452                                 $( this ).removeClass( focusClass );
16453                         });
16454
16455                 if ( toggleButton ) {
16456                         this.element.bind( "change.button", function() {
16457                                 self.refresh();
16458                         });
16459                 }
16460
16461                 if ( this.type === "checkbox" ) {
16462                         this.buttonElement.bind( "click.button", function() {
16463                                 if ( options.disabled ) {
16464                                         return false;
16465                                 }
16466                                 $( this ).toggleClass( "ui-state-active" );
16467                                 self.buttonElement.attr( "aria-pressed", self.element[0].checked );
16468                         });
16469                 } else if ( this.type === "radio" ) {
16470                         this.buttonElement.bind( "click.button", function() {
16471                                 if ( options.disabled ) {
16472                                         return false;
16473                                 }
16474                                 $( this ).addClass( "ui-state-active" );
16475                                 self.buttonElement.attr( "aria-pressed", true );
16476
16477                                 var radio = self.element[ 0 ];
16478                                 radioGroup( radio )
16479                                         .not( radio )
16480                                         .map(function() {
16481                                                 return $( this ).button( "widget" )[ 0 ];
16482                                         })
16483                                         .removeClass( "ui-state-active" )
16484                                         .attr( "aria-pressed", false );
16485                         });
16486                 } else {
16487                         this.buttonElement
16488                                 .bind( "mousedown.button", function() {
16489                                         if ( options.disabled ) {
16490                                                 return false;
16491                                         }
16492                                         $( this ).addClass( "ui-state-active" );
16493                                         lastActive = this;
16494                                         $( document ).one( "mouseup", function() {
16495                                                 lastActive = null;
16496                                         });
16497                                 })
16498                                 .bind( "mouseup.button", function() {
16499                                         if ( options.disabled ) {
16500                                                 return false;
16501                                         }
16502                                         $( this ).removeClass( "ui-state-active" );
16503                                 })
16504                                 .bind( "keydown.button", function(event) {
16505                                         if ( options.disabled ) {
16506                                                 return false;
16507                                         }
16508                                         if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
16509                                                 $( this ).addClass( "ui-state-active" );
16510                                         }
16511                                 })
16512                                 .bind( "keyup.button", function() {
16513                                         $( this ).removeClass( "ui-state-active" );
16514                                 });
16515
16516                         if ( this.buttonElement.is("a") ) {
16517                                 this.buttonElement.keyup(function(event) {
16518                                         if ( event.keyCode === $.ui.keyCode.SPACE ) {
16519                                                 // TODO pass through original event correctly (just as 2nd argument doesn't work)
16520                                                 $( this ).click();
16521                                         }
16522                                 });
16523                         }
16524                 }
16525
16526                 // TODO: pull out $.Widget's handling for the disabled option into
16527                 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
16528                 // be overridden by individual plugins
16529                 this._setOption( "disabled", options.disabled );
16530         },
16531
16532         _determineButtonType: function() {
16533
16534                 if ( this.element.is(":checkbox") ) {
16535                         this.type = "checkbox";
16536                 } else if ( this.element.is(":radio") ) {
16537                         this.type = "radio";
16538                 } else if ( this.element.is("input") ) {
16539                         this.type = "input";
16540                 } else {
16541                         this.type = "button";
16542                 }
16543
16544                 if ( this.type === "checkbox" || this.type === "radio" ) {
16545                         // we don't search against the document in case the element
16546                         // is disconnected from the DOM
16547                         var ancestor = this.element.parents().filter(":last"),
16548                                 labelSelector = "label[for=" + this.element.attr("id") + "]";
16549                         this.buttonElement = ancestor.find( labelSelector );
16550                         if ( !this.buttonElement.length ) {
16551                                 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
16552                                 this.buttonElement = ancestor.filter( labelSelector );
16553                                 if ( !this.buttonElement.length ) {
16554                                         this.buttonElement = ancestor.find( labelSelector );
16555                                 }
16556                         }
16557                         this.element.addClass( "ui-helper-hidden-accessible" );
16558
16559                         var checked = this.element.is( ":checked" );
16560                         if ( checked ) {
16561                                 this.buttonElement.addClass( "ui-state-active" );
16562                         }
16563                         this.buttonElement.attr( "aria-pressed", checked );
16564                 } else {
16565                         this.buttonElement = this.element;
16566                 }
16567         },
16568
16569         widget: function() {
16570                 return this.buttonElement;
16571         },
16572
16573         destroy: function() {
16574                 this.element
16575                         .removeClass( "ui-helper-hidden-accessible" );
16576                 this.buttonElement
16577                         .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
16578                         .removeAttr( "role" )
16579                         .removeAttr( "aria-pressed" )
16580                         .html( this.buttonElement.find(".ui-button-text").html() );
16581
16582                 if ( !this.hasTitle ) {
16583                         this.buttonElement.removeAttr( "title" );
16584                 }
16585
16586                 $.Widget.prototype.destroy.call( this );
16587         },
16588
16589         _setOption: function( key, value ) {
16590                 $.Widget.prototype._setOption.apply( this, arguments );
16591                 if ( key === "disabled" ) {
16592                         if ( value ) {
16593                                 this.element.attr( "disabled", true );
16594                         } else {
16595                                 this.element.removeAttr( "disabled" );
16596                         }
16597                 }
16598                 this._resetButton();
16599         },
16600
16601         refresh: function() {
16602                 var isDisabled = this.element.is( ":disabled" );
16603                 if ( isDisabled !== this.options.disabled ) {
16604                         this._setOption( "disabled", isDisabled );
16605                 }
16606                 if ( this.type === "radio" ) {
16607                         radioGroup( this.element[0] ).each(function() {
16608                                 if ( $( this ).is( ":checked" ) ) {
16609                                         $( this ).button( "widget" )
16610                                                 .addClass( "ui-state-active" )
16611                                                 .attr( "aria-pressed", true );
16612                                 } else {
16613                                         $( this ).button( "widget" )
16614                                                 .removeClass( "ui-state-active" )
16615                                                 .attr( "aria-pressed", false );
16616                                 }
16617                         });
16618                 } else if ( this.type === "checkbox" ) {
16619                         if ( this.element.is( ":checked" ) ) {
16620                                 this.buttonElement
16621                                         .addClass( "ui-state-active" )
16622                                         .attr( "aria-pressed", true );
16623                         } else {
16624                                 this.buttonElement
16625                                         .removeClass( "ui-state-active" )
16626                                         .attr( "aria-pressed", false );
16627                         }
16628                 }
16629         },
16630
16631         _resetButton: function() {
16632                 if ( this.type === "input" ) {
16633                         if ( this.options.label ) {
16634                                 this.element.val( this.options.label );
16635                         }
16636                         return;
16637                 }
16638                 var buttonElement = this.buttonElement.removeClass( typeClasses ),
16639                         buttonText = $( "<span></span>" )
16640                                 .addClass( "ui-button-text" )
16641                                 .html( this.options.label )
16642                                 .appendTo( buttonElement.empty() )
16643                                 .text(),
16644                         icons = this.options.icons,
16645                         multipleIcons = icons.primary && icons.secondary,
16646                         buttonClasses = [];  
16647
16648                 if ( icons.primary || icons.secondary ) {
16649                         if ( this.options.text ) {
16650                                 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
16651                         }
16652
16653                         if ( icons.primary ) {
16654                                 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
16655                         }
16656
16657                         if ( icons.secondary ) {
16658                                 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
16659                         }
16660
16661                         if ( !this.options.text ) {
16662                                 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
16663
16664                                 if ( !this.hasTitle ) {
16665                                         buttonElement.attr( "title", buttonText );
16666                                 }
16667                         }
16668                 } else {
16669                         buttonClasses.push( "ui-button-text-only" );
16670                 }
16671                 buttonElement.addClass( buttonClasses.join( " " ) );
16672         }
16673 });
16674
16675 $.widget( "ui.buttonset", {
16676         options: {
16677                 items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
16678         },
16679
16680         _create: function() {
16681                 this.element.addClass( "ui-buttonset" );
16682         },
16683         
16684         _init: function() {
16685                 this.refresh();
16686         },
16687
16688         _setOption: function( key, value ) {
16689                 if ( key === "disabled" ) {
16690                         this.buttons.button( "option", key, value );
16691                 }
16692
16693                 $.Widget.prototype._setOption.apply( this, arguments );
16694         },
16695         
16696         refresh: function() {
16697                 this.buttons = this.element.find( this.options.items )
16698                         .filter( ":ui-button" )
16699                                 .button( "refresh" )
16700                         .end()
16701                         .not( ":ui-button" )
16702                                 .button()
16703                         .end()
16704                         .map(function() {
16705                                 return $( this ).button( "widget" )[ 0 ];
16706                         })
16707                                 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
16708                                 .filter( ":first" )
16709                                         .addClass( "ui-corner-left" )
16710                                 .end()
16711                                 .filter( ":last" )
16712                                         .addClass( "ui-corner-right" )
16713                                 .end()
16714                         .end();
16715         },
16716
16717         destroy: function() {
16718                 this.element.removeClass( "ui-buttonset" );
16719                 this.buttons
16720                         .map(function() {
16721                                 return $( this ).button( "widget" )[ 0 ];
16722                         })
16723                                 .removeClass( "ui-corner-left ui-corner-right" )
16724                         .end()
16725                         .button( "destroy" );
16726
16727                 $.Widget.prototype.destroy.call( this );
16728         }
16729 });
16730
16731 }( jQuery ) );
16732 /*
16733  * jQuery UI Datepicker 1.8.12
16734  *
16735  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
16736  * Dual licensed under the MIT or GPL Version 2 licenses.
16737  * http://jquery.org/license
16738  *
16739  * http://docs.jquery.com/UI/Datepicker
16740  *
16741  * Depends:
16742  *      jquery.ui.core.js
16743  */
16744 (function( $, undefined ) {
16745
16746 $.extend($.ui, { datepicker: { version: "1.8.12" } });
16747
16748 var PROP_NAME = 'datepicker';
16749 var dpuuid = new Date().getTime();
16750
16751 /* Date picker manager.
16752    Use the singleton instance of this class, $.datepicker, to interact with the date picker.
16753    Settings for (groups of) date pickers are maintained in an instance object,
16754    allowing multiple different settings on the same page. */
16755
16756 function Datepicker() {
16757         this.debug = false; // Change this to true to start debugging
16758         this._curInst = null; // The current instance in use
16759         this._keyEvent = false; // If the last event was a key event
16760         this._disabledInputs = []; // List of date picker inputs that have been disabled
16761         this._datepickerShowing = false; // True if the popup picker is showing , false if not
16762         this._inDialog = false; // True if showing within a "dialog", false if not
16763         this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
16764         this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
16765         this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
16766         this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
16767         this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
16768         this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
16769         this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
16770         this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
16771         this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
16772         this.regional = []; // Available regional settings, indexed by language code
16773         this.regional[''] = { // Default regional settings
16774                 closeText: 'Done', // Display text for close link
16775                 prevText: 'Prev', // Display text for previous month link
16776                 nextText: 'Next', // Display text for next month link
16777                 currentText: 'Today', // Display text for current month link
16778                 monthNames: ['January','February','March','April','May','June',
16779                         'July','August','September','October','November','December'], // Names of months for drop-down and formatting
16780                 monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
16781                 dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
16782                 dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
16783                 dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
16784                 weekHeader: 'Wk', // Column header for week of the year
16785                 dateFormat: 'mm/dd/yy', // See format options on parseDate
16786                 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
16787                 isRTL: false, // True if right-to-left language, false if left-to-right
16788                 showMonthAfterYear: false, // True if the year select precedes month, false for month then year
16789                 yearSuffix: '' // Additional text to append to the year in the month headers
16790         };
16791         this._defaults = { // Global defaults for all the date picker instances
16792                 showOn: 'focus', // 'focus' for popup on focus,
16793                         // 'button' for trigger button, or 'both' for either
16794                 showAnim: 'fadeIn', // Name of jQuery animation for popup
16795                 showOptions: {}, // Options for enhanced animations
16796                 defaultDate: null, // Used when field is blank: actual date,
16797                         // +/-number for offset from today, null for today
16798                 appendText: '', // Display text following the input box, e.g. showing the format
16799                 buttonText: '...', // Text for trigger button
16800                 buttonImage: '', // URL for trigger button image
16801                 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
16802                 hideIfNoPrevNext: false, // True to hide next/previous month links
16803                         // if not applicable, false to just disable them
16804                 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
16805                 gotoCurrent: false, // True if today link goes back to current selection instead
16806                 changeMonth: false, // True if month can be selected directly, false if only prev/next
16807                 changeYear: false, // True if year can be selected directly, false if only prev/next
16808                 yearRange: 'c-10:c+10', // Range of years to display in drop-down,
16809                         // either relative to today's year (-nn:+nn), relative to currently displayed year
16810                         // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
16811                 showOtherMonths: false, // True to show dates in other months, false to leave blank
16812                 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
16813                 showWeek: false, // True to show week of the year, false to not show it
16814                 calculateWeek: this.iso8601Week, // How to calculate the week of the year,
16815                         // takes a Date and returns the number of the week for it
16816                 shortYearCutoff: '+10', // Short year values < this are in the current century,
16817                         // > this are in the previous century,
16818                         // string value starting with '+' for current year + value
16819                 minDate: null, // The earliest selectable date, or null for no limit
16820                 maxDate: null, // The latest selectable date, or null for no limit
16821                 duration: 'fast', // Duration of display/closure
16822                 beforeShowDay: null, // Function that takes a date and returns an array with
16823                         // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
16824                         // [2] = cell title (optional), e.g. $.datepicker.noWeekends
16825                 beforeShow: null, // Function that takes an input field and
16826                         // returns a set of custom settings for the date picker
16827                 onSelect: null, // Define a callback function when a date is selected
16828                 onChangeMonthYear: null, // Define a callback function when the month or year is changed
16829                 onClose: null, // Define a callback function when the datepicker is closed
16830                 numberOfMonths: 1, // Number of months to show at a time
16831                 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
16832                 stepMonths: 1, // Number of months to step back/forward
16833                 stepBigMonths: 12, // Number of months to step back/forward for the big links
16834                 altField: '', // Selector for an alternate field to store selected dates into
16835                 altFormat: '', // The date format to use for the alternate field
16836                 constrainInput: true, // The input is constrained by the current date format
16837                 showButtonPanel: false, // True to show button panel, false to not show it
16838                 autoSize: false // True to size the input for the date format, false to leave as is
16839         };
16840         $.extend(this._defaults, this.regional['']);
16841         this.dpDiv = $('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>');
16842 }
16843
16844 $.extend(Datepicker.prototype, {
16845         /* Class name added to elements to indicate already configured with a date picker. */
16846         markerClassName: 'hasDatepicker',
16847
16848         /* Debug logging (if enabled). */
16849         log: function () {
16850                 if (this.debug)
16851                         console.log.apply('', arguments);
16852         },
16853         
16854         // TODO rename to "widget" when switching to widget factory
16855         _widgetDatepicker: function() {
16856                 return this.dpDiv;
16857         },
16858
16859         /* Override the default settings for all instances of the date picker.
16860            @param  settings  object - the new settings to use as defaults (anonymous object)
16861            @return the manager object */
16862         setDefaults: function(settings) {
16863                 extendRemove(this._defaults, settings || {});
16864                 return this;
16865         },
16866
16867         /* Attach the date picker to a jQuery selection.
16868            @param  target    element - the target input field or division or span
16869            @param  settings  object - the new settings to use for this date picker instance (anonymous) */
16870         _attachDatepicker: function(target, settings) {
16871                 // check for settings on the control itself - in namespace 'date:'
16872                 var inlineSettings = null;
16873                 for (var attrName in this._defaults) {
16874                         var attrValue = target.getAttribute('date:' + attrName);
16875                         if (attrValue) {
16876                                 inlineSettings = inlineSettings || {};
16877                                 try {
16878                                         inlineSettings[attrName] = eval(attrValue);
16879                                 } catch (err) {
16880                                         inlineSettings[attrName] = attrValue;
16881                                 }
16882                         }
16883                 }
16884                 var nodeName = target.nodeName.toLowerCase();
16885                 var inline = (nodeName == 'div' || nodeName == 'span');
16886                 if (!target.id) {
16887                         this.uuid += 1;
16888                         target.id = 'dp' + this.uuid;
16889                 }
16890                 var inst = this._newInst($(target), inline);
16891                 inst.settings = $.extend({}, settings || {}, inlineSettings || {});
16892                 if (nodeName == 'input') {
16893                         this._connectDatepicker(target, inst);
16894                 } else if (inline) {
16895                         this._inlineDatepicker(target, inst);
16896                 }
16897         },
16898
16899         /* Create a new instance object. */
16900         _newInst: function(target, inline) {
16901                 var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
16902                 return {id: id, input: target, // associated target
16903                         selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
16904                         drawMonth: 0, drawYear: 0, // month being drawn
16905                         inline: inline, // is datepicker inline or not
16906                         dpDiv: (!inline ? this.dpDiv : // presentation div
16907                         $('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))};
16908         },
16909
16910         /* Attach the date picker to an input field. */
16911         _connectDatepicker: function(target, inst) {
16912                 var input = $(target);
16913                 inst.append = $([]);
16914                 inst.trigger = $([]);
16915                 if (input.hasClass(this.markerClassName))
16916                         return;
16917                 this._attachments(input, inst);
16918                 input.addClass(this.markerClassName).keydown(this._doKeyDown).
16919                         keypress(this._doKeyPress).keyup(this._doKeyUp).
16920                         bind("setData.datepicker", function(event, key, value) {
16921                                 inst.settings[key] = value;
16922                         }).bind("getData.datepicker", function(event, key) {
16923                                 return this._get(inst, key);
16924                         });
16925                 this._autoSize(inst);
16926                 $.data(target, PROP_NAME, inst);
16927         },
16928
16929         /* Make attachments based on settings. */
16930         _attachments: function(input, inst) {
16931                 var appendText = this._get(inst, 'appendText');
16932                 var isRTL = this._get(inst, 'isRTL');
16933                 if (inst.append)
16934                         inst.append.remove();
16935                 if (appendText) {
16936                         inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
16937                         input[isRTL ? 'before' : 'after'](inst.append);
16938                 }
16939                 input.unbind('focus', this._showDatepicker);
16940                 if (inst.trigger)
16941                         inst.trigger.remove();
16942                 var showOn = this._get(inst, 'showOn');
16943                 if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
16944                         input.focus(this._showDatepicker);
16945                 if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
16946                         var buttonText = this._get(inst, 'buttonText');
16947                         var buttonImage = this._get(inst, 'buttonImage');
16948                         inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
16949                                 $('<img/>').addClass(this._triggerClass).
16950                                         attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
16951                                 $('<button type="button"></button>').addClass(this._triggerClass).
16952                                         html(buttonImage == '' ? buttonText : $('<img/>').attr(
16953                                         { src:buttonImage, alt:buttonText, title:buttonText })));
16954                         input[isRTL ? 'before' : 'after'](inst.trigger);
16955                         inst.trigger.click(function() {
16956                                 if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
16957                                         $.datepicker._hideDatepicker();
16958                                 else
16959                                         $.datepicker._showDatepicker(input[0]);
16960                                 return false;
16961                         });
16962                 }
16963         },
16964
16965         /* Apply the maximum length for the date format. */
16966         _autoSize: function(inst) {
16967                 if (this._get(inst, 'autoSize') && !inst.inline) {
16968                         var date = new Date(2009, 12 - 1, 20); // Ensure double digits
16969                         var dateFormat = this._get(inst, 'dateFormat');
16970                         if (dateFormat.match(/[DM]/)) {
16971                                 var findMax = function(names) {
16972                                         var max = 0;
16973                                         var maxI = 0;
16974                                         for (var i = 0; i < names.length; i++) {
16975                                                 if (names[i].length > max) {
16976                                                         max = names[i].length;
16977                                                         maxI = i;
16978                                                 }
16979                                         }
16980                                         return maxI;
16981                                 };
16982                                 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
16983                                         'monthNames' : 'monthNamesShort'))));
16984                                 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
16985                                         'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
16986                         }
16987                         inst.input.attr('size', this._formatDate(inst, date).length);
16988                 }
16989         },
16990
16991         /* Attach an inline date picker to a div. */
16992         _inlineDatepicker: function(target, inst) {
16993                 var divSpan = $(target);
16994                 if (divSpan.hasClass(this.markerClassName))
16995                         return;
16996                 divSpan.addClass(this.markerClassName).append(inst.dpDiv).
16997                         bind("setData.datepicker", function(event, key, value){
16998                                 inst.settings[key] = value;
16999                         }).bind("getData.datepicker", function(event, key){
17000                                 return this._get(inst, key);
17001                         });
17002                 $.data(target, PROP_NAME, inst);
17003                 this._setDate(inst, this._getDefaultDate(inst), true);
17004                 this._updateDatepicker(inst);
17005                 this._updateAlternate(inst);
17006                 inst.dpDiv.show();
17007         },
17008
17009         /* Pop-up the date picker in a "dialog" box.
17010            @param  input     element - ignored
17011            @param  date      string or Date - the initial date to display
17012            @param  onSelect  function - the function to call when a date is selected
17013            @param  settings  object - update the dialog date picker instance's settings (anonymous object)
17014            @param  pos       int[2] - coordinates for the dialog's position within the screen or
17015                              event - with x/y coordinates or
17016                              leave empty for default (screen centre)
17017            @return the manager object */
17018         _dialogDatepicker: function(input, date, onSelect, settings, pos) {
17019                 var inst = this._dialogInst; // internal instance
17020                 if (!inst) {
17021                         this.uuid += 1;
17022                         var id = 'dp' + this.uuid;
17023                         this._dialogInput = $('<input type="text" id="' + id +
17024                                 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
17025                         this._dialogInput.keydown(this._doKeyDown);
17026                         $('body').append(this._dialogInput);
17027                         inst = this._dialogInst = this._newInst(this._dialogInput, false);
17028                         inst.settings = {};
17029                         $.data(this._dialogInput[0], PROP_NAME, inst);
17030                 }
17031                 extendRemove(inst.settings, settings || {});
17032                 date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
17033                 this._dialogInput.val(date);
17034
17035                 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
17036                 if (!this._pos) {
17037                         var browserWidth = document.documentElement.clientWidth;
17038                         var browserHeight = document.documentElement.clientHeight;
17039                         var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
17040                         var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
17041                         this._pos = // should use actual width/height below
17042                                 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
17043                 }
17044
17045                 // move input on screen for focus, but hidden behind dialog
17046                 this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
17047                 inst.settings.onSelect = onSelect;
17048                 this._inDialog = true;
17049                 this.dpDiv.addClass(this._dialogClass);
17050                 this._showDatepicker(this._dialogInput[0]);
17051                 if ($.blockUI)
17052                         $.blockUI(this.dpDiv);
17053                 $.data(this._dialogInput[0], PROP_NAME, inst);
17054                 return this;
17055         },
17056
17057         /* Detach a datepicker from its control.
17058            @param  target    element - the target input field or division or span */
17059         _destroyDatepicker: function(target) {
17060                 var $target = $(target);
17061                 var inst = $.data(target, PROP_NAME);
17062                 if (!$target.hasClass(this.markerClassName)) {
17063                         return;
17064                 }
17065                 var nodeName = target.nodeName.toLowerCase();
17066                 $.removeData(target, PROP_NAME);
17067                 if (nodeName == 'input') {
17068                         inst.append.remove();
17069                         inst.trigger.remove();
17070                         $target.removeClass(this.markerClassName).
17071                                 unbind('focus', this._showDatepicker).
17072                                 unbind('keydown', this._doKeyDown).
17073                                 unbind('keypress', this._doKeyPress).
17074                                 unbind('keyup', this._doKeyUp);
17075                 } else if (nodeName == 'div' || nodeName == 'span')
17076                         $target.removeClass(this.markerClassName).empty();
17077         },
17078
17079         /* Enable the date picker to a jQuery selection.
17080            @param  target    element - the target input field or division or span */
17081         _enableDatepicker: function(target) {
17082                 var $target = $(target);
17083                 var inst = $.data(target, PROP_NAME);
17084                 if (!$target.hasClass(this.markerClassName)) {
17085                         return;
17086                 }
17087                 var nodeName = target.nodeName.toLowerCase();
17088                 if (nodeName == 'input') {
17089                         target.disabled = false;
17090                         inst.trigger.filter('button').
17091                                 each(function() { this.disabled = false; }).end().
17092                                 filter('img').css({opacity: '1.0', cursor: ''});
17093                 }
17094                 else if (nodeName == 'div' || nodeName == 'span') {
17095                         var inline = $target.children('.' + this._inlineClass);
17096                         inline.children().removeClass('ui-state-disabled');
17097                 }
17098                 this._disabledInputs = $.map(this._disabledInputs,
17099                         function(value) { return (value == target ? null : value); }); // delete entry
17100         },
17101
17102         /* Disable the date picker to a jQuery selection.
17103            @param  target    element - the target input field or division or span */
17104         _disableDatepicker: function(target) {
17105                 var $target = $(target);
17106                 var inst = $.data(target, PROP_NAME);
17107                 if (!$target.hasClass(this.markerClassName)) {
17108                         return;
17109                 }
17110                 var nodeName = target.nodeName.toLowerCase();
17111                 if (nodeName == 'input') {
17112                         target.disabled = true;
17113                         inst.trigger.filter('button').
17114                                 each(function() { this.disabled = true; }).end().
17115                                 filter('img').css({opacity: '0.5', cursor: 'default'});
17116                 }
17117                 else if (nodeName == 'div' || nodeName == 'span') {
17118                         var inline = $target.children('.' + this._inlineClass);
17119                         inline.children().addClass('ui-state-disabled');
17120                 }
17121                 this._disabledInputs = $.map(this._disabledInputs,
17122                         function(value) { return (value == target ? null : value); }); // delete entry
17123                 this._disabledInputs[this._disabledInputs.length] = target;
17124         },
17125
17126         /* Is the first field in a jQuery collection disabled as a datepicker?
17127            @param  target    element - the target input field or division or span
17128            @return boolean - true if disabled, false if enabled */
17129         _isDisabledDatepicker: function(target) {
17130                 if (!target) {
17131                         return false;
17132                 }
17133                 for (var i = 0; i < this._disabledInputs.length; i++) {
17134                         if (this._disabledInputs[i] == target)
17135                                 return true;
17136                 }
17137                 return false;
17138         },
17139
17140         /* Retrieve the instance data for the target control.
17141            @param  target  element - the target input field or division or span
17142            @return  object - the associated instance data
17143            @throws  error if a jQuery problem getting data */
17144         _getInst: function(target) {
17145                 try {
17146                         return $.data(target, PROP_NAME);
17147                 }
17148                 catch (err) {
17149                         throw 'Missing instance data for this datepicker';
17150                 }
17151         },
17152
17153         /* Update or retrieve the settings for a date picker attached to an input field or division.
17154            @param  target  element - the target input field or division or span
17155            @param  name    object - the new settings to update or
17156                            string - the name of the setting to change or retrieve,
17157                            when retrieving also 'all' for all instance settings or
17158                            'defaults' for all global defaults
17159            @param  value   any - the new value for the setting
17160                            (omit if above is an object or to retrieve a value) */
17161         _optionDatepicker: function(target, name, value) {
17162                 var inst = this._getInst(target);
17163                 if (arguments.length == 2 && typeof name == 'string') {
17164                         return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
17165                                 (inst ? (name == 'all' ? $.extend({}, inst.settings) :
17166                                 this._get(inst, name)) : null));
17167                 }
17168                 var settings = name || {};
17169                 if (typeof name == 'string') {
17170                         settings = {};
17171                         settings[name] = value;
17172                 }
17173                 if (inst) {
17174                         if (this._curInst == inst) {
17175                                 this._hideDatepicker();
17176                         }
17177                         var date = this._getDateDatepicker(target, true);
17178                         var minDate = this._getMinMaxDate(inst, 'min');
17179                         var maxDate = this._getMinMaxDate(inst, 'max');
17180                         extendRemove(inst.settings, settings);
17181                         // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
17182                         if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
17183                                 inst.settings.minDate = this._formatDate(inst, minDate);
17184                         if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
17185                                 inst.settings.maxDate = this._formatDate(inst, maxDate);
17186                         this._attachments($(target), inst);
17187                         this._autoSize(inst);
17188                         this._setDateDatepicker(target, date);
17189                         this._updateDatepicker(inst);
17190                 }
17191         },
17192
17193         // change method deprecated
17194         _changeDatepicker: function(target, name, value) {
17195                 this._optionDatepicker(target, name, value);
17196         },
17197
17198         /* Redraw the date picker attached to an input field or division.
17199            @param  target  element - the target input field or division or span */
17200         _refreshDatepicker: function(target) {
17201                 var inst = this._getInst(target);
17202                 if (inst) {
17203                         this._updateDatepicker(inst);
17204                 }
17205         },
17206
17207         /* Set the dates for a jQuery selection.
17208            @param  target   element - the target input field or division or span
17209            @param  date     Date - the new date */
17210         _setDateDatepicker: function(target, date) {
17211                 var inst = this._getInst(target);
17212                 if (inst) {
17213                         this._setDate(inst, date);
17214                         this._updateDatepicker(inst);
17215                         this._updateAlternate(inst);
17216                 }
17217         },
17218
17219         /* Get the date(s) for the first entry in a jQuery selection.
17220            @param  target     element - the target input field or division or span
17221            @param  noDefault  boolean - true if no default date is to be used
17222            @return Date - the current date */
17223         _getDateDatepicker: function(target, noDefault) {
17224                 var inst = this._getInst(target);
17225                 if (inst && !inst.inline)
17226                         this._setDateFromField(inst, noDefault);
17227                 return (inst ? this._getDate(inst) : null);
17228         },
17229
17230         /* Handle keystrokes. */
17231         _doKeyDown: function(event) {
17232                 var inst = $.datepicker._getInst(event.target);
17233                 var handled = true;
17234                 var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
17235                 inst._keyEvent = true;
17236                 if ($.datepicker._datepickerShowing)
17237                         switch (event.keyCode) {
17238                                 case 9: $.datepicker._hideDatepicker();
17239                                                 handled = false;
17240                                                 break; // hide on tab out
17241                                 case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + 
17242                                                                         $.datepicker._currentClass + ')', inst.dpDiv);
17243                                                 if (sel[0])
17244                                                         $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
17245                                                 else
17246                                                         $.datepicker._hideDatepicker();
17247                                                 return false; // don't submit the form
17248                                                 break; // select the value on enter
17249                                 case 27: $.datepicker._hideDatepicker();
17250                                                 break; // hide on escape
17251                                 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
17252                                                         -$.datepicker._get(inst, 'stepBigMonths') :
17253                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
17254                                                 break; // previous month/year on page up/+ ctrl
17255                                 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
17256                                                         +$.datepicker._get(inst, 'stepBigMonths') :
17257                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
17258                                                 break; // next month/year on page down/+ ctrl
17259                                 case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
17260                                                 handled = event.ctrlKey || event.metaKey;
17261                                                 break; // clear on ctrl or command +end
17262                                 case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
17263                                                 handled = event.ctrlKey || event.metaKey;
17264                                                 break; // current on ctrl or command +home
17265                                 case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
17266                                                 handled = event.ctrlKey || event.metaKey;
17267                                                 // -1 day on ctrl or command +left
17268                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
17269                                                                         -$.datepicker._get(inst, 'stepBigMonths') :
17270                                                                         -$.datepicker._get(inst, 'stepMonths')), 'M');
17271                                                 // next month/year on alt +left on Mac
17272                                                 break;
17273                                 case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
17274                                                 handled = event.ctrlKey || event.metaKey;
17275                                                 break; // -1 week on ctrl or command +up
17276                                 case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
17277                                                 handled = event.ctrlKey || event.metaKey;
17278                                                 // +1 day on ctrl or command +right
17279                                                 if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
17280                                                                         +$.datepicker._get(inst, 'stepBigMonths') :
17281                                                                         +$.datepicker._get(inst, 'stepMonths')), 'M');
17282                                                 // next month/year on alt +right
17283                                                 break;
17284                                 case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
17285                                                 handled = event.ctrlKey || event.metaKey;
17286                                                 break; // +1 week on ctrl or command +down
17287                                 default: handled = false;
17288                         }
17289                 else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
17290                         $.datepicker._showDatepicker(this);
17291                 else {
17292                         handled = false;
17293                 }
17294                 if (handled) {
17295                         event.preventDefault();
17296                         event.stopPropagation();
17297                 }
17298         },
17299
17300         /* Filter entered characters - based on date format. */
17301         _doKeyPress: function(event) {
17302                 var inst = $.datepicker._getInst(event.target);
17303                 if ($.datepicker._get(inst, 'constrainInput')) {
17304                         var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
17305                         var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
17306                         return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
17307                 }
17308         },
17309
17310         /* Synchronise manual entry and field/alternate field. */
17311         _doKeyUp: function(event) {
17312                 var inst = $.datepicker._getInst(event.target);
17313                 if (inst.input.val() != inst.lastVal) {
17314                         try {
17315                                 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
17316                                         (inst.input ? inst.input.val() : null),
17317                                         $.datepicker._getFormatConfig(inst));
17318                                 if (date) { // only if valid
17319                                         $.datepicker._setDateFromField(inst);
17320                                         $.datepicker._updateAlternate(inst);
17321                                         $.datepicker._updateDatepicker(inst);
17322                                 }
17323                         }
17324                         catch (event) {
17325                                 $.datepicker.log(event);
17326                         }
17327                 }
17328                 return true;
17329         },
17330
17331         /* Pop-up the date picker for a given input field.
17332            @param  input  element - the input field attached to the date picker or
17333                           event - if triggered by focus */
17334         _showDatepicker: function(input) {
17335                 input = input.target || input;
17336                 if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
17337                         input = $('input', input.parentNode)[0];
17338                 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
17339                         return;
17340                 var inst = $.datepicker._getInst(input);
17341                 if ($.datepicker._curInst && $.datepicker._curInst != inst) {
17342                         $.datepicker._curInst.dpDiv.stop(true, true);
17343                 }
17344                 var beforeShow = $.datepicker._get(inst, 'beforeShow');
17345                 extendRemove(inst.settings, (beforeShow ? beforeShow.apply(input, [input, inst]) : {}));
17346                 inst.lastVal = null;
17347                 $.datepicker._lastInput = input;
17348                 $.datepicker._setDateFromField(inst);
17349                 if ($.datepicker._inDialog) // hide cursor
17350                         input.value = '';
17351                 if (!$.datepicker._pos) { // position below input
17352                         $.datepicker._pos = $.datepicker._findPos(input);
17353                         $.datepicker._pos[1] += input.offsetHeight; // add the height
17354                 }
17355                 var isFixed = false;
17356                 $(input).parents().each(function() {
17357                         isFixed |= $(this).css('position') == 'fixed';
17358                         return !isFixed;
17359                 });
17360                 if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
17361                         $.datepicker._pos[0] -= document.documentElement.scrollLeft;
17362                         $.datepicker._pos[1] -= document.documentElement.scrollTop;
17363                 }
17364                 var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
17365                 $.datepicker._pos = null;
17366                 //to avoid flashes on Firefox
17367                 inst.dpDiv.empty();
17368                 // determine sizing offscreen
17369                 inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
17370                 $.datepicker._updateDatepicker(inst);
17371                 // fix width for dynamic number of date pickers
17372                 // and adjust position before showing
17373                 offset = $.datepicker._checkOffset(inst, offset, isFixed);
17374                 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
17375                         'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
17376                         left: offset.left + 'px', top: offset.top + 'px'});
17377                 if (!inst.inline) {
17378                         var showAnim = $.datepicker._get(inst, 'showAnim');
17379                         var duration = $.datepicker._get(inst, 'duration');
17380                         var postProcess = function() {
17381                                 $.datepicker._datepickerShowing = true;
17382                                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
17383                                 if( !! cover.length ){
17384                                         var borders = $.datepicker._getBorders(inst.dpDiv);
17385                                         cover.css({left: -borders[0], top: -borders[1],
17386                                                 width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
17387                                 }
17388                         };
17389                         inst.dpDiv.zIndex($(input).zIndex()+1);
17390                         if ($.effects && $.effects[showAnim])
17391                                 inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
17392                         else
17393                                 inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
17394                         if (!showAnim || !duration)
17395                                 postProcess();
17396                         if (inst.input.is(':visible') && !inst.input.is(':disabled'))
17397                                 inst.input.focus();
17398                         $.datepicker._curInst = inst;
17399                 }
17400         },
17401
17402         /* Generate the date picker content. */
17403         _updateDatepicker: function(inst) {
17404                 var self = this;
17405                 var borders = $.datepicker._getBorders(inst.dpDiv);
17406                 inst.dpDiv.empty().append(this._generateHTML(inst));
17407                 var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
17408                 if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
17409                         cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
17410                 }
17411                 inst.dpDiv.find('button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a')
17412                                 .bind('mouseout', function(){
17413                                         $(this).removeClass('ui-state-hover');
17414                                         if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).removeClass('ui-datepicker-prev-hover');
17415                                         if(this.className.indexOf('ui-datepicker-next') != -1) $(this).removeClass('ui-datepicker-next-hover');
17416                                 })
17417                                 .bind('mouseover', function(){
17418                                         if (!self._isDisabledDatepicker( inst.inline ? inst.dpDiv.parent()[0] : inst.input[0])) {
17419                                                 $(this).parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
17420                                                 $(this).addClass('ui-state-hover');
17421                                                 if(this.className.indexOf('ui-datepicker-prev') != -1) $(this).addClass('ui-datepicker-prev-hover');
17422                                                 if(this.className.indexOf('ui-datepicker-next') != -1) $(this).addClass('ui-datepicker-next-hover');
17423                                         }
17424                                 })
17425                         .end()
17426                         .find('.' + this._dayOverClass + ' a')
17427                                 .trigger('mouseover')
17428                         .end();
17429                 var numMonths = this._getNumberOfMonths(inst);
17430                 var cols = numMonths[1];
17431                 var width = 17;
17432                 if (cols > 1)
17433                         inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
17434                 else
17435                         inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
17436                 inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
17437                         'Class']('ui-datepicker-multi');
17438                 inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
17439                         'Class']('ui-datepicker-rtl');
17440                 if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
17441                                 // #6694 - don't focus the input if it's already focused
17442                                 // this breaks the change event in IE
17443                                 inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
17444                         inst.input.focus();
17445                 // deffered render of the years select (to avoid flashes on Firefox) 
17446                 if( inst.yearshtml ){
17447                         var origyearshtml = inst.yearshtml;
17448                         setTimeout(function(){
17449                                 //assure that inst.yearshtml didn't change.
17450                                 if( origyearshtml === inst.yearshtml ){
17451                                         inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
17452                                 }
17453                                 origyearshtml = inst.yearshtml = null;
17454                         }, 0);
17455                 }
17456         },
17457
17458         /* Retrieve the size of left and top borders for an element.
17459            @param  elem  (jQuery object) the element of interest
17460            @return  (number[2]) the left and top borders */
17461         _getBorders: function(elem) {
17462                 var convert = function(value) {
17463                         return {thin: 1, medium: 2, thick: 3}[value] || value;
17464                 };
17465                 return [parseFloat(convert(elem.css('border-left-width'))),
17466                         parseFloat(convert(elem.css('border-top-width')))];
17467         },
17468
17469         /* Check positioning to remain on screen. */
17470         _checkOffset: function(inst, offset, isFixed) {
17471                 var dpWidth = inst.dpDiv.outerWidth();
17472                 var dpHeight = inst.dpDiv.outerHeight();
17473                 var inputWidth = inst.input ? inst.input.outerWidth() : 0;
17474                 var inputHeight = inst.input ? inst.input.outerHeight() : 0;
17475                 var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
17476                 var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
17477
17478                 offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
17479                 offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
17480                 offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
17481
17482                 // now check if datepicker is showing outside window viewport - move to a better place if so.
17483                 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
17484                         Math.abs(offset.left + dpWidth - viewWidth) : 0);
17485                 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
17486                         Math.abs(dpHeight + inputHeight) : 0);
17487
17488                 return offset;
17489         },
17490
17491         /* Find an object's position on the screen. */
17492         _findPos: function(obj) {
17493                 var inst = this._getInst(obj);
17494                 var isRTL = this._get(inst, 'isRTL');
17495         while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
17496             obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
17497         }
17498         var position = $(obj).offset();
17499             return [position.left, position.top];
17500         },
17501
17502         /* Hide the date picker from view.
17503            @param  input  element - the input field attached to the date picker */
17504         _hideDatepicker: function(input) {
17505                 var inst = this._curInst;
17506                 if (!inst || (input && inst != $.data(input, PROP_NAME)))
17507                         return;
17508                 if (this._datepickerShowing) {
17509                         var showAnim = this._get(inst, 'showAnim');
17510                         var duration = this._get(inst, 'duration');
17511                         var postProcess = function() {
17512                                 $.datepicker._tidyDialog(inst);
17513                                 this._curInst = null;
17514                         };
17515                         if ($.effects && $.effects[showAnim])
17516                                 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
17517                         else
17518                                 inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
17519                                         (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
17520                         if (!showAnim)
17521                                 postProcess();
17522                         var onClose = this._get(inst, 'onClose');
17523                         if (onClose)
17524                                 onClose.apply((inst.input ? inst.input[0] : null),
17525                                         [(inst.input ? inst.input.val() : ''), inst]);  // trigger custom callback
17526                         this._datepickerShowing = false;
17527                         this._lastInput = null;
17528                         if (this._inDialog) {
17529                                 this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
17530                                 if ($.blockUI) {
17531                                         $.unblockUI();
17532                                         $('body').append(this.dpDiv);
17533                                 }
17534                         }
17535                         this._inDialog = false;
17536                 }
17537         },
17538
17539         /* Tidy up after a dialog display. */
17540         _tidyDialog: function(inst) {
17541                 inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
17542         },
17543
17544         /* Close date picker if clicked elsewhere. */
17545         _checkExternalClick: function(event) {
17546                 if (!$.datepicker._curInst)
17547                         return;
17548                 var $target = $(event.target);
17549                 if ($target[0].id != $.datepicker._mainDivId &&
17550                                 $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
17551                                 !$target.hasClass($.datepicker.markerClassName) &&
17552                                 !$target.hasClass($.datepicker._triggerClass) &&
17553                                 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
17554                         $.datepicker._hideDatepicker();
17555         },
17556
17557         /* Adjust one of the date sub-fields. */
17558         _adjustDate: function(id, offset, period) {
17559                 var target = $(id);
17560                 var inst = this._getInst(target[0]);
17561                 if (this._isDisabledDatepicker(target[0])) {
17562                         return;
17563                 }
17564                 this._adjustInstDate(inst, offset +
17565                         (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
17566                         period);
17567                 this._updateDatepicker(inst);
17568         },
17569
17570         /* Action for current link. */
17571         _gotoToday: function(id) {
17572                 var target = $(id);
17573                 var inst = this._getInst(target[0]);
17574                 if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
17575                         inst.selectedDay = inst.currentDay;
17576                         inst.drawMonth = inst.selectedMonth = inst.currentMonth;
17577                         inst.drawYear = inst.selectedYear = inst.currentYear;
17578                 }
17579                 else {
17580                         var date = new Date();
17581                         inst.selectedDay = date.getDate();
17582                         inst.drawMonth = inst.selectedMonth = date.getMonth();
17583                         inst.drawYear = inst.selectedYear = date.getFullYear();
17584                 }
17585                 this._notifyChange(inst);
17586                 this._adjustDate(target);
17587         },
17588
17589         /* Action for selecting a new month/year. */
17590         _selectMonthYear: function(id, select, period) {
17591                 var target = $(id);
17592                 var inst = this._getInst(target[0]);
17593                 inst._selectingMonthYear = false;
17594                 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
17595                 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
17596                         parseInt(select.options[select.selectedIndex].value,10);
17597                 this._notifyChange(inst);
17598                 this._adjustDate(target);
17599         },
17600
17601         /* Restore input focus after not changing month/year. */
17602         _clickMonthYear: function(id) {
17603                 var target = $(id);
17604                 var inst = this._getInst(target[0]);
17605                 if (inst.input && inst._selectingMonthYear) {
17606                         setTimeout(function() {
17607                                 inst.input.focus();
17608                         }, 0);
17609                 }
17610                 inst._selectingMonthYear = !inst._selectingMonthYear;
17611         },
17612
17613         /* Action for selecting a day. */
17614         _selectDay: function(id, month, year, td) {
17615                 var target = $(id);
17616                 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
17617                         return;
17618                 }
17619                 var inst = this._getInst(target[0]);
17620                 inst.selectedDay = inst.currentDay = $('a', td).html();
17621                 inst.selectedMonth = inst.currentMonth = month;
17622                 inst.selectedYear = inst.currentYear = year;
17623                 this._selectDate(id, this._formatDate(inst,
17624                         inst.currentDay, inst.currentMonth, inst.currentYear));
17625         },
17626
17627         /* Erase the input field and hide the date picker. */
17628         _clearDate: function(id) {
17629                 var target = $(id);
17630                 var inst = this._getInst(target[0]);
17631                 this._selectDate(target, '');
17632         },
17633
17634         /* Update the input field with the selected date. */
17635         _selectDate: function(id, dateStr) {
17636                 var target = $(id);
17637                 var inst = this._getInst(target[0]);
17638                 dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
17639                 if (inst.input)
17640                         inst.input.val(dateStr);
17641                 this._updateAlternate(inst);
17642                 var onSelect = this._get(inst, 'onSelect');
17643                 if (onSelect)
17644                         onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
17645                 else if (inst.input)
17646                         inst.input.trigger('change'); // fire the change event
17647                 if (inst.inline)
17648                         this._updateDatepicker(inst);
17649                 else {
17650                         this._hideDatepicker();
17651                         this._lastInput = inst.input[0];
17652                         if (typeof(inst.input[0]) != 'object')
17653                                 inst.input.focus(); // restore focus
17654                         this._lastInput = null;
17655                 }
17656         },
17657
17658         /* Update any alternate field to synchronise with the main field. */
17659         _updateAlternate: function(inst) {
17660                 var altField = this._get(inst, 'altField');
17661                 if (altField) { // update alternate field too
17662                         var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
17663                         var date = this._getDate(inst);
17664                         var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
17665                         $(altField).each(function() { $(this).val(dateStr); });
17666                 }
17667         },
17668
17669         /* Set as beforeShowDay function to prevent selection of weekends.
17670            @param  date  Date - the date to customise
17671            @return [boolean, string] - is this date selectable?, what is its CSS class? */
17672         noWeekends: function(date) {
17673                 var day = date.getDay();
17674                 return [(day > 0 && day < 6), ''];
17675         },
17676
17677         /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
17678            @param  date  Date - the date to get the week for
17679            @return  number - the number of the week within the year that contains this date */
17680         iso8601Week: function(date) {
17681                 var checkDate = new Date(date.getTime());
17682                 // Find Thursday of this week starting on Monday
17683                 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
17684                 var time = checkDate.getTime();
17685                 checkDate.setMonth(0); // Compare with Jan 1
17686                 checkDate.setDate(1);
17687                 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
17688         },
17689
17690         /* Parse a string value into a date object.
17691            See formatDate below for the possible formats.
17692
17693            @param  format    string - the expected format of the date
17694            @param  value     string - the date in the above format
17695            @param  settings  Object - attributes include:
17696                              shortYearCutoff  number - the cutoff year for determining the century (optional)
17697                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
17698                              dayNames         string[7] - names of the days from Sunday (optional)
17699                              monthNamesShort  string[12] - abbreviated names of the months (optional)
17700                              monthNames       string[12] - names of the months (optional)
17701            @return  Date - the extracted date value or null if value is blank */
17702         parseDate: function (format, value, settings) {
17703                 if (format == null || value == null)
17704                         throw 'Invalid arguments';
17705                 value = (typeof value == 'object' ? value.toString() : value + '');
17706                 if (value == '')
17707                         return null;
17708                 var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
17709                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
17710                                 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
17711                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
17712                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
17713                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
17714                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
17715                 var year = -1;
17716                 var month = -1;
17717                 var day = -1;
17718                 var doy = -1;
17719                 var literal = false;
17720                 // Check whether a format character is doubled
17721                 var lookAhead = function(match) {
17722                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
17723                         if (matches)
17724                                 iFormat++;
17725                         return matches;
17726                 };
17727                 // Extract a number from the string value
17728                 var getNumber = function(match) {
17729                         var isDoubled = lookAhead(match);
17730                         var size = (match == '@' ? 14 : (match == '!' ? 20 :
17731                                 (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
17732                         var digits = new RegExp('^\\d{1,' + size + '}');
17733                         var num = value.substring(iValue).match(digits);
17734                         if (!num)
17735                                 throw 'Missing number at position ' + iValue;
17736                         iValue += num[0].length;
17737                         return parseInt(num[0], 10);
17738                 };
17739                 // Extract a name from the string value and convert to an index
17740                 var getName = function(match, shortNames, longNames) {
17741                         var names = (lookAhead(match) ? longNames : shortNames);
17742                         for (var i = 0; i < names.length; i++) {
17743                                 if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) {
17744                                         iValue += names[i].length;
17745                                         return i + 1;
17746                                 }
17747                         }
17748                         throw 'Unknown name at position ' + iValue;
17749                 };
17750                 // Confirm that a literal character matches the string value
17751                 var checkLiteral = function() {
17752                         if (value.charAt(iValue) != format.charAt(iFormat))
17753                                 throw 'Unexpected literal at position ' + iValue;
17754                         iValue++;
17755                 };
17756                 var iValue = 0;
17757                 for (var iFormat = 0; iFormat < format.length; iFormat++) {
17758                         if (literal)
17759                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
17760                                         literal = false;
17761                                 else
17762                                         checkLiteral();
17763                         else
17764                                 switch (format.charAt(iFormat)) {
17765                                         case 'd':
17766                                                 day = getNumber('d');
17767                                                 break;
17768                                         case 'D':
17769                                                 getName('D', dayNamesShort, dayNames);
17770                                                 break;
17771                                         case 'o':
17772                                                 doy = getNumber('o');
17773                                                 break;
17774                                         case 'm':
17775                                                 month = getNumber('m');
17776                                                 break;
17777                                         case 'M':
17778                                                 month = getName('M', monthNamesShort, monthNames);
17779                                                 break;
17780                                         case 'y':
17781                                                 year = getNumber('y');
17782                                                 break;
17783                                         case '@':
17784                                                 var date = new Date(getNumber('@'));
17785                                                 year = date.getFullYear();
17786                                                 month = date.getMonth() + 1;
17787                                                 day = date.getDate();
17788                                                 break;
17789                                         case '!':
17790                                                 var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
17791                                                 year = date.getFullYear();
17792                                                 month = date.getMonth() + 1;
17793                                                 day = date.getDate();
17794                                                 break;
17795                                         case "'":
17796                                                 if (lookAhead("'"))
17797                                                         checkLiteral();
17798                                                 else
17799                                                         literal = true;
17800                                                 break;
17801                                         default:
17802                                                 checkLiteral();
17803                                 }
17804                 }
17805                 if (year == -1)
17806                         year = new Date().getFullYear();
17807                 else if (year < 100)
17808                         year += new Date().getFullYear() - new Date().getFullYear() % 100 +
17809                                 (year <= shortYearCutoff ? 0 : -100);
17810                 if (doy > -1) {
17811                         month = 1;
17812                         day = doy;
17813                         do {
17814                                 var dim = this._getDaysInMonth(year, month - 1);
17815                                 if (day <= dim)
17816                                         break;
17817                                 month++;
17818                                 day -= dim;
17819                         } while (true);
17820                 }
17821                 var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
17822                 if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
17823                         throw 'Invalid date'; // E.g. 31/02/00
17824                 return date;
17825         },
17826
17827         /* Standard date formats. */
17828         ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
17829         COOKIE: 'D, dd M yy',
17830         ISO_8601: 'yy-mm-dd',
17831         RFC_822: 'D, d M y',
17832         RFC_850: 'DD, dd-M-y',
17833         RFC_1036: 'D, d M y',
17834         RFC_1123: 'D, d M yy',
17835         RFC_2822: 'D, d M yy',
17836         RSS: 'D, d M y', // RFC 822
17837         TICKS: '!',
17838         TIMESTAMP: '@',
17839         W3C: 'yy-mm-dd', // ISO 8601
17840
17841         _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
17842                 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
17843
17844         /* Format a date object into a string value.
17845            The format can be combinations of the following:
17846            d  - day of month (no leading zero)
17847            dd - day of month (two digit)
17848            o  - day of year (no leading zeros)
17849            oo - day of year (three digit)
17850            D  - day name short
17851            DD - day name long
17852            m  - month of year (no leading zero)
17853            mm - month of year (two digit)
17854            M  - month name short
17855            MM - month name long
17856            y  - year (two digit)
17857            yy - year (four digit)
17858            @ - Unix timestamp (ms since 01/01/1970)
17859            ! - Windows ticks (100ns since 01/01/0001)
17860            '...' - literal text
17861            '' - single quote
17862
17863            @param  format    string - the desired format of the date
17864            @param  date      Date - the date value to format
17865            @param  settings  Object - attributes include:
17866                              dayNamesShort    string[7] - abbreviated names of the days from Sunday (optional)
17867                              dayNames         string[7] - names of the days from Sunday (optional)
17868                              monthNamesShort  string[12] - abbreviated names of the months (optional)
17869                              monthNames       string[12] - names of the months (optional)
17870            @return  string - the date in the above format */
17871         formatDate: function (format, date, settings) {
17872                 if (!date)
17873                         return '';
17874                 var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
17875                 var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
17876                 var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
17877                 var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
17878                 // Check whether a format character is doubled
17879                 var lookAhead = function(match) {
17880                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
17881                         if (matches)
17882                                 iFormat++;
17883                         return matches;
17884                 };
17885                 // Format a number, with leading zero if necessary
17886                 var formatNumber = function(match, value, len) {
17887                         var num = '' + value;
17888                         if (lookAhead(match))
17889                                 while (num.length < len)
17890                                         num = '0' + num;
17891                         return num;
17892                 };
17893                 // Format a name, short or long as requested
17894                 var formatName = function(match, value, shortNames, longNames) {
17895                         return (lookAhead(match) ? longNames[value] : shortNames[value]);
17896                 };
17897                 var output = '';
17898                 var literal = false;
17899                 if (date)
17900                         for (var iFormat = 0; iFormat < format.length; iFormat++) {
17901                                 if (literal)
17902                                         if (format.charAt(iFormat) == "'" && !lookAhead("'"))
17903                                                 literal = false;
17904                                         else
17905                                                 output += format.charAt(iFormat);
17906                                 else
17907                                         switch (format.charAt(iFormat)) {
17908                                                 case 'd':
17909                                                         output += formatNumber('d', date.getDate(), 2);
17910                                                         break;
17911                                                 case 'D':
17912                                                         output += formatName('D', date.getDay(), dayNamesShort, dayNames);
17913                                                         break;
17914                                                 case 'o':
17915                                                         output += formatNumber('o',
17916                                                                 (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);
17917                                                         break;
17918                                                 case 'm':
17919                                                         output += formatNumber('m', date.getMonth() + 1, 2);
17920                                                         break;
17921                                                 case 'M':
17922                                                         output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
17923                                                         break;
17924                                                 case 'y':
17925                                                         output += (lookAhead('y') ? date.getFullYear() :
17926                                                                 (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
17927                                                         break;
17928                                                 case '@':
17929                                                         output += date.getTime();
17930                                                         break;
17931                                                 case '!':
17932                                                         output += date.getTime() * 10000 + this._ticksTo1970;
17933                                                         break;
17934                                                 case "'":
17935                                                         if (lookAhead("'"))
17936                                                                 output += "'";
17937                                                         else
17938                                                                 literal = true;
17939                                                         break;
17940                                                 default:
17941                                                         output += format.charAt(iFormat);
17942                                         }
17943                         }
17944                 return output;
17945         },
17946
17947         /* Extract all possible characters from the date format. */
17948         _possibleChars: function (format) {
17949                 var chars = '';
17950                 var literal = false;
17951                 // Check whether a format character is doubled
17952                 var lookAhead = function(match) {
17953                         var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
17954                         if (matches)
17955                                 iFormat++;
17956                         return matches;
17957                 };
17958                 for (var iFormat = 0; iFormat < format.length; iFormat++)
17959                         if (literal)
17960                                 if (format.charAt(iFormat) == "'" && !lookAhead("'"))
17961                                         literal = false;
17962                                 else
17963                                         chars += format.charAt(iFormat);
17964                         else
17965                                 switch (format.charAt(iFormat)) {
17966                                         case 'd': case 'm': case 'y': case '@':
17967                                                 chars += '0123456789';
17968                                                 break;
17969                                         case 'D': case 'M':
17970                                                 return null; // Accept anything
17971                                         case "'":
17972                                                 if (lookAhead("'"))
17973                                                         chars += "'";
17974                                                 else
17975                                                         literal = true;
17976                                                 break;
17977                                         default:
17978                                                 chars += format.charAt(iFormat);
17979                                 }
17980                 return chars;
17981         },
17982
17983         /* Get a setting value, defaulting if necessary. */
17984         _get: function(inst, name) {
17985                 return inst.settings[name] !== undefined ?
17986                         inst.settings[name] : this._defaults[name];
17987         },
17988
17989         /* Parse existing date and initialise date picker. */
17990         _setDateFromField: function(inst, noDefault) {
17991                 if (inst.input.val() == inst.lastVal) {
17992                         return;
17993                 }
17994                 var dateFormat = this._get(inst, 'dateFormat');
17995                 var dates = inst.lastVal = inst.input ? inst.input.val() : null;
17996                 var date, defaultDate;
17997                 date = defaultDate = this._getDefaultDate(inst);
17998                 var settings = this._getFormatConfig(inst);
17999                 try {
18000                         date = this.parseDate(dateFormat, dates, settings) || defaultDate;
18001                 } catch (event) {
18002                         this.log(event);
18003                         dates = (noDefault ? '' : dates);
18004                 }
18005                 inst.selectedDay = date.getDate();
18006                 inst.drawMonth = inst.selectedMonth = date.getMonth();
18007                 inst.drawYear = inst.selectedYear = date.getFullYear();
18008                 inst.currentDay = (dates ? date.getDate() : 0);
18009                 inst.currentMonth = (dates ? date.getMonth() : 0);
18010                 inst.currentYear = (dates ? date.getFullYear() : 0);
18011                 this._adjustInstDate(inst);
18012         },
18013
18014         /* Retrieve the default date shown on opening. */
18015         _getDefaultDate: function(inst) {
18016                 return this._restrictMinMax(inst,
18017                         this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
18018         },
18019
18020         /* A date may be specified as an exact value or a relative one. */
18021         _determineDate: function(inst, date, defaultDate) {
18022                 var offsetNumeric = function(offset) {
18023                         var date = new Date();
18024                         date.setDate(date.getDate() + offset);
18025                         return date;
18026                 };
18027                 var offsetString = function(offset) {
18028                         try {
18029                                 return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
18030                                         offset, $.datepicker._getFormatConfig(inst));
18031                         }
18032                         catch (e) {
18033                                 // Ignore
18034                         }
18035                         var date = (offset.toLowerCase().match(/^c/) ?
18036                                 $.datepicker._getDate(inst) : null) || new Date();
18037                         var year = date.getFullYear();
18038                         var month = date.getMonth();
18039                         var day = date.getDate();
18040                         var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
18041                         var matches = pattern.exec(offset);
18042                         while (matches) {
18043                                 switch (matches[2] || 'd') {
18044                                         case 'd' : case 'D' :
18045                                                 day += parseInt(matches[1],10); break;
18046                                         case 'w' : case 'W' :
18047                                                 day += parseInt(matches[1],10) * 7; break;
18048                                         case 'm' : case 'M' :
18049                                                 month += parseInt(matches[1],10);
18050                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
18051                                                 break;
18052                                         case 'y': case 'Y' :
18053                                                 year += parseInt(matches[1],10);
18054                                                 day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
18055                                                 break;
18056                                 }
18057                                 matches = pattern.exec(offset);
18058                         }
18059                         return new Date(year, month, day);
18060                 };
18061                 var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
18062                         (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
18063                 newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
18064                 if (newDate) {
18065                         newDate.setHours(0);
18066                         newDate.setMinutes(0);
18067                         newDate.setSeconds(0);
18068                         newDate.setMilliseconds(0);
18069                 }
18070                 return this._daylightSavingAdjust(newDate);
18071         },
18072
18073         /* Handle switch to/from daylight saving.
18074            Hours may be non-zero on daylight saving cut-over:
18075            > 12 when midnight changeover, but then cannot generate
18076            midnight datetime, so jump to 1AM, otherwise reset.
18077            @param  date  (Date) the date to check
18078            @return  (Date) the corrected date */
18079         _daylightSavingAdjust: function(date) {
18080                 if (!date) return null;
18081                 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
18082                 return date;
18083         },
18084
18085         /* Set the date(s) directly. */
18086         _setDate: function(inst, date, noChange) {
18087                 var clear = !date;
18088                 var origMonth = inst.selectedMonth;
18089                 var origYear = inst.selectedYear;
18090                 var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
18091                 inst.selectedDay = inst.currentDay = newDate.getDate();
18092                 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
18093                 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
18094                 if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
18095                         this._notifyChange(inst);
18096                 this._adjustInstDate(inst);
18097                 if (inst.input) {
18098                         inst.input.val(clear ? '' : this._formatDate(inst));
18099                 }
18100         },
18101
18102         /* Retrieve the date(s) directly. */
18103         _getDate: function(inst) {
18104                 var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
18105                         this._daylightSavingAdjust(new Date(
18106                         inst.currentYear, inst.currentMonth, inst.currentDay)));
18107                         return startDate;
18108         },
18109
18110         /* Generate the HTML for the current state of the date picker. */
18111         _generateHTML: function(inst) {
18112                 var today = new Date();
18113                 today = this._daylightSavingAdjust(
18114                         new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
18115                 var isRTL = this._get(inst, 'isRTL');
18116                 var showButtonPanel = this._get(inst, 'showButtonPanel');
18117                 var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
18118                 var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
18119                 var numMonths = this._getNumberOfMonths(inst);
18120                 var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
18121                 var stepMonths = this._get(inst, 'stepMonths');
18122                 var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
18123                 var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
18124                         new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
18125                 var minDate = this._getMinMaxDate(inst, 'min');
18126                 var maxDate = this._getMinMaxDate(inst, 'max');
18127                 var drawMonth = inst.drawMonth - showCurrentAtPos;
18128                 var drawYear = inst.drawYear;
18129                 if (drawMonth < 0) {
18130                         drawMonth += 12;
18131                         drawYear--;
18132                 }
18133                 if (maxDate) {
18134                         var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
18135                                 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
18136                         maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
18137                         while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
18138                                 drawMonth--;
18139                                 if (drawMonth < 0) {
18140                                         drawMonth = 11;
18141                                         drawYear--;
18142                                 }
18143                         }
18144                 }
18145                 inst.drawMonth = drawMonth;
18146                 inst.drawYear = drawYear;
18147                 var prevText = this._get(inst, 'prevText');
18148                 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
18149                         this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
18150                         this._getFormatConfig(inst)));
18151                 var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
18152                         '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
18153                         '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
18154                         ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
18155                         (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
18156                 var nextText = this._get(inst, 'nextText');
18157                 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
18158                         this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
18159                         this._getFormatConfig(inst)));
18160                 var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
18161                         '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
18162                         '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
18163                         ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
18164                         (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
18165                 var currentText = this._get(inst, 'currentText');
18166                 var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
18167                 currentText = (!navigationAsDateFormat ? currentText :
18168                         this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
18169                 var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
18170                         '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
18171                 var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
18172                         (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
18173                         '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
18174                         '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
18175                 var firstDay = parseInt(this._get(inst, 'firstDay'),10);
18176                 firstDay = (isNaN(firstDay) ? 0 : firstDay);
18177                 var showWeek = this._get(inst, 'showWeek');
18178                 var dayNames = this._get(inst, 'dayNames');
18179                 var dayNamesShort = this._get(inst, 'dayNamesShort');
18180                 var dayNamesMin = this._get(inst, 'dayNamesMin');
18181                 var monthNames = this._get(inst, 'monthNames');
18182                 var monthNamesShort = this._get(inst, 'monthNamesShort');
18183                 var beforeShowDay = this._get(inst, 'beforeShowDay');
18184                 var showOtherMonths = this._get(inst, 'showOtherMonths');
18185                 var selectOtherMonths = this._get(inst, 'selectOtherMonths');
18186                 var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
18187                 var defaultDate = this._getDefaultDate(inst);
18188                 var html = '';
18189                 for (var row = 0; row < numMonths[0]; row++) {
18190                         var group = '';
18191                         for (var col = 0; col < numMonths[1]; col++) {
18192                                 var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
18193                                 var cornerClass = ' ui-corner-all';
18194                                 var calender = '';
18195                                 if (isMultiMonth) {
18196                                         calender += '<div class="ui-datepicker-group';
18197                                         if (numMonths[1] > 1)
18198                                                 switch (col) {
18199                                                         case 0: calender += ' ui-datepicker-group-first';
18200                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
18201                                                         case numMonths[1]-1: calender += ' ui-datepicker-group-last';
18202                                                                 cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
18203                                                         default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
18204                                                 }
18205                                         calender += '">';
18206                                 }
18207                                 calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
18208                                         (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
18209                                         (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
18210                                         this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
18211                                         row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
18212                                         '</div><table class="ui-datepicker-calendar"><thead>' +
18213                                         '<tr>';
18214                                 var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
18215                                 for (var dow = 0; dow < 7; dow++) { // days of the week
18216                                         var day = (dow + firstDay) % 7;
18217                                         thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
18218                                                 '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
18219                                 }
18220                                 calender += thead + '</tr></thead><tbody>';
18221                                 var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
18222                                 if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
18223                                         inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
18224                                 var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
18225                                 var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
18226                                 var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
18227                                 for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
18228                                         calender += '<tr>';
18229                                         var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
18230                                                 this._get(inst, 'calculateWeek')(printDate) + '</td>');
18231                                         for (var dow = 0; dow < 7; dow++) { // create date picker days
18232                                                 var daySettings = (beforeShowDay ?
18233                                                         beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
18234                                                 var otherMonth = (printDate.getMonth() != drawMonth);
18235                                                 var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
18236                                                         (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
18237                                                 tbody += '<td class="' +
18238                                                         ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
18239                                                         (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
18240                                                         ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
18241                                                         (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
18242                                                         // or defaultDate is current printedDate and defaultDate is selectedDate
18243                                                         ' ' + this._dayOverClass : '') + // highlight selected day
18244                                                         (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') +  // highlight unselectable days
18245                                                         (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
18246                                                         (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
18247                                                         (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
18248                                                         ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
18249                                                         (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
18250                                                         inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
18251                                                         (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
18252                                                         (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
18253                                                         (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
18254                                                         (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
18255                                                         (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
18256                                                         '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
18257                                                 printDate.setDate(printDate.getDate() + 1);
18258                                                 printDate = this._daylightSavingAdjust(printDate);
18259                                         }
18260                                         calender += tbody + '</tr>';
18261                                 }
18262                                 drawMonth++;
18263                                 if (drawMonth > 11) {
18264                                         drawMonth = 0;
18265                                         drawYear++;
18266                                 }
18267                                 calender += '</tbody></table>' + (isMultiMonth ? '</div>' + 
18268                                                         ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
18269                                 group += calender;
18270                         }
18271                         html += group;
18272                 }
18273                 html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
18274                         '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
18275                 inst._keyEvent = false;
18276                 return html;
18277         },
18278
18279         /* Generate the month and year header. */
18280         _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
18281                         secondary, monthNames, monthNamesShort) {
18282                 var changeMonth = this._get(inst, 'changeMonth');
18283                 var changeYear = this._get(inst, 'changeYear');
18284                 var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
18285                 var html = '<div class="ui-datepicker-title">';
18286                 var monthHtml = '';
18287                 // month selection
18288                 if (secondary || !changeMonth)
18289                         monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
18290                 else {
18291                         var inMinYear = (minDate && minDate.getFullYear() == drawYear);
18292                         var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
18293                         monthHtml += '<select class="ui-datepicker-month" ' +
18294                                 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
18295                                 'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
18296                                 '>';
18297                         for (var month = 0; month < 12; month++) {
18298                                 if ((!inMinYear || month >= minDate.getMonth()) &&
18299                                                 (!inMaxYear || month <= maxDate.getMonth()))
18300                                         monthHtml += '<option value="' + month + '"' +
18301                                                 (month == drawMonth ? ' selected="selected"' : '') +
18302                                                 '>' + monthNamesShort[month] + '</option>';
18303                         }
18304                         monthHtml += '</select>';
18305                 }
18306                 if (!showMonthAfterYear)
18307                         html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
18308                 // year selection
18309                 if ( !inst.yearshtml ) {
18310                         inst.yearshtml = '';
18311                         if (secondary || !changeYear)
18312                                 html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
18313                         else {
18314                                 // determine range of years to display
18315                                 var years = this._get(inst, 'yearRange').split(':');
18316                                 var thisYear = new Date().getFullYear();
18317                                 var determineYear = function(value) {
18318                                         var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
18319                                                 (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
18320                                                 parseInt(value, 10)));
18321                                         return (isNaN(year) ? thisYear : year);
18322                                 };
18323                                 var year = determineYear(years[0]);
18324                                 var endYear = Math.max(year, determineYear(years[1] || ''));
18325                                 year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
18326                                 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
18327                                 inst.yearshtml += '<select class="ui-datepicker-year" ' +
18328                                         'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
18329                                         'onclick="DP_jQuery_' + dpuuid + '.datepicker._clickMonthYear(\'#' + inst.id + '\');"' +
18330                                         '>';
18331                                 for (; year <= endYear; year++) {
18332                                         inst.yearshtml += '<option value="' + year + '"' +
18333                                                 (year == drawYear ? ' selected="selected"' : '') +
18334                                                 '>' + year + '</option>';
18335                                 }
18336                                 inst.yearshtml += '</select>';
18337                                 //when showing there is no need for later update
18338                                 if( ! $.browser.mozilla ){
18339                                         html += inst.yearshtml;
18340                                         inst.yearshtml = null;
18341                                 } else {
18342                                         // will be replaced later with inst.yearshtml
18343                                         html += '<select class="ui-datepicker-year"><option value="' + drawYear + '" selected="selected">' + drawYear + '</option></select>';
18344                                 }
18345                         }
18346                 }
18347                 html += this._get(inst, 'yearSuffix');
18348                 if (showMonthAfterYear)
18349                         html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
18350                 html += '</div>'; // Close datepicker_header
18351                 return html;
18352         },
18353
18354         /* Adjust one of the date sub-fields. */
18355         _adjustInstDate: function(inst, offset, period) {
18356                 var year = inst.drawYear + (period == 'Y' ? offset : 0);
18357                 var month = inst.drawMonth + (period == 'M' ? offset : 0);
18358                 var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
18359                         (period == 'D' ? offset : 0);
18360                 var date = this._restrictMinMax(inst,
18361                         this._daylightSavingAdjust(new Date(year, month, day)));
18362                 inst.selectedDay = date.getDate();
18363                 inst.drawMonth = inst.selectedMonth = date.getMonth();
18364                 inst.drawYear = inst.selectedYear = date.getFullYear();
18365                 if (period == 'M' || period == 'Y')
18366                         this._notifyChange(inst);
18367         },
18368
18369         /* Ensure a date is within any min/max bounds. */
18370         _restrictMinMax: function(inst, date) {
18371                 var minDate = this._getMinMaxDate(inst, 'min');
18372                 var maxDate = this._getMinMaxDate(inst, 'max');
18373                 var newDate = (minDate && date < minDate ? minDate : date);
18374                 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
18375                 return newDate;
18376         },
18377
18378         /* Notify change of month/year. */
18379         _notifyChange: function(inst) {
18380                 var onChange = this._get(inst, 'onChangeMonthYear');
18381                 if (onChange)
18382                         onChange.apply((inst.input ? inst.input[0] : null),
18383                                 [inst.selectedYear, inst.selectedMonth + 1, inst]);
18384         },
18385
18386         /* Determine the number of months to show. */
18387         _getNumberOfMonths: function(inst) {
18388                 var numMonths = this._get(inst, 'numberOfMonths');
18389                 return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
18390         },
18391
18392         /* Determine the current maximum date - ensure no time components are set. */
18393         _getMinMaxDate: function(inst, minMax) {
18394                 return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
18395         },
18396
18397         /* Find the number of days in a given month. */
18398         _getDaysInMonth: function(year, month) {
18399                 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
18400         },
18401
18402         /* Find the day of the week of the first of a month. */
18403         _getFirstDayOfMonth: function(year, month) {
18404                 return new Date(year, month, 1).getDay();
18405         },
18406
18407         /* Determines if we should allow a "next/prev" month display change. */
18408         _canAdjustMonth: function(inst, offset, curYear, curMonth) {
18409                 var numMonths = this._getNumberOfMonths(inst);
18410                 var date = this._daylightSavingAdjust(new Date(curYear,
18411                         curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
18412                 if (offset < 0)
18413                         date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
18414                 return this._isInRange(inst, date);
18415         },
18416
18417         /* Is the given date in the accepted range? */
18418         _isInRange: function(inst, date) {
18419                 var minDate = this._getMinMaxDate(inst, 'min');
18420                 var maxDate = this._getMinMaxDate(inst, 'max');
18421                 return ((!minDate || date.getTime() >= minDate.getTime()) &&
18422                         (!maxDate || date.getTime() <= maxDate.getTime()));
18423         },
18424
18425         /* Provide the configuration settings for formatting/parsing. */
18426         _getFormatConfig: function(inst) {
18427                 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
18428                 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
18429                         new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
18430                 return {shortYearCutoff: shortYearCutoff,
18431                         dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
18432                         monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
18433         },
18434
18435         /* Format the given date for display. */
18436         _formatDate: function(inst, day, month, year) {
18437                 if (!day) {
18438                         inst.currentDay = inst.selectedDay;
18439                         inst.currentMonth = inst.selectedMonth;
18440                         inst.currentYear = inst.selectedYear;
18441                 }
18442                 var date = (day ? (typeof day == 'object' ? day :
18443                         this._daylightSavingAdjust(new Date(year, month, day))) :
18444                         this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
18445                 return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
18446         }
18447 });
18448
18449 /* jQuery extend now ignores nulls! */
18450 function extendRemove(target, props) {
18451         $.extend(target, props);
18452         for (var name in props)
18453                 if (props[name] == null || props[name] == undefined)
18454                         target[name] = props[name];
18455         return target;
18456 };
18457
18458 /* Determine whether an object is an array. */
18459 function isArray(a) {
18460         return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
18461                 (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
18462 };
18463
18464 /* Invoke the datepicker functionality.
18465    @param  options  string - a command, optionally followed by additional parameters or
18466                     Object - settings for attaching new datepicker functionality
18467    @return  jQuery object */
18468 $.fn.datepicker = function(options){
18469         
18470         /* Verify an empty collection wasn't passed - Fixes #6976 */
18471         if ( !this.length ) {
18472                 return this;
18473         }
18474         
18475         /* Initialise the date picker. */
18476         if (!$.datepicker.initialized) {
18477                 $(document).mousedown($.datepicker._checkExternalClick).
18478                         find('body').append($.datepicker.dpDiv);
18479                 $.datepicker.initialized = true;
18480         }
18481
18482         var otherArgs = Array.prototype.slice.call(arguments, 1);
18483         if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
18484                 return $.datepicker['_' + options + 'Datepicker'].
18485                         apply($.datepicker, [this[0]].concat(otherArgs));
18486         if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
18487                 return $.datepicker['_' + options + 'Datepicker'].
18488                         apply($.datepicker, [this[0]].concat(otherArgs));
18489         return this.each(function() {
18490                 typeof options == 'string' ?
18491                         $.datepicker['_' + options + 'Datepicker'].
18492                                 apply($.datepicker, [this].concat(otherArgs)) :
18493                         $.datepicker._attachDatepicker(this, options);
18494         });
18495 };
18496
18497 $.datepicker = new Datepicker(); // singleton instance
18498 $.datepicker.initialized = false;
18499 $.datepicker.uuid = new Date().getTime();
18500 $.datepicker.version = "1.8.12";
18501
18502 // Workaround for #4055
18503 // Add another global to avoid noConflict issues with inline event handlers
18504 window['DP_jQuery_' + dpuuid] = $;
18505
18506 })(jQuery);
18507 /*
18508  * jQuery UI Dialog 1.8.12
18509  *
18510  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
18511  * Dual licensed under the MIT or GPL Version 2 licenses.
18512  * http://jquery.org/license
18513  *
18514  * http://docs.jquery.com/UI/Dialog
18515  *
18516  * Depends:
18517  *      jquery.ui.core.js
18518  *      jquery.ui.widget.js
18519  *  jquery.ui.button.js
18520  *      jquery.ui.draggable.js
18521  *      jquery.ui.mouse.js
18522  *      jquery.ui.position.js
18523  *      jquery.ui.resizable.js
18524  */
18525 (function( $, undefined ) {
18526
18527 var uiDialogClasses =
18528                 'ui-dialog ' +
18529                 'ui-widget ' +
18530                 'ui-widget-content ' +
18531                 'ui-corner-all ',
18532         sizeRelatedOptions = {
18533                 buttons: true,
18534                 height: true,
18535                 maxHeight: true,
18536                 maxWidth: true,
18537                 minHeight: true,
18538                 minWidth: true,
18539                 width: true
18540         },
18541         resizableRelatedOptions = {
18542                 maxHeight: true,
18543                 maxWidth: true,
18544                 minHeight: true,
18545                 minWidth: true
18546         },
18547         // support for jQuery 1.3.2 - handle common attrFn methods for dialog
18548         attrFn = $.attrFn || {
18549                 val: true,
18550                 css: true,
18551                 html: true,
18552                 text: true,
18553                 data: true,
18554                 width: true,
18555                 height: true,
18556                 offset: true,
18557                 click: true
18558         };
18559
18560 $.widget("ui.dialog", {
18561         options: {
18562                 autoOpen: true,
18563                 buttons: {},
18564                 closeOnEscape: true,
18565                 closeText: 'close',
18566                 dialogClass: '',
18567                 draggable: true,
18568                 hide: null,
18569                 height: 'auto',
18570                 maxHeight: false,
18571                 maxWidth: false,
18572                 minHeight: 150,
18573                 minWidth: 150,
18574                 modal: false,
18575                 position: {
18576                         my: 'center',
18577                         at: 'center',
18578                         collision: 'fit',
18579                         // ensure that the titlebar is never outside the document
18580                         using: function(pos) {
18581                                 var topOffset = $(this).css(pos).offset().top;
18582                                 if (topOffset < 0) {
18583                                         $(this).css('top', pos.top - topOffset);
18584                                 }
18585                         }
18586                 },
18587                 resizable: true,
18588                 show: null,
18589                 stack: true,
18590                 title: '',
18591                 width: 300,
18592                 zIndex: 1000
18593         },
18594
18595         _create: function() {
18596                 this.originalTitle = this.element.attr('title');
18597                 // #5742 - .attr() might return a DOMElement
18598                 if ( typeof this.originalTitle !== "string" ) {
18599                         this.originalTitle = "";
18600                 }
18601
18602                 this.options.title = this.options.title || this.originalTitle;
18603                 var self = this,
18604                         options = self.options,
18605
18606                         title = options.title || '&#160;',
18607                         titleId = $.ui.dialog.getTitleId(self.element),
18608
18609                         uiDialog = (self.uiDialog = $('<div></div>'))
18610                                 .appendTo(document.body)
18611                                 .hide()
18612                                 .addClass(uiDialogClasses + options.dialogClass)
18613                                 .css({
18614                                         zIndex: options.zIndex
18615                                 })
18616                                 // setting tabIndex makes the div focusable
18617                                 // setting outline to 0 prevents a border on focus in Mozilla
18618                                 .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
18619                                         if (options.closeOnEscape && event.keyCode &&
18620                                                 event.keyCode === $.ui.keyCode.ESCAPE) {
18621                                                 
18622                                                 self.close(event);
18623                                                 event.preventDefault();
18624                                         }
18625                                 })
18626                                 .attr({
18627                                         role: 'dialog',
18628                                         'aria-labelledby': titleId
18629                                 })
18630                                 .mousedown(function(event) {
18631                                         self.moveToTop(false, event);
18632                                 }),
18633
18634                         uiDialogContent = self.element
18635                                 .show()
18636                                 .removeAttr('title')
18637                                 .addClass(
18638                                         'ui-dialog-content ' +
18639                                         'ui-widget-content')
18640                                 .appendTo(uiDialog),
18641
18642                         uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
18643                                 .addClass(
18644                                         'ui-dialog-titlebar ' +
18645                                         'ui-widget-header ' +
18646                                         'ui-corner-top ' +
18647                                         'ui-helper-clearfix'
18648                                 )
18649                                 .prependTo(uiDialog),
18650
18651                         uiDialogTitlebarClose = $('<a href="#"></a>')
18652                                 .addClass(
18653                                         'ui-dialog-titlebar-close ' +
18654                                         'ui-corner-all'
18655                                 )
18656                                 .attr('role', 'button')
18657                                 .hover(
18658                                         function() {
18659                                                 uiDialogTitlebarClose.addClass('ui-state-hover');
18660                                         },
18661                                         function() {
18662                                                 uiDialogTitlebarClose.removeClass('ui-state-hover');
18663                                         }
18664                                 )
18665                                 .focus(function() {
18666                                         uiDialogTitlebarClose.addClass('ui-state-focus');
18667                                 })
18668                                 .blur(function() {
18669                                         uiDialogTitlebarClose.removeClass('ui-state-focus');
18670                                 })
18671                                 .click(function(event) {
18672                                         self.close(event);
18673                                         return false;
18674                                 })
18675                                 .appendTo(uiDialogTitlebar),
18676
18677                         uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
18678                                 .addClass(
18679                                         'ui-icon ' +
18680                                         'ui-icon-closethick'
18681                                 )
18682                                 .text(options.closeText)
18683                                 .appendTo(uiDialogTitlebarClose),
18684
18685                         uiDialogTitle = $('<span></span>')
18686                                 .addClass('ui-dialog-title')
18687                                 .attr('id', titleId)
18688                                 .html(title)
18689                                 .prependTo(uiDialogTitlebar);
18690
18691                 //handling of deprecated beforeclose (vs beforeClose) option
18692                 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
18693                 //TODO: remove in 1.9pre
18694                 if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
18695                         options.beforeClose = options.beforeclose;
18696                 }
18697
18698                 uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
18699
18700                 if (options.draggable && $.fn.draggable) {
18701                         self._makeDraggable();
18702                 }
18703                 if (options.resizable && $.fn.resizable) {
18704                         self._makeResizable();
18705                 }
18706
18707                 self._createButtons(options.buttons);
18708                 self._isOpen = false;
18709
18710                 if ($.fn.bgiframe) {
18711                         uiDialog.bgiframe();
18712                 }
18713         },
18714
18715         _init: function() {
18716                 if ( this.options.autoOpen ) {
18717                         this.open();
18718                 }
18719         },
18720
18721         destroy: function() {
18722                 var self = this;
18723                 
18724                 if (self.overlay) {
18725                         self.overlay.destroy();
18726                 }
18727                 self.uiDialog.hide();
18728                 self.element
18729                         .unbind('.dialog')
18730                         .removeData('dialog')
18731                         .removeClass('ui-dialog-content ui-widget-content')
18732                         .hide().appendTo('body');
18733                 self.uiDialog.remove();
18734
18735                 if (self.originalTitle) {
18736                         self.element.attr('title', self.originalTitle);
18737                 }
18738
18739                 return self;
18740         },
18741
18742         widget: function() {
18743                 return this.uiDialog;
18744         },
18745
18746         close: function(event) {
18747                 var self = this,
18748                         maxZ, thisZ;
18749                 
18750                 if (false === self._trigger('beforeClose', event)) {
18751                         return;
18752                 }
18753
18754                 if (self.overlay) {
18755                         self.overlay.destroy();
18756                 }
18757                 self.uiDialog.unbind('keypress.ui-dialog');
18758
18759                 self._isOpen = false;
18760
18761                 if (self.options.hide) {
18762                         self.uiDialog.hide(self.options.hide, function() {
18763                                 self._trigger('close', event);
18764                         });
18765                 } else {
18766                         self.uiDialog.hide();
18767                         self._trigger('close', event);
18768                 }
18769
18770                 $.ui.dialog.overlay.resize();
18771
18772                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
18773                 if (self.options.modal) {
18774                         maxZ = 0;
18775                         $('.ui-dialog').each(function() {
18776                                 if (this !== self.uiDialog[0]) {
18777                                         thisZ = $(this).css('z-index');
18778                                         if(!isNaN(thisZ)) {
18779                                                 maxZ = Math.max(maxZ, thisZ);
18780                                         }
18781                                 }
18782                         });
18783                         $.ui.dialog.maxZ = maxZ;
18784                 }
18785
18786                 return self;
18787         },
18788
18789         isOpen: function() {
18790                 return this._isOpen;
18791         },
18792
18793         // the force parameter allows us to move modal dialogs to their correct
18794         // position on open
18795         moveToTop: function(force, event) {
18796                 var self = this,
18797                         options = self.options,
18798                         saveScroll;
18799
18800                 if ((options.modal && !force) ||
18801                         (!options.stack && !options.modal)) {
18802                         return self._trigger('focus', event);
18803                 }
18804
18805                 if (options.zIndex > $.ui.dialog.maxZ) {
18806                         $.ui.dialog.maxZ = options.zIndex;
18807                 }
18808                 if (self.overlay) {
18809                         $.ui.dialog.maxZ += 1;
18810                         self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
18811                 }
18812
18813                 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
18814                 //  http://ui.jquery.com/bugs/ticket/3193
18815                 saveScroll = { scrollTop: self.element.attr('scrollTop'), scrollLeft: self.element.attr('scrollLeft') };
18816                 $.ui.dialog.maxZ += 1;
18817                 self.uiDialog.css('z-index', $.ui.dialog.maxZ);
18818                 self.element.attr(saveScroll);
18819                 self._trigger('focus', event);
18820
18821                 return self;
18822         },
18823
18824         open: function() {
18825                 if (this._isOpen) { return; }
18826
18827                 var self = this,
18828                         options = self.options,
18829                         uiDialog = self.uiDialog;
18830
18831                 self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
18832                 self._size();
18833                 self._position(options.position);
18834                 uiDialog.show(options.show);
18835                 self.moveToTop(true);
18836
18837                 // prevent tabbing out of modal dialogs
18838                 if (options.modal) {
18839                         uiDialog.bind('keypress.ui-dialog', function(event) {
18840                                 if (event.keyCode !== $.ui.keyCode.TAB) {
18841                                         return;
18842                                 }
18843
18844                                 var tabbables = $(':tabbable', this),
18845                                         first = tabbables.filter(':first'),
18846                                         last  = tabbables.filter(':last');
18847
18848                                 if (event.target === last[0] && !event.shiftKey) {
18849                                         first.focus(1);
18850                                         return false;
18851                                 } else if (event.target === first[0] && event.shiftKey) {
18852                                         last.focus(1);
18853                                         return false;
18854                                 }
18855                         });
18856                 }
18857
18858                 // set focus to the first tabbable element in the content area or the first button
18859                 // if there are no tabbable elements, set focus on the dialog itself
18860                 $(self.element.find(':tabbable').get().concat(
18861                         uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
18862                                 uiDialog.get()))).eq(0).focus();
18863
18864                 self._isOpen = true;
18865                 self._trigger('open');
18866
18867                 return self;
18868         },
18869
18870         _createButtons: function(buttons) {
18871                 var self = this,
18872                         hasButtons = false,
18873                         uiDialogButtonPane = $('<div></div>')
18874                                 .addClass(
18875                                         'ui-dialog-buttonpane ' +
18876                                         'ui-widget-content ' +
18877                                         'ui-helper-clearfix'
18878                                 ),
18879                         uiButtonSet = $( "<div></div>" )
18880                                 .addClass( "ui-dialog-buttonset" )
18881                                 .appendTo( uiDialogButtonPane );
18882
18883                 // if we already have a button pane, remove it
18884                 self.uiDialog.find('.ui-dialog-buttonpane').remove();
18885
18886                 if (typeof buttons === 'object' && buttons !== null) {
18887                         $.each(buttons, function() {
18888                                 return !(hasButtons = true);
18889                         });
18890                 }
18891                 if (hasButtons) {
18892                         $.each(buttons, function(name, props) {
18893                                 props = $.isFunction( props ) ?
18894                                         { click: props, text: name } :
18895                                         props;
18896                                 var button = $('<button type="button"></button>')
18897                                         .click(function() {
18898                                                 props.click.apply(self.element[0], arguments);
18899                                         })
18900                                         .appendTo(uiButtonSet);
18901                                 // can't use .attr( props, true ) with jQuery 1.3.2.
18902                                 $.each( props, function( key, value ) {
18903                                         if ( key === "click" ) {
18904                                                 return;
18905                                         }
18906                                         if ( key in attrFn ) {
18907                                                 button[ key ]( value );
18908                                         } else {
18909                                                 button.attr( key, value );
18910                                         }
18911                                 });
18912                                 if ($.fn.button) {
18913                                         button.button();
18914                                 }
18915                         });
18916                         uiDialogButtonPane.appendTo(self.uiDialog);
18917                 }
18918         },
18919
18920         _makeDraggable: function() {
18921                 var self = this,
18922                         options = self.options,
18923                         doc = $(document),
18924                         heightBeforeDrag;
18925
18926                 function filteredUi(ui) {
18927                         return {
18928                                 position: ui.position,
18929                                 offset: ui.offset
18930                         };
18931                 }
18932
18933                 self.uiDialog.draggable({
18934                         cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
18935                         handle: '.ui-dialog-titlebar',
18936                         containment: 'document',
18937                         start: function(event, ui) {
18938                                 heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
18939                                 $(this).height($(this).height()).addClass("ui-dialog-dragging");
18940                                 self._trigger('dragStart', event, filteredUi(ui));
18941                         },
18942                         drag: function(event, ui) {
18943                                 self._trigger('drag', event, filteredUi(ui));
18944                         },
18945                         stop: function(event, ui) {
18946                                 options.position = [ui.position.left - doc.scrollLeft(),
18947                                         ui.position.top - doc.scrollTop()];
18948                                 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
18949                                 self._trigger('dragStop', event, filteredUi(ui));
18950                                 $.ui.dialog.overlay.resize();
18951                         }
18952                 });
18953         },
18954
18955         _makeResizable: function(handles) {
18956                 handles = (handles === undefined ? this.options.resizable : handles);
18957                 var self = this,
18958                         options = self.options,
18959                         // .ui-resizable has position: relative defined in the stylesheet
18960                         // but dialogs have to use absolute or fixed positioning
18961                         position = self.uiDialog.css('position'),
18962                         resizeHandles = (typeof handles === 'string' ?
18963                                 handles :
18964                                 'n,e,s,w,se,sw,ne,nw'
18965                         );
18966
18967                 function filteredUi(ui) {
18968                         return {
18969                                 originalPosition: ui.originalPosition,
18970                                 originalSize: ui.originalSize,
18971                                 position: ui.position,
18972                                 size: ui.size
18973                         };
18974                 }
18975
18976                 self.uiDialog.resizable({
18977                         cancel: '.ui-dialog-content',
18978                         containment: 'document',
18979                         alsoResize: self.element,
18980                         maxWidth: options.maxWidth,
18981                         maxHeight: options.maxHeight,
18982                         minWidth: options.minWidth,
18983                         minHeight: self._minHeight(),
18984                         handles: resizeHandles,
18985                         start: function(event, ui) {
18986                                 $(this).addClass("ui-dialog-resizing");
18987                                 self._trigger('resizeStart', event, filteredUi(ui));
18988                         },
18989                         resize: function(event, ui) {
18990                                 self._trigger('resize', event, filteredUi(ui));
18991                         },
18992                         stop: function(event, ui) {
18993                                 $(this).removeClass("ui-dialog-resizing");
18994                                 options.height = $(this).height();
18995                                 options.width = $(this).width();
18996                                 self._trigger('resizeStop', event, filteredUi(ui));
18997                                 $.ui.dialog.overlay.resize();
18998                         }
18999                 })
19000                 .css('position', position)
19001                 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
19002         },
19003
19004         _minHeight: function() {
19005                 var options = this.options;
19006
19007                 if (options.height === 'auto') {
19008                         return options.minHeight;
19009                 } else {
19010                         return Math.min(options.minHeight, options.height);
19011                 }
19012         },
19013
19014         _position: function(position) {
19015                 var myAt = [],
19016                         offset = [0, 0],
19017                         isVisible;
19018
19019                 if (position) {
19020                         // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
19021         //              if (typeof position == 'string' || $.isArray(position)) {
19022         //                      myAt = $.isArray(position) ? position : position.split(' ');
19023
19024                         if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
19025                                 myAt = position.split ? position.split(' ') : [position[0], position[1]];
19026                                 if (myAt.length === 1) {
19027                                         myAt[1] = myAt[0];
19028                                 }
19029
19030                                 $.each(['left', 'top'], function(i, offsetPosition) {
19031                                         if (+myAt[i] === myAt[i]) {
19032                                                 offset[i] = myAt[i];
19033                                                 myAt[i] = offsetPosition;
19034                                         }
19035                                 });
19036
19037                                 position = {
19038                                         my: myAt.join(" "),
19039                                         at: myAt.join(" "),
19040                                         offset: offset.join(" ")
19041                                 };
19042                         } 
19043
19044                         position = $.extend({}, $.ui.dialog.prototype.options.position, position);
19045                 } else {
19046                         position = $.ui.dialog.prototype.options.position;
19047                 }
19048
19049                 // need to show the dialog to get the actual offset in the position plugin
19050                 isVisible = this.uiDialog.is(':visible');
19051                 if (!isVisible) {
19052                         this.uiDialog.show();
19053                 }
19054                 this.uiDialog
19055                         // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
19056                         .css({ top: 0, left: 0 })
19057                         .position($.extend({ of: window }, position));
19058                 if (!isVisible) {
19059                         this.uiDialog.hide();
19060                 }
19061         },
19062
19063         _setOptions: function( options ) {
19064                 var self = this,
19065                         resizableOptions = {},
19066                         resize = false;
19067
19068                 $.each( options, function( key, value ) {
19069                         self._setOption( key, value );
19070                         
19071                         if ( key in sizeRelatedOptions ) {
19072                                 resize = true;
19073                         }
19074                         if ( key in resizableRelatedOptions ) {
19075                                 resizableOptions[ key ] = value;
19076                         }
19077                 });
19078
19079                 if ( resize ) {
19080                         this._size();
19081                 }
19082                 if ( this.uiDialog.is( ":data(resizable)" ) ) {
19083                         this.uiDialog.resizable( "option", resizableOptions );
19084                 }
19085         },
19086
19087         _setOption: function(key, value){
19088                 var self = this,
19089                         uiDialog = self.uiDialog;
19090
19091                 switch (key) {
19092                         //handling of deprecated beforeclose (vs beforeClose) option
19093                         //Ticket #4669 http://dev.jqueryui.com/ticket/4669
19094                         //TODO: remove in 1.9pre
19095                         case "beforeclose":
19096                                 key = "beforeClose";
19097                                 break;
19098                         case "buttons":
19099                                 self._createButtons(value);
19100                                 break;
19101                         case "closeText":
19102                                 // ensure that we always pass a string
19103                                 self.uiDialogTitlebarCloseText.text("" + value);
19104                                 break;
19105                         case "dialogClass":
19106                                 uiDialog
19107                                         .removeClass(self.options.dialogClass)
19108                                         .addClass(uiDialogClasses + value);
19109                                 break;
19110                         case "disabled":
19111                                 if (value) {
19112                                         uiDialog.addClass('ui-dialog-disabled');
19113                                 } else {
19114                                         uiDialog.removeClass('ui-dialog-disabled');
19115                                 }
19116                                 break;
19117                         case "draggable":
19118                                 var isDraggable = uiDialog.is( ":data(draggable)" );
19119                                 if ( isDraggable && !value ) {
19120                                         uiDialog.draggable( "destroy" );
19121                                 }
19122                                 
19123                                 if ( !isDraggable && value ) {
19124                                         self._makeDraggable();
19125                                 }
19126                                 break;
19127                         case "position":
19128                                 self._position(value);
19129                                 break;
19130                         case "resizable":
19131                                 // currently resizable, becoming non-resizable
19132                                 var isResizable = uiDialog.is( ":data(resizable)" );
19133                                 if (isResizable && !value) {
19134                                         uiDialog.resizable('destroy');
19135                                 }
19136
19137                                 // currently resizable, changing handles
19138                                 if (isResizable && typeof value === 'string') {
19139                                         uiDialog.resizable('option', 'handles', value);
19140                                 }
19141
19142                                 // currently non-resizable, becoming resizable
19143                                 if (!isResizable && value !== false) {
19144                                         self._makeResizable(value);
19145                                 }
19146                                 break;
19147                         case "title":
19148                                 // convert whatever was passed in o a string, for html() to not throw up
19149                                 $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
19150                                 break;
19151                 }
19152
19153                 $.Widget.prototype._setOption.apply(self, arguments);
19154         },
19155
19156         _size: function() {
19157                 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
19158                  * divs will both have width and height set, so we need to reset them
19159                  */
19160                 var options = this.options,
19161                         nonContentHeight,
19162                         minContentHeight,
19163                         isVisible = this.uiDialog.is( ":visible" );
19164
19165                 // reset content sizing
19166                 this.element.show().css({
19167                         width: 'auto',
19168                         minHeight: 0,
19169                         height: 0
19170                 });
19171
19172                 if (options.minWidth > options.width) {
19173                         options.width = options.minWidth;
19174                 }
19175
19176                 // reset wrapper sizing
19177                 // determine the height of all the non-content elements
19178                 nonContentHeight = this.uiDialog.css({
19179                                 height: 'auto',
19180                                 width: options.width
19181                         })
19182                         .height();
19183                 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
19184                 
19185                 if ( options.height === "auto" ) {
19186                         // only needed for IE6 support
19187                         if ( $.support.minHeight ) {
19188                                 this.element.css({
19189                                         minHeight: minContentHeight,
19190                                         height: "auto"
19191                                 });
19192                         } else {
19193                                 this.uiDialog.show();
19194                                 var autoHeight = this.element.css( "height", "auto" ).height();
19195                                 if ( !isVisible ) {
19196                                         this.uiDialog.hide();
19197                                 }
19198                                 this.element.height( Math.max( autoHeight, minContentHeight ) );
19199                         }
19200                 } else {
19201                         this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
19202                 }
19203
19204                 if (this.uiDialog.is(':data(resizable)')) {
19205                         this.uiDialog.resizable('option', 'minHeight', this._minHeight());
19206                 }
19207         }
19208 });
19209
19210 $.extend($.ui.dialog, {
19211         version: "1.8.12",
19212
19213         uuid: 0,
19214         maxZ: 0,
19215
19216         getTitleId: function($el) {
19217                 var id = $el.attr('id');
19218                 if (!id) {
19219                         this.uuid += 1;
19220                         id = this.uuid;
19221                 }
19222                 return 'ui-dialog-title-' + id;
19223         },
19224
19225         overlay: function(dialog) {
19226                 this.$el = $.ui.dialog.overlay.create(dialog);
19227         }
19228 });
19229
19230 $.extend($.ui.dialog.overlay, {
19231         instances: [],
19232         // reuse old instances due to IE memory leak with alpha transparency (see #5185)
19233         oldInstances: [],
19234         maxZ: 0,
19235         events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
19236                 function(event) { return event + '.dialog-overlay'; }).join(' '),
19237         create: function(dialog) {
19238                 if (this.instances.length === 0) {
19239                         // prevent use of anchors and inputs
19240                         // we use a setTimeout in case the overlay is created from an
19241                         // event that we're going to be cancelling (see #2804)
19242                         setTimeout(function() {
19243                                 // handle $(el).dialog().dialog('close') (see #4065)
19244                                 if ($.ui.dialog.overlay.instances.length) {
19245                                         $(document).bind($.ui.dialog.overlay.events, function(event) {
19246                                                 // stop events if the z-index of the target is < the z-index of the overlay
19247                                                 // we cannot return true when we don't want to cancel the event (#3523)
19248                                                 if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
19249                                                         return false;
19250                                                 }
19251                                         });
19252                                 }
19253                         }, 1);
19254
19255                         // allow closing by pressing the escape key
19256                         $(document).bind('keydown.dialog-overlay', function(event) {
19257                                 if (dialog.options.closeOnEscape && event.keyCode &&
19258                                         event.keyCode === $.ui.keyCode.ESCAPE) {
19259                                         
19260                                         dialog.close(event);
19261                                         event.preventDefault();
19262                                 }
19263                         });
19264
19265                         // handle window resize
19266                         $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
19267                 }
19268
19269                 var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
19270                         .appendTo(document.body)
19271                         .css({
19272                                 width: this.width(),
19273                                 height: this.height()
19274                         });
19275
19276                 if ($.fn.bgiframe) {
19277                         $el.bgiframe();
19278                 }
19279
19280                 this.instances.push($el);
19281                 return $el;
19282         },
19283
19284         destroy: function($el) {
19285                 var indexOf = $.inArray($el, this.instances);
19286                 if (indexOf != -1){
19287                         this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
19288                 }
19289
19290                 if (this.instances.length === 0) {
19291                         $([document, window]).unbind('.dialog-overlay');
19292                 }
19293
19294                 $el.remove();
19295                 
19296                 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
19297                 var maxZ = 0;
19298                 $.each(this.instances, function() {
19299                         maxZ = Math.max(maxZ, this.css('z-index'));
19300                 });
19301                 this.maxZ = maxZ;
19302         },
19303
19304         height: function() {
19305                 var scrollHeight,
19306                         offsetHeight;
19307                 // handle IE 6
19308                 if ($.browser.msie && $.browser.version < 7) {
19309                         scrollHeight = Math.max(
19310                                 document.documentElement.scrollHeight,
19311                                 document.body.scrollHeight
19312                         );
19313                         offsetHeight = Math.max(
19314                                 document.documentElement.offsetHeight,
19315                                 document.body.offsetHeight
19316                         );
19317
19318                         if (scrollHeight < offsetHeight) {
19319                                 return $(window).height() + 'px';
19320                         } else {
19321                                 return scrollHeight + 'px';
19322                         }
19323                 // handle "good" browsers
19324                 } else {
19325                         return $(document).height() + 'px';
19326                 }
19327         },
19328
19329         width: function() {
19330                 var scrollWidth,
19331                         offsetWidth;
19332                 // handle IE 6
19333                 if ($.browser.msie && $.browser.version < 7) {
19334                         scrollWidth = Math.max(
19335                                 document.documentElement.scrollWidth,
19336                                 document.body.scrollWidth
19337                         );
19338                         offsetWidth = Math.max(
19339                                 document.documentElement.offsetWidth,
19340                                 document.body.offsetWidth
19341                         );
19342
19343                         if (scrollWidth < offsetWidth) {
19344                                 return $(window).width() + 'px';
19345                         } else {
19346                                 return scrollWidth + 'px';
19347                         }
19348                 // handle "good" browsers
19349                 } else {
19350                         return $(document).width() + 'px';
19351                 }
19352         },
19353
19354         resize: function() {
19355                 /* If the dialog is draggable and the user drags it past the
19356                  * right edge of the window, the document becomes wider so we
19357                  * need to stretch the overlay. If the user then drags the
19358                  * dialog back to the left, the document will become narrower,
19359                  * so we need to shrink the overlay to the appropriate size.
19360                  * This is handled by shrinking the overlay before setting it
19361                  * to the full document size.
19362                  */
19363                 var $overlays = $([]);
19364                 $.each($.ui.dialog.overlay.instances, function() {
19365                         $overlays = $overlays.add(this);
19366                 });
19367
19368                 $overlays.css({
19369                         width: 0,
19370                         height: 0
19371                 }).css({
19372                         width: $.ui.dialog.overlay.width(),
19373                         height: $.ui.dialog.overlay.height()
19374                 });
19375         }
19376 });
19377
19378 $.extend($.ui.dialog.overlay.prototype, {
19379         destroy: function() {
19380                 $.ui.dialog.overlay.destroy(this.$el);
19381         }
19382 });
19383
19384 }(jQuery));
19385 /*
19386  * jQuery UI Position 1.8.12
19387  *
19388  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
19389  * Dual licensed under the MIT or GPL Version 2 licenses.
19390  * http://jquery.org/license
19391  *
19392  * http://docs.jquery.com/UI/Position
19393  */
19394 (function( $, undefined ) {
19395
19396 $.ui = $.ui || {};
19397
19398 var horizontalPositions = /left|center|right/,
19399         verticalPositions = /top|center|bottom/,
19400         center = "center",
19401         _position = $.fn.position,
19402         _offset = $.fn.offset;
19403
19404 $.fn.position = function( options ) {
19405         if ( !options || !options.of ) {
19406                 return _position.apply( this, arguments );
19407         }
19408
19409         // make a copy, we don't want to modify arguments
19410         options = $.extend( {}, options );
19411
19412         var target = $( options.of ),
19413                 targetElem = target[0],
19414                 collision = ( options.collision || "flip" ).split( " " ),
19415                 offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
19416                 targetWidth,
19417                 targetHeight,
19418                 basePosition;
19419
19420         if ( targetElem.nodeType === 9 ) {
19421                 targetWidth = target.width();
19422                 targetHeight = target.height();
19423                 basePosition = { top: 0, left: 0 };
19424         // TODO: use $.isWindow() in 1.9
19425         } else if ( targetElem.setTimeout ) {
19426                 targetWidth = target.width();
19427                 targetHeight = target.height();
19428                 basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
19429         } else if ( targetElem.preventDefault ) {
19430                 // force left top to allow flipping
19431                 options.at = "left top";
19432                 targetWidth = targetHeight = 0;
19433                 basePosition = { top: options.of.pageY, left: options.of.pageX };
19434         } else {
19435                 targetWidth = target.outerWidth();
19436                 targetHeight = target.outerHeight();
19437                 basePosition = target.offset();
19438         }
19439
19440         // force my and at to have valid horizontal and veritcal positions
19441         // if a value is missing or invalid, it will be converted to center 
19442         $.each( [ "my", "at" ], function() {
19443                 var pos = ( options[this] || "" ).split( " " );
19444                 if ( pos.length === 1) {
19445                         pos = horizontalPositions.test( pos[0] ) ?
19446                                 pos.concat( [center] ) :
19447                                 verticalPositions.test( pos[0] ) ?
19448                                         [ center ].concat( pos ) :
19449                                         [ center, center ];
19450                 }
19451                 pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
19452                 pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
19453                 options[ this ] = pos;
19454         });
19455
19456         // normalize collision option
19457         if ( collision.length === 1 ) {
19458                 collision[ 1 ] = collision[ 0 ];
19459         }
19460
19461         // normalize offset option
19462         offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
19463         if ( offset.length === 1 ) {
19464                 offset[ 1 ] = offset[ 0 ];
19465         }
19466         offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
19467
19468         if ( options.at[0] === "right" ) {
19469                 basePosition.left += targetWidth;
19470         } else if ( options.at[0] === center ) {
19471                 basePosition.left += targetWidth / 2;
19472         }
19473
19474         if ( options.at[1] === "bottom" ) {
19475                 basePosition.top += targetHeight;
19476         } else if ( options.at[1] === center ) {
19477                 basePosition.top += targetHeight / 2;
19478         }
19479
19480         basePosition.left += offset[ 0 ];
19481         basePosition.top += offset[ 1 ];
19482
19483         return this.each(function() {
19484                 var elem = $( this ),
19485                         elemWidth = elem.outerWidth(),
19486                         elemHeight = elem.outerHeight(),
19487                         marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
19488                         marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
19489                         collisionWidth = elemWidth + marginLeft +
19490                                 ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
19491                         collisionHeight = elemHeight + marginTop +
19492                                 ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
19493                         position = $.extend( {}, basePosition ),
19494                         collisionPosition;
19495
19496                 if ( options.my[0] === "right" ) {
19497                         position.left -= elemWidth;
19498                 } else if ( options.my[0] === center ) {
19499                         position.left -= elemWidth / 2;
19500                 }
19501
19502                 if ( options.my[1] === "bottom" ) {
19503                         position.top -= elemHeight;
19504                 } else if ( options.my[1] === center ) {
19505                         position.top -= elemHeight / 2;
19506                 }
19507
19508                 // prevent fractions (see #5280)
19509                 position.left = Math.round( position.left );
19510                 position.top = Math.round( position.top );
19511
19512                 collisionPosition = {
19513                         left: position.left - marginLeft,
19514                         top: position.top - marginTop
19515                 };
19516
19517                 $.each( [ "left", "top" ], function( i, dir ) {
19518                         if ( $.ui.position[ collision[i] ] ) {
19519                                 $.ui.position[ collision[i] ][ dir ]( position, {
19520                                         targetWidth: targetWidth,
19521                                         targetHeight: targetHeight,
19522                                         elemWidth: elemWidth,
19523                                         elemHeight: elemHeight,
19524                                         collisionPosition: collisionPosition,
19525                                         collisionWidth: collisionWidth,
19526                                         collisionHeight: collisionHeight,
19527                                         offset: offset,
19528                                         my: options.my,
19529                                         at: options.at
19530                                 });
19531                         }
19532                 });
19533
19534                 if ( $.fn.bgiframe ) {
19535                         elem.bgiframe();
19536                 }
19537                 elem.offset( $.extend( position, { using: options.using } ) );
19538         });
19539 };
19540
19541 $.ui.position = {
19542         fit: {
19543                 left: function( position, data ) {
19544                         var win = $( window ),
19545                                 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
19546                         position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
19547                 },
19548                 top: function( position, data ) {
19549                         var win = $( window ),
19550                                 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
19551                         position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
19552                 }
19553         },
19554
19555         flip: {
19556                 left: function( position, data ) {
19557                         if ( data.at[0] === center ) {
19558                                 return;
19559                         }
19560                         var win = $( window ),
19561                                 over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
19562                                 myOffset = data.my[ 0 ] === "left" ?
19563                                         -data.elemWidth :
19564                                         data.my[ 0 ] === "right" ?
19565                                                 data.elemWidth :
19566                                                 0,
19567                                 atOffset = data.at[ 0 ] === "left" ?
19568                                         data.targetWidth :
19569                                         -data.targetWidth,
19570                                 offset = -2 * data.offset[ 0 ];
19571                         position.left += data.collisionPosition.left < 0 ?
19572                                 myOffset + atOffset + offset :
19573                                 over > 0 ?
19574                                         myOffset + atOffset + offset :
19575                                         0;
19576                 },
19577                 top: function( position, data ) {
19578                         if ( data.at[1] === center ) {
19579                                 return;
19580                         }
19581                         var win = $( window ),
19582                                 over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
19583                                 myOffset = data.my[ 1 ] === "top" ?
19584                                         -data.elemHeight :
19585                                         data.my[ 1 ] === "bottom" ?
19586                                                 data.elemHeight :
19587                                                 0,
19588                                 atOffset = data.at[ 1 ] === "top" ?
19589                                         data.targetHeight :
19590                                         -data.targetHeight,
19591                                 offset = -2 * data.offset[ 1 ];
19592                         position.top += data.collisionPosition.top < 0 ?
19593                                 myOffset + atOffset + offset :
19594                                 over > 0 ?
19595                                         myOffset + atOffset + offset :
19596                                         0;
19597                 }
19598         }
19599 };
19600
19601 // offset setter from jQuery 1.4
19602 if ( !$.offset.setOffset ) {
19603         $.offset.setOffset = function( elem, options ) {
19604                 // set position first, in-case top/left are set even on static elem
19605                 if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
19606                         elem.style.position = "relative";
19607                 }
19608                 var curElem   = $( elem ),
19609                         curOffset = curElem.offset(),
19610                         curTop    = parseInt( $.curCSS( elem, "top",  true ), 10 ) || 0,
19611                         curLeft   = parseInt( $.curCSS( elem, "left", true ), 10)  || 0,
19612                         props     = {
19613                                 top:  (options.top  - curOffset.top)  + curTop,
19614                                 left: (options.left - curOffset.left) + curLeft
19615                         };
19616                 
19617                 if ( 'using' in options ) {
19618                         options.using.call( elem, props );
19619                 } else {
19620                         curElem.css( props );
19621                 }
19622         };
19623
19624         $.fn.offset = function( options ) {
19625                 var elem = this[ 0 ];
19626                 if ( !elem || !elem.ownerDocument ) { return null; }
19627                 if ( options ) { 
19628                         return this.each(function() {
19629                                 $.offset.setOffset( this, options );
19630                         });
19631                 }
19632                 return _offset.call( this );
19633         };
19634 }
19635
19636 }( jQuery ));
19637 /*
19638  * jQuery UI Progressbar 1.8.12
19639  *
19640  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
19641  * Dual licensed under the MIT or GPL Version 2 licenses.
19642  * http://jquery.org/license
19643  *
19644  * http://docs.jquery.com/UI/Progressbar
19645  *
19646  * Depends:
19647  *   jquery.ui.core.js
19648  *   jquery.ui.widget.js
19649  */
19650 (function( $, undefined ) {
19651
19652 $.widget( "ui.progressbar", {
19653         options: {
19654                 value: 0,
19655                 max: 100
19656         },
19657
19658         min: 0,
19659
19660         _create: function() {
19661                 this.element
19662                         .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
19663                         .attr({
19664                                 role: "progressbar",
19665                                 "aria-valuemin": this.min,
19666                                 "aria-valuemax": this.options.max,
19667                                 "aria-valuenow": this._value()
19668                         });
19669
19670                 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
19671                         .appendTo( this.element );
19672
19673                 this.oldValue = this._value();
19674                 this._refreshValue();
19675         },
19676
19677         destroy: function() {
19678                 this.element
19679                         .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
19680                         .removeAttr( "role" )
19681                         .removeAttr( "aria-valuemin" )
19682                         .removeAttr( "aria-valuemax" )
19683                         .removeAttr( "aria-valuenow" );
19684
19685                 this.valueDiv.remove();
19686
19687                 $.Widget.prototype.destroy.apply( this, arguments );
19688         },
19689
19690         value: function( newValue ) {
19691                 if ( newValue === undefined ) {
19692                         return this._value();
19693                 }
19694
19695                 this._setOption( "value", newValue );
19696                 return this;
19697         },
19698
19699         _setOption: function( key, value ) {
19700                 if ( key === "value" ) {
19701                         this.options.value = value;
19702                         this._refreshValue();
19703                         if ( this._value() === this.options.max ) {
19704                                 this._trigger( "complete" );
19705                         }
19706                 }
19707
19708                 $.Widget.prototype._setOption.apply( this, arguments );
19709         },
19710
19711         _value: function() {
19712                 var val = this.options.value;
19713                 // normalize invalid value
19714                 if ( typeof val !== "number" ) {
19715                         val = 0;
19716                 }
19717                 return Math.min( this.options.max, Math.max( this.min, val ) );
19718         },
19719
19720         _percentage: function() {
19721                 return 100 * this._value() / this.options.max;
19722         },
19723
19724         _refreshValue: function() {
19725                 var value = this.value();
19726                 var percentage = this._percentage();
19727
19728                 if ( this.oldValue !== value ) {
19729                         this.oldValue = value;
19730                         this._trigger( "change" );
19731                 }
19732
19733                 this.valueDiv
19734                         .toggle( value > this.min )
19735                         .toggleClass( "ui-corner-right", value === this.options.max )
19736                         .width( percentage.toFixed(0) + "%" );
19737                 this.element.attr( "aria-valuenow", value );
19738         }
19739 });
19740
19741 $.extend( $.ui.progressbar, {
19742         version: "1.8.12"
19743 });
19744
19745 })( jQuery );
19746 /*
19747  * jQuery UI Slider 1.8.12
19748  *
19749  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
19750  * Dual licensed under the MIT or GPL Version 2 licenses.
19751  * http://jquery.org/license
19752  *
19753  * http://docs.jquery.com/UI/Slider
19754  *
19755  * Depends:
19756  *      jquery.ui.core.js
19757  *      jquery.ui.mouse.js
19758  *      jquery.ui.widget.js
19759  */
19760 (function( $, undefined ) {
19761
19762 // number of pages in a slider
19763 // (how many times can you page up/down to go through the whole range)
19764 var numPages = 5;
19765
19766 $.widget( "ui.slider", $.ui.mouse, {
19767
19768         widgetEventPrefix: "slide",
19769
19770         options: {
19771                 animate: false,
19772                 distance: 0,
19773                 max: 100,
19774                 min: 0,
19775                 orientation: "horizontal",
19776                 range: false,
19777                 step: 1,
19778                 value: 0,
19779                 values: null
19780         },
19781
19782         _create: function() {
19783                 var self = this,
19784                         o = this.options;
19785
19786                 this._keySliding = false;
19787                 this._mouseSliding = false;
19788                 this._animateOff = true;
19789                 this._handleIndex = null;
19790                 this._detectOrientation();
19791                 this._mouseInit();
19792
19793                 this.element
19794                         .addClass( "ui-slider" +
19795                                 " ui-slider-" + this.orientation +
19796                                 " ui-widget" +
19797                                 " ui-widget-content" +
19798                                 " ui-corner-all" );
19799                 
19800                 if ( o.disabled ) {
19801                         this.element.addClass( "ui-slider-disabled ui-disabled" );
19802                 }
19803
19804                 this.range = $([]);
19805
19806                 if ( o.range ) {
19807                         if ( o.range === true ) {
19808                                 this.range = $( "<div></div>" );
19809                                 if ( !o.values ) {
19810                                         o.values = [ this._valueMin(), this._valueMin() ];
19811                                 }
19812                                 if ( o.values.length && o.values.length !== 2 ) {
19813                                         o.values = [ o.values[0], o.values[0] ];
19814                                 }
19815                         } else {
19816                                 this.range = $( "<div></div>" );
19817                         }
19818
19819                         this.range
19820                                 .appendTo( this.element )
19821                                 .addClass( "ui-slider-range" );
19822
19823                         if ( o.range === "min" || o.range === "max" ) {
19824                                 this.range.addClass( "ui-slider-range-" + o.range );
19825                         }
19826
19827                         // note: this isn't the most fittingly semantic framework class for this element,
19828                         // but worked best visually with a variety of themes
19829                         this.range.addClass( "ui-widget-header" );
19830                 }
19831
19832                 if ( $( ".ui-slider-handle", this.element ).length === 0 ) {
19833                         $( "<a href='#'></a>" )
19834                                 .appendTo( this.element )
19835                                 .addClass( "ui-slider-handle" );
19836                 }
19837
19838                 if ( o.values && o.values.length ) {
19839                         while ( $(".ui-slider-handle", this.element).length < o.values.length ) {
19840                                 $( "<a href='#'></a>" )
19841                                         .appendTo( this.element )
19842                                         .addClass( "ui-slider-handle" );
19843                         }
19844                 }
19845
19846                 this.handles = $( ".ui-slider-handle", this.element )
19847                         .addClass( "ui-state-default" +
19848                                 " ui-corner-all" );
19849
19850                 this.handle = this.handles.eq( 0 );
19851
19852                 this.handles.add( this.range ).filter( "a" )
19853                         .click(function( event ) {
19854                                 event.preventDefault();
19855                         })
19856                         .hover(function() {
19857                                 if ( !o.disabled ) {
19858                                         $( this ).addClass( "ui-state-hover" );
19859                                 }
19860                         }, function() {
19861                                 $( this ).removeClass( "ui-state-hover" );
19862                         })
19863                         .focus(function() {
19864                                 if ( !o.disabled ) {
19865                                         $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
19866                                         $( this ).addClass( "ui-state-focus" );
19867                                 } else {
19868                                         $( this ).blur();
19869                                 }
19870                         })
19871                         .blur(function() {
19872                                 $( this ).removeClass( "ui-state-focus" );
19873                         });
19874
19875                 this.handles.each(function( i ) {
19876                         $( this ).data( "index.ui-slider-handle", i );
19877                 });
19878
19879                 this.handles
19880                         .keydown(function( event ) {
19881                                 var ret = true,
19882                                         index = $( this ).data( "index.ui-slider-handle" ),
19883                                         allowed,
19884                                         curVal,
19885                                         newVal,
19886                                         step;
19887         
19888                                 if ( self.options.disabled ) {
19889                                         return;
19890                                 }
19891         
19892                                 switch ( event.keyCode ) {
19893                                         case $.ui.keyCode.HOME:
19894                                         case $.ui.keyCode.END:
19895                                         case $.ui.keyCode.PAGE_UP:
19896                                         case $.ui.keyCode.PAGE_DOWN:
19897                                         case $.ui.keyCode.UP:
19898                                         case $.ui.keyCode.RIGHT:
19899                                         case $.ui.keyCode.DOWN:
19900                                         case $.ui.keyCode.LEFT:
19901                                                 ret = false;
19902                                                 if ( !self._keySliding ) {
19903                                                         self._keySliding = true;
19904                                                         $( this ).addClass( "ui-state-active" );
19905                                                         allowed = self._start( event, index );
19906                                                         if ( allowed === false ) {
19907                                                                 return;
19908                                                         }
19909                                                 }
19910                                                 break;
19911                                 }
19912         
19913                                 step = self.options.step;
19914                                 if ( self.options.values && self.options.values.length ) {
19915                                         curVal = newVal = self.values( index );
19916                                 } else {
19917                                         curVal = newVal = self.value();
19918                                 }
19919         
19920                                 switch ( event.keyCode ) {
19921                                         case $.ui.keyCode.HOME:
19922                                                 newVal = self._valueMin();
19923                                                 break;
19924                                         case $.ui.keyCode.END:
19925                                                 newVal = self._valueMax();
19926                                                 break;
19927                                         case $.ui.keyCode.PAGE_UP:
19928                                                 newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
19929                                                 break;
19930                                         case $.ui.keyCode.PAGE_DOWN:
19931                                                 newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
19932                                                 break;
19933                                         case $.ui.keyCode.UP:
19934                                         case $.ui.keyCode.RIGHT:
19935                                                 if ( curVal === self._valueMax() ) {
19936                                                         return;
19937                                                 }
19938                                                 newVal = self._trimAlignValue( curVal + step );
19939                                                 break;
19940                                         case $.ui.keyCode.DOWN:
19941                                         case $.ui.keyCode.LEFT:
19942                                                 if ( curVal === self._valueMin() ) {
19943                                                         return;
19944                                                 }
19945                                                 newVal = self._trimAlignValue( curVal - step );
19946                                                 break;
19947                                 }
19948         
19949                                 self._slide( event, index, newVal );
19950         
19951                                 return ret;
19952         
19953                         })
19954                         .keyup(function( event ) {
19955                                 var index = $( this ).data( "index.ui-slider-handle" );
19956         
19957                                 if ( self._keySliding ) {
19958                                         self._keySliding = false;
19959                                         self._stop( event, index );
19960                                         self._change( event, index );
19961                                         $( this ).removeClass( "ui-state-active" );
19962                                 }
19963         
19964                         });
19965
19966                 this._refreshValue();
19967
19968                 this._animateOff = false;
19969         },
19970
19971         destroy: function() {
19972                 this.handles.remove();
19973                 this.range.remove();
19974
19975                 this.element
19976                         .removeClass( "ui-slider" +
19977                                 " ui-slider-horizontal" +
19978                                 " ui-slider-vertical" +
19979                                 " ui-slider-disabled" +
19980                                 " ui-widget" +
19981                                 " ui-widget-content" +
19982                                 " ui-corner-all" )
19983                         .removeData( "slider" )
19984                         .unbind( ".slider" );
19985
19986                 this._mouseDestroy();
19987
19988                 return this;
19989         },
19990
19991         _mouseCapture: function( event ) {
19992                 var o = this.options,
19993                         position,
19994                         normValue,
19995                         distance,
19996                         closestHandle,
19997                         self,
19998                         index,
19999                         allowed,
20000                         offset,
20001                         mouseOverHandle;
20002
20003                 if ( o.disabled ) {
20004                         return false;
20005                 }
20006
20007                 this.elementSize = {
20008                         width: this.element.outerWidth(),
20009                         height: this.element.outerHeight()
20010                 };
20011                 this.elementOffset = this.element.offset();
20012
20013                 position = { x: event.pageX, y: event.pageY };
20014                 normValue = this._normValueFromMouse( position );
20015                 distance = this._valueMax() - this._valueMin() + 1;
20016                 self = this;
20017                 this.handles.each(function( i ) {
20018                         var thisDistance = Math.abs( normValue - self.values(i) );
20019                         if ( distance > thisDistance ) {
20020                                 distance = thisDistance;
20021                                 closestHandle = $( this );
20022                                 index = i;
20023                         }
20024                 });
20025
20026                 // workaround for bug #3736 (if both handles of a range are at 0,
20027                 // the first is always used as the one with least distance,
20028                 // and moving it is obviously prevented by preventing negative ranges)
20029                 if( o.range === true && this.values(1) === o.min ) {
20030                         index += 1;
20031                         closestHandle = $( this.handles[index] );
20032                 }
20033
20034                 allowed = this._start( event, index );
20035                 if ( allowed === false ) {
20036                         return false;
20037                 }
20038                 this._mouseSliding = true;
20039
20040                 self._handleIndex = index;
20041
20042                 closestHandle
20043                         .addClass( "ui-state-active" )
20044                         .focus();
20045                 
20046                 offset = closestHandle.offset();
20047                 mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
20048                 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
20049                         left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
20050                         top: event.pageY - offset.top -
20051                                 ( closestHandle.height() / 2 ) -
20052                                 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
20053                                 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
20054                                 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
20055                 };
20056
20057                 if ( !this.handles.hasClass( "ui-state-hover" ) ) {
20058                         this._slide( event, index, normValue );
20059                 }
20060                 this._animateOff = true;
20061                 return true;
20062         },
20063
20064         _mouseStart: function( event ) {
20065                 return true;
20066         },
20067
20068         _mouseDrag: function( event ) {
20069                 var position = { x: event.pageX, y: event.pageY },
20070                         normValue = this._normValueFromMouse( position );
20071                 
20072                 this._slide( event, this._handleIndex, normValue );
20073
20074                 return false;
20075         },
20076
20077         _mouseStop: function( event ) {
20078                 this.handles.removeClass( "ui-state-active" );
20079                 this._mouseSliding = false;
20080
20081                 this._stop( event, this._handleIndex );
20082                 this._change( event, this._handleIndex );
20083
20084                 this._handleIndex = null;
20085                 this._clickOffset = null;
20086                 this._animateOff = false;
20087
20088                 return false;
20089         },
20090         
20091         _detectOrientation: function() {
20092                 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
20093         },
20094
20095         _normValueFromMouse: function( position ) {
20096                 var pixelTotal,
20097                         pixelMouse,
20098                         percentMouse,
20099                         valueTotal,
20100                         valueMouse;
20101
20102                 if ( this.orientation === "horizontal" ) {
20103                         pixelTotal = this.elementSize.width;
20104                         pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
20105                 } else {
20106                         pixelTotal = this.elementSize.height;
20107                         pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
20108                 }
20109
20110                 percentMouse = ( pixelMouse / pixelTotal );
20111                 if ( percentMouse > 1 ) {
20112                         percentMouse = 1;
20113                 }
20114                 if ( percentMouse < 0 ) {
20115                         percentMouse = 0;
20116                 }
20117                 if ( this.orientation === "vertical" ) {
20118                         percentMouse = 1 - percentMouse;
20119                 }
20120
20121                 valueTotal = this._valueMax() - this._valueMin();
20122                 valueMouse = this._valueMin() + percentMouse * valueTotal;
20123
20124                 return this._trimAlignValue( valueMouse );
20125         },
20126
20127         _start: function( event, index ) {
20128                 var uiHash = {
20129                         handle: this.handles[ index ],
20130                         value: this.value()
20131                 };
20132                 if ( this.options.values && this.options.values.length ) {
20133                         uiHash.value = this.values( index );
20134                         uiHash.values = this.values();
20135                 }
20136                 return this._trigger( "start", event, uiHash );
20137         },
20138
20139         _slide: function( event, index, newVal ) {
20140                 var otherVal,
20141                         newValues,
20142                         allowed;
20143
20144                 if ( this.options.values && this.options.values.length ) {
20145                         otherVal = this.values( index ? 0 : 1 );
20146
20147                         if ( ( this.options.values.length === 2 && this.options.range === true ) && 
20148                                         ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
20149                                 ) {
20150                                 newVal = otherVal;
20151                         }
20152
20153                         if ( newVal !== this.values( index ) ) {
20154                                 newValues = this.values();
20155                                 newValues[ index ] = newVal;
20156                                 // A slide can be canceled by returning false from the slide callback
20157                                 allowed = this._trigger( "slide", event, {
20158                                         handle: this.handles[ index ],
20159                                         value: newVal,
20160                                         values: newValues
20161                                 } );
20162                                 otherVal = this.values( index ? 0 : 1 );
20163                                 if ( allowed !== false ) {
20164                                         this.values( index, newVal, true );
20165                                 }
20166                         }
20167                 } else {
20168                         if ( newVal !== this.value() ) {
20169                                 // A slide can be canceled by returning false from the slide callback
20170                                 allowed = this._trigger( "slide", event, {
20171                                         handle: this.handles[ index ],
20172                                         value: newVal
20173                                 } );
20174                                 if ( allowed !== false ) {
20175                                         this.value( newVal );
20176                                 }
20177                         }
20178                 }
20179         },
20180
20181         _stop: function( event, index ) {
20182                 var uiHash = {
20183                         handle: this.handles[ index ],
20184                         value: this.value()
20185                 };
20186                 if ( this.options.values && this.options.values.length ) {
20187                         uiHash.value = this.values( index );
20188                         uiHash.values = this.values();
20189                 }
20190
20191                 this._trigger( "stop", event, uiHash );
20192         },
20193
20194         _change: function( event, index ) {
20195                 if ( !this._keySliding && !this._mouseSliding ) {
20196                         var uiHash = {
20197                                 handle: this.handles[ index ],
20198                                 value: this.value()
20199                         };
20200                         if ( this.options.values && this.options.values.length ) {
20201                                 uiHash.value = this.values( index );
20202                                 uiHash.values = this.values();
20203                         }
20204
20205                         this._trigger( "change", event, uiHash );
20206                 }
20207         },
20208
20209         value: function( newValue ) {
20210                 if ( arguments.length ) {
20211                         this.options.value = this._trimAlignValue( newValue );
20212                         this._refreshValue();
20213                         this._change( null, 0 );
20214                         return;
20215                 }
20216
20217                 return this._value();
20218         },
20219
20220         values: function( index, newValue ) {
20221                 var vals,
20222                         newValues,
20223                         i;
20224
20225                 if ( arguments.length > 1 ) {
20226                         this.options.values[ index ] = this._trimAlignValue( newValue );
20227                         this._refreshValue();
20228                         this._change( null, index );
20229                         return;
20230                 }
20231
20232                 if ( arguments.length ) {
20233                         if ( $.isArray( arguments[ 0 ] ) ) {
20234                                 vals = this.options.values;
20235                                 newValues = arguments[ 0 ];
20236                                 for ( i = 0; i < vals.length; i += 1 ) {
20237                                         vals[ i ] = this._trimAlignValue( newValues[ i ] );
20238                                         this._change( null, i );
20239                                 }
20240                                 this._refreshValue();
20241                         } else {
20242                                 if ( this.options.values && this.options.values.length ) {
20243                                         return this._values( index );
20244                                 } else {
20245                                         return this.value();
20246                                 }
20247                         }
20248                 } else {
20249                         return this._values();
20250                 }
20251         },
20252
20253         _setOption: function( key, value ) {
20254                 var i,
20255                         valsLength = 0;
20256
20257                 if ( $.isArray( this.options.values ) ) {
20258                         valsLength = this.options.values.length;
20259                 }
20260
20261                 $.Widget.prototype._setOption.apply( this, arguments );
20262
20263                 switch ( key ) {
20264                         case "disabled":
20265                                 if ( value ) {
20266                                         this.handles.filter( ".ui-state-focus" ).blur();
20267                                         this.handles.removeClass( "ui-state-hover" );
20268                                         this.handles.attr( "disabled", "disabled" );
20269                                         this.element.addClass( "ui-disabled" );
20270                                 } else {
20271                                         this.handles.removeAttr( "disabled" );
20272                                         this.element.removeClass( "ui-disabled" );
20273                                 }
20274                                 break;
20275                         case "orientation":
20276                                 this._detectOrientation();
20277                                 this.element
20278                                         .removeClass( "ui-slider-horizontal ui-slider-vertical" )
20279                                         .addClass( "ui-slider-" + this.orientation );
20280                                 this._refreshValue();
20281                                 break;
20282                         case "value":
20283                                 this._animateOff = true;
20284                                 this._refreshValue();
20285                                 this._change( null, 0 );
20286                                 this._animateOff = false;
20287                                 break;
20288                         case "values":
20289                                 this._animateOff = true;
20290                                 this._refreshValue();
20291                                 for ( i = 0; i < valsLength; i += 1 ) {
20292                                         this._change( null, i );
20293                                 }
20294                                 this._animateOff = false;
20295                                 break;
20296                 }
20297         },
20298
20299         //internal value getter
20300         // _value() returns value trimmed by min and max, aligned by step
20301         _value: function() {
20302                 var val = this.options.value;
20303                 val = this._trimAlignValue( val );
20304
20305                 return val;
20306         },
20307
20308         //internal values getter
20309         // _values() returns array of values trimmed by min and max, aligned by step
20310         // _values( index ) returns single value trimmed by min and max, aligned by step
20311         _values: function( index ) {
20312                 var val,
20313                         vals,
20314                         i;
20315
20316                 if ( arguments.length ) {
20317                         val = this.options.values[ index ];
20318                         val = this._trimAlignValue( val );
20319
20320                         return val;
20321                 } else {
20322                         // .slice() creates a copy of the array
20323                         // this copy gets trimmed by min and max and then returned
20324                         vals = this.options.values.slice();
20325                         for ( i = 0; i < vals.length; i+= 1) {
20326                                 vals[ i ] = this._trimAlignValue( vals[ i ] );
20327                         }
20328
20329                         return vals;
20330                 }
20331         },
20332         
20333         // returns the step-aligned value that val is closest to, between (inclusive) min and max
20334         _trimAlignValue: function( val ) {
20335                 if ( val <= this._valueMin() ) {
20336                         return this._valueMin();
20337                 }
20338                 if ( val >= this._valueMax() ) {
20339                         return this._valueMax();
20340                 }
20341                 var step = ( this.options.step > 0 ) ? this.options.step : 1,
20342                         valModStep = (val - this._valueMin()) % step;
20343                         alignValue = val - valModStep;
20344
20345                 if ( Math.abs(valModStep) * 2 >= step ) {
20346                         alignValue += ( valModStep > 0 ) ? step : ( -step );
20347                 }
20348
20349                 // Since JavaScript has problems with large floats, round
20350                 // the final value to 5 digits after the decimal point (see #4124)
20351                 return parseFloat( alignValue.toFixed(5) );
20352         },
20353
20354         _valueMin: function() {
20355                 return this.options.min;
20356         },
20357
20358         _valueMax: function() {
20359                 return this.options.max;
20360         },
20361         
20362         _refreshValue: function() {
20363                 var oRange = this.options.range,
20364                         o = this.options,
20365                         self = this,
20366                         animate = ( !this._animateOff ) ? o.animate : false,
20367                         valPercent,
20368                         _set = {},
20369                         lastValPercent,
20370                         value,
20371                         valueMin,
20372                         valueMax;
20373
20374                 if ( this.options.values && this.options.values.length ) {
20375                         this.handles.each(function( i, j ) {
20376                                 valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
20377                                 _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
20378                                 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
20379                                 if ( self.options.range === true ) {
20380                                         if ( self.orientation === "horizontal" ) {
20381                                                 if ( i === 0 ) {
20382                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
20383                                                 }
20384                                                 if ( i === 1 ) {
20385                                                         self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
20386                                                 }
20387                                         } else {
20388                                                 if ( i === 0 ) {
20389                                                         self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
20390                                                 }
20391                                                 if ( i === 1 ) {
20392                                                         self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
20393                                                 }
20394                                         }
20395                                 }
20396                                 lastValPercent = valPercent;
20397                         });
20398                 } else {
20399                         value = this.value();
20400                         valueMin = this._valueMin();
20401                         valueMax = this._valueMax();
20402                         valPercent = ( valueMax !== valueMin ) ?
20403                                         ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
20404                                         0;
20405                         _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
20406                         this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
20407
20408                         if ( oRange === "min" && this.orientation === "horizontal" ) {
20409                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
20410                         }
20411                         if ( oRange === "max" && this.orientation === "horizontal" ) {
20412                                 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
20413                         }
20414                         if ( oRange === "min" && this.orientation === "vertical" ) {
20415                                 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
20416                         }
20417                         if ( oRange === "max" && this.orientation === "vertical" ) {
20418                                 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
20419                         }
20420                 }
20421         }
20422
20423 });
20424
20425 $.extend( $.ui.slider, {
20426         version: "1.8.12"
20427 });
20428
20429 }(jQuery));
20430 /*
20431  * jQuery UI Tabs 1.8.12
20432  *
20433  * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
20434  * Dual licensed under the MIT or GPL Version 2 licenses.
20435  * http://jquery.org/license
20436  *
20437  * http://docs.jquery.com/UI/Tabs
20438  *
20439  * Depends:
20440  *      jquery.ui.core.js
20441  *      jquery.ui.widget.js
20442  */
20443 (function( $, undefined ) {
20444
20445 var tabId = 0,
20446         listId = 0;
20447
20448 function getNextTabId() {
20449         return ++tabId;
20450 }
20451
20452 function getNextListId() {
20453         return ++listId;
20454 }
20455
20456 $.widget( "ui.tabs", {
20457         options: {
20458                 add: null,
20459                 ajaxOptions: null,
20460                 cache: false,
20461                 cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
20462                 collapsible: false,
20463                 disable: null,
20464                 disabled: [],
20465                 enable: null,
20466                 event: "click",
20467                 fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
20468                 idPrefix: "ui-tabs-",
20469                 load: null,
20470                 panelTemplate: "<div></div>",
20471                 remove: null,
20472                 select: null,
20473                 show: null,
20474                 spinner: "<em>Loading&#8230;</em>",
20475                 tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
20476         },
20477
20478         _create: function() {
20479                 this._tabify( true );
20480         },
20481
20482         _setOption: function( key, value ) {
20483                 if ( key == "selected" ) {
20484                         if (this.options.collapsible && value == this.options.selected ) {
20485                                 return;
20486                         }
20487                         this.select( value );
20488                 } else {
20489                         this.options[ key ] = value;
20490                         this._tabify();
20491                 }
20492         },
20493
20494         _tabId: function( a ) {
20495                 return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
20496                         this.options.idPrefix + getNextTabId();
20497         },
20498
20499         _sanitizeSelector: function( hash ) {
20500                 // we need this because an id may contain a ":"
20501                 return hash.replace( /:/g, "\\:" );
20502         },
20503
20504         _cookie: function() {
20505                 var cookie = this.cookie ||
20506                         ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
20507                 return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
20508         },
20509
20510         _ui: function( tab, panel ) {
20511                 return {
20512                         tab: tab,
20513                         panel: panel,
20514                         index: this.anchors.index( tab )
20515                 };
20516         },
20517
20518         _cleanup: function() {
20519                 // restore all former loading tabs labels
20520                 this.lis.filter( ".ui-state-processing" )
20521                         .removeClass( "ui-state-processing" )
20522                         .find( "span:data(label.tabs)" )
20523                                 .each(function() {
20524                                         var el = $( this );
20525                                         el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
20526                                 });
20527         },
20528
20529         _tabify: function( init ) {
20530                 var self = this,
20531                         o = this.options,
20532                         fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
20533
20534                 this.list = this.element.find( "ol,ul" ).eq( 0 );
20535                 this.lis = $( " > li:has(a[href])", this.list );
20536                 this.anchors = this.lis.map(function() {
20537                         return $( "a", this )[ 0 ];
20538                 });
20539                 this.panels = $( [] );
20540
20541                 this.anchors.each(function( i, a ) {
20542                         var href = $( a ).attr( "href" );
20543                         // For dynamically created HTML that contains a hash as href IE < 8 expands
20544                         // such href to the full page url with hash and then misinterprets tab as ajax.
20545                         // Same consideration applies for an added tab with a fragment identifier
20546                         // since a[href=#fragment-identifier] does unexpectedly not match.
20547                         // Thus normalize href attribute...
20548                         var hrefBase = href.split( "#" )[ 0 ],
20549                                 baseEl;
20550                         if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
20551                                         ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
20552                                 href = a.hash;
20553                                 a.href = href;
20554                         }
20555
20556                         // inline tab
20557                         if ( fragmentId.test( href ) ) {
20558                                 self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
20559                         // remote tab
20560                         // prevent loading the page itself if href is just "#"
20561                         } else if ( href && href !== "#" ) {
20562                                 // required for restore on destroy
20563                                 $.data( a, "href.tabs", href );
20564
20565                                 // TODO until #3808 is fixed strip fragment identifier from url
20566                                 // (IE fails to load from such url)
20567                                 $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
20568
20569                                 var id = self._tabId( a );
20570                                 a.href = "#" + id;
20571                                 var $panel = self.element.find( "#" + id );
20572                                 if ( !$panel.length ) {
20573                                         $panel = $( o.panelTemplate )
20574                                                 .attr( "id", id )
20575                                                 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
20576                                                 .insertAfter( self.panels[ i - 1 ] || self.list );
20577                                         $panel.data( "destroy.tabs", true );
20578                                 }
20579                                 self.panels = self.panels.add( $panel );
20580                         // invalid tab href
20581                         } else {
20582                                 o.disabled.push( i );
20583                         }
20584                 });
20585
20586                 // initialization from scratch
20587                 if ( init ) {
20588                         // attach necessary classes for styling
20589                         this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
20590                         this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
20591                         this.lis.addClass( "ui-state-default ui-corner-top" );
20592                         this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
20593
20594                         // Selected tab
20595                         // use "selected" option or try to retrieve:
20596                         // 1. from fragment identifier in url
20597                         // 2. from cookie
20598                         // 3. from selected class attribute on <li>
20599                         if ( o.selected === undefined ) {
20600                                 if ( location.hash ) {
20601                                         this.anchors.each(function( i, a ) {
20602                                                 if ( a.hash == location.hash ) {
20603                                                         o.selected = i;
20604                                                         return false;
20605                                                 }
20606                                         });
20607                                 }
20608                                 if ( typeof o.selected !== "number" && o.cookie ) {
20609                                         o.selected = parseInt( self._cookie(), 10 );
20610                                 }
20611                                 if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
20612                                         o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
20613                                 }
20614                                 o.selected = o.selected || ( this.lis.length ? 0 : -1 );
20615                         } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
20616                                 o.selected = -1;
20617                         }
20618
20619                         // sanity check - default to first tab...
20620                         o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
20621                                 ? o.selected
20622                                 : 0;
20623
20624                         // Take disabling tabs via class attribute from HTML
20625                         // into account and update option properly.
20626                         // A selected tab cannot become disabled.
20627                         o.disabled = $.unique( o.disabled.concat(
20628                                 $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
20629                                         return self.lis.index( n );
20630                                 })
20631                         ) ).sort();
20632
20633                         if ( $.inArray( o.selected, o.disabled ) != -1 ) {
20634                                 o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
20635                         }
20636
20637                         // highlight selected tab
20638                         this.panels.addClass( "ui-tabs-hide" );
20639                         this.lis.removeClass( "ui-tabs-selected ui-state-active" );
20640                         // check for length avoids error when initializing empty list
20641                         if ( o.selected >= 0 && this.anchors.length ) {
20642                                 self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
20643                                 this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
20644
20645                                 // seems to be expected behavior that the show callback is fired
20646                                 self.element.queue( "tabs", function() {
20647                                         self._trigger( "show", null,
20648                                                 self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
20649                                 });
20650
20651                                 this.load( o.selected );
20652                         }
20653
20654                         // clean up to avoid memory leaks in certain versions of IE 6
20655                         // TODO: namespace this event
20656                         $( window ).bind( "unload", function() {
20657                                 self.lis.add( self.anchors ).unbind( ".tabs" );
20658                                 self.lis = self.anchors = self.panels = null;
20659                         });
20660                 // update selected after add/remove
20661                 } else {
20662                         o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
20663                 }
20664
20665                 // update collapsible
20666                 // TODO: use .toggleClass()
20667                 this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
20668
20669                 // set or update cookie after init and add/remove respectively
20670                 if ( o.cookie ) {
20671                         this._cookie( o.selected, o.cookie );
20672                 }
20673
20674                 // disable tabs
20675                 for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
20676                         $( li )[ $.inArray( i, o.disabled ) != -1 &&
20677                                 // TODO: use .toggleClass()
20678                                 !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
20679                 }
20680
20681                 // reset cache if switching from cached to not cached
20682                 if ( o.cache === false ) {
20683                         this.anchors.removeData( "cache.tabs" );
20684                 }
20685
20686                 // remove all handlers before, tabify may run on existing tabs after add or option change
20687                 this.lis.add( this.anchors ).unbind( ".tabs" );
20688
20689                 if ( o.event !== "mouseover" ) {
20690                         var addState = function( state, el ) {
20691                                 if ( el.is( ":not(.ui-state-disabled)" ) ) {
20692                                         el.addClass( "ui-state-" + state );
20693                                 }
20694                         };
20695                         var removeState = function( state, el ) {
20696                                 el.removeClass( "ui-state-" + state );
20697                         };
20698                         this.lis.bind( "mouseover.tabs" , function() {
20699                                 addState( "hover", $( this ) );
20700                         });
20701                         this.lis.bind( "mouseout.tabs", function() {
20702                                 removeState( "hover", $( this ) );
20703                         });
20704                         this.anchors.bind( "focus.tabs", function() {
20705                                 addState( "focus", $( this ).closest( "li" ) );
20706                         });
20707                         this.anchors.bind( "blur.tabs", function() {
20708                                 removeState( "focus", $( this ).closest( "li" ) );
20709                         });
20710                 }
20711
20712                 // set up animations
20713                 var hideFx, showFx;
20714                 if ( o.fx ) {
20715                         if ( $.isArray( o.fx ) ) {
20716                                 hideFx = o.fx[ 0 ];
20717                                 showFx = o.fx[ 1 ];
20718                         } else {
20719                                 hideFx = showFx = o.fx;
20720                         }
20721                 }
20722
20723                 // Reset certain styles left over from animation
20724                 // and prevent IE's ClearType bug...
20725                 function resetStyle( $el, fx ) {
20726                         $el.css( "display", "" );
20727                         if ( !$.support.opacity && fx.opacity ) {
20728                                 $el[ 0 ].style.removeAttribute( "filter" );
20729                         }
20730                 }
20731
20732                 // Show a tab...
20733                 var showTab = showFx
20734                         ? function( clicked, $show ) {
20735                                 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
20736                                 $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
20737                                         .animate( showFx, showFx.duration || "normal", function() {
20738                                                 resetStyle( $show, showFx );
20739                                                 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
20740                                         });
20741                         }
20742                         : function( clicked, $show ) {
20743                                 $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
20744                                 $show.removeClass( "ui-tabs-hide" );
20745                                 self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
20746                         };
20747
20748                 // Hide a tab, $show is optional...
20749                 var hideTab = hideFx
20750                         ? function( clicked, $hide ) {
20751                                 $hide.animate( hideFx, hideFx.duration || "normal", function() {
20752                                         self.lis.removeClass( "ui-tabs-selected ui-state-active" );
20753                                         $hide.addClass( "ui-tabs-hide" );
20754                                         resetStyle( $hide, hideFx );
20755                                         self.element.dequeue( "tabs" );
20756                                 });
20757                         }
20758                         : function( clicked, $hide, $show ) {
20759                                 self.lis.removeClass( "ui-tabs-selected ui-state-active" );
20760                                 $hide.addClass( "ui-tabs-hide" );
20761                                 self.element.dequeue( "tabs" );
20762                         };
20763
20764                 // attach tab event handler, unbind to avoid duplicates from former tabifying...
20765                 this.anchors.bind( o.event + ".tabs", function() {
20766                         var el = this,
20767                                 $li = $(el).closest( "li" ),
20768                                 $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
20769                                 $show = self.element.find( self._sanitizeSelector( el.hash ) );
20770
20771                         // If tab is already selected and not collapsible or tab disabled or
20772                         // or is already loading or click callback returns false stop here.
20773                         // Check if click handler returns false last so that it is not executed
20774                         // for a disabled or loading tab!
20775                         if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
20776                                 $li.hasClass( "ui-state-disabled" ) ||
20777                                 $li.hasClass( "ui-state-processing" ) ||
20778                                 self.panels.filter( ":animated" ).length ||
20779                                 self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
20780                                 this.blur();
20781                                 return false;
20782                         }
20783
20784                         o.selected = self.anchors.index( this );
20785
20786                         self.abort();
20787
20788                         // if tab may be closed
20789                         if ( o.collapsible ) {
20790                                 if ( $li.hasClass( "ui-tabs-selected" ) ) {
20791                                         o.selected = -1;
20792
20793                                         if ( o.cookie ) {
20794                                                 self._cookie( o.selected, o.cookie );
20795                                         }
20796
20797                                         self.element.queue( "tabs", function() {
20798                                                 hideTab( el, $hide );
20799                                         }).dequeue( "tabs" );
20800
20801                                         this.blur();
20802                                         return false;
20803                                 } else if ( !$hide.length ) {
20804                                         if ( o.cookie ) {
20805                                                 self._cookie( o.selected, o.cookie );
20806                                         }
20807
20808                                         self.element.queue( "tabs", function() {
20809                                                 showTab( el, $show );
20810                                         });
20811
20812                                         // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
20813                                         self.load( self.anchors.index( this ) );
20814
20815                                         this.blur();
20816                                         return false;
20817                                 }
20818                         }
20819
20820                         if ( o.cookie ) {
20821                                 self._cookie( o.selected, o.cookie );
20822                         }
20823
20824                         // show new tab
20825                         if ( $show.length ) {
20826                                 if ( $hide.length ) {
20827                                         self.element.queue( "tabs", function() {
20828                                                 hideTab( el, $hide );
20829                                         });
20830                                 }
20831                                 self.element.queue( "tabs", function() {
20832                                         showTab( el, $show );
20833                                 });
20834
20835                                 self.load( self.anchors.index( this ) );
20836                         } else {
20837                                 throw "jQuery UI Tabs: Mismatching fragment identifier.";
20838                         }
20839
20840                         // Prevent IE from keeping other link focussed when using the back button
20841                         // and remove dotted border from clicked link. This is controlled via CSS
20842                         // in modern browsers; blur() removes focus from address bar in Firefox
20843                         // which can become a usability and annoying problem with tabs('rotate').
20844                         if ( $.browser.msie ) {
20845                                 this.blur();
20846                         }
20847                 });
20848
20849                 // disable click in any case
20850                 this.anchors.bind( "click.tabs", function(){
20851                         return false;
20852                 });
20853         },
20854
20855     _getIndex: function( index ) {
20856                 // meta-function to give users option to provide a href string instead of a numerical index.
20857                 // also sanitizes numerical indexes to valid values.
20858                 if ( typeof index == "string" ) {
20859                         index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
20860                 }
20861
20862                 return index;
20863         },
20864
20865         destroy: function() {
20866                 var o = this.options;
20867
20868                 this.abort();
20869
20870                 this.element
20871                         .unbind( ".tabs" )
20872                         .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
20873                         .removeData( "tabs" );
20874
20875                 this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
20876
20877                 this.anchors.each(function() {
20878                         var href = $.data( this, "href.tabs" );
20879                         if ( href ) {
20880                                 this.href = href;
20881                         }
20882                         var $this = $( this ).unbind( ".tabs" );
20883                         $.each( [ "href", "load", "cache" ], function( i, prefix ) {
20884                                 $this.removeData( prefix + ".tabs" );
20885                         });
20886                 });
20887
20888                 this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
20889                         if ( $.data( this, "destroy.tabs" ) ) {
20890                                 $( this ).remove();
20891                         } else {
20892                                 $( this ).removeClass([
20893                                         "ui-state-default",
20894                                         "ui-corner-top",
20895                                         "ui-tabs-selected",
20896                                         "ui-state-active",
20897                                         "ui-state-hover",
20898                                         "ui-state-focus",
20899                                         "ui-state-disabled",
20900                                         "ui-tabs-panel",
20901                                         "ui-widget-content",
20902                                         "ui-corner-bottom",
20903                                         "ui-tabs-hide"
20904                                 ].join( " " ) );
20905                         }
20906                 });
20907
20908                 if ( o.cookie ) {
20909                         this._cookie( null, o.cookie );
20910                 }
20911
20912                 return this;
20913         },
20914
20915         add: function( url, label, index ) {
20916                 if ( index === undefined ) {
20917                         index = this.anchors.length;
20918                 }
20919
20920                 var self = this,
20921                         o = this.options,
20922                         $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
20923                         id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
20924
20925                 $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
20926
20927                 // try to find an existing element before creating a new one
20928                 var $panel = self.element.find( "#" + id );
20929                 if ( !$panel.length ) {
20930                         $panel = $( o.panelTemplate )
20931                                 .attr( "id", id )
20932                                 .data( "destroy.tabs", true );
20933                 }
20934                 $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
20935
20936                 if ( index >= this.lis.length ) {
20937                         $li.appendTo( this.list );
20938                         $panel.appendTo( this.list[ 0 ].parentNode );
20939                 } else {
20940                         $li.insertBefore( this.lis[ index ] );
20941                         $panel.insertBefore( this.panels[ index ] );
20942                 }
20943
20944                 o.disabled = $.map( o.disabled, function( n, i ) {
20945                         return n >= index ? ++n : n;
20946                 });
20947
20948                 this._tabify();
20949
20950                 if ( this.anchors.length == 1 ) {
20951                         o.selected = 0;
20952                         $li.addClass( "ui-tabs-selected ui-state-active" );
20953                         $panel.removeClass( "ui-tabs-hide" );
20954                         this.element.queue( "tabs", function() {
20955                                 self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
20956                         });
20957
20958                         this.load( 0 );
20959                 }
20960
20961                 this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
20962                 return this;
20963         },
20964
20965         remove: function( index ) {
20966                 index = this._getIndex( index );
20967                 var o = this.options,
20968                         $li = this.lis.eq( index ).remove(),
20969                         $panel = this.panels.eq( index ).remove();
20970
20971                 // If selected tab was removed focus tab to the right or
20972                 // in case the last tab was removed the tab to the left.
20973                 if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
20974                         this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
20975                 }
20976
20977                 o.disabled = $.map(
20978                         $.grep( o.disabled, function(n, i) {
20979                                 return n != index;
20980                         }),
20981                         function( n, i ) {
20982                                 return n >= index ? --n : n;
20983                         });
20984
20985                 this._tabify();
20986
20987                 this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
20988                 return this;
20989         },
20990
20991         enable: function( index ) {
20992                 index = this._getIndex( index );
20993                 var o = this.options;
20994                 if ( $.inArray( index, o.disabled ) == -1 ) {
20995                         return;
20996                 }
20997
20998                 this.lis.eq( index ).removeClass( "ui-state-disabled" );
20999                 o.disabled = $.grep( o.disabled, function( n, i ) {
21000                         return n != index;
21001                 });
21002
21003                 this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
21004                 return this;
21005         },
21006
21007         disable: function( index ) {
21008                 index = this._getIndex( index );
21009                 var self = this, o = this.options;
21010                 // cannot disable already selected tab
21011                 if ( index != o.selected ) {
21012                         this.lis.eq( index ).addClass( "ui-state-disabled" );
21013
21014                         o.disabled.push( index );
21015                         o.disabled.sort();
21016
21017                         this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
21018                 }
21019
21020                 return this;
21021         },
21022
21023         select: function( index ) {
21024                 index = this._getIndex( index );
21025                 if ( index == -1 ) {
21026                         if ( this.options.collapsible && this.options.selected != -1 ) {
21027                                 index = this.options.selected;
21028                         } else {
21029                                 return this;
21030                         }
21031                 }
21032                 this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
21033                 return this;
21034         },
21035
21036         load: function( index ) {
21037                 index = this._getIndex( index );
21038                 var self = this,
21039                         o = this.options,
21040                         a = this.anchors.eq( index )[ 0 ],
21041                         url = $.data( a, "load.tabs" );
21042
21043                 this.abort();
21044
21045                 // not remote or from cache
21046                 if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
21047                         this.element.dequeue( "tabs" );
21048                         return;
21049                 }
21050
21051                 // load remote from here on
21052                 this.lis.eq( index ).addClass( "ui-state-processing" );
21053
21054                 if ( o.spinner ) {
21055                         var span = $( "span", a );
21056                         span.data( "label.tabs", span.html() ).html( o.spinner );
21057                 }
21058
21059                 this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
21060                         url: url,
21061                         success: function( r, s ) {
21062                                 self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
21063
21064                                 // take care of tab labels
21065                                 self._cleanup();
21066
21067                                 if ( o.cache ) {
21068                                         $.data( a, "cache.tabs", true );
21069                                 }
21070
21071                                 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
21072                                 try {
21073                                         o.ajaxOptions.success( r, s );
21074                                 }
21075                                 catch ( e ) {}
21076                         },
21077                         error: function( xhr, s, e ) {
21078                                 // take care of tab labels
21079                                 self._cleanup();
21080
21081                                 self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
21082                                 try {
21083                                         // Passing index avoid a race condition when this method is
21084                                         // called after the user has selected another tab.
21085                                         // Pass the anchor that initiated this request allows
21086                                         // loadError to manipulate the tab content panel via $(a.hash)
21087                                         o.ajaxOptions.error( xhr, s, index, a );
21088                                 }
21089                                 catch ( e ) {}
21090                         }
21091                 } ) );
21092
21093                 // last, so that load event is fired before show...
21094                 self.element.dequeue( "tabs" );
21095
21096                 return this;
21097         },
21098
21099         abort: function() {
21100                 // stop possibly running animations
21101                 this.element.queue( [] );
21102                 this.panels.stop( false, true );
21103
21104                 // "tabs" queue must not contain more than two elements,
21105                 // which are the callbacks for the latest clicked tab...
21106                 this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
21107
21108                 // terminate pending requests from other tabs
21109                 if ( this.xhr ) {
21110                         this.xhr.abort();
21111                         delete this.xhr;
21112                 }
21113
21114                 // take care of tab labels
21115                 this._cleanup();
21116                 return this;
21117         },
21118
21119         url: function( index, url ) {
21120                 this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
21121                 return this;
21122         },
21123
21124         length: function() {
21125                 return this.anchors.length;
21126         }
21127 });
21128
21129 $.extend( $.ui.tabs, {
21130         version: "1.8.12"
21131 });
21132
21133 /*
21134  * Tabs Extensions
21135  */
21136
21137 /*
21138  * Rotate
21139  */
21140 $.extend( $.ui.tabs.prototype, {
21141         rotation: null,
21142         rotate: function( ms, continuing ) {
21143                 var self = this,
21144                         o = this.options;
21145
21146                 var rotate = self._rotate || ( self._rotate = function( e ) {
21147                         clearTimeout( self.rotation );
21148                         self.rotation = setTimeout(function() {
21149                                 var t = o.selected;
21150                                 self.select( ++t < self.anchors.length ? t : 0 );
21151                         }, ms );
21152                         
21153                         if ( e ) {
21154                                 e.stopPropagation();
21155                         }
21156                 });
21157
21158                 var stop = self._unrotate || ( self._unrotate = !continuing
21159                         ? function(e) {
21160                                 if (e.clientX) { // in case of a true click
21161                                         self.rotate(null);
21162                                 }
21163                         }
21164                         : function( e ) {
21165                                 t = o.selected;
21166                                 rotate();
21167                         });
21168
21169                 // start rotation
21170                 if ( ms ) {
21171                         this.element.bind( "tabsshow", rotate );
21172                         this.anchors.bind( o.event + ".tabs", stop );
21173                         rotate();
21174                 // stop rotation
21175                 } else {
21176                         clearTimeout( self.rotation );
21177                         this.element.unbind( "tabsshow", rotate );
21178                         this.anchors.unbind( o.event + ".tabs", stop );
21179                         delete this._rotate;
21180                         delete this._unrotate;
21181                 }
21182
21183                 return this;
21184         }
21185 });
21186
21187 })( jQuery );
21188 /*
21189  * jQuery Tooltip plugin 1.3
21190  *
21191  * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
21192  * http://docs.jquery.com/Plugins/Tooltip
21193  *
21194  * Copyright (c) 2006 - 2008 Jörn Zaefferer
21195  *
21196  * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
21197  * 
21198  * Dual licensed under the MIT and GPL licenses:
21199  *   http://www.opensource.org/licenses/mit-license.php
21200  *   http://www.gnu.org/licenses/gpl.html
21201  */
21202  
21203 ;(function($) {
21204         
21205                 // the tooltip element
21206         var helper = {},
21207                 // the current tooltipped element
21208                 current,
21209                 // the title of the current element, used for restoring
21210                 title,
21211                 // timeout id for delayed tooltips
21212                 tID,
21213                 // IE 5.5 or 6
21214                 IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
21215                 // flag for mouse tracking
21216                 track = false;
21217         
21218         $.tooltip = {
21219                 blocked: false,
21220                 defaults: {
21221                         delay: 200,
21222                         fade: false,
21223                         showURL: true,
21224                         extraClass: "",
21225                         top: 15,
21226                         left: 15,
21227                         id: "tooltip"
21228                 },
21229                 block: function() {
21230                         $.tooltip.blocked = !$.tooltip.blocked;
21231                 }
21232         };
21233         
21234         $.fn.extend({
21235                 tooltip: function(settings) {
21236                         settings = $.extend({}, $.tooltip.defaults, settings);
21237                         createHelper(settings);
21238                         return this.each(function() {
21239                                         $.data(this, "tooltip", settings);
21240                                         this.tOpacity = helper.parent.css("opacity");
21241                                         // copy tooltip into its own expando and remove the title
21242                                         this.tooltipText = this.title;
21243                                         $(this).removeAttr("title");
21244                                         // also remove alt attribute to prevent default tooltip in IE
21245                                         this.alt = "";
21246                                 })
21247                                 .mouseover(save)
21248                                 .mouseout(hide)
21249                                 .click(hide);
21250                 },
21251                 fixPNG: IE ? function() {
21252                         return this.each(function () {
21253                                 var image = $(this).css('backgroundImage');
21254                                 if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
21255                                         image = RegExp.$1;
21256                                         $(this).css({
21257                                                 'backgroundImage': 'none',
21258                                                 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
21259                                         }).each(function () {
21260                                                 var position = $(this).css('position');
21261                                                 if (position != 'absolute' && position != 'relative')
21262                                                         $(this).css('position', 'relative');
21263                                         });
21264                                 }
21265                         });
21266                 } : function() { return this; },
21267                 unfixPNG: IE ? function() {
21268                         return this.each(function () {
21269                                 $(this).css({'filter': '', backgroundImage: ''});
21270                         });
21271                 } : function() { return this; },
21272                 hideWhenEmpty: function() {
21273                         return this.each(function() {
21274                                 $(this)[ $(this).html() ? "show" : "hide" ]();
21275                         });
21276                 },
21277                 url: function() {
21278                         return this.attr('href') || this.attr('src');
21279                 }
21280         });
21281         
21282         function createHelper(settings) {
21283                 // there can be only one tooltip helper
21284                 if( helper.parent )
21285                         return;
21286                 // create the helper, h3 for title, div for url
21287                 helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')
21288                         // add to document
21289                         .appendTo(document.body)
21290                         // hide it at first
21291                         .hide();
21292                         
21293                 // apply bgiframe if available
21294                 if ( $.fn.bgiframe )
21295                         helper.parent.bgiframe();
21296                 
21297                 // save references to title and url elements
21298                 helper.title = $('h3', helper.parent);
21299                 helper.body = $('div.body', helper.parent);
21300                 helper.url = $('div.url', helper.parent);
21301         }
21302         
21303         function settings(element) {
21304                 return $.data(element, "tooltip");
21305         }
21306         
21307         // main event handler to start showing tooltips
21308         function handle(event) {
21309                 // show helper, either with timeout or on instant
21310                 if( settings(this).delay )
21311                         tID = setTimeout(show, settings(this).delay);
21312                 else
21313                         show();
21314                 
21315                 // if selected, update the helper position when the mouse moves
21316                 track = !!settings(this).track;
21317                 $(document.body).bind('mousemove', update);
21318                         
21319                 // update at least once
21320                 update(event);
21321         }
21322         
21323         // save elements title before the tooltip is displayed
21324         function save() {
21325                 // if this is the current source, or it has no title (occurs with click event), stop
21326                 if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
21327                         return;
21328
21329                 // save current
21330                 current = this;
21331                 title = this.tooltipText;
21332                 
21333                 if ( settings(this).bodyHandler ) {
21334                         helper.title.hide();
21335                         var bodyContent = settings(this).bodyHandler.call(this);
21336                         if (bodyContent.nodeType || bodyContent.jquery) {
21337                                 helper.body.empty().append(bodyContent)
21338                         } else {
21339                                 helper.body.html( bodyContent );
21340                         }
21341                         helper.body.show();
21342                 } else if ( settings(this).showBody ) {
21343                         var parts = title.split(settings(this).showBody);
21344                         helper.title.html(parts.shift()).show();
21345                         helper.body.empty();
21346                         for(var i = 0, part; (part = parts[i]); i++) {
21347                                 if(i > 0)
21348                                         helper.body.append("<br/>");
21349                                 helper.body.append(part);
21350                         }
21351                         helper.body.hideWhenEmpty();
21352                 } else {
21353                         helper.title.html(title).show();
21354                         helper.body.hide();
21355                 }
21356                 
21357                 // if element has href or src, add and show it, otherwise hide it
21358                 if( settings(this).showURL && $(this).url() )
21359                         helper.url.html( $(this).url().replace('http://', '') ).show();
21360                 else 
21361                         helper.url.hide();
21362                 
21363                 // add an optional class for this tip
21364                 helper.parent.addClass(settings(this).extraClass);
21365
21366                 // fix PNG background for IE
21367                 if (settings(this).fixPNG )
21368                         helper.parent.fixPNG();
21369                         
21370                 handle.apply(this, arguments);
21371         }
21372         
21373         // delete timeout and show helper
21374         function show() {
21375                 tID = null;
21376                 if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
21377                         if (helper.parent.is(":animated"))
21378                                 helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);
21379                         else
21380                                 helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
21381                 } else {
21382                         helper.parent.show();
21383                 }
21384                 update();
21385         }
21386         
21387         /**
21388          * callback for mousemove
21389          * updates the helper position
21390          * removes itself when no current element
21391          */
21392         function update(event)  {
21393                 if($.tooltip.blocked)
21394                         return;
21395                 
21396                 if (event && event.target.tagName == "OPTION") {
21397                         return;
21398                 }
21399                 
21400                 // stop updating when tracking is disabled and the tooltip is visible
21401                 if ( !track && helper.parent.is(":visible")) {
21402                         $(document.body).unbind('mousemove', update)
21403                 }
21404                 
21405                 // if no current element is available, remove this listener
21406                 if( current == null ) {
21407                         $(document.body).unbind('mousemove', update);
21408                         return; 
21409                 }
21410                 
21411                 // remove position helper classes
21412                 helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
21413                 
21414                 var left = helper.parent[0].offsetLeft;
21415                 var top = helper.parent[0].offsetTop;
21416                 if (event) {
21417                         // position the helper 15 pixel to bottom right, starting from mouse position
21418                         left = event.pageX + settings(current).left;
21419                         top = event.pageY + settings(current).top;
21420                         var right='auto';
21421                         if (settings(current).positionLeft) {
21422                                 right = $(window).width() - left;
21423                                 left = 'auto';
21424                         }
21425                         helper.parent.css({
21426                                 left: left,
21427                                 right: right,
21428                                 top: top
21429                         });
21430                 }
21431                 
21432                 var v = viewport(),
21433                         h = helper.parent[0];
21434                 // check horizontal position
21435                 if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
21436                         left -= h.offsetWidth + 20 + settings(current).left;
21437                         helper.parent.css({left: left + 'px'}).addClass("viewport-right");
21438                 }
21439                 // check vertical position
21440                 if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
21441                         top -= h.offsetHeight + 20 + settings(current).top;
21442                         helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
21443                 }
21444         }
21445         
21446         function viewport() {
21447                 return {
21448                         x: $(window).scrollLeft(),
21449                         y: $(window).scrollTop(),
21450                         cx: $(window).width(),
21451                         cy: $(window).height()
21452                 };
21453         }
21454         
21455         // hide helper and restore added classes and the title
21456         function hide(event) {
21457                 if($.tooltip.blocked)
21458                         return;
21459                 // clear timeout if possible
21460                 if(tID)
21461                         clearTimeout(tID);
21462                 // no more current element
21463                 current = null;
21464                 
21465                 var tsettings = settings(this);
21466                 function complete() {
21467                         helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");
21468                 }
21469                 if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
21470                         if (helper.parent.is(':animated'))
21471                                 helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
21472                         else
21473                                 helper.parent.stop().fadeOut(tsettings.fade, complete);
21474                 } else
21475                         complete();
21476                 
21477                 if( settings(this).fixPNG )
21478                         helper.parent.unfixPNG();
21479         }
21480         
21481 })(jQuery);
21482 /*!
21483 Math.uuid.js (v1.4)
21484 http://www.broofa.com
21485 mailto:robert@broofa.com
21486
21487 Copyright (c) 2010 Robert Kieffer
21488 Dual licensed under the MIT and GPL licenses.
21489 */
21490
21491 /*
21492  * Generate a random uuid.
21493  *
21494  * USAGE: Math.uuid(length, radix)
21495  *   length - the desired number of characters
21496  *   radix  - the number of allowable values for each character.
21497  *
21498  * EXAMPLES:
21499  *   // No arguments  - returns RFC4122, version 4 ID
21500  *   >>> Math.uuid()
21501  *   "92329D39-6F5C-4520-ABFC-AAB64544E172"
21502  *
21503  *   // One argument - returns ID of the specified length
21504  *   >>> Math.uuid(15)     // 15 character ID (default base=62)
21505  *   "VcydxgltxrVZSTV"
21506  *
21507  *   // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62)
21508  *   >>> Math.uuid(8, 2)  // 8 character ID (base=2)
21509  *   "01001010"
21510  *   >>> Math.uuid(8, 10) // 8 character ID (base=10)
21511  *   "47473046"
21512  *   >>> Math.uuid(8, 16) // 8 character ID (base=16)
21513  *   "098F4D35"
21514  */
21515 (function() {
21516   // Private array of chars to use
21517   var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
21518
21519   Math.uuid = function (len, radix) {
21520     var chars = CHARS, uuid = [], i;
21521     radix = radix || chars.length;
21522
21523     if (len) {
21524       // Compact form
21525       for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
21526     } else {
21527       // rfc4122, version 4 form
21528       var r;
21529
21530       // rfc4122 requires these characters
21531       uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
21532       uuid[14] = '4';
21533
21534       // Fill in random data.  At i==19 set the high bits of clock sequence as
21535       // per rfc4122, sec. 4.1.5
21536       for (i = 0; i < 36; i++) {
21537         if (!uuid[i]) {
21538           r = 0 | Math.random()*16;
21539           uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
21540         }
21541       }
21542     }
21543
21544     return uuid.join('');
21545   };
21546
21547   // A more performant, but slightly bulkier, RFC4122v4 solution.  We boost performance
21548   // by minimizing calls to random()
21549   Math.uuidFast = function() {
21550     var chars = CHARS, uuid = new Array(36), rnd=0, r;
21551     for (var i = 0; i < 36; i++) {
21552       if (i==8 || i==13 ||  i==18 || i==23) {
21553         uuid[i] = '-';
21554       } else if (i==14) {
21555         uuid[i] = '4';
21556       } else {
21557         if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0;
21558         r = rnd & 0xf;
21559         rnd = rnd >> 4;
21560         uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
21561       }
21562     }
21563     return uuid.join('');
21564   };
21565
21566   // A more compact, but less performant, RFC4122v4 solution:
21567   Math.uuidCompact = function() {
21568     return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
21569       var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
21570       return v.toString(16);
21571     });
21572   };
21573 })();
21574 // jXHR.js (JSON-P XHR)\r
21575 // v0.1 (c) Kyle Simpson\r
21576 // MIT License\r
21577 \r
21578 (function(global){\r
21579         var SETTIMEOUT = global.setTimeout, // for better compression\r
21580                 doc = global.document,\r
21581                 callback_counter = 0;\r
21582                 \r
21583         global.jXHR = function() {\r
21584                 var script_url,\r
21585                         script_loaded,\r
21586                         jsonp_callback,\r
21587                         scriptElem,\r
21588                         publicAPI = null;\r
21589                         \r
21590                 function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } }\r
21591                         \r
21592                 function reset() {\r
21593                         script_loaded = false;\r
21594                         script_url = "";\r
21595                         removeScript();\r
21596                         scriptElem = null;\r
21597                         fireReadyStateChange(0);\r
21598                 }\r
21599                 \r
21600                 function ThrowError(msg) {\r
21601                         try { publicAPI.onerror.call(publicAPI,msg,script_url); } catch (err) { throw new Error(msg); }\r
21602                 }\r
21603 \r
21604                 function handleScriptLoad() {\r
21605                         if ((this.readyState && this.readyState!=="complete" && this.readyState!=="loaded") || script_loaded) { return; }\r
21606                         this.onload = this.onreadystatechange = null; // prevent memory leak\r
21607                         script_loaded = true;\r
21608                         if (publicAPI.readyState !== 4) ThrowError("Script failed to load ["+script_url+"].");\r
21609                         removeScript();\r
21610                 }\r
21611                 \r
21612                 function fireReadyStateChange(rs,args) {\r
21613                         args = args || [];\r
21614                         publicAPI.readyState = rs;\r
21615                         if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args);\r
21616                 }\r
21617                                 \r
21618                 publicAPI = {\r
21619                         onerror:null,\r
21620                         onreadystatechange:null,\r
21621                         readyState:0,\r
21622                         open:function(method,url){\r
21623                                 reset();\r
21624                                 internal_callback = "cb"+(callback_counter++);\r
21625                                 (function(icb){\r
21626                                         global.jXHR[icb] = function() {\r
21627                                                 try { fireReadyStateChange.call(publicAPI,4,arguments); } \r
21628                                                 catch(err) { \r
21629                                                         publicAPI.readyState = -1;\r
21630                                                         ThrowError("Script failed to run ["+script_url+"]."); \r
21631                                                 }\r
21632                                                 global.jXHR[icb] = null;\r
21633                                         };\r
21634                                 })(internal_callback);\r
21635                                 script_url = url.replace(/=\?/,"=jXHR."+internal_callback);\r
21636                                 fireReadyStateChange(1);\r
21637                         },\r
21638                         send:function(){\r
21639                                 SETTIMEOUT(function(){\r
21640                                         scriptElem = doc.createElement("script");\r
21641                                         scriptElem.setAttribute("type","text/javascript");\r
21642                                         scriptElem.onload = scriptElem.onreadystatechange = function(){handleScriptLoad.call(scriptElem);};\r
21643                                         scriptElem.setAttribute("src",script_url);\r
21644                                         doc.getElementsByTagName("head")[0].appendChild(scriptElem);\r
21645                                 },0);\r
21646                                 fireReadyStateChange(2);\r
21647                         },\r
21648                         setRequestHeader:function(){}, // noop\r
21649                         getResponseHeader:function(){return "";}, // basically noop\r
21650                         getAllResponseHeaders:function(){return [];} // ditto\r
21651                 };\r
21652 \r
21653                 reset();\r
21654                 \r
21655                 return publicAPI;\r
21656         };\r
21657 })(window);//////////////////////////////////////////////////////////////////////////////
21658 //                                                                          //
21659 // Wii Opera SDK - 3D Math Class v2.7.22 2008-12-14                         //
21660 // (c) 2007-2008 Daniel Gump. All Rights Reserved.                          //
21661 // http://wiioperasdk.com, http://hullbreachonline.com                      //
21662 // hullbreach@hullbreachonline.com                                          //
21663 //                                                                          //
21664 //  Wii is a trademark of Nintendo Co., Ltd.                                //
21665 //  Opera is a trademark of Opera, ASA.                                     //
21666 //  This software package is not associated with either company             //
21667 //  but was created to support users of both.  Its alternative name         //
21668 //  when supporting other products is the HULLBREACH SDK.                   //
21669 //                                                                          //
21670 //  Redistribution and use in source and binary forms, with or without      //
21671 //  modification, are permitted provided that the following conditions      //
21672 //  are met:                                                                //
21673 //    * Redistributions of source code must retain the above copyright      //
21674 //      notice, this list of conditions and the following disclaimer.       //
21675 //    * Redistributions in binary form must reproduce the above copyright   //
21676 //      notice, this list of conditions and the following disclaimer in     //
21677 //      the documentation and/or other materials provided with the          //
21678 //      distribution.                                                       //
21679 //    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names //
21680 //      of its contributors may be used to endorse or promote products      //
21681 //      derived from this software without specific prior written           //
21682 //      permission.                                                         //
21683 //    * If the explicit purpose of the software is not to support the       //
21684 //      Nintendo Wii or the Opera Web browser, then the names of such must  //
21685 //      not be used in any derived product. The name shall be the           //
21686 //      HULLBREACH SDK with a reference link to http://hullbreachonline.    //
21687 //                                                                          //
21688 //  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   //
21689 //  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          //
21690 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  //
21691 //  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     //
21692 //  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      //
21693 //  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      //
21694 //  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      //
21695 //  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     //
21696 //  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   //
21697 //  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      //
21698 //  POSSIBILITY OF SUCH DAMAGE.                                             //
21699 //////////////////////////////////////////////////////////////////////////////
21700
21701 function ThreeD(){
21702         POLYMESH = new Array();
21703
21704         CENTERX = 400; CENTERY = 240;
21705         LIGHTX = -1000; LIGHTY = -1000; LIGHTZ = -1000;
21706         ORIGINX = 0; ORIGINY = 0; ORIGINZ = 0;
21707         ANGLEX = 0; ANGLEY = 0; ANGLEZ = 0;
21708 }
21709
21710 ThreeD.prototype.setPoints = function(Points){
21711         POLYMESH = [];
21712         for(var value=Points.length;--value>=0;) POLYMESH[value] = Points[value].slice();
21713 }
21714 ThreeD.prototype.loadMesh = function(array){
21715         if(POLYMESH = array.split(";")) for(i=POLYMESH.length;--i>=0;) POLYMESH[i] = POLYMESH[i].split(",");
21716 }
21717 ThreeD.prototype.getPoints = function(){ return POLYMESH; }
21718
21719 ThreeD.prototype.setCenter = function(x,y){ CENTERX = x|0; CENTERY = y|0; }
21720 ThreeD.prototype.setLight = function(x,y,z){ LIGHTX = x|0; LIGHTY = y|0; LIGHTZ = z|0; }
21721
21722 ThreeD.prototype.explode = function(z){
21723         var x1, y1, z1, x2, y2, z2;
21724         var normali, normalj, normalk, magNormal;
21725
21726         for(var value=POLYMESH.length;--value>=0;){
21727                 x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
21728                 x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
21729
21730                 normali = y2*z1-y1*z2; normalj = x1*z2-x2*z1; normalk = x2*y1-x1*y2;
21731                 magNormal = z/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
21732
21733                 var movex = -normali*magNormal|0;
21734                 var movey = -normalj*magNormal|0;
21735                 var movez = -normalk*magNormal|0;
21736
21737                 POLYMESH[value][0] += movex; POLYMESH[value][1] += movey; POLYMESH[value][2] += movez;
21738                 POLYMESH[value][3] += movex; POLYMESH[value][4] += movey; POLYMESH[value][5] += movez;
21739                 POLYMESH[value][6] += movex; POLYMESH[value][7] += movey; POLYMESH[value][8] += movez;
21740         }
21741 }
21742 ThreeD.prototype.normalMap = function(normalMap){
21743         var x1, y1, z1, x2, y2, z2;
21744         var normali, normalj, normalk, magNormal;
21745
21746         for(var value=POLYMESH.length;--value>=0;){
21747                 x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
21748                 x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
21749
21750                 normali = y2*z1-y1*z2; normalj = x1*z2-x2*z1; normalk = x2*y1-x1*y2;
21751                 normal = 1/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
21752                 
21753                 for(index2=0; index2<4; index2++){
21754                         for(index=0; index<=index2; index++){
21755                                 magNormal = normalMap[index][index2]*normal|0;
21756
21757                                 var movex = -normali*magNormal;
21758                                 var movey = -normalj*magNormal;
21759                                 var movez = -normalk*magNormal;
21760                                 
21761                                 POLYMESH[POLYMESH.length] = new Array(POLYMESH[value][0]+movex,POLYMESH[value][1]+movey,POLYMESH[value][2]+movez,
21762                                                         POLYMESH[value][3]+movex,POLYMESH[value][4]+movey,POLYMESH[value][7]+movez,
21763                                                         POLYMESH[value][6]+movex,POLYMESH[value][7]+movey,POLYMESH[value][8]+movez,
21764                                                         POLYMESH[value][9],POLYMESH[value][10],POLYMESH[value][11],
21765                                                         POLYMESH[value][12],POLYMESH[value][13], true, index, index2);
21766                         }
21767                 }
21768         }
21769 }
21770 ThreeD.prototype.move = function(x,y,z){
21771         for(var value=POLYMESH.length;--value>=0;)
21772                 for(var point=-1;++point<3;){
21773                         POLYMESH[value][point*3+2] += z;
21774                         POLYMESH[value][point*3+1] += y;
21775                         POLYMESH[value][point*3] += x;
21776                 }
21777 }
21778 ThreeD.prototype.rotate = function(anglex,angley,anglez){
21779         var cosx = Math.cos(anglex*0.01745329); var sinx = Math.sin(anglex*0.01745329);
21780         var cosy = Math.cos(angley*0.01745329); var siny = Math.sin(angley*0.01745329);
21781         var cosz = Math.cos(anglez*0.01745329); var sinz = Math.sin(anglez*0.01745329);
21782
21783         for(var value=POLYMESH.length;--value>=0;)
21784                 for(var point=-1;++point<3;){
21785                         var tempz = sinx*POLYMESH[value][point*3+1]+cosx*POLYMESH[value][point*3+2];
21786                         var tempy = cosx*POLYMESH[value][point*3+1]-sinx*POLYMESH[value][point*3+2];
21787                         var tempx = cosy*POLYMESH[value][point*3]+siny*tempz;
21788                         POLYMESH[value][point*3+2] = cosy*tempz-siny*POLYMESH[value][point*3];
21789                         POLYMESH[value][point*3+1] = sinz*tempx+cosz*tempy;
21790                         POLYMESH[value][point*3] = cosz*tempx-sinz*tempy;
21791                 }
21792 }
21793 ThreeD.prototype.scale = function(scalex,scaley,scalez){
21794         for(var value=POLYMESH.length;--value>=0;)
21795                 for(var point=-1;++point<3;){
21796                         POLYMESH[value][point*3+2] *= scalex;
21797                         POLYMESH[value][point*3+1] *= scaley;
21798                         POLYMESH[value][point*3] *= scalez;
21799                 }
21800 }
21801
21802 ThreeD.prototype.backface = function(){
21803         for(var value=POLYMESH.length, newvalue=0, TempPOLYMESH = [];--value>=0;)
21804                 if((POLYMESH[value][3]-POLYMESH[value][0])*(POLYMESH[value][7]-POLYMESH[value][1])-(POLYMESH[value][6]-POLYMESH[value][0])*(POLYMESH[value][4]-POLYMESH[value][1])>0){
21805                         TempPOLYMESH[newvalue++] = POLYMESH[value].slice();
21806                 }
21807         POLYMESH = TempPOLYMESH;
21808 }
21809 ThreeD.prototype.zSort = function(){ POLYMESH.sort(function(b,a){return b[2]+b[5]+b[8]-a[2]-a[5]-a[8]}); }
21810
21811 ThreeD.prototype.fade = function(bright){
21812         for(var value=POLYMESH.length;--value>=0;) POLYMESH[value][13] += bright;
21813 }
21814 ThreeD.prototype.shade = function(){
21815         var x1, y1, z1, x2, y2, z2;
21816         var normali, normalj, normalk, magNormal;
21817         var lighti, lightj, lightk, magLight;
21818
21819         for(var value=POLYMESH.length;--value>=0;){
21820                 x1 = POLYMESH[value][3]-POLYMESH[value][0]; y1 = POLYMESH[value][4]-POLYMESH[value][1]; z1 = POLYMESH[value][5]-POLYMESH[value][2]; 
21821                 x2 = POLYMESH[value][6]-POLYMESH[value][0]; y2 = POLYMESH[value][7]-POLYMESH[value][1]; z2 = POLYMESH[value][8]-POLYMESH[value][2]; 
21822
21823                 normali = y1*z2-y2*z1; normalj = x2*z1-x1*z2; normalk = x1*y2-x2*y1;
21824
21825                 lighti = LIGHTX-(POLYMESH[value][0]+POLYMESH[value][3]+POLYMESH[value][6])*0.33333333333333333;
21826                 lightj = LIGHTY-(POLYMESH[value][1]+POLYMESH[value][4]+POLYMESH[value][7])*0.33333333333333333;
21827                 lightk = LIGHTZ-(POLYMESH[value][2]+POLYMESH[value][5]+POLYMESH[value][8])*0.33333333333333333;
21828
21829                 POLYMESH[value][13] = 2*(normali*lighti + normalj*lightj + normalk*lightk)/Math.sqrt((normali*normali+normalj*normalj+normalk*normalk)*(lighti*lighti+lightj*lightj+lightk*lightk))-1;
21830         }
21831 }
21832 ThreeD.prototype.reColor = function(r,g,b){
21833         r=r>255?255:(r<0?0:r|0);
21834         g=g>255?255:(g<0?0:g|0);
21835         b=b>255?255:(b<0?0:b|0);
21836         for(var value=POLYMESH.length;--value>=0;){
21837                 POLYMESH[value][9]=r;
21838                 POLYMESH[value][10]=g;
21839                 POLYMESH[value][11]=b;
21840         }
21841 }
21842 ThreeD.prototype.shadow = function(){
21843         rayorigins = []; 
21844         raynormals = [];
21845         edge1 = [];
21846         edge2 = [];
21847
21848         for(var value=0, normali, normalj, normalk, magNormal;value<POLYMESH.length;value++){
21849                 edge1[value] = new Array(POLYMESH[value][3]-POLYMESH[value][0], POLYMESH[value][4]-POLYMESH[value][1], POLYMESH[value][5]-POLYMESH[value][2]);
21850                 edge2[value] = new Array(POLYMESH[value][6]-POLYMESH[value][0], POLYMESH[value][7]-POLYMESH[value][1], POLYMESH[value][8]-POLYMESH[value][2]);
21851
21852                 rayorigins[value] = new Array((POLYMESH[value][0]+POLYMESH[value][3]+POLYMESH[value][6])*0.33333333333333333, (POLYMESH[value][1]+POLYMESH[value][4]+POLYMESH[value][7])*0.33333333333333333, (POLYMESH[value][2]+POLYMESH[value][5]+POLYMESH[value][8])*0.33333333333333333);
21853
21854                 normali = LIGHTX-rayorigins[value][0];
21855                 normalj = LIGHTY-rayorigins[value][1];
21856                 normalk = LIGHTZ-rayorigins[value][2];
21857                 magNormal = 1/Math.sqrt(normali*normali+normalj*normalj+normalk*normalk);
21858                 raynormals[value] = new Array(normali*magNormal, normalj*magNormal, normalk*magNormal);
21859         }
21860
21861         for(var value=POLYMESH.length;--value>=0;){
21862                 for(var value2=POLYMESH.length;--value2>=0;){
21863                         if(value2!=value){
21864                                 var pvecti = raynormals[value][1]*edge2[value2][2]-edge2[value2][1]*raynormals[value][2];
21865                                 var pvectj = edge2[value2][0]*raynormals[value][2]-raynormals[value][0]*edge2[value2][2];
21866                                 var pvectk = raynormals[value][0]*edge2[value2][1]-edge2[value2][0]*raynormals[value][1];
21867
21868                                 if((det = edge1[value2][0]*pvecti+edge1[value2][1]*pvectj+edge1[value2][2]*pvectk)<0){
21869                                         det=1/det;
21870
21871                                         var tvecti = rayorigins[value][0]-POLYMESH[value2][0];
21872                                         var tvectj = rayorigins[value][1]-POLYMESH[value2][1];
21873                                         var tvectk = rayorigins[value][2]-POLYMESH[value2][2];
21874
21875                                         if((u = (pvecti*tvecti+pvectj*tvectj+pvectk*tvectk) * det)>=0 && u<=1){
21876                                                 if((v = (raynormals[value][0]*(tvectj*edge1[value2][2]-edge1[value2][1]*tvectk)+raynormals[value][1]*(edge1[value2][0]*tvectk-tvecti*edge1[value2][2])+raynormals[value][2]*(tvecti*edge1[value2][1]-edge1[value2][0]*tvectj)) * det)>=0 && u+v<=1){
21877                                                         POLYMESH[value][13] -=.5;
21878                                                         break;
21879                                                 }
21880                                         }
21881                                 }
21882                                 
21883                         }
21884                 }
21885         }
21886 }
21887
21888 ThreeD.prototype.getTranslation = function(){
21889         for(var value=POLYMESH.length,newvalue=0,TransPOLYMESH = [];--value>=0;){
21890                 var POLYMESH2=5000/(5000-POLYMESH[value][2]), POLYMESH5=5000/(5000-POLYMESH[value][5]), POLYMESH8=5000/(5000-POLYMESH[value][8]);
21891                 TransPOLYMESH[newvalue++] = new Array((CENTERX+POLYMESH[value][0]*POLYMESH2),(CENTERY+POLYMESH[value][1]*POLYMESH2),
21892                                                                         (CENTERX+POLYMESH[value][3]*POLYMESH5),(CENTERY+POLYMESH[value][4]*POLYMESH5),
21893                                                                         (CENTERX+POLYMESH[value][6]*POLYMESH8),(CENTERY+POLYMESH[value][7]*POLYMESH8),
21894                                                                         POLYMESH[value][9]|0,POLYMESH[value][10]|0,POLYMESH[value][11]|0,POLYMESH[value][12]|0,POLYMESH[value][13]);
21895         }
21896         return TransPOLYMESH;
21897 }
21898
21899 ThreeDee = new ThreeD();/**
21900  * @author mrdoob / http://mrdoob.com/
21901  */
21902
21903 var THREE = THREE || { REVISION: '51' };
21904
21905 if ( self.console === undefined ) {
21906
21907     self.console = {
21908
21909         info: function () {},
21910         log: function () {},
21911         debug: function () {},
21912         warn: function () {},
21913         error: function () {}
21914
21915     };
21916
21917 }
21918
21919 if ( self.Int32Array === undefined ) {
21920
21921     self.Int32Array = Array;
21922     self.Float32Array = Array;
21923
21924 }
21925
21926 // Shims for "startsWith", "endsWith", and "trim" for browsers where this is not yet implemented
21927 // not sure we should have this, or at least not have it here
21928
21929 // http://stackoverflow.com/questions/646628/javascript-startswith
21930 // http://stackoverflow.com/questions/498970/how-do-i-trim-a-string-in-javascript
21931 // http://wiki.ecmascript.org/doku.php?id=harmony%3astring_extras
21932
21933 if ( String.prototype.startsWith === undefined ) {
21934
21935     String.prototype.startsWith = function ( str ) {
21936
21937         return this.slice( 0, str.length ) === str;
21938
21939     };
21940
21941 }
21942
21943 if ( String.prototype.endsWith === undefined ) {
21944
21945     String.prototype.endsWith = function ( str ) {
21946
21947         var t = String( str );
21948         var index = this.lastIndexOf( t );
21949         return index >= 0 && index === this.length - t.length;
21950
21951     };
21952
21953 }
21954
21955 if ( ! String.prototype.trim === undefined ) {
21956
21957     String.prototype.trim = function () {
21958
21959         return this.replace( /^\s+|\s+$/g, '' );
21960
21961     };
21962
21963 }
21964
21965 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
21966 // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
21967
21968 // requestAnimationFrame polyfill by Erik Möller
21969 // fixes from Paul Irish and Tino Zijdel
21970
21971 ( function () {
21972
21973     var lastTime = 0;
21974     var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
21975
21976     for ( var x = 0; x < vendors.length && !window.requestAnimationFrame; ++ x ) {
21977
21978         window.requestAnimationFrame = window[ vendors[ x ] + 'RequestAnimationFrame' ];
21979         window.cancelAnimationFrame = window[ vendors[ x ] + 'CancelAnimationFrame' ] || window[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
21980
21981     }
21982
21983     if ( window.requestAnimationFrame === undefined ) {
21984
21985         window.requestAnimationFrame = function ( callback, element ) {
21986
21987             var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
21988             var id = window.setTimeout( function() { callback( currTime + timeToCall ); }, timeToCall );
21989             lastTime = currTime + timeToCall;
21990             return id;
21991
21992         };
21993
21994     }
21995
21996
21997     if ( window.cancelAnimationFrame === undefined ) {
21998
21999         window.cancelAnimationFrame = function ( id ) { clearTimeout( id ); };
22000
22001     }
22002
22003 }() );
22004
22005
22006 // MATERIAL CONSTANTS
22007
22008 // side
22009
22010 THREE.FrontSide = 0;
22011 THREE.BackSide = 1;
22012 THREE.DoubleSide = 2;
22013
22014 // shading
22015
22016 THREE.NoShading = 0;
22017 THREE.FlatShading = 1;
22018 THREE.SmoothShading = 2;
22019
22020 // colors
22021
22022 THREE.NoColors = 0;
22023 THREE.FaceColors = 1;
22024 THREE.VertexColors = 2;
22025
22026 // blending modes
22027
22028 THREE.NoBlending = 0;
22029 THREE.NormalBlending = 1;
22030 THREE.AdditiveBlending = 2;
22031 THREE.SubtractiveBlending = 3;
22032 THREE.MultiplyBlending = 4;
22033 THREE.CustomBlending = 5;
22034
22035 // custom blending equations
22036 // (numbers start from 100 not to clash with other
22037 //  mappings to OpenGL constants defined in Texture.js)
22038
22039 THREE.AddEquation = 100;
22040 THREE.SubtractEquation = 101;
22041 THREE.ReverseSubtractEquation = 102;
22042
22043 // custom blending destination factors
22044
22045 THREE.ZeroFactor = 200;
22046 THREE.OneFactor = 201;
22047 THREE.SrcColorFactor = 202;
22048 THREE.OneMinusSrcColorFactor = 203;
22049 THREE.SrcAlphaFactor = 204;
22050 THREE.OneMinusSrcAlphaFactor = 205;
22051 THREE.DstAlphaFactor = 206;
22052 THREE.OneMinusDstAlphaFactor = 207;
22053
22054 // custom blending source factors
22055
22056 //THREE.ZeroFactor = 200;
22057 //THREE.OneFactor = 201;
22058 //THREE.SrcAlphaFactor = 204;
22059 //THREE.OneMinusSrcAlphaFactor = 205;
22060 //THREE.DstAlphaFactor = 206;
22061 //THREE.OneMinusDstAlphaFactor = 207;
22062 THREE.DstColorFactor = 208;
22063 THREE.OneMinusDstColorFactor = 209;
22064 THREE.SrcAlphaSaturateFactor = 210;
22065
22066
22067 // TEXTURE CONSTANTS
22068
22069 THREE.MultiplyOperation = 0;
22070 THREE.MixOperation = 1;
22071
22072 // Mapping modes
22073
22074 THREE.UVMapping = function () {};
22075
22076 THREE.CubeReflectionMapping = function () {};
22077 THREE.CubeRefractionMapping = function () {};
22078
22079 THREE.SphericalReflectionMapping = function () {};
22080 THREE.SphericalRefractionMapping = function () {};
22081
22082 // Wrapping modes
22083
22084 THREE.RepeatWrapping = 1000;
22085 THREE.ClampToEdgeWrapping = 1001;
22086 THREE.MirroredRepeatWrapping = 1002;
22087
22088 // Filters
22089
22090 THREE.NearestFilter = 1003;
22091 THREE.NearestMipMapNearestFilter = 1004;
22092 THREE.NearestMipMapLinearFilter = 1005;
22093 THREE.LinearFilter = 1006;
22094 THREE.LinearMipMapNearestFilter = 1007;
22095 THREE.LinearMipMapLinearFilter = 1008;
22096
22097 // Data types
22098
22099 THREE.UnsignedByteType = 1009;
22100 THREE.ByteType = 1010;
22101 THREE.ShortType = 1011;
22102 THREE.UnsignedShortType = 1012;
22103 THREE.IntType = 1013;
22104 THREE.UnsignedIntType = 1014;
22105 THREE.FloatType = 1015;
22106
22107 // Pixel types
22108
22109 //THREE.UnsignedByteType = 1009;
22110 THREE.UnsignedShort4444Type = 1016;
22111 THREE.UnsignedShort5551Type = 1017;
22112 THREE.UnsignedShort565Type = 1018;
22113
22114 // Pixel formats
22115
22116 THREE.AlphaFormat = 1019;
22117 THREE.RGBFormat = 1020;
22118 THREE.RGBAFormat = 1021;
22119 THREE.LuminanceFormat = 1022;
22120 THREE.LuminanceAlphaFormat = 1023;
22121
22122 // Compressed texture formats
22123
22124 THREE.RGB_S3TC_DXT1_Format = 2001;
22125 THREE.RGBA_S3TC_DXT1_Format = 2002;
22126 THREE.RGBA_S3TC_DXT3_Format = 2003;
22127 THREE.RGBA_S3TC_DXT5_Format = 2004;
22128
22129 /*
22130 // Potential future PVRTC compressed texture formats
22131 THREE.RGB_PVRTC_4BPPV1_Format = 2100;
22132 THREE.RGB_PVRTC_2BPPV1_Format = 2101;
22133 THREE.RGBA_PVRTC_4BPPV1_Format = 2102;
22134 THREE.RGBA_PVRTC_2BPPV1_Format = 2103;
22135 */
22136 /**
22137  * @author alteredq / http://alteredqualia.com/
22138  */
22139
22140 THREE.Clock = function ( autoStart ) {
22141
22142     this.autoStart = ( autoStart !== undefined ) ? autoStart : true;
22143
22144     this.startTime = 0;
22145     this.oldTime = 0;
22146     this.elapsedTime = 0;
22147
22148     this.running = false;
22149
22150 };
22151
22152 THREE.Clock.prototype.start = function () {
22153
22154     this.startTime = Date.now();
22155     this.oldTime = this.startTime;
22156
22157     this.running = true;
22158
22159 };
22160
22161 THREE.Clock.prototype.stop = function () {
22162
22163     this.getElapsedTime();
22164
22165     this.running = false;
22166
22167 };
22168
22169 THREE.Clock.prototype.getElapsedTime = function () {
22170
22171     this.elapsedTime += this.getDelta();
22172
22173     return this.elapsedTime;
22174
22175 };
22176
22177
22178 THREE.Clock.prototype.getDelta = function () {
22179
22180     var diff = 0;
22181
22182     if ( this.autoStart && ! this.running ) {
22183
22184         this.start();
22185
22186     }
22187
22188     if ( this.running ) {
22189
22190         var newTime = Date.now();
22191         diff = 0.001 * ( newTime - this.oldTime );
22192         this.oldTime = newTime;
22193
22194         this.elapsedTime += diff;
22195
22196     }
22197
22198     return diff;
22199
22200 };/**
22201  * @author mrdoob / http://mrdoob.com/
22202  */
22203
22204 THREE.Color = function ( hex ) {
22205
22206     if ( hex !== undefined ) this.setHex( hex );
22207
22208     return this;
22209
22210 };
22211
22212 THREE.Color.prototype = {
22213
22214     constructor: THREE.Color,
22215
22216     r: 1, g: 1, b: 1,
22217
22218     copy: function ( color ) {
22219
22220         this.r = color.r;
22221         this.g = color.g;
22222         this.b = color.b;
22223
22224         return this;
22225
22226     },
22227
22228     copyGammaToLinear: function ( color ) {
22229
22230         this.r = color.r * color.r;
22231         this.g = color.g * color.g;
22232         this.b = color.b * color.b;
22233
22234         return this;
22235
22236     },
22237
22238     copyLinearToGamma: function ( color ) {
22239
22240         this.r = Math.sqrt( color.r );
22241         this.g = Math.sqrt( color.g );
22242         this.b = Math.sqrt( color.b );
22243
22244         return this;
22245
22246     },
22247
22248     convertGammaToLinear: function () {
22249
22250         var r = this.r, g = this.g, b = this.b;
22251
22252         this.r = r * r;
22253         this.g = g * g;
22254         this.b = b * b;
22255
22256         return this;
22257
22258     },
22259
22260     convertLinearToGamma: function () {
22261
22262         this.r = Math.sqrt( this.r );
22263         this.g = Math.sqrt( this.g );
22264         this.b = Math.sqrt( this.b );
22265
22266         return this;
22267
22268     },
22269
22270     setRGB: function ( r, g, b ) {
22271
22272         this.r = r;
22273         this.g = g;
22274         this.b = b;
22275
22276         return this;
22277
22278     },
22279
22280     setHSV: function ( h, s, v ) {
22281
22282         // based on MochiKit implementation by Bob Ippolito
22283         // h,s,v ranges are < 0.0 - 1.0 >
22284
22285         var i, f, p, q, t;
22286
22287         if ( v === 0 ) {
22288
22289             this.r = this.g = this.b = 0;
22290
22291         } else {
22292
22293             i = Math.floor( h * 6 );
22294             f = ( h * 6 ) - i;
22295             p = v * ( 1 - s );
22296             q = v * ( 1 - ( s * f ) );
22297             t = v * ( 1 - ( s * ( 1 - f ) ) );
22298
22299             if ( i === 0 ) {
22300
22301                 this.r = v;
22302                 this.g = t;
22303                 this.b = p;
22304
22305             } else if ( i === 1 ) {
22306
22307                 this.r = q;
22308                 this.g = v;
22309                 this.b = p;
22310
22311             } else if ( i === 2 ) {
22312
22313                 this.r = p;
22314                 this.g = v;
22315                 this.b = t;
22316
22317             } else if ( i === 3 ) {
22318
22319                 this.r = p;
22320                 this.g = q;
22321                 this.b = v;
22322
22323             } else if ( i === 4 ) {
22324
22325                 this.r = t;
22326                 this.g = p;
22327                 this.b = v;
22328
22329             } else if ( i === 5 ) {
22330
22331                 this.r = v;
22332                 this.g = p;
22333                 this.b = q;
22334
22335             }
22336
22337         }
22338
22339         return this;
22340
22341     },
22342
22343     setHex: function ( hex ) {
22344
22345         hex = Math.floor( hex );
22346
22347         this.r = ( hex >> 16 & 255 ) / 255;
22348         this.g = ( hex >> 8 & 255 ) / 255;
22349         this.b = ( hex & 255 ) / 255;
22350
22351         return this;
22352
22353     },
22354
22355     lerpSelf: function ( color, alpha ) {
22356
22357         this.r += ( color.r - this.r ) * alpha;
22358         this.g += ( color.g - this.g ) * alpha;
22359         this.b += ( color.b - this.b ) * alpha;
22360
22361         return this;
22362
22363     },
22364
22365     getHex: function () {
22366
22367         return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0;
22368
22369     },
22370
22371     getContextStyle: function () {
22372
22373         return 'rgb(' + ( ( this.r * 255 ) | 0 )  + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')';
22374
22375     },
22376
22377     clone: function () {
22378
22379         return new THREE.Color().setRGB( this.r, this.g, this.b );
22380
22381     }
22382
22383 };
22384 /**
22385  * @author mrdoob / http://mrdoob.com/
22386  * @author philogb / http://blog.thejit.org/
22387  * @author egraether / http://egraether.com/
22388  * @author zz85 / http://www.lab4games.net/zz85/blog
22389  */
22390
22391 THREE.Vector2 = function ( x, y ) {
22392
22393     this.x = x || 0;
22394     this.y = y || 0;
22395
22396 };
22397
22398 THREE.Vector2.prototype = {
22399
22400     constructor: THREE.Vector2,
22401
22402     set: function ( x, y ) {
22403
22404         this.x = x;
22405         this.y = y;
22406
22407         return this;
22408
22409     },
22410
22411     copy: function ( v ) {
22412
22413         this.x = v.x;
22414         this.y = v.y;
22415
22416         return this;
22417
22418     },
22419
22420     add: function ( a, b ) {
22421
22422         this.x = a.x + b.x;
22423         this.y = a.y + b.y;
22424
22425         return this;
22426
22427     },
22428
22429     addSelf: function ( v ) {
22430
22431         this.x += v.x;
22432         this.y += v.y;
22433
22434         return this;
22435
22436     },
22437
22438     sub: function ( a, b ) {
22439
22440         this.x = a.x - b.x;
22441         this.y = a.y - b.y;
22442
22443         return this;
22444
22445     },
22446
22447     subSelf: function ( v ) {
22448
22449         this.x -= v.x;
22450         this.y -= v.y;
22451
22452         return this;
22453
22454     },
22455
22456     multiplyScalar: function ( s ) {
22457
22458         this.x *= s;
22459         this.y *= s;
22460
22461         return this;
22462
22463     },
22464
22465     divideScalar: function ( s ) {
22466
22467         if ( s ) {
22468
22469             this.x /= s;
22470             this.y /= s;
22471
22472         } else {
22473
22474             this.set( 0, 0 );
22475
22476         }
22477
22478         return this;
22479
22480     },
22481
22482     negate: function() {
22483
22484         return this.multiplyScalar( - 1 );
22485
22486     },
22487
22488     dot: function ( v ) {
22489
22490         return this.x * v.x + this.y * v.y;
22491
22492     },
22493
22494     lengthSq: function () {
22495
22496         return this.x * this.x + this.y * this.y;
22497
22498     },
22499
22500     length: function () {
22501
22502         return Math.sqrt( this.lengthSq() );
22503
22504     },
22505
22506     normalize: function () {
22507
22508         return this.divideScalar( this.length() );
22509
22510     },
22511
22512     distanceTo: function ( v ) {
22513
22514         return Math.sqrt( this.distanceToSquared( v ) );
22515
22516     },
22517
22518     distanceToSquared: function ( v ) {
22519
22520         var dx = this.x - v.x, dy = this.y - v.y;
22521         return dx * dx + dy * dy;
22522
22523     },
22524
22525     setLength: function ( l ) {
22526
22527         return this.normalize().multiplyScalar( l );
22528
22529     },
22530
22531     lerpSelf: function ( v, alpha ) {
22532
22533         this.x += ( v.x - this.x ) * alpha;
22534         this.y += ( v.y - this.y ) * alpha;
22535
22536         return this;
22537
22538     },
22539
22540     equals: function( v ) {
22541
22542         return ( ( v.x === this.x ) && ( v.y === this.y ) );
22543
22544     },
22545
22546     isZero: function () {
22547
22548         return ( this.lengthSq() < 0.0001 /* almostZero */ );
22549
22550     },
22551
22552     clone: function () {
22553
22554         return new THREE.Vector2( this.x, this.y );
22555
22556     }
22557
22558 };
22559 /**
22560  * @author mrdoob / http://mrdoob.com/
22561  * @author kile / http://kile.stravaganza.org/
22562  * @author philogb / http://blog.thejit.org/
22563  * @author mikael emtinger / http://gomo.se/
22564  * @author egraether / http://egraether.com/
22565  * @author WestLangley / http://github.com/WestLangley
22566  */
22567
22568 THREE.Vector3 = function ( x, y, z ) {
22569
22570     this.x = x || 0;
22571     this.y = y || 0;
22572     this.z = z || 0;
22573
22574 };
22575
22576
22577 THREE.Vector3.prototype = {
22578
22579     constructor: THREE.Vector3,
22580
22581     set: function ( x, y, z ) {
22582
22583         this.x = x;
22584         this.y = y;
22585         this.z = z;
22586
22587         return this;
22588
22589     },
22590
22591     setX: function ( x ) {
22592
22593         this.x = x;
22594
22595         return this;
22596
22597     },
22598
22599     setY: function ( y ) {
22600
22601         this.y = y;
22602
22603         return this;
22604
22605     },
22606
22607     setZ: function ( z ) {
22608
22609         this.z = z;
22610
22611         return this;
22612
22613     },
22614
22615     copy: function ( v ) {
22616
22617         this.x = v.x;
22618         this.y = v.y;
22619         this.z = v.z;
22620
22621         return this;
22622
22623     },
22624
22625     add: function ( a, b ) {
22626
22627         this.x = a.x + b.x;
22628         this.y = a.y + b.y;
22629         this.z = a.z + b.z;
22630
22631         return this;
22632
22633     },
22634
22635     addSelf: function ( v ) {
22636
22637         this.x += v.x;
22638         this.y += v.y;
22639         this.z += v.z;
22640
22641         return this;
22642
22643     },
22644
22645     addScalar: function ( s ) {
22646
22647         this.x += s;
22648         this.y += s;
22649         this.z += s;
22650
22651         return this;
22652
22653     },
22654
22655     sub: function ( a, b ) {
22656
22657         this.x = a.x - b.x;
22658         this.y = a.y - b.y;
22659         this.z = a.z - b.z;
22660
22661         return this;
22662
22663     },
22664
22665     subSelf: function ( v ) {
22666
22667         this.x -= v.x;
22668         this.y -= v.y;
22669         this.z -= v.z;
22670
22671         return this;
22672
22673     },
22674
22675     multiply: function ( a, b ) {
22676
22677         this.x = a.x * b.x;
22678         this.y = a.y * b.y;
22679         this.z = a.z * b.z;
22680
22681         return this;
22682
22683     },
22684
22685     multiplySelf: function ( v ) {
22686
22687         this.x *= v.x;
22688         this.y *= v.y;
22689         this.z *= v.z;
22690
22691         return this;
22692
22693     },
22694
22695     multiplyScalar: function ( s ) {
22696
22697         this.x *= s;
22698         this.y *= s;
22699         this.z *= s;
22700
22701         return this;
22702
22703     },
22704
22705     divideSelf: function ( v ) {
22706
22707         this.x /= v.x;
22708         this.y /= v.y;
22709         this.z /= v.z;
22710
22711         return this;
22712
22713     },
22714
22715     divideScalar: function ( s ) {
22716
22717         if ( s ) {
22718
22719             this.x /= s;
22720             this.y /= s;
22721             this.z /= s;
22722
22723         } else {
22724
22725             this.x = 0;
22726             this.y = 0;
22727             this.z = 0;
22728
22729         }
22730
22731         return this;
22732
22733     },
22734
22735
22736     negate: function() {
22737
22738         return this.multiplyScalar( - 1 );
22739
22740     },
22741
22742     dot: function ( v ) {
22743
22744         return this.x * v.x + this.y * v.y + this.z * v.z;
22745
22746     },
22747
22748     lengthSq: function () {
22749
22750         return this.x * this.x + this.y * this.y + this.z * this.z;
22751
22752     },
22753
22754     length: function () {
22755
22756         return Math.sqrt( this.lengthSq() );
22757
22758     },
22759
22760     lengthManhattan: function () {
22761
22762         return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z );
22763
22764     },
22765
22766     normalize: function () {
22767
22768         return this.divideScalar( this.length() );
22769
22770     },
22771
22772     setLength: function ( l ) {
22773
22774         return this.normalize().multiplyScalar( l );
22775
22776     },
22777
22778     lerpSelf: function ( v, alpha ) {
22779
22780         this.x += ( v.x - this.x ) * alpha;
22781         this.y += ( v.y - this.y ) * alpha;
22782         this.z += ( v.z - this.z ) * alpha;
22783
22784         return this;
22785
22786     },
22787
22788     cross: function ( a, b ) {
22789
22790         this.x = a.y * b.z - a.z * b.y;
22791         this.y = a.z * b.x - a.x * b.z;
22792         this.z = a.x * b.y - a.y * b.x;
22793
22794         return this;
22795
22796     },
22797
22798     crossSelf: function ( v ) {
22799
22800         var x = this.x, y = this.y, z = this.z;
22801
22802         this.x = y * v.z - z * v.y;
22803         this.y = z * v.x - x * v.z;
22804         this.z = x * v.y - y * v.x;
22805
22806         return this;
22807
22808     },
22809
22810     distanceTo: function ( v ) {
22811
22812         return Math.sqrt( this.distanceToSquared( v ) );
22813
22814     },
22815
22816     distanceToSquared: function ( v ) {
22817
22818         return new THREE.Vector3().sub( this, v ).lengthSq();
22819
22820     },
22821
22822     getPositionFromMatrix: function ( m ) {
22823
22824         this.x = m.elements[12];
22825         this.y = m.elements[13];
22826         this.z = m.elements[14];
22827
22828         return this;
22829
22830     },
22831
22832     setEulerFromRotationMatrix: function ( m, order ) {
22833
22834         // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
22835
22836         // clamp, to handle numerical problems
22837
22838         function clamp( x ) {
22839
22840             return Math.min( Math.max( x, -1 ), 1 );
22841
22842         }
22843
22844         var te = m.elements;
22845         var m11 = te[0], m12 = te[4], m13 = te[8];
22846         var m21 = te[1], m22 = te[5], m23 = te[9];
22847         var m31 = te[2], m32 = te[6], m33 = te[10];
22848
22849         if ( order === undefined || order === 'XYZ' ) {
22850
22851             this.y = Math.asin( clamp( m13 ) );
22852
22853             if ( Math.abs( m13 ) < 0.99999 ) {
22854
22855                 this.x = Math.atan2( - m23, m33 );
22856                 this.z = Math.atan2( - m12, m11 );
22857
22858             } else {
22859
22860                 this.x = Math.atan2( m32, m22 );
22861                 this.z = 0;
22862
22863             }
22864
22865         } else if ( order === 'YXZ' ) {
22866
22867             this.x = Math.asin( - clamp( m23 ) );
22868
22869             if ( Math.abs( m23 ) < 0.99999 ) {
22870
22871                 this.y = Math.atan2( m13, m33 );
22872                 this.z = Math.atan2( m21, m22 );
22873
22874             } else {
22875
22876                 this.y = Math.atan2( - m31, m11 );
22877                 this.z = 0;
22878
22879             }
22880
22881         } else if ( order === 'ZXY' ) {
22882
22883             this.x = Math.asin( clamp( m32 ) );
22884
22885             if ( Math.abs( m32 ) < 0.99999 ) {
22886
22887                 this.y = Math.atan2( - m31, m33 );
22888                 this.z = Math.atan2( - m12, m22 );
22889
22890             } else {
22891
22892                 this.y = 0;
22893                 this.z = Math.atan2( m21, m11 );
22894
22895             }
22896
22897         } else if ( order === 'ZYX' ) {
22898
22899             this.y = Math.asin( - clamp( m31 ) );
22900
22901             if ( Math.abs( m31 ) < 0.99999 ) {
22902
22903                 this.x = Math.atan2( m32, m33 );
22904                 this.z = Math.atan2( m21, m11 );
22905
22906             } else {
22907
22908                 this.x = 0;
22909                 this.z = Math.atan2( - m12, m22 );
22910
22911             }
22912
22913         } else if ( order === 'YZX' ) {
22914
22915             this.z = Math.asin( clamp( m21 ) );
22916
22917             if ( Math.abs( m21 ) < 0.99999 ) {
22918
22919                 this.x = Math.atan2( - m23, m22 );
22920                 this.y = Math.atan2( - m31, m11 );
22921
22922             } else {
22923
22924                 this.x = 0;
22925                 this.y = Math.atan2( m13, m33 );
22926
22927             }
22928
22929         } else if ( order === 'XZY' ) {
22930
22931             this.z = Math.asin( - clamp( m12 ) );
22932
22933             if ( Math.abs( m12 ) < 0.99999 ) {
22934
22935                 this.x = Math.atan2( m32, m22 );
22936                 this.y = Math.atan2( m13, m11 );
22937
22938             } else {
22939
22940                 this.x = Math.atan2( - m23, m33 );
22941                 this.y = 0;
22942
22943             }
22944
22945         }
22946
22947         return this;
22948
22949     },
22950
22951     setEulerFromQuaternion: function ( q, order ) {
22952
22953         // q is assumed to be normalized
22954
22955         // clamp, to handle numerical problems
22956
22957         function clamp( x ) {
22958
22959             return Math.min( Math.max( x, -1 ), 1 );
22960
22961         }
22962
22963         // http://www.mathworks.com/matlabcentral/fileexchange/20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/content/SpinCalc.m
22964
22965         var sqx = q.x * q.x;
22966         var sqy = q.y * q.y;
22967         var sqz = q.z * q.z;
22968         var sqw = q.w * q.w;
22969
22970         if ( order === undefined || order === 'XYZ' ) {
22971
22972             this.x = Math.atan2( 2 * ( q.x * q.w - q.y * q.z ), ( sqw - sqx - sqy + sqz ) );
22973             this.y = Math.asin(  clamp( 2 * ( q.x * q.z + q.y * q.w ) ) );
22974             this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw + sqx - sqy - sqz ) );
22975
22976         } else if ( order ===  'YXZ' ) {
22977
22978             this.x = Math.asin(  clamp( 2 * ( q.x * q.w - q.y * q.z ) ) );
22979             this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw - sqx - sqy + sqz ) );
22980             this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw - sqx + sqy - sqz ) );
22981
22982         } else if ( order === 'ZXY' ) {
22983
22984             this.x = Math.asin(  clamp( 2 * ( q.x * q.w + q.y * q.z ) ) );
22985             this.y = Math.atan2( 2 * ( q.y * q.w - q.z * q.x ), ( sqw - sqx - sqy + sqz ) );
22986             this.z = Math.atan2( 2 * ( q.z * q.w - q.x * q.y ), ( sqw - sqx + sqy - sqz ) );
22987
22988         } else if ( order === 'ZYX' ) {
22989
22990             this.x = Math.atan2( 2 * ( q.x * q.w + q.z * q.y ), ( sqw - sqx - sqy + sqz ) );
22991             this.y = Math.asin(  clamp( 2 * ( q.y * q.w - q.x * q.z ) ) );
22992             this.z = Math.atan2( 2 * ( q.x * q.y + q.z * q.w ), ( sqw + sqx - sqy - sqz ) );
22993
22994         } else if ( order === 'YZX' ) {
22995
22996             this.x = Math.atan2( 2 * ( q.x * q.w - q.z * q.y ), ( sqw - sqx + sqy - sqz ) );
22997             this.y = Math.atan2( 2 * ( q.y * q.w - q.x * q.z ), ( sqw + sqx - sqy - sqz ) );
22998             this.z = Math.asin(  clamp( 2 * ( q.x * q.y + q.z * q.w ) ) );
22999
23000         } else if ( order === 'XZY' ) {
23001
23002             this.x = Math.atan2( 2 * ( q.x * q.w + q.y * q.z ), ( sqw - sqx + sqy - sqz ) );
23003             this.y = Math.atan2( 2 * ( q.x * q.z + q.y * q.w ), ( sqw + sqx - sqy - sqz ) );
23004             this.z = Math.asin(  clamp( 2 * ( q.z * q.w - q.x * q.y ) ) );
23005
23006         }
23007
23008         return this;
23009
23010     },
23011
23012     getScaleFromMatrix: function ( m ) {
23013
23014         var sx = this.set( m.elements[0], m.elements[1], m.elements[2] ).length();
23015         var sy = this.set( m.elements[4], m.elements[5], m.elements[6] ).length();
23016         var sz = this.set( m.elements[8], m.elements[9], m.elements[10] ).length();
23017
23018         this.x = sx;
23019         this.y = sy;
23020         this.z = sz;
23021
23022         return this;
23023     },
23024
23025     equals: function ( v ) {
23026
23027         return ( ( v.x === this.x ) && ( v.y === this.y ) && ( v.z === this.z ) );
23028
23029     },
23030
23031     isZero: function () {
23032
23033         return ( this.lengthSq() < 0.0001 /* almostZero */ );
23034
23035     },
23036
23037     clone: function () {
23038
23039         return new THREE.Vector3( this.x, this.y, this.z );
23040
23041     }
23042
23043 };
23044
23045 /**
23046  * @author supereggbert / http://www.paulbrunt.co.uk/
23047  * @author philogb / http://blog.thejit.org/
23048  * @author mikael emtinger / http://gomo.se/
23049  * @author egraether / http://egraether.com/
23050  * @author WestLangley / http://github.com/WestLangley
23051  */
23052
23053 THREE.Vector4 = function ( x, y, z, w ) {
23054
23055     this.x = x || 0;
23056     this.y = y || 0;
23057     this.z = z || 0;
23058     this.w = ( w !== undefined ) ? w : 1;
23059
23060 };
23061
23062 THREE.Vector4.prototype = {
23063
23064     constructor: THREE.Vector4,
23065
23066     set: function ( x, y, z, w ) {
23067
23068         this.x = x;
23069         this.y = y;
23070         this.z = z;
23071         this.w = w;
23072
23073         return this;
23074
23075     },
23076
23077     copy: function ( v ) {
23078
23079         this.x = v.x;
23080         this.y = v.y;
23081         this.z = v.z;
23082         this.w = ( v.w !== undefined ) ? v.w : 1;
23083
23084         return this;
23085
23086     },
23087
23088     add: function ( a, b ) {
23089
23090         this.x = a.x + b.x;
23091         this.y = a.y + b.y;
23092         this.z = a.z + b.z;
23093         this.w = a.w + b.w;
23094
23095         return this;
23096
23097     },
23098
23099     addSelf: function ( v ) {
23100
23101         this.x += v.x;
23102         this.y += v.y;
23103         this.z += v.z;
23104         this.w += v.w;
23105
23106         return this;
23107
23108     },
23109
23110     sub: function ( a, b ) {
23111
23112         this.x = a.x - b.x;
23113         this.y = a.y - b.y;
23114         this.z = a.z - b.z;
23115         this.w = a.w - b.w;
23116
23117         return this;
23118
23119     },
23120
23121     subSelf: function ( v ) {
23122
23123         this.x -= v.x;
23124         this.y -= v.y;
23125         this.z -= v.z;
23126         this.w -= v.w;
23127
23128         return this;
23129
23130     },
23131
23132     multiplyScalar: function ( s ) {
23133
23134         this.x *= s;
23135         this.y *= s;
23136         this.z *= s;
23137         this.w *= s;
23138
23139         return this;
23140
23141     },
23142
23143     divideScalar: function ( s ) {
23144
23145         if ( s ) {
23146
23147             this.x /= s;
23148             this.y /= s;
23149             this.z /= s;
23150             this.w /= s;
23151
23152         } else {
23153
23154             this.x = 0;
23155             this.y = 0;
23156             this.z = 0;
23157             this.w = 1;
23158
23159         }
23160
23161         return this;
23162
23163     },
23164
23165
23166     negate: function() {
23167
23168         return this.multiplyScalar( -1 );
23169
23170     },
23171
23172     dot: function ( v ) {
23173
23174         return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
23175
23176     },
23177
23178     lengthSq: function () {
23179
23180         return this.dot( this );
23181
23182     },
23183
23184     length: function () {
23185
23186         return Math.sqrt( this.lengthSq() );
23187
23188     },
23189
23190     lengthManhattan: function () {
23191
23192         return Math.abs( this.x ) + Math.abs( this.y ) + Math.abs( this.z ) + Math.abs( this.w );
23193
23194     },
23195
23196     normalize: function () {
23197
23198         return this.divideScalar( this.length() );
23199
23200     },
23201
23202     setLength: function ( l ) {
23203
23204         return this.normalize().multiplyScalar( l );
23205
23206     },
23207
23208     lerpSelf: function ( v, alpha ) {
23209
23210         this.x += ( v.x - this.x ) * alpha;
23211         this.y += ( v.y - this.y ) * alpha;
23212         this.z += ( v.z - this.z ) * alpha;
23213         this.w += ( v.w - this.w ) * alpha;
23214
23215         return this;
23216
23217     },
23218
23219     clone: function () {
23220
23221         return new THREE.Vector4( this.x, this.y, this.z, this.w );
23222
23223     },
23224
23225     setAxisAngleFromQuaternion: function ( q ) {
23226
23227         // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
23228
23229         // q is assumed to be normalized
23230
23231         this.w = 2 * Math.acos( q.w );
23232
23233         var s = Math.sqrt( 1 - q.w * q.w );
23234
23235         if ( s < 0.0001 ) {
23236
23237              this.x = 1;
23238              this.y = 0;
23239              this.z = 0;
23240
23241         } else {
23242
23243              this.x = q.x / s;
23244              this.y = q.y / s;
23245              this.z = q.z / s;
23246
23247         }
23248
23249         return this;
23250
23251     },
23252
23253     setAxisAngleFromRotationMatrix: function ( m ) {
23254
23255         // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
23256
23257         // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
23258
23259         var angle, x, y, z,        // variables for result
23260             epsilon = 0.01,        // margin to allow for rounding errors
23261             epsilon2 = 0.1,        // margin to distinguish between 0 and 180 degrees
23262
23263             te = m.elements,
23264
23265             m11 = te[0], m12 = te[4], m13 = te[8],
23266             m21 = te[1], m22 = te[5], m23 = te[9],
23267             m31 = te[2], m32 = te[6], m33 = te[10];
23268
23269         if ( ( Math.abs( m12 - m21 ) < epsilon )
23270           && ( Math.abs( m13 - m31 ) < epsilon )
23271           && ( Math.abs( m23 - m32 ) < epsilon ) ) {
23272
23273             // singularity found
23274             // first check for identity matrix which must have +1 for all terms
23275             // in leading diagonal and zero in other terms
23276
23277             if ( ( Math.abs( m12 + m21 ) < epsilon2 )
23278               && ( Math.abs( m13 + m31 ) < epsilon2 )
23279               && ( Math.abs( m23 + m32 ) < epsilon2 )
23280               && ( Math.abs( m11 + m22 + m33 - 3 ) < epsilon2 ) ) {
23281
23282                 // this singularity is identity matrix so angle = 0
23283
23284                 this.set( 1, 0, 0, 0 );
23285
23286                 return this; // zero angle, arbitrary axis
23287
23288             }
23289
23290             // otherwise this singularity is angle = 180
23291
23292             angle = Math.PI;
23293
23294             var xx = ( m11 + 1 ) / 2;
23295             var yy = ( m22 + 1 ) / 2;
23296             var zz = ( m33 + 1 ) / 2;
23297             var xy = ( m12 + m21 ) / 4;
23298             var xz = ( m13 + m31 ) / 4;
23299             var yz = ( m23 + m32 ) / 4;
23300
23301             if ( ( xx > yy ) && ( xx > zz ) ) { // m11 is the largest diagonal term
23302
23303                 if ( xx < epsilon ) {
23304
23305                     x = 0;
23306                     y = 0.707106781;
23307                     z = 0.707106781;
23308
23309                 } else {
23310
23311                     x = Math.sqrt( xx );
23312                     y = xy / x;
23313                     z = xz / x;
23314
23315                 }
23316
23317             } else if ( yy > zz ) { // m22 is the largest diagonal term
23318
23319                 if ( yy < epsilon ) {
23320
23321                     x = 0.707106781;
23322                     y = 0;
23323                     z = 0.707106781;
23324
23325                 } else {
23326
23327                     y = Math.sqrt( yy );
23328                     x = xy / y;
23329                     z = yz / y;
23330
23331                 }
23332
23333             } else { // m33 is the largest diagonal term so base result on this
23334
23335                 if ( zz < epsilon ) {
23336
23337                     x = 0.707106781;
23338                     y = 0.707106781;
23339                     z = 0;
23340
23341                 } else {
23342
23343                     z = Math.sqrt( zz );
23344                     x = xz / z;
23345                     y = yz / z;
23346
23347                 }
23348
23349             }
23350
23351             this.set( x, y, z, angle );
23352
23353             return this; // return 180 deg rotation
23354
23355         }
23356
23357         // as we have reached here there are no singularities so we can handle normally
23358
23359         var s = Math.sqrt( ( m32 - m23 ) * ( m32 - m23 )
23360                          + ( m13 - m31 ) * ( m13 - m31 )
23361                          + ( m21 - m12 ) * ( m21 - m12 ) ); // used to normalize
23362
23363         if ( Math.abs( s ) < 0.001 ) s = 1;
23364
23365         // prevent divide by zero, should not happen if matrix is orthogonal and should be
23366         // caught by singularity test above, but I've left it in just in case
23367
23368         this.x = ( m32 - m23 ) / s;
23369         this.y = ( m13 - m31 ) / s;
23370         this.z = ( m21 - m12 ) / s;
23371         this.w = Math.acos( ( m11 + m22 + m33 - 1 ) / 2 );
23372
23373         return this;
23374
23375     }
23376
23377 };
23378 /**
23379  * @author alteredq / http://alteredqualia.com/
23380  */
23381
23382 THREE.Matrix3 = function () {
23383
23384     this.elements = new Float32Array(9);
23385
23386 };
23387
23388 THREE.Matrix3.prototype = {
23389
23390     constructor: THREE.Matrix3,
23391
23392     getInverse: function ( matrix ) {
23393
23394         // input: THREE.Matrix4
23395         // ( based on http://code.google.com/p/webgl-mjs/ )
23396
23397         var me = matrix.elements;
23398
23399         var a11 =   me[10] * me[5] - me[6] * me[9];
23400         var a21 = - me[10] * me[1] + me[2] * me[9];
23401         var a31 =   me[6] * me[1] - me[2] * me[5];
23402         var a12 = - me[10] * me[4] + me[6] * me[8];
23403         var a22 =   me[10] * me[0] - me[2] * me[8];
23404         var a32 = - me[6] * me[0] + me[2] * me[4];
23405         var a13 =   me[9] * me[4] - me[5] * me[8];
23406         var a23 = - me[9] * me[0] + me[1] * me[8];
23407         var a33 =   me[5] * me[0] - me[1] * me[4];
23408
23409         var det = me[0] * a11 + me[1] * a12 + me[2] * a13;
23410
23411         // no inverse
23412
23413         if ( det === 0 ) {
23414
23415             console.warn( "Matrix3.getInverse(): determinant == 0" );
23416
23417         }
23418
23419         var idet = 1.0 / det;
23420
23421         var m = this.elements;
23422
23423         m[ 0 ] = idet * a11; m[ 1 ] = idet * a21; m[ 2 ] = idet * a31;
23424         m[ 3 ] = idet * a12; m[ 4 ] = idet * a22; m[ 5 ] = idet * a32;
23425         m[ 6 ] = idet * a13; m[ 7 ] = idet * a23; m[ 8 ] = idet * a33;
23426
23427         return this;
23428
23429     },
23430
23431
23432     transpose: function () {
23433
23434         var tmp, m = this.elements;
23435
23436         tmp = m[1]; m[1] = m[3]; m[3] = tmp;
23437         tmp = m[2]; m[2] = m[6]; m[6] = tmp;
23438         tmp = m[5]; m[5] = m[7]; m[7] = tmp;
23439
23440         return this;
23441
23442     },
23443
23444
23445     transposeIntoArray: function ( r ) {
23446
23447         var m = this.m;
23448
23449         r[ 0 ] = m[ 0 ];
23450         r[ 1 ] = m[ 3 ];
23451         r[ 2 ] = m[ 6 ];
23452         r[ 3 ] = m[ 1 ];
23453         r[ 4 ] = m[ 4 ];
23454         r[ 5 ] = m[ 7 ];
23455         r[ 6 ] = m[ 2 ];
23456         r[ 7 ] = m[ 5 ];
23457         r[ 8 ] = m[ 8 ];
23458
23459         return this;
23460
23461     }
23462
23463 };
23464 /**
23465  * @author mrdoob / http://mrdoob.com/
23466  * @author supereggbert / http://www.paulbrunt.co.uk/
23467  * @author philogb / http://blog.thejit.org/
23468  * @author jordi_ros / http://plattsoft.com
23469  * @author D1plo1d / http://github.com/D1plo1d
23470  * @author alteredq / http://alteredqualia.com/
23471  * @author mikael emtinger / http://gomo.se/
23472  * @author timknip / http://www.floorplanner.com/
23473  */
23474
23475
23476 THREE.Matrix4 = function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
23477
23478     this.elements = new Float32Array( 16 );
23479
23480     this.set(
23481
23482         ( n11 !== undefined ) ? n11 : 1, n12 || 0, n13 || 0, n14 || 0,
23483         n21 || 0, ( n22 !== undefined ) ? n22 : 1, n23 || 0, n24 || 0,
23484         n31 || 0, n32 || 0, ( n33 !== undefined ) ? n33 : 1, n34 || 0,
23485         n41 || 0, n42 || 0, n43 || 0, ( n44 !== undefined ) ? n44 : 1
23486
23487     );
23488
23489 };
23490
23491 THREE.Matrix4.prototype = {
23492
23493     constructor: THREE.Matrix4,
23494
23495     set: function ( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
23496
23497         var te = this.elements;
23498
23499         te[0] = n11; te[4] = n12; te[8] = n13; te[12] = n14;
23500         te[1] = n21; te[5] = n22; te[9] = n23; te[13] = n24;
23501         te[2] = n31; te[6] = n32; te[10] = n33; te[14] = n34;
23502         te[3] = n41; te[7] = n42; te[11] = n43; te[15] = n44;
23503
23504         return this;
23505
23506     },
23507
23508     identity: function () {
23509
23510         this.set(
23511
23512             1, 0, 0, 0,
23513             0, 1, 0, 0,
23514             0, 0, 1, 0,
23515             0, 0, 0, 1
23516
23517         );
23518
23519         return this;
23520
23521     },
23522
23523     copy: function ( m ) {
23524
23525         var me = m.elements;
23526
23527         this.set(
23528
23529             me[0], me[4], me[8], me[12],
23530             me[1], me[5], me[9], me[13],
23531             me[2], me[6], me[10], me[14],
23532             me[3], me[7], me[11], me[15]
23533
23534         );
23535
23536         return this;
23537
23538     },
23539
23540     lookAt: function ( eye, target, up ) {
23541
23542         var te = this.elements;
23543
23544         var x = THREE.Matrix4.__v1;
23545         var y = THREE.Matrix4.__v2;
23546         var z = THREE.Matrix4.__v3;
23547
23548         z.sub( eye, target ).normalize();
23549
23550         if ( z.length() === 0 ) {
23551
23552             z.z = 1;
23553
23554         }
23555
23556         x.cross( up, z ).normalize();
23557
23558         if ( x.length() === 0 ) {
23559
23560             z.x += 0.0001;
23561             x.cross( up, z ).normalize();
23562
23563         }
23564
23565         y.cross( z, x );
23566
23567
23568         te[0] = x.x; te[4] = y.x; te[8] = z.x;
23569         te[1] = x.y; te[5] = y.y; te[9] = z.y;
23570         te[2] = x.z; te[6] = y.z; te[10] = z.z;
23571
23572         return this;
23573
23574     },
23575
23576     multiply: function ( a, b ) {
23577
23578         var ae = a.elements;
23579         var be = b.elements;
23580         var te = this.elements;
23581
23582         var a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12];
23583         var a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13];
23584         var a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14];
23585         var a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15];
23586
23587         var b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12];
23588         var b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13];
23589         var b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14];
23590         var b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15];
23591
23592         te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
23593         te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
23594         te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
23595         te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
23596
23597         te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
23598         te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
23599         te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
23600         te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
23601
23602         te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
23603         te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
23604         te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
23605         te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
23606
23607         te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
23608         te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
23609         te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
23610         te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
23611
23612         return this;
23613
23614     },
23615
23616     multiplySelf: function ( m ) {
23617
23618         return this.multiply( this, m );
23619
23620     },
23621
23622     multiplyToArray: function ( a, b, r ) {
23623
23624         var te = this.elements;
23625
23626         this.multiply( a, b );
23627
23628         r[ 0 ] = te[0]; r[ 1 ] = te[1]; r[ 2 ] = te[2]; r[ 3 ] = te[3];
23629         r[ 4 ] = te[4]; r[ 5 ] = te[5]; r[ 6 ] = te[6]; r[ 7 ] = te[7];
23630         r[ 8 ]  = te[8]; r[ 9 ]  = te[9]; r[ 10 ] = te[10]; r[ 11 ] = te[11];
23631         r[ 12 ] = te[12]; r[ 13 ] = te[13]; r[ 14 ] = te[14]; r[ 15 ] = te[15];
23632
23633         return this;
23634
23635     },
23636
23637     multiplyScalar: function ( s ) {
23638
23639         var te = this.elements;
23640
23641         te[0] *= s; te[4] *= s; te[8] *= s; te[12] *= s;
23642         te[1] *= s; te[5] *= s; te[9] *= s; te[13] *= s;
23643         te[2] *= s; te[6] *= s; te[10] *= s; te[14] *= s;
23644         te[3] *= s; te[7] *= s; te[11] *= s; te[15] *= s;
23645
23646         return this;
23647
23648     },
23649
23650     multiplyVector3: function ( v ) {
23651
23652         var te = this.elements;
23653
23654         var vx = v.x, vy = v.y, vz = v.z;
23655         var d = 1 / ( te[3] * vx + te[7] * vy + te[11] * vz + te[15] );
23656
23657         v.x = ( te[0] * vx + te[4] * vy + te[8] * vz + te[12] ) * d;
23658         v.y = ( te[1] * vx + te[5] * vy + te[9] * vz + te[13] ) * d;
23659         v.z = ( te[2] * vx + te[6] * vy + te[10] * vz + te[14] ) * d;
23660
23661         return v;
23662
23663     },
23664
23665     multiplyVector4: function ( v ) {
23666
23667         var te = this.elements;
23668         var vx = v.x, vy = v.y, vz = v.z, vw = v.w;
23669
23670         v.x = te[0] * vx + te[4] * vy + te[8] * vz + te[12] * vw;
23671         v.y = te[1] * vx + te[5] * vy + te[9] * vz + te[13] * vw;
23672         v.z = te[2] * vx + te[6] * vy + te[10] * vz + te[14] * vw;
23673         v.w = te[3] * vx + te[7] * vy + te[11] * vz + te[15] * vw;
23674
23675         return v;
23676
23677     },
23678
23679     multiplyVector3Array: function ( a ) {
23680
23681         var tmp = THREE.Matrix4.__v1;
23682
23683         for ( var i = 0, il = a.length; i < il; i += 3 ) {
23684
23685             tmp.x = a[ i ];
23686             tmp.y = a[ i + 1 ];
23687             tmp.z = a[ i + 2 ];
23688
23689             this.multiplyVector3( tmp );
23690
23691             a[ i ]     = tmp.x;
23692             a[ i + 1 ] = tmp.y;
23693             a[ i + 2 ] = tmp.z;
23694
23695         }
23696
23697         return a;
23698
23699     },
23700
23701     rotateAxis: function ( v ) {
23702
23703         var te = this.elements;
23704         var vx = v.x, vy = v.y, vz = v.z;
23705
23706         v.x = vx * te[0] + vy * te[4] + vz * te[8];
23707         v.y = vx * te[1] + vy * te[5] + vz * te[9];
23708         v.z = vx * te[2] + vy * te[6] + vz * te[10];
23709
23710         v.normalize();
23711
23712         return v;
23713
23714     },
23715
23716     crossVector: function ( a ) {
23717
23718         var te = this.elements;
23719         var v = new THREE.Vector4();
23720
23721         v.x = te[0] * a.x + te[4] * a.y + te[8] * a.z + te[12] * a.w;
23722         v.y = te[1] * a.x + te[5] * a.y + te[9] * a.z + te[13] * a.w;
23723         v.z = te[2] * a.x + te[6] * a.y + te[10] * a.z + te[14] * a.w;
23724
23725         v.w = ( a.w ) ? te[3] * a.x + te[7] * a.y + te[11] * a.z + te[15] * a.w : 1;
23726
23727         return v;
23728
23729     },
23730
23731     determinant: function () {
23732
23733         var te = this.elements;
23734
23735         var n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12];
23736         var n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13];
23737         var n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14];
23738         var n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15];
23739
23740         //TODO: make this more efficient
23741         //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
23742
23743         return (
23744             n14 * n23 * n32 * n41-
23745             n13 * n24 * n32 * n41-
23746             n14 * n22 * n33 * n41+
23747             n12 * n24 * n33 * n41+
23748
23749             n13 * n22 * n34 * n41-
23750             n12 * n23 * n34 * n41-
23751             n14 * n23 * n31 * n42+
23752             n13 * n24 * n31 * n42+
23753
23754             n14 * n21 * n33 * n42-
23755             n11 * n24 * n33 * n42-
23756             n13 * n21 * n34 * n42+
23757             n11 * n23 * n34 * n42+
23758
23759             n14 * n22 * n31 * n43-
23760             n12 * n24 * n31 * n43-
23761             n14 * n21 * n32 * n43+
23762             n11 * n24 * n32 * n43+
23763
23764             n12 * n21 * n34 * n43-
23765             n11 * n22 * n34 * n43-
23766             n13 * n22 * n31 * n44+
23767             n12 * n23 * n31 * n44+
23768
23769             n13 * n21 * n32 * n44-
23770             n11 * n23 * n32 * n44-
23771             n12 * n21 * n33 * n44+
23772             n11 * n22 * n33 * n44
23773         );
23774
23775     },
23776
23777     transpose: function () {
23778
23779         var te = this.elements;
23780         var tmp;
23781
23782         tmp = te[1]; te[1] = te[4]; te[4] = tmp;
23783         tmp = te[2]; te[2] = te[8]; te[8] = tmp;
23784         tmp = te[6]; te[6] = te[9]; te[9] = tmp;
23785
23786         tmp = te[3]; te[3] = te[12]; te[12] = tmp;
23787         tmp = te[7]; te[7] = te[13]; te[13] = tmp;
23788         tmp = te[11]; te[11] = te[14]; te[14] = tmp;
23789
23790         return this;
23791
23792     },
23793
23794     flattenToArray: function ( flat ) {
23795
23796         var te = this.elements;
23797         flat[ 0 ] = te[0]; flat[ 1 ] = te[1]; flat[ 2 ] = te[2]; flat[ 3 ] = te[3];
23798         flat[ 4 ] = te[4]; flat[ 5 ] = te[5]; flat[ 6 ] = te[6]; flat[ 7 ] = te[7];
23799         flat[ 8 ]  = te[8]; flat[ 9 ]  = te[9]; flat[ 10 ] = te[10]; flat[ 11 ] = te[11];
23800         flat[ 12 ] = te[12]; flat[ 13 ] = te[13]; flat[ 14 ] = te[14]; flat[ 15 ] = te[15];
23801
23802         return flat;
23803
23804     },
23805
23806     flattenToArrayOffset: function( flat, offset ) {
23807
23808         var te = this.elements;
23809         flat[ offset ] = te[0];
23810         flat[ offset + 1 ] = te[1];
23811         flat[ offset + 2 ] = te[2];
23812         flat[ offset + 3 ] = te[3];
23813
23814         flat[ offset + 4 ] = te[4];
23815         flat[ offset + 5 ] = te[5];
23816         flat[ offset + 6 ] = te[6];
23817         flat[ offset + 7 ] = te[7];
23818
23819         flat[ offset + 8 ]  = te[8];
23820         flat[ offset + 9 ]  = te[9];
23821         flat[ offset + 10 ] = te[10];
23822         flat[ offset + 11 ] = te[11];
23823
23824         flat[ offset + 12 ] = te[12];
23825         flat[ offset + 13 ] = te[13];
23826         flat[ offset + 14 ] = te[14];
23827         flat[ offset + 15 ] = te[15];
23828
23829         return flat;
23830
23831     },
23832
23833     getPosition: function () {
23834
23835         var te = this.elements;
23836         return THREE.Matrix4.__v1.set( te[12], te[13], te[14] );
23837
23838     },
23839
23840     setPosition: function ( v ) {
23841
23842         var te = this.elements;
23843
23844         te[12] = v.x;
23845         te[13] = v.y;
23846         te[14] = v.z;
23847
23848         return this;
23849
23850     },
23851
23852     getColumnX: function () {
23853
23854         var te = this.elements;
23855         return THREE.Matrix4.__v1.set( te[0], te[1], te[2] );
23856
23857     },
23858
23859     getColumnY: function () {
23860
23861         var te = this.elements;
23862         return THREE.Matrix4.__v1.set( te[4], te[5], te[6] );
23863
23864     },
23865
23866     getColumnZ: function() {
23867
23868         var te = this.elements;
23869         return THREE.Matrix4.__v1.set( te[8], te[9], te[10] );
23870
23871     },
23872
23873     getInverse: function ( m ) {
23874
23875         // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
23876         var te = this.elements;
23877         var me = m.elements;
23878
23879         var n11 = me[0], n12 = me[4], n13 = me[8], n14 = me[12];
23880         var n21 = me[1], n22 = me[5], n23 = me[9], n24 = me[13];
23881         var n31 = me[2], n32 = me[6], n33 = me[10], n34 = me[14];
23882         var n41 = me[3], n42 = me[7], n43 = me[11], n44 = me[15];
23883
23884         te[0] = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
23885         te[4] = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
23886         te[8] = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
23887         te[12] = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
23888         te[1] = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
23889         te[5] = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
23890         te[9] = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
23891         te[13] = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
23892         te[2] = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
23893         te[6] = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
23894         te[10] = n12*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
23895         te[14] = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
23896         te[3] = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
23897         te[7] = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
23898         te[11] = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
23899         te[15] = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
23900         this.multiplyScalar( 1 / m.determinant() );
23901
23902         return this;
23903
23904     },
23905
23906     setRotationFromEuler: function ( v, order ) {
23907
23908         var te = this.elements;
23909
23910         var x = v.x, y = v.y, z = v.z;
23911         var a = Math.cos( x ), b = Math.sin( x );
23912         var c = Math.cos( y ), d = Math.sin( y );
23913         var e = Math.cos( z ), f = Math.sin( z );
23914
23915         if ( order === undefined || order === 'XYZ' ) {
23916
23917             var ae = a * e, af = a * f, be = b * e, bf = b * f;
23918
23919             te[0] = c * e;
23920             te[4] = - c * f;
23921             te[8] = d;
23922
23923             te[1] = af + be * d;
23924             te[5] = ae - bf * d;
23925             te[9] = - b * c;
23926
23927             te[2] = bf - ae * d;
23928             te[6] = be + af * d;
23929             te[10] = a * c;
23930
23931         } else if ( order === 'YXZ' ) {
23932
23933             var ce = c * e, cf = c * f, de = d * e, df = d * f;
23934
23935             te[0] = ce + df * b;
23936             te[4] = de * b - cf;
23937             te[8] = a * d;
23938
23939             te[1] = a * f;
23940             te[5] = a * e;
23941             te[9] = - b;
23942
23943             te[2] = cf * b - de;
23944             te[6] = df + ce * b;
23945             te[10] = a * c;
23946
23947         } else if ( order === 'ZXY' ) {
23948
23949             var ce = c * e, cf = c * f, de = d * e, df = d * f;
23950
23951             te[0] = ce - df * b;
23952             te[4] = - a * f;
23953             te[8] = de + cf * b;
23954
23955             te[1] = cf + de * b;
23956             te[5] = a * e;
23957             te[9] = df - ce * b;
23958
23959             te[2] = - a * d;
23960             te[6] = b;
23961             te[10] = a * c;
23962
23963         } else if ( order === 'ZYX' ) {
23964
23965             var ae = a * e, af = a * f, be = b * e, bf = b * f;
23966
23967             te[0] = c * e;
23968             te[4] = be * d - af;
23969             te[8] = ae * d + bf;
23970
23971             te[1] = c * f;
23972             te[5] = bf * d + ae;
23973             te[9] = af * d - be;
23974
23975             te[2] = - d;
23976             te[6] = b * c;
23977             te[10] = a * c;
23978
23979         } else if ( order === 'YZX' ) {
23980
23981             var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
23982
23983             te[0] = c * e;
23984             te[4] = bd - ac * f;
23985             te[8] = bc * f + ad;
23986
23987             te[1] = f;
23988             te[5] = a * e;
23989             te[9] = - b * e;
23990
23991             te[2] = - d * e;
23992             te[6] = ad * f + bc;
23993             te[10] = ac - bd * f;
23994
23995         } else if ( order === 'XZY' ) {
23996
23997             var ac = a * c, ad = a * d, bc = b * c, bd = b * d;
23998
23999             te[0] = c * e;
24000             te[4] = - f;
24001             te[8] = d * e;
24002
24003             te[1] = ac * f + bd;
24004             te[5] = a * e;
24005             te[9] = ad * f - bc;
24006
24007             te[2] = bc * f - ad;
24008             te[6] = b * e;
24009             te[10] = bd * f + ac;
24010
24011         }
24012
24013         return this;
24014
24015     },
24016
24017
24018     setRotationFromQuaternion: function ( q ) {
24019
24020         var te = this.elements;
24021
24022         var x = q.x, y = q.y, z = q.z, w = q.w;
24023         var x2 = x + x, y2 = y + y, z2 = z + z;
24024         var xx = x * x2, xy = x * y2, xz = x * z2;
24025         var yy = y * y2, yz = y * z2, zz = z * z2;
24026         var wx = w * x2, wy = w * y2, wz = w * z2;
24027
24028         te[0] = 1 - ( yy + zz );
24029         te[4] = xy - wz;
24030         te[8] = xz + wy;
24031
24032         te[1] = xy + wz;
24033         te[5] = 1 - ( xx + zz );
24034         te[9] = yz - wx;
24035
24036         te[2] = xz - wy;
24037         te[6] = yz + wx;
24038         te[10] = 1 - ( xx + yy );
24039
24040         return this;
24041
24042     },
24043
24044     compose: function ( translation, rotation, scale ) {
24045
24046         var te = this.elements;
24047         var mRotation = THREE.Matrix4.__m1;
24048         var mScale = THREE.Matrix4.__m2;
24049
24050         mRotation.identity();
24051         mRotation.setRotationFromQuaternion( rotation );
24052
24053         mScale.makeScale( scale.x, scale.y, scale.z );
24054
24055         this.multiply( mRotation, mScale );
24056
24057         te[12] = translation.x;
24058         te[13] = translation.y;
24059         te[14] = translation.z;
24060
24061         return this;
24062
24063     },
24064
24065     decompose: function ( translation, rotation, scale ) {
24066
24067         var te = this.elements;
24068
24069         // grab the axis vectors
24070         var x = THREE.Matrix4.__v1;
24071         var y = THREE.Matrix4.__v2;
24072         var z = THREE.Matrix4.__v3;
24073
24074         x.set( te[0], te[1], te[2] );
24075         y.set( te[4], te[5], te[6] );
24076         z.set( te[8], te[9], te[10] );
24077
24078         translation = ( translation instanceof THREE.Vector3 ) ? translation : new THREE.Vector3();
24079         rotation = ( rotation instanceof THREE.Quaternion ) ? rotation : new THREE.Quaternion();
24080         scale = ( scale instanceof THREE.Vector3 ) ? scale : new THREE.Vector3();
24081
24082         scale.x = x.length();
24083         scale.y = y.length();
24084         scale.z = z.length();
24085
24086         translation.x = te[12];
24087         translation.y = te[13];
24088         translation.z = te[14];
24089
24090         // scale the rotation part
24091
24092         var matrix = THREE.Matrix4.__m1;
24093
24094         matrix.copy( this );
24095
24096         matrix.elements[0] /= scale.x;
24097         matrix.elements[1] /= scale.x;
24098         matrix.elements[2] /= scale.x;
24099
24100         matrix.elements[4] /= scale.y;
24101         matrix.elements[5] /= scale.y;
24102         matrix.elements[6] /= scale.y;
24103
24104         matrix.elements[8] /= scale.z;
24105         matrix.elements[9] /= scale.z;
24106         matrix.elements[10] /= scale.z;
24107
24108         rotation.setFromRotationMatrix( matrix );
24109
24110         return [ translation, rotation, scale ];
24111
24112     },
24113
24114     extractPosition: function ( m ) {
24115
24116         var te = this.elements;
24117         var me = m.elements;
24118
24119         te[12] = me[12];
24120         te[13] = me[13];
24121         te[14] = me[14];
24122
24123         return this;
24124
24125     },
24126
24127     extractRotation: function ( m ) {
24128
24129         var te = this.elements;
24130         var me = m.elements;
24131
24132         var vector = THREE.Matrix4.__v1;
24133
24134         var scaleX = 1 / vector.set( me[0], me[1], me[2] ).length();
24135         var scaleY = 1 / vector.set( me[4], me[5], me[6] ).length();
24136         var scaleZ = 1 / vector.set( me[8], me[9], me[10] ).length();
24137
24138         te[0] = me[0] * scaleX;
24139         te[1] = me[1] * scaleX;
24140         te[2] = me[2] * scaleX;
24141
24142         te[4] = me[4] * scaleY;
24143         te[5] = me[5] * scaleY;
24144         te[6] = me[6] * scaleY;
24145
24146         te[8] = me[8] * scaleZ;
24147         te[9] = me[9] * scaleZ;
24148         te[10] = me[10] * scaleZ;
24149
24150         return this;
24151
24152     },
24153
24154     //
24155
24156     translate: function ( v ) {
24157
24158         var te = this.elements;
24159         var x = v.x, y = v.y, z = v.z;
24160
24161         te[12] = te[0] * x + te[4] * y + te[8] * z + te[12];
24162         te[13] = te[1] * x + te[5] * y + te[9] * z + te[13];
24163         te[14] = te[2] * x + te[6] * y + te[10] * z + te[14];
24164         te[15] = te[3] * x + te[7] * y + te[11] * z + te[15];
24165
24166         return this;
24167
24168     },
24169
24170     rotateX: function ( angle ) {
24171
24172         var te = this.elements;
24173         var m12 = te[4];
24174         var m22 = te[5];
24175         var m32 = te[6];
24176         var m42 = te[7];
24177         var m13 = te[8];
24178         var m23 = te[9];
24179         var m33 = te[10];
24180         var m43 = te[11];
24181         var c = Math.cos( angle );
24182         var s = Math.sin( angle );
24183
24184         te[4] = c * m12 + s * m13;
24185         te[5] = c * m22 + s * m23;
24186         te[6] = c * m32 + s * m33;
24187         te[7] = c * m42 + s * m43;
24188
24189         te[8] = c * m13 - s * m12;
24190         te[9] = c * m23 - s * m22;
24191         te[10] = c * m33 - s * m32;
24192         te[11] = c * m43 - s * m42;
24193
24194         return this;
24195
24196     },
24197
24198     rotateY: function ( angle ) {
24199
24200         var te = this.elements;
24201         var m11 = te[0];
24202         var m21 = te[1];
24203         var m31 = te[2];
24204         var m41 = te[3];
24205         var m13 = te[8];
24206         var m23 = te[9];
24207         var m33 = te[10];
24208         var m43 = te[11];
24209         var c = Math.cos( angle );
24210         var s = Math.sin( angle );
24211
24212         te[0] = c * m11 - s * m13;
24213         te[1] = c * m21 - s * m23;
24214         te[2] = c * m31 - s * m33;
24215         te[3] = c * m41 - s * m43;
24216
24217         te[8] = c * m13 + s * m11;
24218         te[9] = c * m23 + s * m21;
24219         te[10] = c * m33 + s * m31;
24220         te[11] = c * m43 + s * m41;
24221
24222         return this;
24223
24224     },
24225
24226     rotateZ: function ( angle ) {
24227
24228         var te = this.elements;
24229         var m11 = te[0];
24230         var m21 = te[1];
24231         var m31 = te[2];
24232         var m41 = te[3];
24233         var m12 = te[4];
24234         var m22 = te[5];
24235         var m32 = te[6];
24236         var m42 = te[7];
24237         var c = Math.cos( angle );
24238         var s = Math.sin( angle );
24239
24240         te[0] = c * m11 + s * m12;
24241         te[1] = c * m21 + s * m22;
24242         te[2] = c * m31 + s * m32;
24243         te[3] = c * m41 + s * m42;
24244
24245         te[4] = c * m12 - s * m11;
24246         te[5] = c * m22 - s * m21;
24247         te[6] = c * m32 - s * m31;
24248         te[7] = c * m42 - s * m41;
24249
24250         return this;
24251
24252     },
24253
24254     rotateByAxis: function ( axis, angle ) {
24255
24256         var te = this.elements;
24257
24258         // optimize by checking axis
24259
24260         if ( axis.x === 1 && axis.y === 0 && axis.z === 0 ) {
24261
24262             return this.rotateX( angle );
24263
24264         } else if ( axis.x === 0 && axis.y === 1 && axis.z === 0 ) {
24265
24266             return this.rotateY( angle );
24267
24268         } else if ( axis.x === 0 && axis.y === 0 && axis.z === 1 ) {
24269
24270             return this.rotateZ( angle );
24271
24272         }
24273
24274         var x = axis.x, y = axis.y, z = axis.z;
24275         var n = Math.sqrt(x * x + y * y + z * z);
24276
24277         x /= n;
24278         y /= n;
24279         z /= n;
24280
24281         var xx = x * x, yy = y * y, zz = z * z;
24282         var c = Math.cos( angle );
24283         var s = Math.sin( angle );
24284         var oneMinusCosine = 1 - c;
24285         var xy = x * y * oneMinusCosine;
24286         var xz = x * z * oneMinusCosine;
24287         var yz = y * z * oneMinusCosine;
24288         var xs = x * s;
24289         var ys = y * s;
24290         var zs = z * s;
24291
24292         var r11 = xx + (1 - xx) * c;
24293         var r21 = xy + zs;
24294         var r31 = xz - ys;
24295         var r12 = xy - zs;
24296         var r22 = yy + (1 - yy) * c;
24297         var r32 = yz + xs;
24298         var r13 = xz + ys;
24299         var r23 = yz - xs;
24300         var r33 = zz + (1 - zz) * c;
24301
24302         var m11 = te[0], m21 = te[1], m31 = te[2], m41 = te[3];
24303         var m12 = te[4], m22 = te[5], m32 = te[6], m42 = te[7];
24304         var m13 = te[8], m23 = te[9], m33 = te[10], m43 = te[11];
24305         var m14 = te[12], m24 = te[13], m34 = te[14], m44 = te[15];
24306
24307         te[0] = r11 * m11 + r21 * m12 + r31 * m13;
24308         te[1] = r11 * m21 + r21 * m22 + r31 * m23;
24309         te[2] = r11 * m31 + r21 * m32 + r31 * m33;
24310         te[3] = r11 * m41 + r21 * m42 + r31 * m43;
24311
24312         te[4] = r12 * m11 + r22 * m12 + r32 * m13;
24313         te[5] = r12 * m21 + r22 * m22 + r32 * m23;
24314         te[6] = r12 * m31 + r22 * m32 + r32 * m33;
24315         te[7] = r12 * m41 + r22 * m42 + r32 * m43;
24316
24317         te[8] = r13 * m11 + r23 * m12 + r33 * m13;
24318         te[9] = r13 * m21 + r23 * m22 + r33 * m23;
24319         te[10] = r13 * m31 + r23 * m32 + r33 * m33;
24320         te[11] = r13 * m41 + r23 * m42 + r33 * m43;
24321
24322         return this;
24323
24324     },
24325
24326     scale: function ( v ) {
24327
24328         var te = this.elements;
24329         var x = v.x, y = v.y, z = v.z;
24330
24331         te[0] *= x; te[4] *= y; te[8] *= z;
24332         te[1] *= x; te[5] *= y; te[9] *= z;
24333         te[2] *= x; te[6] *= y; te[10] *= z;
24334         te[3] *= x; te[7] *= y; te[11] *= z;
24335
24336         return this;
24337
24338     },
24339
24340     getMaxScaleOnAxis: function () {
24341
24342         var te = this.elements;
24343
24344         var scaleXSq =  te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
24345         var scaleYSq =  te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
24346         var scaleZSq =  te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
24347
24348         return Math.sqrt( Math.max( scaleXSq, Math.max( scaleYSq, scaleZSq ) ) );
24349
24350     },
24351
24352     //
24353
24354     makeTranslation: function ( x, y, z ) {
24355
24356         this.set(
24357
24358             1, 0, 0, x,
24359             0, 1, 0, y,
24360             0, 0, 1, z,
24361             0, 0, 0, 1
24362
24363         );
24364
24365         return this;
24366
24367     },
24368
24369     makeRotationX: function ( theta ) {
24370
24371         var c = Math.cos( theta ), s = Math.sin( theta );
24372
24373         this.set(
24374
24375             1, 0,  0, 0,
24376             0, c, -s, 0,
24377             0, s,  c, 0,
24378             0, 0,  0, 1
24379
24380         );
24381
24382         return this;
24383
24384     },
24385
24386     makeRotationY: function ( theta ) {
24387
24388         var c = Math.cos( theta ), s = Math.sin( theta );
24389
24390         this.set(
24391
24392              c, 0, s, 0,
24393              0, 1, 0, 0,
24394             -s, 0, c, 0,
24395              0, 0, 0, 1
24396
24397         );
24398
24399         return this;
24400
24401     },
24402
24403     makeRotationZ: function ( theta ) {
24404
24405         var c = Math.cos( theta ), s = Math.sin( theta );
24406
24407         this.set(
24408
24409             c, -s, 0, 0,
24410             s,  c, 0, 0,
24411             0,  0, 1, 0,
24412             0,  0, 0, 1
24413
24414         );
24415
24416         return this;
24417
24418     },
24419
24420     makeRotationAxis: function ( axis, angle ) {
24421
24422         // Based on http://www.gamedev.net/reference/articles/article1199.asp
24423
24424         var c = Math.cos( angle );
24425         var s = Math.sin( angle );
24426         var t = 1 - c;
24427         var x = axis.x, y = axis.y, z = axis.z;
24428         var tx = t * x, ty = t * y;
24429
24430         this.set(
24431
24432             tx * x + c, tx * y - s * z, tx * z + s * y, 0,
24433             tx * y + s * z, ty * y + c, ty * z - s * x, 0,
24434             tx * z - s * y, ty * z + s * x, t * z * z + c, 0,
24435             0, 0, 0, 1
24436
24437         );
24438
24439          return this;
24440
24441     },
24442
24443     makeScale: function ( x, y, z ) {
24444
24445         this.set(
24446
24447             x, 0, 0, 0,
24448             0, y, 0, 0,
24449             0, 0, z, 0,
24450             0, 0, 0, 1
24451
24452         );
24453
24454         return this;
24455
24456     },
24457
24458     makeFrustum: function ( left, right, bottom, top, near, far ) {
24459
24460         var te = this.elements;
24461         var x = 2 * near / ( right - left );
24462         var y = 2 * near / ( top - bottom );
24463
24464         var a = ( right + left ) / ( right - left );
24465         var b = ( top + bottom ) / ( top - bottom );
24466         var c = - ( far + near ) / ( far - near );
24467         var d = - 2 * far * near / ( far - near );
24468
24469         te[0] = x;  te[4] = 0;  te[8] = a;   te[12] = 0;
24470         te[1] = 0;  te[5] = y;  te[9] = b;   te[13] = 0;
24471         te[2] = 0;  te[6] = 0;  te[10] = c;   te[14] = d;
24472         te[3] = 0;  te[7] = 0;  te[11] = - 1; te[15] = 0;
24473
24474         return this;
24475
24476     },
24477
24478     makePerspective: function ( fov, aspect, near, far ) {
24479
24480         var ymax = near * Math.tan( fov * Math.PI / 360 );
24481         var ymin = - ymax;
24482         var xmin = ymin * aspect;
24483         var xmax = ymax * aspect;
24484
24485         return this.makeFrustum( xmin, xmax, ymin, ymax, near, far );
24486
24487     },
24488
24489     makeOrthographic: function ( left, right, top, bottom, near, far ) {
24490
24491         var te = this.elements;
24492         var w = right - left;
24493         var h = top - bottom;
24494         var p = far - near;
24495
24496         var x = ( right + left ) / w;
24497         var y = ( top + bottom ) / h;
24498         var z = ( far + near ) / p;
24499
24500         te[0] = 2 / w; te[4] = 0;     te[8] = 0;      te[12] = -x;
24501         te[1] = 0;     te[5] = 2 / h; te[9] = 0;      te[13] = -y;
24502         te[2] = 0;     te[6] = 0;     te[10] = -2 / p; te[14] = -z;
24503         te[3] = 0;     te[7] = 0;     te[11] = 0;      te[15] = 1;
24504
24505         return this;
24506
24507     },
24508
24509
24510     clone: function () {
24511
24512         var te = this.elements;
24513
24514         return new THREE.Matrix4(
24515
24516             te[0], te[4], te[8], te[12],
24517             te[1], te[5], te[9], te[13],
24518             te[2], te[6], te[10], te[14],
24519             te[3], te[7], te[11], te[15]
24520
24521         );
24522
24523     }
24524
24525 };
24526
24527 THREE.Matrix4.__v1 = new THREE.Vector3();
24528 THREE.Matrix4.__v2 = new THREE.Vector3();
24529 THREE.Matrix4.__v3 = new THREE.Vector3();
24530
24531 THREE.Matrix4.__m1 = new THREE.Matrix4();
24532 THREE.Matrix4.__m2 = new THREE.Matrix4();
24533 /**
24534  * https://github.com/mrdoob/eventtarget.js/
24535  */
24536
24537 THREE.EventTarget = function () {
24538
24539     var listeners = {};
24540
24541     this.addEventListener = function ( type, listener ) {
24542
24543         if ( listeners[ type ] === undefined ) {
24544
24545             listeners[ type ] = [];
24546
24547         }
24548
24549         if ( listeners[ type ].indexOf( listener ) === - 1 ) {
24550
24551             listeners[ type ].push( listener );
24552
24553         }
24554
24555     };
24556
24557     this.dispatchEvent = function ( event ) {
24558
24559         for ( var listener in listeners[ event.type ] ) {
24560
24561             listeners[ event.type ][ listener ]( event );
24562
24563         }
24564
24565     };
24566
24567     this.removeEventListener = function ( type, listener ) {
24568
24569         var index = listeners[ type ].indexOf( listener );
24570
24571         if ( index !== - 1 ) {
24572
24573             listeners[ type ].splice( index, 1 );
24574
24575         }
24576
24577     };
24578
24579 };
24580 /**
24581  * @author mrdoob / http://mrdoob.com/
24582  * @author alteredq / http://alteredqualia.com/
24583  */
24584
24585 THREE.Frustum = function ( ) {
24586
24587     this.planes = [
24588
24589         new THREE.Vector4(),
24590         new THREE.Vector4(),
24591         new THREE.Vector4(),
24592         new THREE.Vector4(),
24593         new THREE.Vector4(),
24594         new THREE.Vector4()
24595
24596     ];
24597
24598 };
24599
24600 THREE.Frustum.prototype.setFromMatrix = function ( m ) {
24601
24602     var plane;
24603     var planes = this.planes;
24604
24605     var me = m.elements;
24606     var me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3];
24607     var me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7];
24608     var me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
24609     var me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
24610
24611     planes[ 0 ].set( me3 - me0, me7 - me4, me11 - me8, me15 - me12 );
24612     planes[ 1 ].set( me3 + me0, me7 + me4, me11 + me8, me15 + me12 );
24613     planes[ 2 ].set( me3 + me1, me7 + me5, me11 + me9, me15 + me13 );
24614     planes[ 3 ].set( me3 - me1, me7 - me5, me11 - me9, me15 - me13 );
24615     planes[ 4 ].set( me3 - me2, me7 - me6, me11 - me10, me15 - me14 );
24616     planes[ 5 ].set( me3 + me2, me7 + me6, me11 + me10, me15 + me14 );
24617
24618     for ( var i = 0; i < 6; i ++ ) {
24619
24620         plane = planes[ i ];
24621         plane.divideScalar( Math.sqrt( plane.x * plane.x + plane.y * plane.y + plane.z * plane.z ) );
24622
24623     }
24624
24625 };
24626
24627 THREE.Frustum.prototype.contains = function ( object ) {
24628
24629     var distance = 0.0;
24630     var planes = this.planes;
24631     var matrix = object.matrixWorld;
24632     var me = matrix.elements;
24633     var radius = - object.geometry.boundingSphere.radius * matrix.getMaxScaleOnAxis();
24634
24635     for ( var i = 0; i < 6; i ++ ) {
24636
24637         distance = planes[ i ].x * me[12] + planes[ i ].y * me[13] + planes[ i ].z * me[14] + planes[ i ].w;
24638         if ( distance <= radius ) return false;
24639
24640     }
24641
24642     return true;
24643
24644 };
24645
24646 THREE.Frustum.__v1 = new THREE.Vector3();
24647 /**
24648  * @author mrdoob / http://mrdoob.com/
24649  */
24650
24651 ( function ( THREE ) {
24652
24653     THREE.Ray = function ( origin, direction, near, far ) {
24654
24655         this.origin = origin || new THREE.Vector3();
24656         this.direction = direction || new THREE.Vector3();
24657         this.near = near || 0;
24658         this.far = far || Infinity;
24659
24660     };
24661
24662     var originCopy = new THREE.Vector3();
24663
24664     var localOriginCopy = new THREE.Vector3();
24665     var localDirectionCopy = new THREE.Vector3();
24666
24667     var vector = new THREE.Vector3();
24668     var normal = new THREE.Vector3();
24669     var intersectPoint = new THREE.Vector3();
24670
24671     var inverseMatrix = new THREE.Matrix4();
24672
24673     var descSort = function ( a, b ) {
24674
24675         return a.distance - b.distance;
24676
24677     };
24678
24679     var v0 = new THREE.Vector3(), v1 = new THREE.Vector3(), v2 = new THREE.Vector3();
24680
24681     var distanceFromIntersection = function ( origin, direction, position ) {
24682
24683         v0.sub( position, origin );
24684
24685         var dot = v0.dot( direction );
24686
24687         var intersect = v1.add( origin, v2.copy( direction ).multiplyScalar( dot ) );
24688         var distance = position.distanceTo( intersect );
24689
24690         return distance;
24691
24692     };
24693
24694     // http://www.blackpawn.com/texts/pointinpoly/default.html
24695
24696     var pointInFace3 = function ( p, a, b, c ) {
24697
24698         v0.sub( c, a );
24699         v1.sub( b, a );
24700         v2.sub( p, a );
24701
24702         var dot00 = v0.dot( v0 );
24703         var dot01 = v0.dot( v1 );
24704         var dot02 = v0.dot( v2 );
24705         var dot11 = v1.dot( v1 );
24706         var dot12 = v1.dot( v2 );
24707
24708         var invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
24709         var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
24710         var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
24711
24712         return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );
24713
24714     };
24715
24716     var intersectObject = function ( object, ray, intersects ) {
24717
24718         var distance,intersect;
24719
24720         if ( object instanceof THREE.Particle ) {
24721
24722             distance = distanceFromIntersection( ray.origin, ray.direction, object.matrixWorld.getPosition() );
24723
24724             if ( distance > object.scale.x ) {
24725
24726                 return intersects;
24727
24728             }
24729
24730             intersect = {
24731
24732                 distance: distance,
24733                 point: object.position,
24734                 face: null,
24735                 object: object
24736
24737             };
24738
24739             intersects.push( intersect );
24740
24741         } else if ( object instanceof THREE.Mesh ) {
24742
24743             // Checking boundingSphere
24744
24745             var scaledRadius = object.geometry.boundingSphere.radius * object.matrixWorld.getMaxScaleOnAxis();
24746
24747             // Checking distance to ray
24748
24749             distance = distanceFromIntersection( ray.origin, ray.direction, object.matrixWorld.getPosition() );
24750
24751             if ( distance > scaledRadius) {
24752
24753                 return intersects;
24754
24755             }
24756
24757             // Checking faces
24758
24759             var f, fl, face, dot, scalar,
24760             geometry = object.geometry,
24761             vertices = geometry.vertices,
24762             objMatrix, geometryMaterials,
24763             isFaceMaterial, material, side, point;
24764
24765             geometryMaterials = object.geometry.materials;
24766             isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
24767             side = object.material.side;
24768
24769             var a, b, c, d;
24770             var precision = ray.precision;
24771
24772             object.matrixRotationWorld.extractRotation( object.matrixWorld );
24773
24774             originCopy.copy( ray.origin );
24775
24776             objMatrix = object.matrixWorld;
24777             inverseMatrix.getInverse( objMatrix );
24778
24779             localOriginCopy.copy( originCopy );
24780             inverseMatrix.multiplyVector3( localOriginCopy );
24781
24782             localDirectionCopy.copy( ray.direction );
24783             inverseMatrix.rotateAxis( localDirectionCopy ).normalize();
24784
24785             for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
24786
24787                 face = geometry.faces[ f ];
24788
24789                 material = isFaceMaterial === true ? geometryMaterials[ face.materialIndex ] : object.material;
24790                 if ( material === undefined ) continue;
24791                 side = material.side;
24792
24793                 vector.sub( face.centroid, localOriginCopy );
24794                 normal = face.normal;
24795                 dot = localDirectionCopy.dot( normal );
24796
24797                 // bail if ray and plane are parallel
24798
24799                 if ( Math.abs( dot ) < precision ) continue;
24800
24801                 // calc distance to plane
24802
24803                 scalar = normal.dot( vector ) / dot;
24804
24805                 // if negative distance, then plane is behind ray
24806
24807                 if ( scalar < 0 ) continue;
24808
24809                 if ( side === THREE.DoubleSide || ( side === THREE.FrontSide ? dot < 0 : dot > 0 ) ) {
24810
24811                     intersectPoint.add( localOriginCopy, localDirectionCopy.multiplyScalar( scalar ) );
24812
24813                     if ( face instanceof THREE.Face3 ) {
24814
24815                         a = vertices[ face.a ];
24816                         b = vertices[ face.b ];
24817                         c = vertices[ face.c ];
24818
24819                         if ( pointInFace3( intersectPoint, a, b, c ) ) {
24820
24821                             point = object.matrixWorld.multiplyVector3( intersectPoint.clone() );
24822                             distance = originCopy.distanceTo( point );
24823
24824                             if ( distance < ray.near || distance > ray.far ) continue;
24825
24826                             intersect = {
24827
24828                                 distance: distance,
24829                                 point: point,
24830                                 face: face,
24831                                 faceIndex: f,
24832                                 object: object
24833
24834                             };
24835
24836                             intersects.push( intersect );
24837
24838                         }
24839
24840                     } else if ( face instanceof THREE.Face4 ) {
24841
24842                         a = vertices[ face.a ];
24843                         b = vertices[ face.b ];
24844                         c = vertices[ face.c ];
24845                         d = vertices[ face.d ];
24846
24847                         if ( pointInFace3( intersectPoint, a, b, d ) || pointInFace3( intersectPoint, b, c, d ) ) {
24848
24849                             point = object.matrixWorld.multiplyVector3( intersectPoint.clone() );
24850                             distance = originCopy.distanceTo( point );
24851
24852                             if ( distance < ray.near || distance > ray.far ) continue;
24853
24854                             intersect = {
24855
24856                                 distance: distance,
24857                                 point: point,
24858                                 face: face,
24859                                 faceIndex: f,
24860                                 object: object
24861
24862                             };
24863
24864                             intersects.push( intersect );
24865
24866                         }
24867
24868                     }
24869
24870                 }
24871
24872             }
24873
24874         }
24875
24876     };
24877
24878     var intersectDescendants = function ( object, ray, intersects ) {
24879
24880         var descendants = object.getDescendants();
24881
24882         for ( var i = 0, l = descendants.length; i < l; i ++ ) {
24883
24884             intersectObject( descendants[ i ], ray, intersects );
24885
24886         }
24887     };
24888
24889     //
24890
24891     THREE.Ray.prototype.precision = 0.0001;
24892
24893     THREE.Ray.prototype.set = function ( origin, direction ) {
24894
24895         this.origin = origin;
24896         this.direction = direction;
24897
24898     };
24899
24900     THREE.Ray.prototype.intersectObject = function ( object, recursive ) {
24901
24902         var intersects = [];
24903
24904         if ( recursive === true ) {
24905
24906             intersectDescendants( object, this, intersects );
24907
24908         }
24909
24910         intersectObject( object, this, intersects );
24911
24912         intersects.sort( descSort );
24913
24914         return intersects;
24915
24916     };
24917
24918     THREE.Ray.prototype.intersectObjects = function ( objects, recursive ) {
24919
24920         var intersects = [];
24921
24922         for ( var i = 0, l = objects.length; i < l; i ++ ) {
24923
24924             intersectObject( objects[ i ], this, intersects );
24925
24926             if ( recursive === true ) {
24927
24928                 intersectDescendants( objects[ i ], this, intersects );
24929
24930             }
24931         }
24932
24933         intersects.sort( descSort );
24934
24935         return intersects;
24936
24937     };
24938
24939 }( THREE ) );
24940 /**
24941  * @author mrdoob / http://mrdoob.com/
24942  */
24943
24944 THREE.Rectangle = function () {
24945
24946     var _left = 0;
24947     var _top = 0;
24948     var _right = 0;
24949     var _bottom = 0;
24950     var _width = 0;
24951     var _height = 0;
24952     var _isEmpty = true;
24953
24954     function resize() {
24955
24956         _width = _right - _left;
24957         _height = _bottom - _top;
24958
24959     }
24960
24961     this.getX = function () {
24962
24963         return _left;
24964
24965     };
24966
24967     this.getY = function () {
24968
24969         return _top;
24970
24971     };
24972
24973     this.getWidth = function () {
24974
24975         return _width;
24976
24977     };
24978
24979     this.getHeight = function () {
24980
24981         return _height;
24982
24983     };
24984
24985     this.getLeft = function() {
24986
24987         return _left;
24988
24989     };
24990
24991     this.getTop = function() {
24992
24993         return _top;
24994
24995     };
24996
24997     this.getRight = function() {
24998
24999         return _right;
25000
25001     };
25002
25003     this.getBottom = function() {
25004
25005         return _bottom;
25006
25007     };
25008
25009     this.set = function ( left, top, right, bottom ) {
25010
25011         _isEmpty = false;
25012
25013         _left = left; _top = top;
25014         _right = right; _bottom = bottom;
25015
25016         resize();
25017
25018     };
25019
25020     this.addPoint = function ( x, y ) {
25021
25022         if ( _isEmpty === true ) {
25023
25024             _isEmpty = false;
25025             _left = x; _top = y;
25026             _right = x; _bottom = y;
25027
25028             resize();
25029
25030         } else {
25031
25032             _left = _left < x ? _left : x; // Math.min( _left, x );
25033             _top = _top < y ? _top : y; // Math.min( _top, y );
25034             _right = _right > x ? _right : x; // Math.max( _right, x );
25035             _bottom = _bottom > y ? _bottom : y; // Math.max( _bottom, y );
25036
25037             resize();
25038         }
25039
25040     };
25041
25042     this.add3Points = function ( x1, y1, x2, y2, x3, y3 ) {
25043
25044         if ( _isEmpty === true ) {
25045
25046             _isEmpty = false;
25047             _left = x1 < x2 ? ( x1 < x3 ? x1 : x3 ) : ( x2 < x3 ? x2 : x3 );
25048             _top = y1 < y2 ? ( y1 < y3 ? y1 : y3 ) : ( y2 < y3 ? y2 : y3 );
25049             _right = x1 > x2 ? ( x1 > x3 ? x1 : x3 ) : ( x2 > x3 ? x2 : x3 );
25050             _bottom = y1 > y2 ? ( y1 > y3 ? y1 : y3 ) : ( y2 > y3 ? y2 : y3 );
25051
25052             resize();
25053
25054         } else {
25055
25056             _left = x1 < x2 ? ( x1 < x3 ? ( x1 < _left ? x1 : _left ) : ( x3 < _left ? x3 : _left ) ) : ( x2 < x3 ? ( x2 < _left ? x2 : _left ) : ( x3 < _left ? x3 : _left ) );
25057             _top = y1 < y2 ? ( y1 < y3 ? ( y1 < _top ? y1 : _top ) : ( y3 < _top ? y3 : _top ) ) : ( y2 < y3 ? ( y2 < _top ? y2 : _top ) : ( y3 < _top ? y3 : _top ) );
25058             _right = x1 > x2 ? ( x1 > x3 ? ( x1 > _right ? x1 : _right ) : ( x3 > _right ? x3 : _right ) ) : ( x2 > x3 ? ( x2 > _right ? x2 : _right ) : ( x3 > _right ? x3 : _right ) );
25059             _bottom = y1 > y2 ? ( y1 > y3 ? ( y1 > _bottom ? y1 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) ) : ( y2 > y3 ? ( y2 > _bottom ? y2 : _bottom ) : ( y3 > _bottom ? y3 : _bottom ) );
25060
25061             resize();
25062
25063         };
25064
25065     };
25066
25067     this.addRectangle = function ( r ) {
25068
25069         if ( _isEmpty === true ) {
25070
25071             _isEmpty = false;
25072             _left = r.getLeft(); _top = r.getTop();
25073             _right = r.getRight(); _bottom = r.getBottom();
25074
25075             resize();
25076
25077         } else {
25078
25079             _left = _left < r.getLeft() ? _left : r.getLeft(); // Math.min(_left, r.getLeft() );
25080             _top = _top < r.getTop() ? _top : r.getTop(); // Math.min(_top, r.getTop() );
25081             _right = _right > r.getRight() ? _right : r.getRight(); // Math.max(_right, r.getRight() );
25082             _bottom = _bottom > r.getBottom() ? _bottom : r.getBottom(); // Math.max(_bottom, r.getBottom() );
25083
25084             resize();
25085
25086         }
25087
25088     };
25089
25090     this.inflate = function ( v ) {
25091
25092         _left -= v; _top -= v;
25093         _right += v; _bottom += v;
25094
25095         resize();
25096
25097     };
25098
25099     this.minSelf = function ( r ) {
25100
25101         _left = _left > r.getLeft() ? _left : r.getLeft(); // Math.max( _left, r.getLeft() );
25102         _top = _top > r.getTop() ? _top : r.getTop(); // Math.max( _top, r.getTop() );
25103         _right = _right < r.getRight() ? _right : r.getRight(); // Math.min( _right, r.getRight() );
25104         _bottom = _bottom < r.getBottom() ? _bottom : r.getBottom(); // Math.min( _bottom, r.getBottom() );
25105
25106         resize();
25107
25108     };
25109
25110     this.intersects = function ( r ) {
25111
25112         // http://gamemath.com/2011/09/detecting-whether-two-boxes-overlap/
25113
25114         if ( _right < r.getLeft() ) return false;
25115         if ( _left > r.getRight() ) return false;
25116         if ( _bottom < r.getTop() ) return false;
25117         if ( _top > r.getBottom() ) return false;
25118
25119         return true;
25120
25121     };
25122
25123     this.empty = function () {
25124
25125         _isEmpty = true;
25126
25127         _left = 0; _top = 0;
25128         _right = 0; _bottom = 0;
25129
25130         resize();
25131
25132     };
25133
25134     this.isEmpty = function () {
25135
25136         return _isEmpty;
25137
25138     };
25139
25140 };
25141 /**
25142  * @author alteredq / http://alteredqualia.com/
25143  */
25144
25145 THREE.Math = {
25146
25147     // Clamp value to range <a, b>
25148
25149     clamp: function ( x, a, b ) {
25150
25151         return ( x < a ) ? a : ( ( x > b ) ? b : x );
25152
25153     },
25154
25155     // Clamp value to range <a, inf)
25156
25157     clampBottom: function ( x, a ) {
25158
25159         return x < a ? a : x;
25160
25161     },
25162
25163     // Linear mapping from range <a1, a2> to range <b1, b2>
25164
25165     mapLinear: function ( x, a1, a2, b1, b2 ) {
25166
25167         return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
25168
25169     },
25170
25171     // Random float from <0, 1> with 16 bits of randomness
25172     // (standard Math.random() creates repetitive patterns when applied over larger space)
25173
25174     random16: function () {
25175
25176         return ( 65280 * Math.random() + 255 * Math.random() ) / 65535;
25177
25178     },
25179
25180     // Random integer from <low, high> interval
25181
25182     randInt: function ( low, high ) {
25183
25184         return low + Math.floor( Math.random() * ( high - low + 1 ) );
25185
25186     },
25187
25188     // Random float from <low, high> interval
25189
25190     randFloat: function ( low, high ) {
25191
25192         return low + Math.random() * ( high - low );
25193
25194     },
25195
25196     // Random float from <-range/2, range/2> interval
25197
25198     randFloatSpread: function ( range ) {
25199
25200         return range * ( 0.5 - Math.random() );
25201
25202     },
25203
25204     sign: function ( x ) {
25205
25206         return ( x < 0 ) ? -1 : ( ( x > 0 ) ? 1 : 0 );
25207
25208     }
25209
25210 };
25211 /**
25212  * @author mrdoob / http://mrdoob.com/
25213  * @author mikael emtinger / http://gomo.se/
25214  * @author alteredq / http://alteredqualia.com/
25215  */
25216
25217 THREE.Object3D = function () {
25218
25219     this.id = THREE.Object3DCount ++;
25220
25221     this.name = '';
25222     this.properties = {};
25223
25224     this.parent = undefined;
25225     this.children = [];
25226
25227     this.up = new THREE.Vector3( 0, 1, 0 );
25228
25229     this.position = new THREE.Vector3();
25230     this.rotation = new THREE.Vector3();
25231     this.eulerOrder = 'XYZ';
25232     this.scale = new THREE.Vector3( 1, 1, 1 );
25233
25234     this.renderDepth = null;
25235
25236     this.rotationAutoUpdate = true;
25237
25238     this.matrix = new THREE.Matrix4();
25239     this.matrixWorld = new THREE.Matrix4();
25240     this.matrixRotationWorld = new THREE.Matrix4();
25241
25242     this.matrixAutoUpdate = true;
25243     this.matrixWorldNeedsUpdate = true;
25244
25245     this.quaternion = new THREE.Quaternion();
25246     this.useQuaternion = false;
25247
25248     this.boundRadius = 0.0;
25249     this.boundRadiusScale = 1.0;
25250
25251     this.visible = true;
25252
25253     this.castShadow = false;
25254     this.receiveShadow = false;
25255
25256     this.frustumCulled = true;
25257
25258     this._vector = new THREE.Vector3();
25259
25260 };
25261
25262
25263 THREE.Object3D.prototype = {
25264
25265     constructor: THREE.Object3D,
25266
25267     applyMatrix: function ( matrix ) {
25268
25269         this.matrix.multiply( matrix, this.matrix );
25270
25271         this.scale.getScaleFromMatrix( this.matrix );
25272
25273         var mat = new THREE.Matrix4().extractRotation( this.matrix );
25274         this.rotation.setEulerFromRotationMatrix( mat, this.eulerOrder );
25275
25276         this.position.getPositionFromMatrix( this.matrix );
25277
25278     },
25279
25280     translate: function ( distance, axis ) {
25281
25282         this.matrix.rotateAxis( axis );
25283         this.position.addSelf( axis.multiplyScalar( distance ) );
25284
25285     },
25286
25287     translateX: function ( distance ) {
25288
25289         this.translate( distance, this._vector.set( 1, 0, 0 ) );
25290
25291     },
25292
25293     translateY: function ( distance ) {
25294
25295         this.translate( distance, this._vector.set( 0, 1, 0 ) );
25296
25297     },
25298
25299     translateZ: function ( distance ) {
25300
25301         this.translate( distance, this._vector.set( 0, 0, 1 ) );
25302
25303     },
25304
25305     localToWorld: function ( vector ) {
25306
25307         return this.matrixWorld.multiplyVector3( vector );
25308
25309     },
25310
25311     worldToLocal: function ( vector ) {
25312
25313         return THREE.Object3D.__m1.getInverse( this.matrixWorld ).multiplyVector3( vector );
25314
25315     },
25316
25317     lookAt: function ( vector ) {
25318
25319         // TODO: Add hierarchy support.
25320
25321         this.matrix.lookAt( vector, this.position, this.up );
25322
25323         if ( this.rotationAutoUpdate ) {
25324
25325             this.rotation.setEulerFromRotationMatrix( this.matrix, this.eulerOrder );
25326
25327         }
25328
25329     },
25330
25331     add: function ( object ) {
25332
25333         if ( object === this ) {
25334
25335             console.warn( 'THREE.Object3D.add: An object can\'t be added as a child of itself.' );
25336             return;
25337
25338         }
25339
25340         if ( object instanceof THREE.Object3D ) {
25341
25342             if ( object.parent !== undefined ) {
25343
25344                 object.parent.remove( object );
25345
25346             }
25347
25348             object.parent = this;
25349             this.children.push( object );
25350
25351             // add to scene
25352
25353             var scene = this;
25354
25355             while ( scene.parent !== undefined ) {
25356
25357                 scene = scene.parent;
25358
25359             }
25360
25361             if ( scene !== undefined && scene instanceof THREE.Scene )  {
25362
25363                 scene.__addObject( object );
25364
25365             }
25366
25367         }
25368
25369     },
25370
25371     remove: function ( object ) {
25372
25373         var index = this.children.indexOf( object );
25374
25375         if ( index !== - 1 ) {
25376
25377             object.parent = undefined;
25378             this.children.splice( index, 1 );
25379
25380             // remove from scene
25381
25382             var scene = this;
25383
25384             while ( scene.parent !== undefined ) {
25385
25386                 scene = scene.parent;
25387
25388             }
25389
25390             if ( scene !== undefined && scene instanceof THREE.Scene ) {
25391
25392                 scene.__removeObject( object );
25393
25394             }
25395
25396         }
25397
25398     },
25399
25400     getChildByName: function ( name, recursive ) {
25401
25402         var c, cl, child;
25403
25404         for ( c = 0, cl = this.children.length; c < cl; c ++ ) {
25405
25406             child = this.children[ c ];
25407
25408             if ( child.name === name ) {
25409
25410                 return child;
25411
25412             }
25413
25414             if ( recursive ) {
25415
25416                 child = child.getChildByName( name, recursive );
25417
25418                 if ( child !== undefined ) {
25419
25420                     return child;
25421
25422                 }
25423
25424             }
25425
25426         }
25427
25428         return undefined;
25429
25430     },
25431
25432     getDescendants: function ( array ) {
25433
25434         if ( array === undefined ) array = [];
25435
25436         Array.prototype.push.apply( array, this.children );
25437
25438         for ( var i = 0, l = this.children.length; i < l; i ++ ) {
25439
25440             this.children[ i ].getDescendants( array );
25441
25442         };
25443
25444         return array;
25445
25446     },
25447
25448     updateMatrix: function () {
25449
25450         this.matrix.setPosition( this.position );
25451
25452         if ( this.useQuaternion === false )  {
25453
25454             this.matrix.setRotationFromEuler( this.rotation, this.eulerOrder );
25455
25456         } else {
25457
25458             this.matrix.setRotationFromQuaternion( this.quaternion );
25459
25460         }
25461
25462         if ( this.scale.x !== 1 || this.scale.y !== 1 || this.scale.z !== 1 ) {
25463
25464             this.matrix.scale( this.scale );
25465             this.boundRadiusScale = Math.max( this.scale.x, Math.max( this.scale.y, this.scale.z ) );
25466
25467         }
25468
25469         this.matrixWorldNeedsUpdate = true;
25470
25471     },
25472
25473     updateMatrixWorld: function ( force ) {
25474
25475         if ( this.matrixAutoUpdate === true ) this.updateMatrix();
25476
25477         if ( this.matrixWorldNeedsUpdate === true || force === true ) {
25478
25479             if ( this.parent === undefined ) {
25480
25481                 this.matrixWorld.copy( this.matrix );
25482
25483             } else {
25484
25485                 this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
25486
25487             }
25488
25489             this.matrixWorldNeedsUpdate = false;
25490
25491             force = true;
25492
25493         }
25494
25495         // update children
25496
25497         for ( var i = 0, l = this.children.length; i < l; i ++ ) {
25498
25499             this.children[ i ].updateMatrixWorld( force );
25500
25501         }
25502
25503     },
25504
25505     clone: function () {
25506
25507         // TODO
25508
25509     }
25510
25511 };
25512
25513 THREE.Object3D.__m1 = new THREE.Matrix4();
25514
25515 THREE.Object3DCount = 0;
25516 /**
25517  * @author mrdoob / http://mrdoob.com/
25518  * @author supereggbert / http://www.paulbrunt.co.uk/
25519  * @author julianwa / https://github.com/julianwa
25520  */
25521
25522 THREE.Projector = function() {
25523
25524     var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
25525     _vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
25526     _face, _face3Count, _face3Pool = [], _face3PoolLength = 0,
25527     _face4Count, _face4Pool = [], _face4PoolLength = 0,
25528     _line, _lineCount, _linePool = [], _linePoolLength = 0,
25529     _particle, _particleCount, _particlePool = [], _particlePoolLength = 0,
25530
25531     _renderData = { objects: [], sprites: [], lights: [], elements: [] },
25532
25533     _vector3 = new THREE.Vector3(),
25534     _vector4 = new THREE.Vector4(),
25535
25536     _viewProjectionMatrix = new THREE.Matrix4(),
25537     _modelViewProjectionMatrix = new THREE.Matrix4(),
25538
25539     _frustum = new THREE.Frustum(),
25540
25541     _clippedVertex1PositionScreen = new THREE.Vector4(),
25542     _clippedVertex2PositionScreen = new THREE.Vector4(),
25543
25544     _face3VertexNormals;
25545
25546     this.projectVector = function ( vector, camera ) {
25547
25548         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
25549
25550         _viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
25551         _viewProjectionMatrix.multiplyVector3( vector );
25552
25553         return vector;
25554
25555     };
25556
25557     this.unprojectVector = function ( vector, camera ) {
25558
25559         camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
25560
25561         _viewProjectionMatrix.multiply( camera.matrixWorld, camera.projectionMatrixInverse );
25562         _viewProjectionMatrix.multiplyVector3( vector );
25563
25564         return vector;
25565
25566     };
25567
25568     this.pickingRay = function ( vector, camera ) {
25569
25570         var end, ray, t;
25571
25572         // set two vectors with opposing z values
25573         vector.z = -1.0;
25574         end = new THREE.Vector3( vector.x, vector.y, 1.0 );
25575
25576         this.unprojectVector( vector, camera );
25577         this.unprojectVector( end, camera );
25578
25579         // find direction from vector to end
25580         end.subSelf( vector ).normalize();
25581
25582         return new THREE.Ray( vector, end );
25583
25584     };
25585
25586     var projectGraph = function ( root, sortObjects ) {
25587
25588         _objectCount = 0;
25589
25590         _renderData.objects.length = 0;
25591         _renderData.sprites.length = 0;
25592         _renderData.lights.length = 0;
25593
25594         var projectObject = function ( parent ) {
25595
25596             for ( var c = 0, cl = parent.children.length; c < cl; c ++ ) {
25597
25598                 var object = parent.children[ c ];
25599
25600                 if ( object.visible === false ) continue;
25601
25602                 if ( object instanceof THREE.Light ) {
25603
25604                     _renderData.lights.push( object );
25605
25606                 } else if ( object instanceof THREE.Mesh || object instanceof THREE.Line ) {
25607
25608                     if ( object.frustumCulled === false || _frustum.contains( object ) === true ) {
25609
25610                         _object = getNextObjectInPool();
25611                         _object.object = object;
25612
25613                         if ( object.renderDepth !== null ) {
25614
25615                             _object.z = object.renderDepth;
25616
25617                         } else {
25618
25619                             _vector3.copy( object.matrixWorld.getPosition() );
25620                             _viewProjectionMatrix.multiplyVector3( _vector3 );
25621                             _object.z = _vector3.z;
25622
25623                         }
25624
25625                         _renderData.objects.push( _object );
25626
25627                     }
25628
25629                 } else if ( object instanceof THREE.Sprite || object instanceof THREE.Particle ) {
25630
25631                     _object = getNextObjectInPool();
25632                     _object.object = object;
25633
25634                     // TODO: Find an elegant and performant solution and remove this dupe code.
25635
25636                     if ( object.renderDepth !== null ) {
25637
25638                         _object.z = object.renderDepth;
25639
25640                     } else {
25641
25642                         _vector3.copy( object.matrixWorld.getPosition() );
25643                         _viewProjectionMatrix.multiplyVector3( _vector3 );
25644                         _object.z = _vector3.z;
25645
25646                     }
25647
25648                     _renderData.sprites.push( _object );
25649
25650                 } else {
25651
25652                     _object = getNextObjectInPool();
25653                     _object.object = object;
25654
25655                     if ( object.renderDepth !== null ) {
25656
25657                         _object.z = object.renderDepth;
25658
25659                     } else {
25660
25661                         _vector3.copy( object.matrixWorld.getPosition() );
25662                         _viewProjectionMatrix.multiplyVector3( _vector3 );
25663                         _object.z = _vector3.z;
25664
25665                     }
25666
25667                     _renderData.objects.push( _object );
25668
25669                 }
25670
25671                 projectObject( object );
25672
25673             }
25674
25675         };
25676
25677         projectObject( root );
25678
25679         if ( sortObjects === true ) _renderData.objects.sort( painterSort );
25680
25681         return _renderData;
25682
25683     };
25684
25685     this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
25686
25687         var near = camera.near, far = camera.far, visible = false,
25688         o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object,
25689         modelMatrix, rotationMatrix,
25690         geometry, geometryMaterials, vertices, vertex, vertexPositionScreen,
25691         faces, face, faceVertexNormals, normal, faceVertexUvs, uvs,
25692         v1, v2, v3, v4, isFaceMaterial, material, side;
25693
25694         _face3Count = 0;
25695         _face4Count = 0;
25696         _lineCount = 0;
25697         _particleCount = 0;
25698
25699         _renderData.elements.length = 0;
25700
25701         scene.updateMatrixWorld();
25702
25703         if ( camera.parent === undefined ) camera.updateMatrixWorld();
25704
25705         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
25706
25707         _viewProjectionMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
25708
25709         _frustum.setFromMatrix( _viewProjectionMatrix );
25710
25711         _renderData = projectGraph( scene, sortObjects );
25712
25713         for ( o = 0, ol = _renderData.objects.length; o < ol; o++ ) {
25714
25715             object = _renderData.objects[ o ].object;
25716
25717             modelMatrix = object.matrixWorld;
25718
25719             _vertexCount = 0;
25720
25721             if ( object instanceof THREE.Mesh ) {
25722
25723                 geometry = object.geometry;
25724                 geometryMaterials = object.geometry.materials;
25725                 vertices = geometry.vertices;
25726                 faces = geometry.faces;
25727                 faceVertexUvs = geometry.faceVertexUvs;
25728
25729                 rotationMatrix = object.matrixRotationWorld.extractRotation( modelMatrix );
25730
25731                 isFaceMaterial = object.material instanceof THREE.MeshFaceMaterial;
25732                 side = object.material.side;
25733
25734                 for ( v = 0, vl = vertices.length; v < vl; v ++ ) {
25735
25736                     _vertex = getNextVertexInPool();
25737                     _vertex.positionWorld.copy( vertices[ v ] );
25738
25739                     modelMatrix.multiplyVector3( _vertex.positionWorld );
25740
25741                     _vertex.positionScreen.copy( _vertex.positionWorld );
25742                     _viewProjectionMatrix.multiplyVector4( _vertex.positionScreen );
25743
25744                     _vertex.positionScreen.x /= _vertex.positionScreen.w;
25745                     _vertex.positionScreen.y /= _vertex.positionScreen.w;
25746
25747                     _vertex.visible = _vertex.positionScreen.z > near && _vertex.positionScreen.z < far;
25748
25749                 }
25750
25751                 for ( f = 0, fl = faces.length; f < fl; f ++ ) {
25752
25753                     face = faces[ f ];
25754
25755                     material = isFaceMaterial === true ? geometryMaterials[ face.materialIndex ] : object.material;
25756
25757                     if ( material === undefined ) continue;
25758
25759                     side = material.side;
25760
25761                     if ( face instanceof THREE.Face3 ) {
25762
25763                         v1 = _vertexPool[ face.a ];
25764                         v2 = _vertexPool[ face.b ];
25765                         v3 = _vertexPool[ face.c ];
25766
25767                         if ( v1.visible === true && v2.visible === true && v3.visible === true ) {
25768
25769                             visible = ( ( v3.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
25770                                 ( v3.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
25771
25772                             if ( side === THREE.DoubleSide || visible === ( side === THREE.FrontSide ) ) {
25773
25774                                 _face = getNextFace3InPool();
25775
25776                                 _face.v1.copy( v1 );
25777                                 _face.v2.copy( v2 );
25778                                 _face.v3.copy( v3 );
25779
25780                             } else {
25781
25782                                 continue;
25783
25784                             }
25785
25786                         } else {
25787
25788                             continue;
25789
25790                         }
25791
25792                     } else if ( face instanceof THREE.Face4 ) {
25793
25794                         v1 = _vertexPool[ face.a ];
25795                         v2 = _vertexPool[ face.b ];
25796                         v3 = _vertexPool[ face.c ];
25797                         v4 = _vertexPool[ face.d ];
25798
25799                         if ( v1.visible === true && v2.visible === true && v3.visible === true && v4.visible === true ) {
25800
25801                             visible = ( v4.positionScreen.x - v1.positionScreen.x ) * ( v2.positionScreen.y - v1.positionScreen.y ) -
25802                                 ( v4.positionScreen.y - v1.positionScreen.y ) * ( v2.positionScreen.x - v1.positionScreen.x ) < 0 ||
25803                                 ( v2.positionScreen.x - v3.positionScreen.x ) * ( v4.positionScreen.y - v3.positionScreen.y ) -
25804                                 ( v2.positionScreen.y - v3.positionScreen.y ) * ( v4.positionScreen.x - v3.positionScreen.x ) < 0;
25805
25806
25807                             if ( side === THREE.DoubleSide || visible === ( side === THREE.FrontSide ) ) {
25808
25809                                 _face = getNextFace4InPool();
25810
25811                                 _face.v1.copy( v1 );
25812                                 _face.v2.copy( v2 );
25813                                 _face.v3.copy( v3 );
25814                                 _face.v4.copy( v4 );
25815
25816                             } else {
25817
25818                                 continue;
25819
25820                             }
25821
25822                         } else {
25823
25824                             continue;
25825
25826                         }
25827
25828                     }
25829
25830                     _face.normalWorld.copy( face.normal );
25831
25832                     if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) _face.normalWorld.negate();
25833                     rotationMatrix.multiplyVector3( _face.normalWorld );
25834
25835                     _face.centroidWorld.copy( face.centroid );
25836                     modelMatrix.multiplyVector3( _face.centroidWorld );
25837
25838                     _face.centroidScreen.copy( _face.centroidWorld );
25839                     _viewProjectionMatrix.multiplyVector3( _face.centroidScreen );
25840
25841                     faceVertexNormals = face.vertexNormals;
25842
25843                     for ( n = 0, nl = faceVertexNormals.length; n < nl; n ++ ) {
25844
25845                         normal = _face.vertexNormalsWorld[ n ];
25846                         normal.copy( faceVertexNormals[ n ] );
25847
25848                         if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) normal.negate();
25849
25850                         rotationMatrix.multiplyVector3( normal );
25851
25852                     }
25853
25854                     _face.vertexNormalsLength = faceVertexNormals.length;
25855
25856                     for ( c = 0, cl = faceVertexUvs.length; c < cl; c ++ ) {
25857
25858                         uvs = faceVertexUvs[ c ][ f ];
25859
25860                         if ( uvs === undefined ) continue;
25861
25862                         for ( u = 0, ul = uvs.length; u < ul; u ++ ) {
25863
25864                             _face.uvs[ c ][ u ] = uvs[ u ];
25865
25866                         }
25867
25868                     }
25869
25870                     _face.material = material;
25871
25872                     _face.z = _face.centroidScreen.z;
25873
25874                     _renderData.elements.push( _face );
25875
25876                 }
25877
25878             } else if ( object instanceof THREE.Line ) {
25879
25880                 _modelViewProjectionMatrix.multiply( _viewProjectionMatrix, modelMatrix );
25881
25882                 vertices = object.geometry.vertices;
25883
25884                 v1 = getNextVertexInPool();
25885                 v1.positionScreen.copy( vertices[ 0 ] );
25886                 _modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
25887
25888                 // Handle LineStrip and LinePieces
25889                 var step = object.type === THREE.LinePieces ? 2 : 1;
25890
25891                 for ( v = 1, vl = vertices.length; v < vl; v ++ ) {
25892
25893                     v1 = getNextVertexInPool();
25894                     v1.positionScreen.copy( vertices[ v ] );
25895                     _modelViewProjectionMatrix.multiplyVector4( v1.positionScreen );
25896
25897                     if ( ( v + 1 ) % step > 0 ) continue;
25898
25899                     v2 = _vertexPool[ _vertexCount - 2 ];
25900
25901                     _clippedVertex1PositionScreen.copy( v1.positionScreen );
25902                     _clippedVertex2PositionScreen.copy( v2.positionScreen );
25903
25904                     if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) {
25905
25906                         // Perform the perspective divide
25907                         _clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
25908                         _clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
25909
25910                         _line = getNextLineInPool();
25911                         _line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
25912                         _line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
25913
25914                         _line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
25915
25916                         _line.material = object.material;
25917
25918                         _renderData.elements.push( _line );
25919
25920                     }
25921
25922                 }
25923
25924             }
25925
25926         }
25927
25928         for ( o = 0, ol = _renderData.sprites.length; o < ol; o++ ) {
25929
25930             object = _renderData.sprites[ o ].object;
25931
25932             modelMatrix = object.matrixWorld;
25933
25934             if ( object instanceof THREE.Particle ) {
25935
25936                 _vector4.set( modelMatrix.elements[12], modelMatrix.elements[13], modelMatrix.elements[14], 1 );
25937                 _viewProjectionMatrix.multiplyVector4( _vector4 );
25938
25939                 _vector4.z /= _vector4.w;
25940
25941                 if ( _vector4.z > 0 && _vector4.z < 1 ) {
25942
25943                     _particle = getNextParticleInPool();
25944                     _particle.object = object;
25945                     _particle.x = _vector4.x / _vector4.w;
25946                     _particle.y = _vector4.y / _vector4.w;
25947                     _particle.z = _vector4.z;
25948
25949                     _particle.rotation = object.rotation.z;
25950
25951                     _particle.scale.x = object.scale.x * Math.abs( _particle.x - ( _vector4.x + camera.projectionMatrix.elements[0] ) / ( _vector4.w + camera.projectionMatrix.elements[12] ) );
25952                     _particle.scale.y = object.scale.y * Math.abs( _particle.y - ( _vector4.y + camera.projectionMatrix.elements[5] ) / ( _vector4.w + camera.projectionMatrix.elements[13] ) );
25953
25954                     _particle.material = object.material;
25955
25956                     _renderData.elements.push( _particle );
25957
25958                 }
25959
25960             }
25961
25962         }
25963
25964         if ( sortElements === true ) _renderData.elements.sort( painterSort );
25965
25966         return _renderData;
25967
25968     };
25969
25970     // Pools
25971
25972     function getNextObjectInPool() {
25973
25974         if ( _objectCount === _objectPoolLength ) {
25975
25976             var object = new THREE.RenderableObject();
25977             _objectPool.push( object );
25978             _objectPoolLength ++;
25979             _objectCount ++;
25980             return object;
25981
25982         }
25983
25984         return _objectPool[ _objectCount ++ ];
25985
25986     }
25987
25988     function getNextVertexInPool() {
25989
25990         if ( _vertexCount === _vertexPoolLength ) {
25991
25992             var vertex = new THREE.RenderableVertex();
25993             _vertexPool.push( vertex );
25994             _vertexPoolLength ++;
25995             _vertexCount ++;
25996             return vertex;
25997
25998         }
25999
26000         return _vertexPool[ _vertexCount ++ ];
26001
26002     }
26003
26004     function getNextFace3InPool() {
26005
26006         if ( _face3Count === _face3PoolLength ) {
26007
26008             var face = new THREE.RenderableFace3();
26009             _face3Pool.push( face );
26010             _face3PoolLength ++;
26011             _face3Count ++;
26012             return face;
26013
26014         }
26015
26016         return _face3Pool[ _face3Count ++ ];
26017
26018
26019     }
26020
26021     function getNextFace4InPool() {
26022
26023         if ( _face4Count === _face4PoolLength ) {
26024
26025             var face = new THREE.RenderableFace4();
26026             _face4Pool.push( face );
26027             _face4PoolLength ++;
26028             _face4Count ++;
26029             return face;
26030
26031         }
26032
26033         return _face4Pool[ _face4Count ++ ];
26034
26035     }
26036
26037     function getNextLineInPool() {
26038
26039         if ( _lineCount === _linePoolLength ) {
26040
26041             var line = new THREE.RenderableLine();
26042             _linePool.push( line );
26043             _linePoolLength ++;
26044             _lineCount ++
26045             return line;
26046
26047         }
26048
26049         return _linePool[ _lineCount ++ ];
26050
26051     }
26052
26053     function getNextParticleInPool() {
26054
26055         if ( _particleCount === _particlePoolLength ) {
26056
26057             var particle = new THREE.RenderableParticle();
26058             _particlePool.push( particle );
26059             _particlePoolLength ++;
26060             _particleCount ++
26061             return particle;
26062
26063         }
26064
26065         return _particlePool[ _particleCount ++ ];
26066
26067     }
26068
26069     //
26070
26071     function painterSort( a, b ) {
26072
26073         return b.z - a.z;
26074
26075     }
26076
26077     function clipLine( s1, s2 ) {
26078
26079         var alpha1 = 0, alpha2 = 1,
26080
26081         // Calculate the boundary coordinate of each vertex for the near and far clip planes,
26082         // Z = -1 and Z = +1, respectively.
26083         bc1near =  s1.z + s1.w,
26084         bc2near =  s2.z + s2.w,
26085         bc1far =  - s1.z + s1.w,
26086         bc2far =  - s2.z + s2.w;
26087
26088         if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
26089
26090             // Both vertices lie entirely within all clip planes.
26091             return true;
26092
26093         } else if ( ( bc1near < 0 && bc2near < 0) || (bc1far < 0 && bc2far < 0 ) ) {
26094
26095             // Both vertices lie entirely outside one of the clip planes.
26096             return false;
26097
26098         } else {
26099
26100             // The line segment spans at least one clip plane.
26101
26102             if ( bc1near < 0 ) {
26103
26104                 // v1 lies outside the near plane, v2 inside
26105                 alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) );
26106
26107             } else if ( bc2near < 0 ) {
26108
26109                 // v2 lies outside the near plane, v1 inside
26110                 alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) );
26111
26112             }
26113
26114             if ( bc1far < 0 ) {
26115
26116                 // v1 lies outside the far plane, v2 inside
26117                 alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) );
26118
26119             } else if ( bc2far < 0 ) {
26120
26121                 // v2 lies outside the far plane, v2 inside
26122                 alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) );
26123
26124             }
26125
26126             if ( alpha2 < alpha1 ) {
26127
26128                 // The line segment spans two boundaries, but is outside both of them.
26129                 // (This can't happen when we're only clipping against just near/far but good
26130                 //  to leave the check here for future usage if other clip planes are added.)
26131                 return false;
26132
26133             } else {
26134
26135                 // Update the s1 and s2 vertices to match the clipped line segment.
26136                 s1.lerpSelf( s2, alpha1 );
26137                 s2.lerpSelf( s1, 1 - alpha2 );
26138
26139                 return true;
26140
26141             }
26142
26143         }
26144
26145     }
26146
26147 };
26148 /**
26149  * @author mikael emtinger / http://gomo.se/
26150  * @author alteredq / http://alteredqualia.com/
26151  * @author WestLangley / http://github.com/WestLangley
26152  */
26153
26154 THREE.Quaternion = function( x, y, z, w ) {
26155
26156     this.x = x || 0;
26157     this.y = y || 0;
26158     this.z = z || 0;
26159     this.w = ( w !== undefined ) ? w : 1;
26160
26161 };
26162
26163 THREE.Quaternion.prototype = {
26164
26165     constructor: THREE.Quaternion,
26166
26167     set: function ( x, y, z, w ) {
26168
26169         this.x = x;
26170         this.y = y;
26171         this.z = z;
26172         this.w = w;
26173
26174         return this;
26175
26176     },
26177
26178     copy: function ( q ) {
26179
26180         this.x = q.x;
26181         this.y = q.y;
26182         this.z = q.z;
26183         this.w = q.w;
26184
26185         return this;
26186
26187     },
26188
26189     setFromEuler: function ( v, order ) {
26190
26191         // http://www.mathworks.com/matlabcentral/fileexchange/
26192         //     20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
26193         //    content/SpinCalc.m
26194
26195         var c1 = Math.cos( v.x / 2 );
26196         var c2 = Math.cos( v.y / 2 );
26197         var c3 = Math.cos( v.z / 2 );
26198         var s1 = Math.sin( v.x / 2 );
26199         var s2 = Math.sin( v.y / 2 );
26200         var s3 = Math.sin( v.z / 2 );
26201
26202         if ( order === undefined || order === 'XYZ' ) {
26203
26204             this.x = s1 * c2 * c3 + c1 * s2 * s3;
26205             this.y = c1 * s2 * c3 - s1 * c2 * s3;
26206             this.z = c1 * c2 * s3 + s1 * s2 * c3;
26207             this.w = c1 * c2 * c3 - s1 * s2 * s3;
26208
26209         } else if ( order === 'YXZ' ) {
26210
26211             this.x = s1 * c2 * c3 + c1 * s2 * s3;
26212             this.y = c1 * s2 * c3 - s1 * c2 * s3;
26213             this.z = c1 * c2 * s3 - s1 * s2 * c3;
26214             this.w = c1 * c2 * c3 + s1 * s2 * s3;
26215
26216         } else if ( order === 'ZXY' ) {
26217
26218             this.x = s1 * c2 * c3 - c1 * s2 * s3;
26219             this.y = c1 * s2 * c3 + s1 * c2 * s3;
26220             this.z = c1 * c2 * s3 + s1 * s2 * c3;
26221             this.w = c1 * c2 * c3 - s1 * s2 * s3;
26222
26223         } else if ( order === 'ZYX' ) {
26224
26225             this.x = s1 * c2 * c3 - c1 * s2 * s3;
26226             this.y = c1 * s2 * c3 + s1 * c2 * s3;
26227             this.z = c1 * c2 * s3 - s1 * s2 * c3;
26228             this.w = c1 * c2 * c3 + s1 * s2 * s3;
26229
26230         } else if ( order === 'YZX' ) {
26231
26232             this.x = s1 * c2 * c3 + c1 * s2 * s3;
26233             this.y = c1 * s2 * c3 + s1 * c2 * s3;
26234             this.z = c1 * c2 * s3 - s1 * s2 * c3;
26235             this.w = c1 * c2 * c3 - s1 * s2 * s3;
26236
26237         } else if ( order === 'XZY' ) {
26238
26239             this.x = s1 * c2 * c3 - c1 * s2 * s3;
26240             this.y = c1 * s2 * c3 - s1 * c2 * s3;
26241             this.z = c1 * c2 * s3 + s1 * s2 * c3;
26242             this.w = c1 * c2 * c3 + s1 * s2 * s3;
26243
26244         }
26245
26246         return this;
26247
26248     },
26249
26250     setFromAxisAngle: function ( axis, angle ) {
26251
26252         // from http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
26253         // axis have to be normalized
26254
26255         var halfAngle = angle / 2,
26256             s = Math.sin( halfAngle );
26257
26258         this.x = axis.x * s;
26259         this.y = axis.y * s;
26260         this.z = axis.z * s;
26261         this.w = Math.cos( halfAngle );
26262
26263         return this;
26264
26265     },
26266
26267     setFromRotationMatrix: function ( m ) {
26268
26269         // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
26270
26271         // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
26272
26273         var te = m.elements,
26274
26275             m11 = te[0], m12 = te[4], m13 = te[8],
26276             m21 = te[1], m22 = te[5], m23 = te[9],
26277             m31 = te[2], m32 = te[6], m33 = te[10],
26278
26279             trace = m11 + m22 + m33,
26280             s;
26281
26282         if( trace > 0 ) {
26283
26284             s = 0.5 / Math.sqrt( trace + 1.0 );
26285
26286             this.w = 0.25 / s;
26287             this.x = ( m32 - m23 ) * s;
26288             this.y = ( m13 - m31 ) * s;
26289             this.z = ( m21 - m12 ) * s;
26290
26291         } else if ( m11 > m22 && m11 > m33 ) {
26292
26293             s = 2.0 * Math.sqrt( 1.0 + m11 - m22 - m33 );
26294
26295             this.w = (m32 - m23 ) / s;
26296             this.x = 0.25 * s;
26297             this.y = (m12 + m21 ) / s;
26298             this.z = (m13 + m31 ) / s;
26299
26300         } else if (m22 > m33) {
26301
26302             s = 2.0 * Math.sqrt( 1.0 + m22 - m11 - m33 );
26303
26304             this.w = (m13 - m31 ) / s;
26305             this.x = (m12 + m21 ) / s;
26306             this.y = 0.25 * s;
26307             this.z = (m23 + m32 ) / s;
26308
26309         } else {
26310
26311             s = 2.0 * Math.sqrt( 1.0 + m33 - m11 - m22 );
26312
26313             this.w = ( m21 - m12 ) / s;
26314             this.x = ( m13 + m31 ) / s;
26315             this.y = ( m23 + m32 ) / s;
26316             this.z = 0.25 * s;
26317
26318         }
26319
26320         return this;
26321
26322     },
26323
26324     calculateW : function () {
26325
26326         this.w = - Math.sqrt( Math.abs( 1.0 - this.x * this.x - this.y * this.y - this.z * this.z ) );
26327
26328         return this;
26329
26330     },
26331
26332     inverse: function () {
26333
26334         this.x *= -1;
26335         this.y *= -1;
26336         this.z *= -1;
26337
26338         return this;
26339
26340     },
26341
26342     length: function () {
26343
26344         return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
26345
26346     },
26347
26348     normalize: function () {
26349
26350         var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
26351
26352         if ( l === 0 ) {
26353
26354             this.x = 0;
26355             this.y = 0;
26356             this.z = 0;
26357             this.w = 0;
26358
26359         } else {
26360
26361             l = 1 / l;
26362
26363             this.x = this.x * l;
26364             this.y = this.y * l;
26365             this.z = this.z * l;
26366             this.w = this.w * l;
26367
26368         }
26369
26370         return this;
26371
26372     },
26373
26374     multiply: function ( a, b ) {
26375
26376         // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
26377         var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w,
26378         qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
26379
26380         this.x =  qax * qbw + qay * qbz - qaz * qby + qaw * qbx;
26381         this.y = -qax * qbz + qay * qbw + qaz * qbx + qaw * qby;
26382         this.z =  qax * qby - qay * qbx + qaz * qbw + qaw * qbz;
26383         this.w = -qax * qbx - qay * qby - qaz * qbz + qaw * qbw;
26384
26385         return this;
26386
26387     },
26388
26389     multiplySelf: function ( b ) {
26390
26391         var qax = this.x, qay = this.y, qaz = this.z, qaw = this.w,
26392         qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
26393
26394         this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
26395         this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
26396         this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
26397         this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
26398
26399         return this;
26400
26401     },
26402
26403     multiplyVector3: function ( vector, dest ) {
26404
26405         if ( !dest ) { dest = vector; }
26406
26407         var x    = vector.x,  y  = vector.y,  z  = vector.z,
26408             qx   = this.x, qy = this.y, qz = this.z, qw = this.w;
26409
26410         // calculate quat * vector
26411
26412         var ix =  qw * x + qy * z - qz * y,
26413             iy =  qw * y + qz * x - qx * z,
26414             iz =  qw * z + qx * y - qy * x,
26415             iw = -qx * x - qy * y - qz * z;
26416
26417         // calculate result * inverse quat
26418
26419         dest.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
26420         dest.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
26421         dest.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
26422
26423         return dest;
26424
26425     },
26426
26427     slerpSelf: function ( qb, t ) {
26428
26429         var x = this.x, y = this.y, z = this.z, w = this.w;
26430
26431         // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
26432
26433         var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;
26434
26435         if ( cosHalfTheta < 0 ) {
26436
26437             this.w = -qb.w;
26438             this.x = -qb.x;
26439             this.y = -qb.y;
26440             this.z = -qb.z;
26441
26442             cosHalfTheta = -cosHalfTheta;
26443
26444         } else {
26445
26446             this.copy( qb );
26447
26448         }
26449
26450         if ( cosHalfTheta >= 1.0 ) {
26451
26452             this.w = w;
26453             this.x = x;
26454             this.y = y;
26455             this.z = z;
26456
26457             return this;
26458
26459         }
26460
26461         var halfTheta = Math.acos( cosHalfTheta );
26462         var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
26463
26464         if ( Math.abs( sinHalfTheta ) < 0.001 ) {
26465
26466             this.w = 0.5 * ( w + this.w );
26467             this.x = 0.5 * ( x + this.x );
26468             this.y = 0.5 * ( y + this.y );
26469             this.z = 0.5 * ( z + this.z );
26470
26471             return this;
26472
26473         }
26474
26475         var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
26476         ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
26477
26478         this.w = ( w * ratioA + this.w * ratioB );
26479         this.x = ( x * ratioA + this.x * ratioB );
26480         this.y = ( y * ratioA + this.y * ratioB );
26481         this.z = ( z * ratioA + this.z * ratioB );
26482
26483         return this;
26484
26485     },
26486
26487     clone: function () {
26488
26489         return new THREE.Quaternion( this.x, this.y, this.z, this.w );
26490
26491     }
26492
26493 }
26494
26495 THREE.Quaternion.slerp = function ( qa, qb, qm, t ) {
26496
26497     // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
26498
26499     var cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
26500
26501     if ( cosHalfTheta < 0 ) {
26502
26503         qm.w = -qb.w;
26504         qm.x = -qb.x;
26505         qm.y = -qb.y;
26506         qm.z = -qb.z;
26507
26508         cosHalfTheta = -cosHalfTheta;
26509
26510     } else {
26511
26512         qm.copy( qb );
26513
26514     }
26515
26516     if ( Math.abs( cosHalfTheta ) >= 1.0 ) {
26517
26518         qm.w = qa.w;
26519         qm.x = qa.x;
26520         qm.y = qa.y;
26521         qm.z = qa.z;
26522
26523         return qm;
26524
26525     }
26526
26527     var halfTheta = Math.acos( cosHalfTheta );
26528     var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
26529
26530     if ( Math.abs( sinHalfTheta ) < 0.001 ) {
26531
26532         qm.w = 0.5 * ( qa.w + qm.w );
26533         qm.x = 0.5 * ( qa.x + qm.x );
26534         qm.y = 0.5 * ( qa.y + qm.y );
26535         qm.z = 0.5 * ( qa.z + qm.z );
26536
26537         return qm;
26538
26539     }
26540
26541     var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta;
26542     var ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
26543
26544     qm.w = ( qa.w * ratioA + qm.w * ratioB );
26545     qm.x = ( qa.x * ratioA + qm.x * ratioB );
26546     qm.y = ( qa.y * ratioA + qm.y * ratioB );
26547     qm.z = ( qa.z * ratioA + qm.z * ratioB );
26548
26549     return qm;
26550
26551 }
26552 /**
26553  * @author mrdoob / http://mrdoob.com/
26554  */
26555
26556 THREE.Vertex = function ( v ) {
26557
26558     console.warn( 'THREE.Vertex has been DEPRECATED. Use THREE.Vector3 instead.')
26559     return v;
26560
26561 };
26562 /**
26563  * @author mrdoob / http://mrdoob.com/
26564  * @author alteredq / http://alteredqualia.com/
26565  */
26566
26567 THREE.Face3 = function ( a, b, c, normal, color, materialIndex ) {
26568
26569     this.a = a;
26570     this.b = b;
26571     this.c = c;
26572
26573     this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
26574     this.vertexNormals = normal instanceof Array ? normal : [ ];
26575
26576     this.color = color instanceof THREE.Color ? color : new THREE.Color();
26577     this.vertexColors = color instanceof Array ? color : [];
26578
26579     this.vertexTangents = [];
26580
26581     this.materialIndex = materialIndex;
26582
26583     this.centroid = new THREE.Vector3();
26584
26585 };
26586
26587 THREE.Face3.prototype = {
26588
26589     constructor: THREE.Face3,
26590
26591     clone: function () {
26592
26593         var face = new THREE.Face3( this.a, this.b, this.c );
26594
26595         face.normal.copy( this.normal );
26596         face.color.copy( this.color );
26597         face.centroid.copy( this.centroid );
26598
26599         face.materialIndex = this.materialIndex;
26600
26601         var i, il;
26602         for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
26603         for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
26604         for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
26605
26606         return face;
26607
26608     }
26609
26610 };
26611 /**
26612  * @author mrdoob / http://mrdoob.com/
26613  * @author alteredq / http://alteredqualia.com/
26614  */
26615
26616 THREE.Face4 = function ( a, b, c, d, normal, color, materialIndex ) {
26617
26618     this.a = a;
26619     this.b = b;
26620     this.c = c;
26621     this.d = d;
26622
26623     this.normal = normal instanceof THREE.Vector3 ? normal : new THREE.Vector3();
26624     this.vertexNormals = normal instanceof Array ? normal : [ ];
26625
26626     this.color = color instanceof THREE.Color ? color : new THREE.Color();
26627     this.vertexColors = color instanceof Array ? color : [];
26628
26629     this.vertexTangents = [];
26630
26631     this.materialIndex = materialIndex;
26632
26633     this.centroid = new THREE.Vector3();
26634
26635 };
26636
26637 THREE.Face4.prototype = {
26638
26639     constructor: THREE.Face4,
26640
26641     clone: function () {
26642
26643         var face = new THREE.Face4( this.a, this.b, this.c, this.d );
26644
26645         face.normal.copy( this.normal );
26646         face.color.copy( this.color );
26647         face.centroid.copy( this.centroid );
26648
26649         face.materialIndex = this.materialIndex;
26650
26651         var i, il;
26652         for ( i = 0, il = this.vertexNormals.length; i < il; i ++ ) face.vertexNormals[ i ] = this.vertexNormals[ i ].clone();
26653         for ( i = 0, il = this.vertexColors.length; i < il; i ++ ) face.vertexColors[ i ] = this.vertexColors[ i ].clone();
26654         for ( i = 0, il = this.vertexTangents.length; i < il; i ++ ) face.vertexTangents[ i ] = this.vertexTangents[ i ].clone();
26655
26656         return face;
26657
26658     }
26659
26660 };
26661 /**
26662  * @author mrdoob / http://mrdoob.com/
26663  */
26664
26665 THREE.UV = function ( u, v ) {
26666
26667     this.u = u || 0;
26668     this.v = v || 0;
26669
26670 };
26671
26672 THREE.UV.prototype = {
26673
26674     constructor: THREE.UV,
26675
26676     set: function ( u, v ) {
26677
26678         this.u = u;
26679         this.v = v;
26680
26681         return this;
26682
26683     },
26684
26685     copy: function ( uv ) {
26686
26687         this.u = uv.u;
26688         this.v = uv.v;
26689
26690         return this;
26691
26692     },
26693
26694     lerpSelf: function ( uv, alpha ) {
26695
26696         this.u += ( uv.u - this.u ) * alpha;
26697         this.v += ( uv.v - this.v ) * alpha;
26698
26699         return this;
26700
26701     },
26702
26703     clone: function () {
26704
26705         return new THREE.UV( this.u, this.v );
26706
26707     }
26708
26709 };
26710 /**
26711  * @author mrdoob / http://mrdoob.com/
26712  * @author kile / http://kile.stravaganza.org/
26713  * @author alteredq / http://alteredqualia.com/
26714  * @author mikael emtinger / http://gomo.se/
26715  * @author zz85 / http://www.lab4games.net/zz85/blog
26716  */
26717
26718 THREE.Geometry = function () {
26719
26720     this.id = THREE.GeometryCount ++;
26721
26722     this.name = '';
26723
26724     this.vertices = [];
26725     this.colors = []; // one-to-one vertex colors, used in ParticleSystem, Line and Ribbon
26726
26727     this.materials = [];
26728
26729     this.faces = [];
26730
26731     this.faceUvs = [[]];
26732     this.faceVertexUvs = [[]];
26733
26734     this.morphTargets = [];
26735     this.morphColors = [];
26736     this.morphNormals = [];
26737
26738     this.skinWeights = [];
26739     this.skinIndices = [];
26740
26741     this.boundingBox = null;
26742     this.boundingSphere = null;
26743
26744     this.hasTangents = false;
26745
26746     this.dynamic = true; // the intermediate typearrays will be deleted when set to false
26747
26748 };
26749
26750 THREE.Geometry.prototype = {
26751
26752     constructor : THREE.Geometry,
26753
26754     applyMatrix: function ( matrix ) {
26755
26756         var matrixRotation = new THREE.Matrix4();
26757         matrixRotation.extractRotation( matrix );
26758
26759         for ( var i = 0, il = this.vertices.length; i < il; i ++ ) {
26760
26761             var vertex = this.vertices[ i ];
26762
26763             matrix.multiplyVector3( vertex );
26764
26765         }
26766
26767         for ( var i = 0, il = this.faces.length; i < il; i ++ ) {
26768
26769             var face = this.faces[ i ];
26770
26771             matrixRotation.multiplyVector3( face.normal );
26772
26773             for ( var j = 0, jl = face.vertexNormals.length; j < jl; j ++ ) {
26774
26775                 matrixRotation.multiplyVector3( face.vertexNormals[ j ] );
26776
26777             }
26778
26779             matrix.multiplyVector3( face.centroid );
26780
26781         }
26782
26783     },
26784
26785     computeCentroids: function () {
26786
26787         var f, fl, face;
26788
26789         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26790
26791             face = this.faces[ f ];
26792             face.centroid.set( 0, 0, 0 );
26793
26794             if ( face instanceof THREE.Face3 ) {
26795
26796                 face.centroid.addSelf( this.vertices[ face.a ] );
26797                 face.centroid.addSelf( this.vertices[ face.b ] );
26798                 face.centroid.addSelf( this.vertices[ face.c ] );
26799                 face.centroid.divideScalar( 3 );
26800
26801             } else if ( face instanceof THREE.Face4 ) {
26802
26803                 face.centroid.addSelf( this.vertices[ face.a ] );
26804                 face.centroid.addSelf( this.vertices[ face.b ] );
26805                 face.centroid.addSelf( this.vertices[ face.c ] );
26806                 face.centroid.addSelf( this.vertices[ face.d ] );
26807                 face.centroid.divideScalar( 4 );
26808
26809             }
26810
26811         }
26812
26813     },
26814
26815     computeFaceNormals: function () {
26816
26817         var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC,
26818         cb = new THREE.Vector3(), ab = new THREE.Vector3();
26819
26820         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26821
26822             face = this.faces[ f ];
26823
26824             vA = this.vertices[ face.a ];
26825             vB = this.vertices[ face.b ];
26826             vC = this.vertices[ face.c ];
26827
26828             cb.sub( vC, vB );
26829             ab.sub( vA, vB );
26830             cb.crossSelf( ab );
26831
26832             if ( !cb.isZero() ) {
26833
26834                 cb.normalize();
26835
26836             }
26837
26838             face.normal.copy( cb );
26839
26840         }
26841
26842     },
26843
26844     computeVertexNormals: function () {
26845
26846         var v, vl, f, fl, face, vertices;
26847
26848         // create internal buffers for reuse when calling this method repeatedly
26849         // (otherwise memory allocation / deallocation every frame is big resource hog)
26850
26851         if ( this.__tmpVertices === undefined ) {
26852
26853             this.__tmpVertices = new Array( this.vertices.length );
26854             vertices = this.__tmpVertices;
26855
26856             for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
26857
26858                 vertices[ v ] = new THREE.Vector3();
26859
26860             }
26861
26862             for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26863
26864                 face = this.faces[ f ];
26865
26866                 if ( face instanceof THREE.Face3 ) {
26867
26868                     face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
26869
26870                 } else if ( face instanceof THREE.Face4 ) {
26871
26872                     face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
26873
26874                 }
26875
26876             }
26877
26878         } else {
26879
26880             vertices = this.__tmpVertices;
26881
26882             for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
26883
26884                 vertices[ v ].set( 0, 0, 0 );
26885
26886             }
26887
26888         }
26889
26890         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26891
26892             face = this.faces[ f ];
26893
26894             if ( face instanceof THREE.Face3 ) {
26895
26896                 vertices[ face.a ].addSelf( face.normal );
26897                 vertices[ face.b ].addSelf( face.normal );
26898                 vertices[ face.c ].addSelf( face.normal );
26899
26900             } else if ( face instanceof THREE.Face4 ) {
26901
26902                 vertices[ face.a ].addSelf( face.normal );
26903                 vertices[ face.b ].addSelf( face.normal );
26904                 vertices[ face.c ].addSelf( face.normal );
26905                 vertices[ face.d ].addSelf( face.normal );
26906
26907             }
26908
26909         }
26910
26911         for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
26912
26913             vertices[ v ].normalize();
26914
26915         }
26916
26917         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26918
26919             face = this.faces[ f ];
26920
26921             if ( face instanceof THREE.Face3 ) {
26922
26923                 face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
26924                 face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
26925                 face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
26926
26927             } else if ( face instanceof THREE.Face4 ) {
26928
26929                 face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
26930                 face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
26931                 face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
26932                 face.vertexNormals[ 3 ].copy( vertices[ face.d ] );
26933
26934             }
26935
26936         }
26937
26938     },
26939
26940     computeMorphNormals: function () {
26941
26942         var i, il, f, fl, face;
26943
26944         // save original normals
26945         // - create temp variables on first access
26946         //   otherwise just copy (for faster repeated calls)
26947
26948         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
26949
26950             face = this.faces[ f ];
26951
26952             if ( ! face.__originalFaceNormal ) {
26953
26954                 face.__originalFaceNormal = face.normal.clone();
26955
26956             } else {
26957
26958                 face.__originalFaceNormal.copy( face.normal );
26959
26960             }
26961
26962             if ( ! face.__originalVertexNormals ) face.__originalVertexNormals = [];
26963
26964             for ( i = 0, il = face.vertexNormals.length; i < il; i ++ ) {
26965
26966                 if ( ! face.__originalVertexNormals[ i ] ) {
26967
26968                     face.__originalVertexNormals[ i ] = face.vertexNormals[ i ].clone();
26969
26970                 } else {
26971
26972                     face.__originalVertexNormals[ i ].copy( face.vertexNormals[ i ] );
26973
26974                 }
26975
26976             }
26977
26978         }
26979
26980         // use temp geometry to compute face and vertex normals for each morph
26981
26982         var tmpGeo = new THREE.Geometry();
26983         tmpGeo.faces = this.faces;
26984
26985         for ( i = 0, il = this.morphTargets.length; i < il; i ++ ) {
26986
26987             // create on first access
26988
26989             if ( ! this.morphNormals[ i ] ) {
26990
26991                 this.morphNormals[ i ] = {};
26992                 this.morphNormals[ i ].faceNormals = [];
26993                 this.morphNormals[ i ].vertexNormals = [];
26994
26995                 var dstNormalsFace = this.morphNormals[ i ].faceNormals;
26996                 var dstNormalsVertex = this.morphNormals[ i ].vertexNormals;
26997
26998                 var faceNormal, vertexNormals;
26999
27000                 for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27001
27002                     face = this.faces[ f ];
27003
27004                     faceNormal = new THREE.Vector3();
27005
27006                     if ( face instanceof THREE.Face3 ) {
27007
27008                         vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3() };
27009
27010                     } else {
27011
27012                         vertexNormals = { a: new THREE.Vector3(), b: new THREE.Vector3(), c: new THREE.Vector3(), d: new THREE.Vector3() };
27013
27014                     }
27015
27016                     dstNormalsFace.push( faceNormal );
27017                     dstNormalsVertex.push( vertexNormals );
27018
27019                 }
27020
27021             }
27022
27023             var morphNormals = this.morphNormals[ i ];
27024
27025             // set vertices to morph target
27026
27027             tmpGeo.vertices = this.morphTargets[ i ].vertices;
27028
27029             // compute morph normals
27030
27031             tmpGeo.computeFaceNormals();
27032             tmpGeo.computeVertexNormals();
27033
27034             // store morph normals
27035
27036             var faceNormal, vertexNormals;
27037
27038             for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27039
27040                 face = this.faces[ f ];
27041
27042                 faceNormal = morphNormals.faceNormals[ f ];
27043                 vertexNormals = morphNormals.vertexNormals[ f ];
27044
27045                 faceNormal.copy( face.normal );
27046
27047                 if ( face instanceof THREE.Face3 ) {
27048
27049                     vertexNormals.a.copy( face.vertexNormals[ 0 ] );
27050                     vertexNormals.b.copy( face.vertexNormals[ 1 ] );
27051                     vertexNormals.c.copy( face.vertexNormals[ 2 ] );
27052
27053                 } else {
27054
27055                     vertexNormals.a.copy( face.vertexNormals[ 0 ] );
27056                     vertexNormals.b.copy( face.vertexNormals[ 1 ] );
27057                     vertexNormals.c.copy( face.vertexNormals[ 2 ] );
27058                     vertexNormals.d.copy( face.vertexNormals[ 3 ] );
27059
27060                 }
27061
27062             }
27063
27064         }
27065
27066         // restore original normals
27067
27068         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27069
27070             face = this.faces[ f ];
27071
27072             face.normal = face.__originalFaceNormal;
27073             face.vertexNormals = face.__originalVertexNormals;
27074
27075         }
27076
27077     },
27078
27079     computeTangents: function () {
27080
27081         // based on http://www.terathon.com/code/tangent.html
27082         // tangents go to vertices
27083
27084         var f, fl, v, vl, i, il, vertexIndex,
27085             face, uv, vA, vB, vC, uvA, uvB, uvC,
27086             x1, x2, y1, y2, z1, z2,
27087             s1, s2, t1, t2, r, t, test,
27088             tan1 = [], tan2 = [],
27089             sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
27090             tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
27091             n = new THREE.Vector3(), w;
27092
27093         for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
27094
27095             tan1[ v ] = new THREE.Vector3();
27096             tan2[ v ] = new THREE.Vector3();
27097
27098         }
27099
27100         function handleTriangle( context, a, b, c, ua, ub, uc ) {
27101
27102             vA = context.vertices[ a ];
27103             vB = context.vertices[ b ];
27104             vC = context.vertices[ c ];
27105
27106             uvA = uv[ ua ];
27107             uvB = uv[ ub ];
27108             uvC = uv[ uc ];
27109
27110             x1 = vB.x - vA.x;
27111             x2 = vC.x - vA.x;
27112             y1 = vB.y - vA.y;
27113             y2 = vC.y - vA.y;
27114             z1 = vB.z - vA.z;
27115             z2 = vC.z - vA.z;
27116
27117             s1 = uvB.u - uvA.u;
27118             s2 = uvC.u - uvA.u;
27119             t1 = uvB.v - uvA.v;
27120             t2 = uvC.v - uvA.v;
27121
27122             r = 1.0 / ( s1 * t2 - s2 * t1 );
27123             sdir.set( ( t2 * x1 - t1 * x2 ) * r,
27124                       ( t2 * y1 - t1 * y2 ) * r,
27125                       ( t2 * z1 - t1 * z2 ) * r );
27126             tdir.set( ( s1 * x2 - s2 * x1 ) * r,
27127                       ( s1 * y2 - s2 * y1 ) * r,
27128                       ( s1 * z2 - s2 * z1 ) * r );
27129
27130             tan1[ a ].addSelf( sdir );
27131             tan1[ b ].addSelf( sdir );
27132             tan1[ c ].addSelf( sdir );
27133
27134             tan2[ a ].addSelf( tdir );
27135             tan2[ b ].addSelf( tdir );
27136             tan2[ c ].addSelf( tdir );
27137
27138         }
27139
27140         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27141
27142             face = this.faces[ f ];
27143             uv = this.faceVertexUvs[ 0 ][ f ]; // use UV layer 0 for tangents
27144
27145             if ( face instanceof THREE.Face3 ) {
27146
27147                 handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
27148
27149             } else if ( face instanceof THREE.Face4 ) {
27150
27151                 handleTriangle( this, face.a, face.b, face.d, 0, 1, 3 );
27152                 handleTriangle( this, face.b, face.c, face.d, 1, 2, 3 );
27153
27154             }
27155
27156         }
27157
27158         var faceIndex = [ 'a', 'b', 'c', 'd' ];
27159
27160         for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
27161
27162             face = this.faces[ f ];
27163
27164             for ( i = 0; i < face.vertexNormals.length; i++ ) {
27165
27166                 n.copy( face.vertexNormals[ i ] );
27167
27168                 vertexIndex = face[ faceIndex[ i ] ];
27169
27170                 t = tan1[ vertexIndex ];
27171
27172                 // Gram-Schmidt orthogonalize
27173
27174                 tmp.copy( t );
27175                 tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
27176
27177                 // Calculate handedness
27178
27179                 tmp2.cross( face.vertexNormals[ i ], t );
27180                 test = tmp2.dot( tan2[ vertexIndex ] );
27181                 w = (test < 0.0) ? -1.0 : 1.0;
27182
27183                 face.vertexTangents[ i ] = new THREE.Vector4( tmp.x, tmp.y, tmp.z, w );
27184
27185             }
27186
27187         }
27188
27189         this.hasTangents = true;
27190
27191     },
27192
27193     computeBoundingBox: function () {
27194
27195         if ( ! this.boundingBox ) {
27196
27197             this.boundingBox = { min: new THREE.Vector3(), max: new THREE.Vector3() };
27198
27199         }
27200
27201         if ( this.vertices.length > 0 ) {
27202
27203             var position, firstPosition = this.vertices[ 0 ];
27204
27205             this.boundingBox.min.copy( firstPosition );
27206             this.boundingBox.max.copy( firstPosition );
27207
27208             var min = this.boundingBox.min,
27209                 max = this.boundingBox.max;
27210
27211             for ( var v = 1, vl = this.vertices.length; v < vl; v ++ ) {
27212
27213                 position = this.vertices[ v ];
27214
27215                 if ( position.x < min.x ) {
27216
27217                     min.x = position.x;
27218
27219                 } else if ( position.x > max.x ) {
27220
27221                     max.x = position.x;
27222
27223                 }
27224
27225                 if ( position.y < min.y ) {
27226
27227                     min.y = position.y;
27228
27229                 } else if ( position.y > max.y ) {
27230
27231                     max.y = position.y;
27232
27233                 }
27234
27235                 if ( position.z < min.z ) {
27236
27237                     min.z = position.z;
27238
27239                 } else if ( position.z > max.z ) {
27240
27241                     max.z = position.z;
27242
27243                 }
27244
27245             }
27246
27247         } else {
27248
27249             this.boundingBox.min.set( 0, 0, 0 );
27250             this.boundingBox.max.set( 0, 0, 0 );
27251
27252         }
27253
27254     },
27255
27256     computeBoundingSphere: function () {
27257
27258         var maxRadiusSq = 0;
27259
27260         if ( this.boundingSphere === null ) this.boundingSphere = { radius: 0 };
27261
27262         for ( var i = 0, l = this.vertices.length; i < l; i ++ ) {
27263
27264             var radiusSq = this.vertices[ i ].lengthSq();
27265             if ( radiusSq > maxRadiusSq ) maxRadiusSq = radiusSq;
27266
27267         }
27268
27269         this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
27270
27271     },
27272
27273     /*
27274      * Checks for duplicate vertices with hashmap.
27275      * Duplicated vertices are removed
27276      * and faces' vertices are updated.
27277      */
27278
27279     mergeVertices: function () {
27280
27281         var verticesMap = {}; // Hashmap for looking up vertice by position coordinates (and making sure they are unique)
27282         var unique = [], changes = [];
27283
27284         var v, key;
27285         var precisionPoints = 4; // number of decimal points, eg. 4 for epsilon of 0.0001
27286         var precision = Math.pow( 10, precisionPoints );
27287         var i,il, face;
27288         var abcd = 'abcd', o, k, j, jl, u;
27289
27290         for ( i = 0, il = this.vertices.length; i < il; i ++ ) {
27291
27292             v = this.vertices[ i ];
27293             key = [ Math.round( v.x * precision ), Math.round( v.y * precision ), Math.round( v.z * precision ) ].join( '_' );
27294
27295             if ( verticesMap[ key ] === undefined ) {
27296
27297                 verticesMap[ key ] = i;
27298                 unique.push( this.vertices[ i ] );
27299                 changes[ i ] = unique.length - 1;
27300
27301             } else {
27302
27303                 //console.log('Duplicate vertex found. ', i, ' could be using ', verticesMap[key]);
27304                 changes[ i ] = changes[ verticesMap[ key ] ];
27305
27306             }
27307
27308         };
27309
27310
27311         // Start to patch face indices
27312
27313         for( i = 0, il = this.faces.length; i < il; i ++ ) {
27314
27315             face = this.faces[ i ];
27316
27317             if ( face instanceof THREE.Face3 ) {
27318
27319                 face.a = changes[ face.a ];
27320                 face.b = changes[ face.b ];
27321                 face.c = changes[ face.c ];
27322
27323             } else if ( face instanceof THREE.Face4 ) {
27324
27325                 face.a = changes[ face.a ];
27326                 face.b = changes[ face.b ];
27327                 face.c = changes[ face.c ];
27328                 face.d = changes[ face.d ];
27329
27330                 // check dups in (a, b, c, d) and convert to -> face3
27331
27332                 o = [ face.a, face.b, face.c, face.d ];
27333
27334                 for ( k = 3; k > 0; k -- ) {
27335
27336                     if ( o.indexOf( face[ abcd[ k ] ] ) !== k ) {
27337
27338                         // console.log('faces', face.a, face.b, face.c, face.d, 'dup at', k);
27339
27340                         o.splice( k, 1 );
27341
27342                         this.faces[ i ] = new THREE.Face3( o[0], o[1], o[2], face.normal, face.color, face.materialIndex );
27343
27344                         for ( j = 0, jl = this.faceVertexUvs.length; j < jl; j ++ ) {
27345
27346                             u = this.faceVertexUvs[ j ][ i ];
27347                             if ( u ) u.splice( k, 1 );
27348
27349                         }
27350
27351                         this.faces[ i ].vertexColors = face.vertexColors;
27352
27353                         break;
27354                     }
27355
27356                 }
27357
27358             }
27359
27360         }
27361
27362         // Use unique set of vertices
27363
27364         var diff = this.vertices.length - unique.length;
27365         this.vertices = unique;
27366         return diff;
27367
27368     },
27369
27370     clone: function () {
27371
27372         // TODO
27373
27374     }
27375
27376 };
27377
27378 THREE.GeometryCount = 0;
27379 /**
27380  * @author alteredq / http://alteredqualia.com/
27381  */
27382
27383 THREE.BufferGeometry = function () {
27384
27385     this.id = THREE.GeometryCount ++;
27386
27387     // attributes
27388
27389     this.attributes = {};
27390
27391     // attributes typed arrays are kept only if dynamic flag is set
27392
27393     this.dynamic = false;
27394
27395     // boundings
27396
27397     this.boundingBox = null;
27398     this.boundingSphere = null;
27399
27400     this.hasTangents = false;
27401
27402     // for compatibility
27403
27404     this.morphTargets = [];
27405
27406 };
27407
27408 THREE.BufferGeometry.prototype = {
27409
27410     constructor : THREE.BufferGeometry,
27411
27412     applyMatrix: function ( matrix ) {
27413
27414         var positionArray;
27415         var normalArray;
27416
27417         if ( this.attributes[ "position" ] ) positionArray = this.attributes[ "position" ].array;
27418         if ( this.attributes[ "normal" ] ) normalArray = this.attributes[ "normal" ].array;
27419
27420         if ( positionArray !== undefined ) {
27421
27422             matrix.multiplyVector3Array( positionArray );
27423             this.verticesNeedUpdate = true;
27424
27425         }
27426
27427         if ( normalArray !== undefined ) {
27428
27429             var matrixRotation = new THREE.Matrix4();
27430             matrixRotation.extractRotation( matrix );
27431
27432             matrixRotation.multiplyVector3Array( normalArray );
27433             this.normalsNeedUpdate = true;
27434
27435         }
27436
27437     },
27438
27439     computeBoundingBox: function () {
27440
27441         if ( ! this.boundingBox ) {
27442
27443             this.boundingBox = {
27444
27445                 min: new THREE.Vector3( Infinity, Infinity, Infinity ),
27446                 max: new THREE.Vector3( -Infinity, -Infinity, -Infinity )
27447
27448             };
27449
27450         }
27451
27452         var positions = this.attributes[ "position" ].array;
27453
27454         if ( positions ) {
27455
27456             var bb = this.boundingBox;
27457             var x, y, z;
27458
27459             for ( var i = 0, il = positions.length; i < il; i += 3 ) {
27460
27461                 x = positions[ i ];
27462                 y = positions[ i + 1 ];
27463                 z = positions[ i + 2 ];
27464
27465                 // bounding box
27466
27467                 if ( x < bb.min.x ) {
27468
27469                     bb.min.x = x;
27470
27471                 } else if ( x > bb.max.x ) {
27472
27473                     bb.max.x = x;
27474
27475                 }
27476
27477                 if ( y < bb.min.y ) {
27478
27479                     bb.min.y = y;
27480
27481                 } else if ( y > bb.max.y ) {
27482
27483                     bb.max.y = y;
27484
27485                 }
27486
27487                 if ( z < bb.min.z ) {
27488
27489                     bb.min.z = z;
27490
27491                 } else if ( z > bb.max.z ) {
27492
27493                     bb.max.z = z;
27494
27495                 }
27496
27497             }
27498
27499         }
27500
27501         if ( positions === undefined || positions.length === 0 ) {
27502
27503             this.boundingBox.min.set( 0, 0, 0 );
27504             this.boundingBox.max.set( 0, 0, 0 );
27505
27506         }
27507
27508     },
27509
27510     computeBoundingSphere: function () {
27511
27512         if ( ! this.boundingSphere ) this.boundingSphere = { radius: 0 };
27513
27514         var positions = this.attributes[ "position" ].array;
27515
27516         if ( positions ) {
27517
27518             var radiusSq, maxRadiusSq = 0;
27519             var x, y, z;
27520
27521             for ( var i = 0, il = positions.length; i < il; i += 3 ) {
27522
27523                 x = positions[ i ];
27524                 y = positions[ i + 1 ];
27525                 z = positions[ i + 2 ];
27526
27527                 radiusSq =  x * x + y * y + z * z;
27528                 if ( radiusSq > maxRadiusSq ) maxRadiusSq = radiusSq;
27529
27530             }
27531
27532             this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
27533
27534         }
27535
27536     },
27537
27538     computeVertexNormals: function () {
27539
27540         if ( this.attributes[ "position" ] && this.attributes[ "index" ] ) {
27541
27542             var i, il;
27543             var j, jl;
27544
27545             var nVertexElements = this.attributes[ "position" ].array.length;
27546
27547             if ( this.attributes[ "normal" ] === undefined ) {
27548
27549                 this.attributes[ "normal" ] = {
27550
27551                     itemSize: 3,
27552                     array: new Float32Array( nVertexElements ),
27553                     numItems: nVertexElements
27554
27555                 };
27556
27557             } else {
27558
27559                 // reset existing normals to zero
27560
27561                 for ( i = 0, il = this.attributes[ "normal" ].array.length; i < il; i ++ ) {
27562
27563                     this.attributes[ "normal" ].array[ i ] = 0;
27564
27565                 }
27566
27567             }
27568
27569             var offsets = this.offsets;
27570
27571             var indices = this.attributes[ "index" ].array;
27572             var positions = this.attributes[ "position" ].array;
27573             var normals = this.attributes[ "normal" ].array;
27574
27575             var vA, vB, vC, x, y, z,
27576
27577             pA = new THREE.Vector3(),
27578             pB = new THREE.Vector3(),
27579             pC = new THREE.Vector3(),
27580
27581             cb = new THREE.Vector3(),
27582             ab = new THREE.Vector3();
27583
27584             for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
27585
27586                 var start = offsets[ j ].start;
27587                 var count = offsets[ j ].count;
27588                 var index = offsets[ j ].index;
27589
27590                 for ( i = start, il = start + count; i < il; i += 3 ) {
27591
27592                     vA = index + indices[ i ];
27593                     vB = index + indices[ i + 1 ];
27594                     vC = index + indices[ i + 2 ];
27595
27596                     x = positions[ vA * 3 ];
27597                     y = positions[ vA * 3 + 1 ];
27598                     z = positions[ vA * 3 + 2 ];
27599                     pA.set( x, y, z );
27600
27601                     x = positions[ vB * 3 ];
27602                     y = positions[ vB * 3 + 1 ];
27603                     z = positions[ vB * 3 + 2 ];
27604                     pB.set( x, y, z );
27605
27606                     x = positions[ vC * 3 ];
27607                     y = positions[ vC * 3 + 1 ];
27608                     z = positions[ vC * 3 + 2 ];
27609                     pC.set( x, y, z );
27610
27611                     cb.sub( pC, pB );
27612                     ab.sub( pA, pB );
27613                     cb.crossSelf( ab );
27614
27615                     normals[ vA * 3 ] += cb.x;
27616                     normals[ vA * 3 + 1 ] += cb.y;
27617                     normals[ vA * 3 + 2 ] += cb.z;
27618
27619                     normals[ vB * 3 ] += cb.x;
27620                     normals[ vB * 3 + 1 ] += cb.y;
27621                     normals[ vB * 3 + 2 ] += cb.z;
27622
27623                     normals[ vC * 3 ] += cb.x;
27624                     normals[ vC * 3 + 1 ] += cb.y;
27625                     normals[ vC * 3 + 2 ] += cb.z;
27626
27627                 }
27628
27629             }
27630
27631             // normalize normals
27632
27633             for ( i = 0, il = normals.length; i < il; i += 3 ) {
27634
27635                 x = normals[ i ];
27636                 y = normals[ i + 1 ];
27637                 z = normals[ i + 2 ];
27638
27639                 var n = 1.0 / Math.sqrt( x * x + y * y + z * z );
27640
27641                 normals[ i ] *= n;
27642                 normals[ i + 1 ] *= n;
27643                 normals[ i + 2 ] *= n;
27644
27645             }
27646
27647             this.normalsNeedUpdate = true;
27648
27649         }
27650
27651     },
27652
27653     computeTangents: function () {
27654
27655         // based on http://www.terathon.com/code/tangent.html
27656         // (per vertex tangents)
27657
27658         if ( this.attributes[ "index" ] === undefined ||
27659              this.attributes[ "position" ] === undefined ||
27660              this.attributes[ "normal" ] === undefined ||
27661              this.attributes[ "uv" ] === undefined ) {
27662
27663             console.warn( "Missing required attributes (index, position, normal or uv) in BufferGeometry.computeTangents()" );
27664             return;
27665
27666         }
27667
27668         var indices = this.attributes[ "index" ].array;
27669         var positions = this.attributes[ "position" ].array;
27670         var normals = this.attributes[ "normal" ].array;
27671         var uvs = this.attributes[ "uv" ].array;
27672
27673         var nVertices = positions.length / 3;
27674
27675         if ( this.attributes[ "tangent" ] === undefined ) {
27676
27677             var nTangentElements = 4 * nVertices;
27678
27679             this.attributes[ "tangent" ] = {
27680
27681                 itemSize: 4,
27682                 array: new Float32Array( nTangentElements ),
27683                 numItems: nTangentElements
27684
27685             };
27686
27687         }
27688
27689         var tangents = this.attributes[ "tangent" ].array;
27690
27691         var tan1 = [], tan2 = [];
27692
27693         for ( var k = 0; k < nVertices; k ++ ) {
27694
27695             tan1[ k ] = new THREE.Vector3();
27696             tan2[ k ] = new THREE.Vector3();
27697
27698         }
27699
27700         var xA, yA, zA,
27701             xB, yB, zB,
27702             xC, yC, zC,
27703
27704             uA, vA,
27705             uB, vB,
27706             uC, vC,
27707
27708             x1, x2, y1, y2, z1, z2,
27709             s1, s2, t1, t2, r;
27710
27711         var sdir = new THREE.Vector3(), tdir = new THREE.Vector3();
27712
27713         function handleTriangle( a, b, c ) {
27714
27715             xA = positions[ a * 3 ];
27716             yA = positions[ a * 3 + 1 ];
27717             zA = positions[ a * 3 + 2 ];
27718
27719             xB = positions[ b * 3 ];
27720             yB = positions[ b * 3 + 1 ];
27721             zB = positions[ b * 3 + 2 ];
27722
27723             xC = positions[ c * 3 ];
27724             yC = positions[ c * 3 + 1 ];
27725             zC = positions[ c * 3 + 2 ];
27726
27727             uA = uvs[ a * 2 ];
27728             vA = uvs[ a * 2 + 1 ];
27729
27730             uB = uvs[ b * 2 ];
27731             vB = uvs[ b * 2 + 1 ];
27732
27733             uC = uvs[ c * 2 ];
27734             vC = uvs[ c * 2 + 1 ];
27735
27736             x1 = xB - xA;
27737             x2 = xC - xA;
27738
27739             y1 = yB - yA;
27740             y2 = yC - yA;
27741
27742             z1 = zB - zA;
27743             z2 = zC - zA;
27744
27745             s1 = uB - uA;
27746             s2 = uC - uA;
27747
27748             t1 = vB - vA;
27749             t2 = vC - vA;
27750
27751             r = 1.0 / ( s1 * t2 - s2 * t1 );
27752
27753             sdir.set(
27754                 ( t2 * x1 - t1 * x2 ) * r,
27755                 ( t2 * y1 - t1 * y2 ) * r,
27756                 ( t2 * z1 - t1 * z2 ) * r
27757             );
27758
27759             tdir.set(
27760                 ( s1 * x2 - s2 * x1 ) * r,
27761                 ( s1 * y2 - s2 * y1 ) * r,
27762                 ( s1 * z2 - s2 * z1 ) * r
27763             );
27764
27765             tan1[ a ].addSelf( sdir );
27766             tan1[ b ].addSelf( sdir );
27767             tan1[ c ].addSelf( sdir );
27768
27769             tan2[ a ].addSelf( tdir );
27770             tan2[ b ].addSelf( tdir );
27771             tan2[ c ].addSelf( tdir );
27772
27773         }
27774
27775         var i, il;
27776         var j, jl;
27777         var iA, iB, iC;
27778
27779         var offsets = this.offsets;
27780
27781         for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
27782
27783             var start = offsets[ j ].start;
27784             var count = offsets[ j ].count;
27785             var index = offsets[ j ].index;
27786
27787             for ( i = start, il = start + count; i < il; i += 3 ) {
27788
27789                 iA = index + indices[ i ];
27790                 iB = index + indices[ i + 1 ];
27791                 iC = index + indices[ i + 2 ];
27792
27793                 handleTriangle( iA, iB, iC );
27794
27795             }
27796
27797         }
27798
27799         var tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3();
27800         var n = new THREE.Vector3(), n2 = new THREE.Vector3();
27801         var w, t, test;
27802         var nx, ny, nz;
27803
27804         function handleVertex( v ) {
27805
27806             n.x = normals[ v * 3 ];
27807             n.y = normals[ v * 3 + 1 ];
27808             n.z = normals[ v * 3 + 2 ];
27809
27810             n2.copy( n );
27811
27812             t = tan1[ v ];
27813
27814             // Gram-Schmidt orthogonalize
27815
27816             tmp.copy( t );
27817             tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
27818
27819             // Calculate handedness
27820
27821             tmp2.cross( n2, t );
27822             test = tmp2.dot( tan2[ v ] );
27823             w = ( test < 0.0 ) ? -1.0 : 1.0;
27824
27825             tangents[ v * 4 ]       = tmp.x;
27826             tangents[ v * 4 + 1 ] = tmp.y;
27827             tangents[ v * 4 + 2 ] = tmp.z;
27828             tangents[ v * 4 + 3 ] = w;
27829
27830         }
27831
27832         for ( j = 0, jl = offsets.length; j < jl; ++ j ) {
27833
27834             var start = offsets[ j ].start;
27835             var count = offsets[ j ].count;
27836             var index = offsets[ j ].index;
27837
27838             for ( i = start, il = start + count; i < il; i += 3 ) {
27839
27840                 iA = index + indices[ i ];
27841                 iB = index + indices[ i + 1 ];
27842                 iC = index + indices[ i + 2 ];
27843
27844                 handleVertex( iA );
27845                 handleVertex( iB );
27846                 handleVertex( iC );
27847
27848             }
27849
27850         }
27851
27852         this.hasTangents = true;
27853         this.tangentsNeedUpdate = true;
27854
27855     }
27856
27857 };
27858
27859 /**
27860  * Spline from Tween.js, slightly optimized (and trashed)
27861  * http://sole.github.com/tween.js/examples/05_spline.html
27862  *
27863  * @author mrdoob / http://mrdoob.com/
27864  * @author alteredq / http://alteredqualia.com/
27865  */
27866
27867 THREE.Spline = function ( points ) {
27868
27869     this.points = points;
27870
27871     var c = [], v3 = { x: 0, y: 0, z: 0 },
27872     point, intPoint, weight, w2, w3,
27873     pa, pb, pc, pd;
27874
27875     this.initFromArray = function( a ) {
27876
27877         this.points = [];
27878
27879         for ( var i = 0; i < a.length; i++ ) {
27880
27881             this.points[ i ] = { x: a[ i ][ 0 ], y: a[ i ][ 1 ], z: a[ i ][ 2 ] };
27882
27883         }
27884
27885     };
27886
27887     this.getPoint = function ( k ) {
27888
27889         point = ( this.points.length - 1 ) * k;
27890         intPoint = Math.floor( point );
27891         weight = point - intPoint;
27892
27893         c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
27894         c[ 1 ] = intPoint;
27895         c[ 2 ] = intPoint  > this.points.length - 2 ? this.points.length - 1 : intPoint + 1;
27896         c[ 3 ] = intPoint  > this.points.length - 3 ? this.points.length - 1 : intPoint + 2;
27897
27898         pa = this.points[ c[ 0 ] ];
27899         pb = this.points[ c[ 1 ] ];
27900         pc = this.points[ c[ 2 ] ];
27901         pd = this.points[ c[ 3 ] ];
27902
27903         w2 = weight * weight;
27904         w3 = weight * w2;
27905
27906         v3.x = interpolate( pa.x, pb.x, pc.x, pd.x, weight, w2, w3 );
27907         v3.y = interpolate( pa.y, pb.y, pc.y, pd.y, weight, w2, w3 );
27908         v3.z = interpolate( pa.z, pb.z, pc.z, pd.z, weight, w2, w3 );
27909
27910         return v3;
27911
27912     };
27913
27914     this.getControlPointsArray = function () {
27915
27916         var i, p, l = this.points.length,
27917             coords = [];
27918
27919         for ( i = 0; i < l; i ++ ) {
27920
27921             p = this.points[ i ];
27922             coords[ i ] = [ p.x, p.y, p.z ];
27923
27924         }
27925
27926         return coords;
27927
27928     };
27929
27930     // approximate length by summing linear segments
27931
27932     this.getLength = function ( nSubDivisions ) {
27933
27934         var i, index, nSamples, position,
27935             point = 0, intPoint = 0, oldIntPoint = 0,
27936             oldPosition = new THREE.Vector3(),
27937             tmpVec = new THREE.Vector3(),
27938             chunkLengths = [],
27939             totalLength = 0;
27940
27941         // first point has 0 length
27942
27943         chunkLengths[ 0 ] = 0;
27944
27945         if ( !nSubDivisions ) nSubDivisions = 100;
27946
27947         nSamples = this.points.length * nSubDivisions;
27948
27949         oldPosition.copy( this.points[ 0 ] );
27950
27951         for ( i = 1; i < nSamples; i ++ ) {
27952
27953             index = i / nSamples;
27954
27955             position = this.getPoint( index );
27956             tmpVec.copy( position );
27957
27958             totalLength += tmpVec.distanceTo( oldPosition );
27959
27960             oldPosition.copy( position );
27961
27962             point = ( this.points.length - 1 ) * index;
27963             intPoint = Math.floor( point );
27964
27965             if ( intPoint != oldIntPoint ) {
27966
27967                 chunkLengths[ intPoint ] = totalLength;
27968                 oldIntPoint = intPoint;
27969
27970             }
27971
27972         }
27973
27974         // last point ends with total length
27975
27976         chunkLengths[ chunkLengths.length ] = totalLength;
27977
27978         return { chunks: chunkLengths, total: totalLength };
27979
27980     };
27981
27982     this.reparametrizeByArcLength = function ( samplingCoef ) {
27983
27984         var i, j,
27985             index, indexCurrent, indexNext,
27986             linearDistance, realDistance,
27987             sampling, position,
27988             newpoints = [],
27989             tmpVec = new THREE.Vector3(),
27990             sl = this.getLength();
27991
27992         newpoints.push( tmpVec.copy( this.points[ 0 ] ).clone() );
27993
27994         for ( i = 1; i < this.points.length; i++ ) {
27995
27996             //tmpVec.copy( this.points[ i - 1 ] );
27997             //linearDistance = tmpVec.distanceTo( this.points[ i ] );
27998
27999             realDistance = sl.chunks[ i ] - sl.chunks[ i - 1 ];
28000
28001             sampling = Math.ceil( samplingCoef * realDistance / sl.total );
28002
28003             indexCurrent = ( i - 1 ) / ( this.points.length - 1 );
28004             indexNext = i / ( this.points.length - 1 );
28005
28006             for ( j = 1; j < sampling - 1; j++ ) {
28007
28008                 index = indexCurrent + j * ( 1 / sampling ) * ( indexNext - indexCurrent );
28009
28010                 position = this.getPoint( index );
28011                 newpoints.push( tmpVec.copy( position ).clone() );
28012
28013             }
28014
28015             newpoints.push( tmpVec.copy( this.points[ i ] ).clone() );
28016
28017         }
28018
28019         this.points = newpoints;
28020
28021     };
28022
28023     // Catmull-Rom
28024
28025     function interpolate( p0, p1, p2, p3, t, t2, t3 ) {
28026
28027         var v0 = ( p2 - p0 ) * 0.5,
28028             v1 = ( p3 - p1 ) * 0.5;
28029
28030         return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
28031
28032     };
28033
28034 };
28035 /**
28036  * @author mrdoob / http://mrdoob.com/
28037  * @author mikael emtinger / http://gomo.se/
28038  */
28039
28040 THREE.Camera = function () {
28041
28042     THREE.Object3D.call( this );
28043
28044     this.matrixWorldInverse = new THREE.Matrix4();
28045
28046     this.projectionMatrix = new THREE.Matrix4();
28047     this.projectionMatrixInverse = new THREE.Matrix4();
28048
28049 };
28050
28051 THREE.Camera.prototype = Object.create( THREE.Object3D.prototype );
28052
28053 THREE.Camera.prototype.lookAt = function ( vector ) {
28054
28055     // TODO: Add hierarchy support.
28056
28057     this.matrix.lookAt( this.position, vector, this.up );
28058
28059     if ( this.rotationAutoUpdate === true ) {
28060
28061         this.rotation.setEulerFromRotationMatrix( this.matrix, this.eulerOrder );
28062
28063     }
28064
28065 };
28066 /**
28067  * @author alteredq / http://alteredqualia.com/
28068  */
28069
28070 THREE.OrthographicCamera = function ( left, right, top, bottom, near, far ) {
28071
28072     THREE.Camera.call( this );
28073
28074     this.left = left;
28075     this.right = right;
28076     this.top = top;
28077     this.bottom = bottom;
28078
28079     this.near = ( near !== undefined ) ? near : 0.1;
28080     this.far = ( far !== undefined ) ? far : 2000;
28081
28082     this.updateProjectionMatrix();
28083
28084 };
28085
28086 THREE.OrthographicCamera.prototype = Object.create( THREE.Camera.prototype );
28087
28088 THREE.OrthographicCamera.prototype.updateProjectionMatrix = function () {
28089
28090     this.projectionMatrix.makeOrthographic( this.left, this.right, this.top, this.bottom, this.near, this.far );
28091
28092 };
28093 /**
28094  * @author mrdoob / http://mrdoob.com/
28095  * @author greggman / http://games.greggman.com/
28096  * @author zz85 / http://www.lab4games.net/zz85/blog
28097  */
28098
28099 THREE.PerspectiveCamera = function ( fov, aspect, near, far ) {
28100
28101     THREE.Camera.call( this );
28102
28103     this.fov = fov !== undefined ? fov : 50;
28104     this.aspect = aspect !== undefined ? aspect : 1;
28105     this.near = near !== undefined ? near : 0.1;
28106     this.far = far !== undefined ? far : 2000;
28107
28108     this.updateProjectionMatrix();
28109
28110 };
28111
28112 THREE.PerspectiveCamera.prototype = Object.create( THREE.Camera.prototype );
28113
28114
28115 /**
28116  * Uses Focal Length (in mm) to estimate and set FOV
28117  * 35mm (fullframe) camera is used if frame size is not specified;
28118  * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
28119  */
28120
28121 THREE.PerspectiveCamera.prototype.setLens = function ( focalLength, frameHeight ) {
28122
28123     if ( frameHeight === undefined ) frameHeight = 24;
28124
28125     this.fov = 2 * Math.atan( frameHeight / ( focalLength * 2 ) ) * ( 180 / Math.PI );
28126     this.updateProjectionMatrix();
28127
28128 }
28129
28130
28131 /**
28132  * Sets an offset in a larger frustum. This is useful for multi-window or
28133  * multi-monitor/multi-machine setups.
28134  *
28135  * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
28136  * the monitors are in grid like this
28137  *
28138  *   +---+---+---+
28139  *   | A | B | C |
28140  *   +---+---+---+
28141  *   | D | E | F |
28142  *   +---+---+---+
28143  *
28144  * then for each monitor you would call it like this
28145  *
28146  *   var w = 1920;
28147  *   var h = 1080;
28148  *   var fullWidth = w * 3;
28149  *   var fullHeight = h * 2;
28150  *
28151  *   --A--
28152  *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
28153  *   --B--
28154  *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
28155  *   --C--
28156  *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
28157  *   --D--
28158  *   camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
28159  *   --E--
28160  *   camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
28161  *   --F--
28162  *   camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
28163  *
28164  *   Note there is no reason monitors have to be the same size or in a grid.
28165  */
28166
28167 THREE.PerspectiveCamera.prototype.setViewOffset = function ( fullWidth, fullHeight, x, y, width, height ) {
28168
28169     this.fullWidth = fullWidth;
28170     this.fullHeight = fullHeight;
28171     this.x = x;
28172     this.y = y;
28173     this.width = width;
28174     this.height = height;
28175
28176     this.updateProjectionMatrix();
28177
28178 };
28179
28180
28181 THREE.PerspectiveCamera.prototype.updateProjectionMatrix = function () {
28182
28183     if ( this.fullWidth ) {
28184
28185         var aspect = this.fullWidth / this.fullHeight;
28186         var top = Math.tan( this.fov * Math.PI / 360 ) * this.near;
28187         var bottom = -top;
28188         var left = aspect * bottom;
28189         var right = aspect * top;
28190         var width = Math.abs( right - left );
28191         var height = Math.abs( top - bottom );
28192
28193         this.projectionMatrix.makeFrustum(
28194             left + this.x * width / this.fullWidth,
28195             left + ( this.x + this.width ) * width / this.fullWidth,
28196             top - ( this.y + this.height ) * height / this.fullHeight,
28197             top - this.y * height / this.fullHeight,
28198             this.near,
28199             this.far
28200         );
28201
28202     } else {
28203
28204         this.projectionMatrix.makePerspective( this.fov, this.aspect, this.near, this.far );
28205
28206     }
28207
28208 };
28209 /**
28210  * @author mrdoob / http://mrdoob.com/
28211  * @author alteredq / http://alteredqualia.com/
28212  */
28213
28214 THREE.Light = function ( hex ) {
28215
28216     THREE.Object3D.call( this );
28217
28218     this.color = new THREE.Color( hex );
28219
28220 };
28221
28222 THREE.Light.prototype = Object.create( THREE.Object3D.prototype );
28223 /**
28224  * @author mrdoob / http://mrdoob.com/
28225  */
28226
28227 THREE.AmbientLight = function ( hex ) {
28228
28229     THREE.Light.call( this, hex );
28230
28231 };
28232
28233 THREE.AmbientLight.prototype = Object.create( THREE.Light.prototype );
28234 /**
28235  * @author mrdoob / http://mrdoob.com/
28236  * @author alteredq / http://alteredqualia.com/
28237  */
28238
28239 THREE.DirectionalLight = function ( hex, intensity, distance ) {
28240
28241     THREE.Light.call( this, hex );
28242
28243     this.position = new THREE.Vector3( 0, 1, 0 );
28244     this.target = new THREE.Object3D();
28245
28246     this.intensity = ( intensity !== undefined ) ? intensity : 1;
28247     this.distance = ( distance !== undefined ) ? distance : 0;
28248
28249     this.castShadow = false;
28250     this.onlyShadow = false;
28251
28252     //
28253
28254     this.shadowCameraNear = 50;
28255     this.shadowCameraFar = 5000;
28256
28257     this.shadowCameraLeft = -500;
28258     this.shadowCameraRight = 500;
28259     this.shadowCameraTop = 500;
28260     this.shadowCameraBottom = -500;
28261
28262     this.shadowCameraVisible = false;
28263
28264     this.shadowBias = 0;
28265     this.shadowDarkness = 0.5;
28266
28267     this.shadowMapWidth = 512;
28268     this.shadowMapHeight = 512;
28269
28270     //
28271
28272     this.shadowCascade = false;
28273
28274     this.shadowCascadeOffset = new THREE.Vector3( 0, 0, -1000 );
28275     this.shadowCascadeCount = 2;
28276
28277     this.shadowCascadeBias = [ 0, 0, 0 ];
28278     this.shadowCascadeWidth = [ 512, 512, 512 ];
28279     this.shadowCascadeHeight = [ 512, 512, 512 ];
28280
28281     this.shadowCascadeNearZ = [ -1.000, 0.990, 0.998 ];
28282     this.shadowCascadeFarZ  = [  0.990, 0.998, 1.000 ];
28283
28284     this.shadowCascadeArray = [];
28285
28286     //
28287
28288     this.shadowMap = null;
28289     this.shadowMapSize = null;
28290     this.shadowCamera = null;
28291     this.shadowMatrix = null;
28292
28293 };
28294
28295 THREE.DirectionalLight.prototype = Object.create( THREE.Light.prototype );
28296 /**
28297  * @author alteredq / http://alteredqualia.com/
28298  */
28299
28300 THREE.HemisphereLight = function ( skyColorHex, groundColorHex, intensity ) {
28301
28302     THREE.Light.call( this, skyColorHex );
28303
28304     this.groundColor = new THREE.Color( groundColorHex );
28305
28306     this.position = new THREE.Vector3( 0, 100, 0 );
28307
28308     this.intensity = ( intensity !== undefined ) ? intensity : 1;
28309
28310 };
28311
28312 THREE.HemisphereLight.prototype = Object.create( THREE.Light.prototype );
28313 /**
28314  * @author mrdoob / http://mrdoob.com/
28315  */
28316
28317 THREE.PointLight = function ( hex, intensity, distance ) {
28318
28319     THREE.Light.call( this, hex );
28320
28321     this.position = new THREE.Vector3( 0, 0, 0 );
28322     this.intensity = ( intensity !== undefined ) ? intensity : 1;
28323     this.distance = ( distance !== undefined ) ? distance : 0;
28324
28325 };
28326
28327 THREE.PointLight.prototype = Object.create( THREE.Light.prototype );
28328 /**
28329  * @author alteredq / http://alteredqualia.com/
28330  */
28331
28332 THREE.SpotLight = function ( hex, intensity, distance, angle, exponent ) {
28333
28334     THREE.Light.call( this, hex );
28335
28336     this.position = new THREE.Vector3( 0, 1, 0 );
28337     this.target = new THREE.Object3D();
28338
28339     this.intensity = ( intensity !== undefined ) ? intensity : 1;
28340     this.distance = ( distance !== undefined ) ? distance : 0;
28341     this.angle = ( angle !== undefined ) ? angle : Math.PI / 2;
28342     this.exponent = ( exponent !== undefined ) ? exponent : 10;
28343
28344     this.castShadow = false;
28345     this.onlyShadow = false;
28346
28347     //
28348
28349     this.shadowCameraNear = 50;
28350     this.shadowCameraFar = 5000;
28351     this.shadowCameraFov = 50;
28352
28353     this.shadowCameraVisible = false;
28354
28355     this.shadowBias = 0;
28356     this.shadowDarkness = 0.5;
28357
28358     this.shadowMapWidth = 512;
28359     this.shadowMapHeight = 512;
28360
28361     //
28362
28363     this.shadowMap = null;
28364     this.shadowMapSize = null;
28365     this.shadowCamera = null;
28366     this.shadowMatrix = null;
28367
28368 };
28369
28370 THREE.SpotLight.prototype = Object.create( THREE.Light.prototype );
28371 /**
28372  * @author alteredq / http://alteredqualia.com/
28373  */
28374
28375 THREE.Loader = function ( showStatus ) {
28376
28377     this.showStatus = showStatus;
28378     this.statusDomElement = showStatus ? THREE.Loader.prototype.addStatusElement() : null;
28379
28380     this.onLoadStart = function () {};
28381     this.onLoadProgress = function () {};
28382     this.onLoadComplete = function () {};
28383
28384 };
28385
28386 THREE.Loader.prototype = {
28387
28388     constructor: THREE.Loader,
28389
28390     crossOrigin: 'anonymous',
28391
28392     addStatusElement: function () {
28393
28394         var e = document.createElement( "div" );
28395
28396         e.style.position = "absolute";
28397         e.style.right = "0px";
28398         e.style.top = "0px";
28399         e.style.fontSize = "0.8em";
28400         e.style.textAlign = "left";
28401         e.style.background = "rgba(0,0,0,0.25)";
28402         e.style.color = "#fff";
28403         e.style.width = "120px";
28404         e.style.padding = "0.5em 0.5em 0.5em 0.5em";
28405         e.style.zIndex = 1000;
28406
28407         e.innerHTML = "Loading ...";
28408
28409         return e;
28410
28411     },
28412
28413     updateProgress: function ( progress ) {
28414
28415         var message = "Loaded ";
28416
28417         if ( progress.total ) {
28418
28419             message += ( 100 * progress.loaded / progress.total ).toFixed(0) + "%";
28420
28421
28422         } else {
28423
28424             message += ( progress.loaded / 1000 ).toFixed(2) + " KB";
28425
28426         }
28427
28428         this.statusDomElement.innerHTML = message;
28429
28430     },
28431
28432     extractUrlBase: function ( url ) {
28433
28434         var parts = url.split( '/' );
28435         parts.pop();
28436         return ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
28437
28438     },
28439
28440     initMaterials: function ( scope, materials, texturePath ) {
28441
28442         scope.materials = [];
28443
28444         for ( var i = 0; i < materials.length; ++ i ) {
28445
28446             scope.materials[ i ] = THREE.Loader.prototype.createMaterial( materials[ i ], texturePath );
28447
28448         }
28449
28450     },
28451
28452     hasNormals: function ( scope ) {
28453
28454         var m, i, il = scope.materials.length;
28455
28456         for( i = 0; i < il; i ++ ) {
28457
28458             m = scope.materials[ i ];
28459
28460             if ( m instanceof THREE.ShaderMaterial ) return true;
28461
28462         }
28463
28464         return false;
28465
28466     },
28467
28468     createMaterial: function ( m, texturePath ) {
28469
28470         var _this = this;
28471
28472         function is_pow2( n ) {
28473
28474             var l = Math.log( n ) / Math.LN2;
28475             return Math.floor( l ) == l;
28476
28477         }
28478
28479         function nearest_pow2( n ) {
28480
28481             var l = Math.log( n ) / Math.LN2;
28482             return Math.pow( 2, Math.round(  l ) );
28483
28484         }
28485
28486         function load_image( where, url ) {
28487
28488             var image = new Image();
28489
28490             image.onload = function () {
28491
28492                 if ( !is_pow2( this.width ) || !is_pow2( this.height ) ) {
28493
28494                     var width = nearest_pow2( this.width );
28495                     var height = nearest_pow2( this.height );
28496
28497                     where.image.width = width;
28498                     where.image.height = height;
28499                     where.image.getContext( '2d' ).drawImage( this, 0, 0, width, height );
28500
28501                 } else {
28502
28503                     where.image = this;
28504
28505                 }
28506
28507                 where.needsUpdate = true;
28508
28509             };
28510
28511             image.crossOrigin = _this.crossOrigin;
28512             image.src = url;
28513
28514         }
28515
28516         function create_texture( where, name, sourceFile, repeat, offset, wrap, anisotropy ) {
28517
28518             var isCompressed = sourceFile.toLowerCase().endsWith( ".dds" );
28519             var fullPath = texturePath + "/" + sourceFile;
28520
28521             if ( isCompressed ) {
28522
28523                 var texture = THREE.ImageUtils.loadCompressedTexture( fullPath );
28524
28525                 where[ name ] = texture;
28526
28527             } else {
28528
28529                 var texture = document.createElement( 'canvas' );
28530
28531                 where[ name ] = new THREE.Texture( texture );
28532
28533             }
28534
28535             where[ name ].sourceFile = sourceFile;
28536
28537             if( repeat ) {
28538
28539                 where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] );
28540
28541                 if ( repeat[ 0 ] !== 1 ) where[ name ].wrapS = THREE.RepeatWrapping;
28542                 if ( repeat[ 1 ] !== 1 ) where[ name ].wrapT = THREE.RepeatWrapping;
28543
28544             }
28545
28546             if ( offset ) {
28547
28548                 where[ name ].offset.set( offset[ 0 ], offset[ 1 ] );
28549
28550             }
28551
28552             if ( wrap ) {
28553
28554                 var wrapMap = {
28555                     "repeat": THREE.RepeatWrapping,
28556                     "mirror": THREE.MirroredRepeatWrapping
28557                 }
28558
28559                 if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ];
28560                 if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ];
28561
28562             }
28563
28564             if ( anisotropy ) {
28565
28566                 where[ name ].anisotropy = anisotropy;
28567
28568             }
28569
28570             if ( ! isCompressed ) {
28571
28572                 load_image( where[ name ], fullPath );
28573
28574             }
28575
28576         }
28577
28578         function rgb2hex( rgb ) {
28579
28580             return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;
28581
28582         }
28583
28584         // defaults
28585
28586         var mtype = "MeshLambertMaterial";
28587         var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, bumpMap: null, wireframe: false };
28588
28589         // parameters from model file
28590
28591         if ( m.shading ) {
28592
28593             var shading = m.shading.toLowerCase();
28594
28595             if ( shading === "phong" ) mtype = "MeshPhongMaterial";
28596             else if ( shading === "basic" ) mtype = "MeshBasicMaterial";
28597
28598         }
28599
28600         if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
28601
28602             mpars.blending = THREE[ m.blending ];
28603
28604         }
28605
28606         if ( m.transparent !== undefined || m.opacity < 1.0 ) {
28607
28608             mpars.transparent = m.transparent;
28609
28610         }
28611
28612         if ( m.depthTest !== undefined ) {
28613
28614             mpars.depthTest = m.depthTest;
28615
28616         }
28617
28618         if ( m.depthWrite !== undefined ) {
28619
28620             mpars.depthWrite = m.depthWrite;
28621
28622         }
28623
28624         if ( m.visible !== undefined ) {
28625
28626             mpars.visible = m.visible;
28627
28628         }
28629
28630         if ( m.flipSided !== undefined ) {
28631
28632             mpars.side = THREE.BackSide;
28633
28634         }
28635
28636         if ( m.doubleSided !== undefined ) {
28637
28638             mpars.side = THREE.DoubleSide;
28639
28640         }
28641
28642         if ( m.wireframe !== undefined ) {
28643
28644             mpars.wireframe = m.wireframe;
28645
28646         }
28647
28648         if ( m.vertexColors !== undefined ) {
28649
28650             if ( m.vertexColors === "face" ) {
28651
28652                 mpars.vertexColors = THREE.FaceColors;
28653
28654             } else if ( m.vertexColors ) {
28655
28656                 mpars.vertexColors = THREE.VertexColors;
28657
28658             }
28659
28660         }
28661
28662         // colors
28663
28664         if ( m.colorDiffuse ) {
28665
28666             mpars.color = rgb2hex( m.colorDiffuse );
28667
28668         } else if ( m.DbgColor ) {
28669
28670             mpars.color = m.DbgColor;
28671
28672         }
28673
28674         if ( m.colorSpecular ) {
28675
28676             mpars.specular = rgb2hex( m.colorSpecular );
28677
28678         }
28679
28680         if ( m.colorAmbient ) {
28681
28682             mpars.ambient = rgb2hex( m.colorAmbient );
28683
28684         }
28685
28686         // modifiers
28687
28688         if ( m.transparency ) {
28689
28690             mpars.opacity = m.transparency;
28691
28692         }
28693
28694         if ( m.specularCoef ) {
28695
28696             mpars.shininess = m.specularCoef;
28697
28698         }
28699
28700         // textures
28701
28702         if ( m.mapDiffuse && texturePath ) {
28703
28704             create_texture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap, m.mapDiffuseAnisotropy );
28705
28706         }
28707
28708         if ( m.mapLight && texturePath ) {
28709
28710             create_texture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap, m.mapLightAnisotropy );
28711
28712         }
28713
28714         if ( m.mapBump && texturePath ) {
28715
28716             create_texture( mpars, "bumpMap", m.mapBump, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap, m.mapBumpAnisotropy );
28717
28718         }
28719
28720         if ( m.mapNormal && texturePath ) {
28721
28722             create_texture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap, m.mapNormalAnisotropy );
28723
28724         }
28725
28726         if ( m.mapSpecular && texturePath ) {
28727
28728             create_texture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap, m.mapSpecularAnisotropy );
28729
28730         }
28731
28732         //
28733
28734         if ( m.mapBumpScale ) {
28735
28736             mpars.bumpScale = m.mapBumpScale;
28737
28738         }
28739
28740         // special case for normal mapped material
28741
28742         if ( m.mapNormal ) {
28743
28744             var shader = THREE.ShaderUtils.lib[ "normal" ];
28745             var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
28746
28747             uniforms[ "tNormal" ].value = mpars.normalMap;
28748
28749             if ( m.mapNormalFactor ) {
28750
28751                 uniforms[ "uNormalScale" ].value.set( m.mapNormalFactor, m.mapNormalFactor );
28752
28753             }
28754
28755             if ( mpars.map ) {
28756
28757                 uniforms[ "tDiffuse" ].value = mpars.map;
28758                 uniforms[ "enableDiffuse" ].value = true;
28759
28760             }
28761
28762             if ( mpars.specularMap ) {
28763
28764                 uniforms[ "tSpecular" ].value = mpars.specularMap;
28765                 uniforms[ "enableSpecular" ].value = true;
28766
28767             }
28768
28769             if ( mpars.lightMap ) {
28770
28771                 uniforms[ "tAO" ].value = mpars.lightMap;
28772                 uniforms[ "enableAO" ].value = true;
28773
28774             }
28775
28776             // for the moment don't handle displacement texture
28777
28778             uniforms[ "uDiffuseColor" ].value.setHex( mpars.color );
28779             uniforms[ "uSpecularColor" ].value.setHex( mpars.specular );
28780             uniforms[ "uAmbientColor" ].value.setHex( mpars.ambient );
28781
28782             uniforms[ "uShininess" ].value = mpars.shininess;
28783
28784             if ( mpars.opacity !== undefined ) {
28785
28786                 uniforms[ "uOpacity" ].value = mpars.opacity;
28787
28788             }
28789
28790             var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
28791             var material = new THREE.ShaderMaterial( parameters );
28792
28793         } else {
28794
28795             var material = new THREE[ mtype ]( mpars );
28796
28797         }
28798
28799         if ( m.DbgName !== undefined ) material.name = m.DbgName;
28800
28801         return material;
28802
28803     }
28804
28805 };
28806 /**
28807  * @author alteredq / http://alteredqualia.com/
28808  */
28809
28810 THREE.BinaryLoader = function ( showStatus ) {
28811
28812     THREE.Loader.call( this, showStatus );
28813
28814 };
28815
28816 THREE.BinaryLoader.prototype = Object.create( THREE.Loader.prototype );
28817
28818 // Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
28819 //  - binary models consist of two files: JS and BIN
28820 //  - parameters
28821 //        - url (required)
28822 //        - callback (required)
28823 //        - texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
28824 //        - binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
28825
28826 THREE.BinaryLoader.prototype.load = function( url, callback, texturePath, binaryPath ) {
28827
28828     texturePath = texturePath ? texturePath : this.extractUrlBase( url );
28829     binaryPath = binaryPath ? binaryPath : this.extractUrlBase( url );
28830
28831     var callbackProgress = this.showProgress ? THREE.Loader.prototype.updateProgress : null;
28832
28833     this.onLoadStart();
28834
28835     // #1 load JS part via web worker
28836
28837     this.loadAjaxJSON( this, url, callback, texturePath, binaryPath, callbackProgress );
28838
28839 };
28840
28841 THREE.BinaryLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, binaryPath, callbackProgress ) {
28842
28843     var xhr = new XMLHttpRequest();
28844
28845     xhr.onreadystatechange = function () {
28846
28847         if ( xhr.readyState == 4 ) {
28848
28849             if ( xhr.status == 200 || xhr.status == 0 ) {
28850
28851                 var json = JSON.parse( xhr.responseText );
28852                 context.loadAjaxBuffers( json, callback, binaryPath, texturePath, callbackProgress );
28853
28854             } else {
28855
28856                 console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
28857
28858             }
28859
28860         }
28861
28862     };
28863
28864     xhr.open( "GET", url, true );
28865     xhr.send( null );
28866
28867 };
28868
28869 THREE.BinaryLoader.prototype.loadAjaxBuffers = function ( json, callback, binaryPath, texturePath, callbackProgress ) {
28870
28871     var xhr = new XMLHttpRequest(),
28872         url = binaryPath + "/" + json.buffers;
28873
28874     var length = 0;
28875
28876     xhr.onreadystatechange = function () {
28877
28878         if ( xhr.readyState == 4 ) {
28879
28880             if ( xhr.status == 200 || xhr.status == 0 ) {
28881
28882                 var buffer = xhr.response;
28883                 if ( buffer === undefined ) buffer = ( new Uint8Array( xhr.responseBody ) ).buffer; // IEWEBGL needs this
28884                 THREE.BinaryLoader.prototype.createBinModel( buffer, callback, texturePath, json.materials );
28885
28886             } else {
28887
28888                 console.error( "THREE.BinaryLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
28889
28890             }
28891
28892         } else if ( xhr.readyState == 3 ) {
28893
28894             if ( callbackProgress ) {
28895
28896                 if ( length == 0 ) {
28897
28898                     length = xhr.getResponseHeader( "Content-Length" );
28899
28900                 }
28901
28902                 callbackProgress( { total: length, loaded: xhr.responseText.length } );
28903
28904             }
28905
28906         } else if ( xhr.readyState == 2 ) {
28907
28908             length = xhr.getResponseHeader( "Content-Length" );
28909
28910         }
28911
28912     };
28913
28914     xhr.open( "GET", url, true );
28915     xhr.responseType = "arraybuffer";
28916     xhr.send( null );
28917
28918 };
28919
28920 // Binary AJAX parser
28921
28922 THREE.BinaryLoader.prototype.createBinModel = function ( data, callback, texturePath, materials ) {
28923
28924     var Model = function ( texturePath ) {
28925
28926         var scope = this,
28927             currentOffset = 0,
28928             md,
28929             normals = [],
28930             uvs = [],
28931             start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
28932             start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
28933             tri_size, quad_size,
28934             len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
28935             len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
28936
28937
28938         THREE.Geometry.call( this );
28939
28940         THREE.Loader.prototype.initMaterials( scope, materials, texturePath );
28941
28942         md = parseMetaData( data, currentOffset );
28943
28944         currentOffset += md.header_bytes;
28945 /*
28946         md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
28947         md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
28948         md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
28949         md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
28950 */
28951         // buffers sizes
28952
28953         tri_size =  md.vertex_index_bytes * 3 + md.material_index_bytes;
28954         quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
28955
28956         len_tri_flat      = md.ntri_flat      * ( tri_size );
28957         len_tri_smooth    = md.ntri_smooth    * ( tri_size + md.normal_index_bytes * 3 );
28958         len_tri_flat_uv   = md.ntri_flat_uv   * ( tri_size + md.uv_index_bytes * 3 );
28959         len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
28960
28961         len_quad_flat      = md.nquad_flat      * ( quad_size );
28962         len_quad_smooth    = md.nquad_smooth    * ( quad_size + md.normal_index_bytes * 4 );
28963         len_quad_flat_uv   = md.nquad_flat_uv   * ( quad_size + md.uv_index_bytes * 4 );
28964         len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
28965
28966         // read buffers
28967
28968         currentOffset += init_vertices( currentOffset );
28969
28970         currentOffset += init_normals( currentOffset );
28971         currentOffset += handlePadding( md.nnormals * 3 );
28972
28973         currentOffset += init_uvs( currentOffset );
28974
28975         start_tri_flat         = currentOffset;
28976         start_tri_smooth    = start_tri_flat    + len_tri_flat    + handlePadding( md.ntri_flat * 2 );
28977         start_tri_flat_uv   = start_tri_smooth  + len_tri_smooth  + handlePadding( md.ntri_smooth * 2 );
28978         start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
28979
28980         start_quad_flat     = start_tri_smooth_uv + len_tri_smooth_uv  + handlePadding( md.ntri_smooth_uv * 2 );
28981         start_quad_smooth   = start_quad_flat     + len_quad_flat       + handlePadding( md.nquad_flat * 2 );
28982         start_quad_flat_uv  = start_quad_smooth   + len_quad_smooth    + handlePadding( md.nquad_smooth * 2 );
28983         start_quad_smooth_uv= start_quad_flat_uv  + len_quad_flat_uv   + handlePadding( md.nquad_flat_uv * 2 );
28984
28985         // have to first process faces with uvs
28986         // so that face and uv indices match
28987
28988         init_triangles_flat_uv( start_tri_flat_uv );
28989         init_triangles_smooth_uv( start_tri_smooth_uv );
28990
28991         init_quads_flat_uv( start_quad_flat_uv );
28992         init_quads_smooth_uv( start_quad_smooth_uv );
28993
28994         // now we can process untextured faces
28995
28996         init_triangles_flat( start_tri_flat );
28997         init_triangles_smooth( start_tri_smooth );
28998
28999         init_quads_flat( start_quad_flat );
29000         init_quads_smooth( start_quad_smooth );
29001
29002         this.computeCentroids();
29003         this.computeFaceNormals();
29004
29005         if ( THREE.Loader.prototype.hasNormals( this ) ) this.computeTangents();
29006
29007         function handlePadding( n ) {
29008
29009             return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
29010
29011         };
29012
29013         function parseMetaData( data, offset ) {
29014
29015             var metaData = {
29016
29017                 'signature'               :parseString( data, offset,  12 ),
29018                 'header_bytes'            :parseUChar8( data, offset + 12 ),
29019
29020                 'vertex_coordinate_bytes' :parseUChar8( data, offset + 13 ),
29021                 'normal_coordinate_bytes' :parseUChar8( data, offset + 14 ),
29022                 'uv_coordinate_bytes'     :parseUChar8( data, offset + 15 ),
29023
29024                 'vertex_index_bytes'      :parseUChar8( data, offset + 16 ),
29025                 'normal_index_bytes'      :parseUChar8( data, offset + 17 ),
29026                 'uv_index_bytes'          :parseUChar8( data, offset + 18 ),
29027                 'material_index_bytes'    :parseUChar8( data, offset + 19 ),
29028
29029                 'nvertices'    :parseUInt32( data, offset + 20 ),
29030                 'nnormals'     :parseUInt32( data, offset + 20 + 4*1 ),
29031                 'nuvs'         :parseUInt32( data, offset + 20 + 4*2 ),
29032
29033                 'ntri_flat'      :parseUInt32( data, offset + 20 + 4*3 ),
29034                 'ntri_smooth'    :parseUInt32( data, offset + 20 + 4*4 ),
29035                 'ntri_flat_uv'   :parseUInt32( data, offset + 20 + 4*5 ),
29036                 'ntri_smooth_uv' :parseUInt32( data, offset + 20 + 4*6 ),
29037
29038                 'nquad_flat'      :parseUInt32( data, offset + 20 + 4*7 ),
29039                 'nquad_smooth'    :parseUInt32( data, offset + 20 + 4*8 ),
29040                 'nquad_flat_uv'   :parseUInt32( data, offset + 20 + 4*9 ),
29041                 'nquad_smooth_uv' :parseUInt32( data, offset + 20 + 4*10 )
29042
29043             };
29044 /*
29045             console.log( "signature: " + metaData.signature );
29046
29047             console.log( "header_bytes: " + metaData.header_bytes );
29048             console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
29049             console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
29050             console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
29051
29052             console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
29053             console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
29054             console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
29055             console.log( "material_index_bytes: " + metaData.material_index_bytes );
29056
29057             console.log( "nvertices: " + metaData.nvertices );
29058             console.log( "nnormals: " + metaData.nnormals );
29059             console.log( "nuvs: " + metaData.nuvs );
29060
29061             console.log( "ntri_flat: " + metaData.ntri_flat );
29062             console.log( "ntri_smooth: " + metaData.ntri_smooth );
29063             console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
29064             console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
29065
29066             console.log( "nquad_flat: " + metaData.nquad_flat );
29067             console.log( "nquad_smooth: " + metaData.nquad_smooth );
29068             console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
29069             console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
29070
29071             var total = metaData.header_bytes
29072                       + metaData.nvertices * metaData.vertex_coordinate_bytes * 3
29073                       + metaData.nnormals * metaData.normal_coordinate_bytes * 3
29074                       + metaData.nuvs * metaData.uv_coordinate_bytes * 2
29075                       + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
29076                       + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
29077                       + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
29078                       + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
29079                       + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
29080                       + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
29081                       + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
29082                       + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
29083             console.log( "total bytes: " + total );
29084 */
29085
29086             return metaData;
29087
29088         };
29089
29090         function parseString( data, offset, length ) {
29091
29092             var charArray = new Uint8Array( data, offset, length );
29093
29094             var text = "";
29095
29096             for ( var i = 0; i < length; i ++ ) {
29097
29098                 text += String.fromCharCode( charArray[ offset + i ] );
29099
29100             }
29101
29102             return text;
29103
29104         };
29105
29106         function parseUChar8( data, offset ) {
29107
29108             var charArray = new Uint8Array( data, offset, 1 );
29109
29110             return charArray[ 0 ];
29111
29112         };
29113
29114         function parseUInt32( data, offset ) {
29115
29116             var intArray = new Uint32Array( data, offset, 1 );
29117
29118             return intArray[ 0 ];
29119
29120         };
29121
29122         function init_vertices( start ) {
29123
29124             var nElements = md.nvertices;
29125
29126             var coordArray = new Float32Array( data, start, nElements * 3 );
29127
29128             var i, x, y, z;
29129
29130             for( i = 0; i < nElements; i ++ ) {
29131
29132                 x = coordArray[ i * 3 ];
29133                 y = coordArray[ i * 3 + 1 ];
29134                 z = coordArray[ i * 3 + 2 ];
29135
29136                 vertex( scope, x, y, z );
29137
29138             }
29139
29140             return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
29141
29142         };
29143
29144         function init_normals( start ) {
29145
29146             var nElements = md.nnormals;
29147
29148             if ( nElements ) {
29149
29150                 var normalArray = new Int8Array( data, start, nElements * 3 );
29151
29152                 var i, x, y, z;
29153
29154                 for( i = 0; i < nElements; i ++ ) {
29155
29156                     x = normalArray[ i * 3 ];
29157                     y = normalArray[ i * 3 + 1 ];
29158                     z = normalArray[ i * 3 + 2 ];
29159
29160                     normals.push( x/127, y/127, z/127 );
29161
29162                 }
29163
29164             }
29165
29166             return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
29167
29168         };
29169
29170         function init_uvs( start ) {
29171
29172             var nElements = md.nuvs;
29173
29174             if ( nElements ) {
29175
29176                 var uvArray = new Float32Array( data, start, nElements * 2 );
29177
29178                 var i, u, v;
29179
29180                 for( i = 0; i < nElements; i ++ ) {
29181
29182                     u = uvArray[ i * 2 ];
29183                     v = uvArray[ i * 2 + 1 ];
29184
29185                     uvs.push( u, v );
29186
29187                 }
29188
29189             }
29190
29191             return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
29192
29193         };
29194
29195         function init_uvs3( nElements, offset ) {
29196
29197             var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
29198
29199             var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
29200
29201             for( i = 0; i < nElements; i ++ ) {
29202
29203                 uva = uvIndexBuffer[ i * 3 ];
29204                 uvb = uvIndexBuffer[ i * 3 + 1 ];
29205                 uvc = uvIndexBuffer[ i * 3 + 2 ];
29206
29207                 u1 = uvs[ uva*2 ];
29208                 v1 = uvs[ uva*2 + 1 ];
29209
29210                 u2 = uvs[ uvb*2 ];
29211                 v2 = uvs[ uvb*2 + 1 ];
29212
29213                 u3 = uvs[ uvc*2 ];
29214                 v3 = uvs[ uvc*2 + 1 ];
29215
29216                 uv3( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3 );
29217
29218             }
29219
29220         };
29221
29222         function init_uvs4( nElements, offset ) {
29223
29224             var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
29225
29226             var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
29227
29228             for( i = 0; i < nElements; i ++ ) {
29229
29230                 uva = uvIndexBuffer[ i * 4 ];
29231                 uvb = uvIndexBuffer[ i * 4 + 1 ];
29232                 uvc = uvIndexBuffer[ i * 4 + 2 ];
29233                 uvd = uvIndexBuffer[ i * 4 + 3 ];
29234
29235                 u1 = uvs[ uva*2 ];
29236                 v1 = uvs[ uva*2 + 1 ];
29237
29238                 u2 = uvs[ uvb*2 ];
29239                 v2 = uvs[ uvb*2 + 1 ];
29240
29241                 u3 = uvs[ uvc*2 ];
29242                 v3 = uvs[ uvc*2 + 1 ];
29243
29244                 u4 = uvs[ uvd*2 ];
29245                 v4 = uvs[ uvd*2 + 1 ];
29246
29247                 uv4( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3, u4, v4 );
29248
29249             }
29250
29251         };
29252
29253         function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
29254
29255             var i, a, b, c, m;
29256
29257             var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
29258             var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
29259
29260             for( i = 0; i < nElements; i ++ ) {
29261
29262                 a = vertexIndexBuffer[ i * 3 ];
29263                 b = vertexIndexBuffer[ i * 3 + 1 ];
29264                 c = vertexIndexBuffer[ i * 3 + 2 ];
29265
29266                 m = materialIndexBuffer[ i ];
29267
29268                 f3( scope, a, b, c, m );
29269
29270             }
29271
29272         };
29273
29274         function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
29275
29276             var i, a, b, c, d, m;
29277
29278             var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
29279             var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
29280
29281             for( i = 0; i < nElements; i ++ ) {
29282
29283                 a = vertexIndexBuffer[ i * 4 ];
29284                 b = vertexIndexBuffer[ i * 4 + 1 ];
29285                 c = vertexIndexBuffer[ i * 4 + 2 ];
29286                 d = vertexIndexBuffer[ i * 4 + 3 ];
29287
29288                 m = materialIndexBuffer[ i ];
29289
29290                 f4( scope, a, b, c, d, m );
29291
29292             }
29293
29294         };
29295
29296         function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
29297
29298             var i, a, b, c, m;
29299             var na, nb, nc;
29300
29301             var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
29302             var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
29303             var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
29304
29305             for( i = 0; i < nElements; i ++ ) {
29306
29307                 a = vertexIndexBuffer[ i * 3 ];
29308                 b = vertexIndexBuffer[ i * 3 + 1 ];
29309                 c = vertexIndexBuffer[ i * 3 + 2 ];
29310
29311                 na = normalIndexBuffer[ i * 3 ];
29312                 nb = normalIndexBuffer[ i * 3 + 1 ];
29313                 nc = normalIndexBuffer[ i * 3 + 2 ];
29314
29315                 m = materialIndexBuffer[ i ];
29316
29317                 f3n( scope, normals, a, b, c, m, na, nb, nc );
29318
29319             }
29320
29321         };
29322
29323         function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
29324
29325             var i, a, b, c, d, m;
29326             var na, nb, nc, nd;
29327
29328             var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
29329             var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
29330             var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
29331
29332             for( i = 0; i < nElements; i ++ ) {
29333
29334                 a = vertexIndexBuffer[ i * 4 ];
29335                 b = vertexIndexBuffer[ i * 4 + 1 ];
29336                 c = vertexIndexBuffer[ i * 4 + 2 ];
29337                 d = vertexIndexBuffer[ i * 4 + 3 ];
29338
29339                 na = normalIndexBuffer[ i * 4 ];
29340                 nb = normalIndexBuffer[ i * 4 + 1 ];
29341                 nc = normalIndexBuffer[ i * 4 + 2 ];
29342                 nd = normalIndexBuffer[ i * 4 + 3 ];
29343
29344                 m = materialIndexBuffer[ i ];
29345
29346                 f4n( scope, normals, a, b, c, d, m, na, nb, nc, nd );
29347
29348             }
29349
29350         };
29351
29352         function init_triangles_flat( start ) {
29353
29354             var nElements = md.ntri_flat;
29355
29356             if ( nElements ) {
29357
29358                 var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29359                 init_faces3_flat( nElements, start, offsetMaterials );
29360
29361             }
29362
29363         };
29364
29365         function init_triangles_flat_uv( start ) {
29366
29367             var nElements = md.ntri_flat_uv;
29368
29369             if ( nElements ) {
29370
29371                 var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29372                 var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29373
29374                 init_faces3_flat( nElements, start, offsetMaterials );
29375                 init_uvs3( nElements, offsetUvs );
29376
29377             }
29378
29379         };
29380
29381         function init_triangles_smooth( start ) {
29382
29383             var nElements = md.ntri_smooth;
29384
29385             if ( nElements ) {
29386
29387                 var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29388                 var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29389
29390                 init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
29391
29392             }
29393
29394         };
29395
29396         function init_triangles_smooth_uv( start ) {
29397
29398             var nElements = md.ntri_smooth_uv;
29399
29400             if ( nElements ) {
29401
29402                 var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29403                 var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29404                 var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
29405
29406                 init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
29407                 init_uvs3( nElements, offsetUvs );
29408
29409             }
29410
29411         };
29412
29413         function init_quads_flat( start ) {
29414
29415             var nElements = md.nquad_flat;
29416
29417             if ( nElements ) {
29418
29419                 var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29420                 init_faces4_flat( nElements, start, offsetMaterials );
29421
29422             }
29423
29424         };
29425
29426         function init_quads_flat_uv( start ) {
29427
29428             var nElements = md.nquad_flat_uv;
29429
29430             if ( nElements ) {
29431
29432                 var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29433                 var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29434
29435                 init_faces4_flat( nElements, start, offsetMaterials );
29436                 init_uvs4( nElements, offsetUvs );
29437
29438             }
29439
29440         };
29441
29442         function init_quads_smooth( start ) {
29443
29444             var nElements = md.nquad_smooth;
29445
29446             if ( nElements ) {
29447
29448                 var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29449                 var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29450
29451                 init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
29452
29453             }
29454
29455         };
29456
29457         function init_quads_smooth_uv( start ) {
29458
29459             var nElements = md.nquad_smooth_uv;
29460
29461             if ( nElements ) {
29462
29463                 var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29464                 var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29465                 var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
29466
29467                 init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
29468                 init_uvs4( nElements, offsetUvs );
29469
29470             }
29471
29472         };
29473
29474     };
29475
29476     function vertex ( scope, x, y, z ) {
29477
29478         scope.vertices.push( new THREE.Vector3( x, y, z ) );
29479
29480     };
29481
29482     function f3 ( scope, a, b, c, mi ) {
29483
29484         scope.faces.push( new THREE.Face3( a, b, c, null, null, mi ) );
29485
29486     };
29487
29488     function f4 ( scope, a, b, c, d, mi ) {
29489
29490         scope.faces.push( new THREE.Face4( a, b, c, d, null, null, mi ) );
29491
29492     };
29493
29494     function f3n ( scope, normals, a, b, c, mi, na, nb, nc ) {
29495
29496         var nax = normals[ na*3     ],
29497             nay = normals[ na*3 + 1 ],
29498             naz = normals[ na*3 + 2 ],
29499
29500             nbx = normals[ nb*3     ],
29501             nby = normals[ nb*3 + 1 ],
29502             nbz = normals[ nb*3 + 2 ],
29503
29504             ncx = normals[ nc*3     ],
29505             ncy = normals[ nc*3 + 1 ],
29506             ncz = normals[ nc*3 + 2 ];
29507
29508         scope.faces.push( new THREE.Face3( a, b, c,
29509                           [new THREE.Vector3( nax, nay, naz ),
29510                            new THREE.Vector3( nbx, nby, nbz ),
29511                            new THREE.Vector3( ncx, ncy, ncz )],
29512                           null,
29513                           mi ) );
29514
29515     };
29516
29517     function f4n ( scope, normals, a, b, c, d, mi, na, nb, nc, nd ) {
29518
29519         var nax = normals[ na*3     ],
29520             nay = normals[ na*3 + 1 ],
29521             naz = normals[ na*3 + 2 ],
29522
29523             nbx = normals[ nb*3     ],
29524             nby = normals[ nb*3 + 1 ],
29525             nbz = normals[ nb*3 + 2 ],
29526
29527             ncx = normals[ nc*3     ],
29528             ncy = normals[ nc*3 + 1 ],
29529             ncz = normals[ nc*3 + 2 ],
29530
29531             ndx = normals[ nd*3     ],
29532             ndy = normals[ nd*3 + 1 ],
29533             ndz = normals[ nd*3 + 2 ];
29534
29535         scope.faces.push( new THREE.Face4( a, b, c, d,
29536                           [new THREE.Vector3( nax, nay, naz ),
29537                            new THREE.Vector3( nbx, nby, nbz ),
29538                            new THREE.Vector3( ncx, ncy, ncz ),
29539                            new THREE.Vector3( ndx, ndy, ndz )],
29540                           null,
29541                           mi ) );
29542
29543     };
29544
29545     function uv3 ( where, u1, v1, u2, v2, u3, v3 ) {
29546
29547         var uv = [];
29548         uv.push( new THREE.UV( u1, v1 ) );
29549         uv.push( new THREE.UV( u2, v2 ) );
29550         uv.push( new THREE.UV( u3, v3 ) );
29551         where.push( uv );
29552
29553     };
29554
29555     function uv4 ( where, u1, v1, u2, v2, u3, v3, u4, v4 ) {
29556
29557         var uv = [];
29558         uv.push( new THREE.UV( u1, v1 ) );
29559         uv.push( new THREE.UV( u2, v2 ) );
29560         uv.push( new THREE.UV( u3, v3 ) );
29561         uv.push( new THREE.UV( u4, v4 ) );
29562         where.push( uv );
29563
29564     };
29565
29566     Model.prototype = Object.create( THREE.Geometry.prototype );
29567
29568     callback( new Model( texturePath ) );
29569
29570 };
29571 /**
29572  * @author mrdoob / http://mrdoob.com/
29573  */
29574
29575 THREE.ImageLoader = function () {
29576
29577     THREE.EventTarget.call( this );
29578
29579     this.crossOrigin = null;
29580
29581 };
29582
29583 THREE.ImageLoader.prototype = {
29584
29585     constructor: THREE.ImageLoader,
29586
29587     load: function ( url, image ) {
29588
29589         var scope = this;
29590
29591         if ( image === undefined ) image = new Image();
29592
29593         image.addEventListener( 'load', function () {
29594
29595             scope.dispatchEvent( { type: 'load', content: image } );
29596
29597         }, false );
29598
29599         image.addEventListener( 'error', function () {
29600
29601             scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
29602
29603         }, false );
29604
29605         if ( scope.crossOrigin ) image.crossOrigin = scope.crossOrigin;
29606
29607         image.src = url;
29608
29609     }
29610
29611 }
29612 /**
29613  * @author mrdoob / http://mrdoob.com/
29614  * @author alteredq / http://alteredqualia.com/
29615  */
29616
29617 THREE.JSONLoader = function ( showStatus ) {
29618
29619     THREE.Loader.call( this, showStatus );
29620
29621 };
29622
29623 THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );
29624
29625 THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {
29626
29627     var scope = this;
29628
29629     texturePath = texturePath ? texturePath : this.extractUrlBase( url );
29630
29631     this.onLoadStart();
29632     this.loadAjaxJSON( this, url, callback, texturePath );
29633
29634 };
29635
29636 THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {
29637
29638     var xhr = new XMLHttpRequest();
29639
29640     var length = 0;
29641
29642     xhr.onreadystatechange = function () {
29643
29644         if ( xhr.readyState === xhr.DONE ) {
29645
29646             if ( xhr.status === 200 || xhr.status === 0 ) {
29647
29648                 if ( xhr.responseText ) {
29649
29650                     var json = JSON.parse( xhr.responseText );
29651                     context.createModel( json, callback, texturePath );
29652
29653                 } else {
29654
29655                     console.warn( "THREE.JSONLoader: [" + url + "] seems to be unreachable or file there is empty" );
29656
29657                 }
29658
29659                 // in context of more complex asset initialization
29660                 // do not block on single failed file
29661                 // maybe should go even one more level up
29662
29663                 context.onLoadComplete();
29664
29665             } else {
29666
29667                 console.error( "THREE.JSONLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
29668
29669             }
29670
29671         } else if ( xhr.readyState === xhr.LOADING ) {
29672
29673             if ( callbackProgress ) {
29674
29675                 if ( length === 0 ) {
29676
29677                     length = xhr.getResponseHeader( "Content-Length" );
29678
29679                 }
29680
29681                 callbackProgress( { total: length, loaded: xhr.responseText.length } );
29682
29683             }
29684
29685         } else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {
29686
29687             length = xhr.getResponseHeader( "Content-Length" );
29688
29689         }
29690
29691     };
29692
29693     xhr.open( "GET", url, true );
29694     xhr.send( null );
29695
29696 };
29697
29698 THREE.JSONLoader.prototype.createModel = function ( json, callback, texturePath ) {
29699
29700     var scope = this,
29701     geometry = new THREE.Geometry(),
29702     scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
29703
29704     this.initMaterials( geometry, json.materials, texturePath );
29705
29706     parseModel( scale );
29707
29708     parseSkin();
29709     parseMorphing( scale );
29710
29711     geometry.computeCentroids();
29712     geometry.computeFaceNormals();
29713
29714     if ( this.hasNormals( geometry ) ) geometry.computeTangents();
29715
29716
29717     function parseModel( scale ) {
29718
29719         function isBitSet( value, position ) {
29720
29721             return value & ( 1 << position );
29722
29723         }
29724
29725         var i, j, fi,
29726
29727         offset, zLength, nVertices,
29728
29729         colorIndex, normalIndex, uvIndex, materialIndex,
29730
29731         type,
29732         isQuad,
29733         hasMaterial,
29734         hasFaceUv, hasFaceVertexUv,
29735         hasFaceNormal, hasFaceVertexNormal,
29736         hasFaceColor, hasFaceVertexColor,
29737
29738         vertex, face, color, normal,
29739
29740         uvLayer, uvs, u, v,
29741
29742         faces = json.faces,
29743         vertices = json.vertices,
29744         normals = json.normals,
29745         colors = json.colors,
29746
29747         nUvLayers = 0;
29748
29749         // disregard empty arrays
29750
29751         for ( i = 0; i < json.uvs.length; i++ ) {
29752
29753             if ( json.uvs[ i ].length ) nUvLayers ++;
29754
29755         }
29756
29757         for ( i = 0; i < nUvLayers; i++ ) {
29758
29759             geometry.faceUvs[ i ] = [];
29760             geometry.faceVertexUvs[ i ] = [];
29761
29762         }
29763
29764         offset = 0;
29765         zLength = vertices.length;
29766
29767         while ( offset < zLength ) {
29768
29769             vertex = new THREE.Vector3();
29770
29771             vertex.x = vertices[ offset ++ ] * scale;
29772             vertex.y = vertices[ offset ++ ] * scale;
29773             vertex.z = vertices[ offset ++ ] * scale;
29774
29775             geometry.vertices.push( vertex );
29776
29777         }
29778
29779         offset = 0;
29780         zLength = faces.length;
29781
29782         while ( offset < zLength ) {
29783
29784             type = faces[ offset ++ ];
29785
29786
29787             isQuad              = isBitSet( type, 0 );
29788             hasMaterial         = isBitSet( type, 1 );
29789             hasFaceUv           = isBitSet( type, 2 );
29790             hasFaceVertexUv     = isBitSet( type, 3 );
29791             hasFaceNormal       = isBitSet( type, 4 );
29792             hasFaceVertexNormal = isBitSet( type, 5 );
29793             hasFaceColor        = isBitSet( type, 6 );
29794             hasFaceVertexColor  = isBitSet( type, 7 );
29795
29796             //console.log("type", type, "bits", isQuad, hasMaterial, hasFaceUv, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
29797
29798             if ( isQuad ) {
29799
29800                 face = new THREE.Face4();
29801
29802                 face.a = faces[ offset ++ ];
29803                 face.b = faces[ offset ++ ];
29804                 face.c = faces[ offset ++ ];
29805                 face.d = faces[ offset ++ ];
29806
29807                 nVertices = 4;
29808
29809             } else {
29810
29811                 face = new THREE.Face3();
29812
29813                 face.a = faces[ offset ++ ];
29814                 face.b = faces[ offset ++ ];
29815                 face.c = faces[ offset ++ ];
29816
29817                 nVertices = 3;
29818
29819             }
29820
29821             if ( hasMaterial ) {
29822
29823                 materialIndex = faces[ offset ++ ];
29824                 face.materialIndex = materialIndex;
29825
29826             }
29827
29828             // to get face <=> uv index correspondence
29829
29830             fi = geometry.faces.length;
29831
29832             if ( hasFaceUv ) {
29833
29834                 for ( i = 0; i < nUvLayers; i++ ) {
29835
29836                     uvLayer = json.uvs[ i ];
29837
29838                     uvIndex = faces[ offset ++ ];
29839
29840                     u = uvLayer[ uvIndex * 2 ];
29841                     v = uvLayer[ uvIndex * 2 + 1 ];
29842
29843                     geometry.faceUvs[ i ][ fi ] = new THREE.UV( u, v );
29844
29845                 }
29846
29847             }
29848
29849             if ( hasFaceVertexUv ) {
29850
29851                 for ( i = 0; i < nUvLayers; i++ ) {
29852
29853                     uvLayer = json.uvs[ i ];
29854
29855                     uvs = [];
29856
29857                     for ( j = 0; j < nVertices; j ++ ) {
29858
29859                         uvIndex = faces[ offset ++ ];
29860
29861                         u = uvLayer[ uvIndex * 2 ];
29862                         v = uvLayer[ uvIndex * 2 + 1 ];
29863
29864                         uvs[ j ] = new THREE.UV( u, v );
29865
29866                     }
29867
29868                     geometry.faceVertexUvs[ i ][ fi ] = uvs;
29869
29870                 }
29871
29872             }
29873
29874             if ( hasFaceNormal ) {
29875
29876                 normalIndex = faces[ offset ++ ] * 3;
29877
29878                 normal = new THREE.Vector3();
29879
29880                 normal.x = normals[ normalIndex ++ ];
29881                 normal.y = normals[ normalIndex ++ ];
29882                 normal.z = normals[ normalIndex ];
29883
29884                 face.normal = normal;
29885
29886             }
29887
29888             if ( hasFaceVertexNormal ) {
29889
29890                 for ( i = 0; i < nVertices; i++ ) {
29891
29892                     normalIndex = faces[ offset ++ ] * 3;
29893
29894                     normal = new THREE.Vector3();
29895
29896                     normal.x = normals[ normalIndex ++ ];
29897                     normal.y = normals[ normalIndex ++ ];
29898                     normal.z = normals[ normalIndex ];
29899
29900                     face.vertexNormals.push( normal );
29901
29902                 }
29903
29904             }
29905
29906
29907             if ( hasFaceColor ) {
29908
29909                 colorIndex = faces[ offset ++ ];
29910
29911                 color = new THREE.Color( colors[ colorIndex ] );
29912                 face.color = color;
29913
29914             }
29915
29916
29917             if ( hasFaceVertexColor ) {
29918
29919                 for ( i = 0; i < nVertices; i++ ) {
29920
29921                     colorIndex = faces[ offset ++ ];
29922
29923                     color = new THREE.Color( colors[ colorIndex ] );
29924                     face.vertexColors.push( color );
29925
29926                 }
29927
29928             }
29929
29930             geometry.faces.push( face );
29931
29932         }
29933
29934     };
29935
29936     function parseSkin() {
29937
29938         var i, l, x, y, z, w, a, b, c, d;
29939
29940         if ( json.skinWeights ) {
29941
29942             for ( i = 0, l = json.skinWeights.length; i < l; i += 2 ) {
29943
29944                 x = json.skinWeights[ i     ];
29945                 y = json.skinWeights[ i + 1 ];
29946                 z = 0;
29947                 w = 0;
29948
29949                 geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
29950
29951             }
29952
29953         }
29954
29955         if ( json.skinIndices ) {
29956
29957             for ( i = 0, l = json.skinIndices.length; i < l; i += 2 ) {
29958
29959                 a = json.skinIndices[ i     ];
29960                 b = json.skinIndices[ i + 1 ];
29961                 c = 0;
29962                 d = 0;
29963
29964                 geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
29965
29966             }
29967
29968         }
29969
29970         geometry.bones = json.bones;
29971         geometry.animation = json.animation;
29972
29973     };
29974
29975     function parseMorphing( scale ) {
29976
29977         if ( json.morphTargets !== undefined ) {
29978
29979             var i, l, v, vl, dstVertices, srcVertices;
29980
29981             for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
29982
29983                 geometry.morphTargets[ i ] = {};
29984                 geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
29985                 geometry.morphTargets[ i ].vertices = [];
29986
29987                 dstVertices = geometry.morphTargets[ i ].vertices;
29988                 srcVertices = json.morphTargets [ i ].vertices;
29989
29990                 for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
29991
29992                     var vertex = new THREE.Vector3();
29993                     vertex.x = srcVertices[ v ] * scale;
29994                     vertex.y = srcVertices[ v + 1 ] * scale;
29995                     vertex.z = srcVertices[ v + 2 ] * scale;
29996
29997                     dstVertices.push( vertex );
29998
29999                 }
30000
30001             }
30002
30003         }
30004
30005         if ( json.morphColors !== undefined ) {
30006
30007             var i, l, c, cl, dstColors, srcColors, color;
30008
30009             for ( i = 0, l = json.morphColors.length; i < l; i++ ) {
30010
30011                 geometry.morphColors[ i ] = {};
30012                 geometry.morphColors[ i ].name = json.morphColors[ i ].name;
30013                 geometry.morphColors[ i ].colors = [];
30014
30015                 dstColors = geometry.morphColors[ i ].colors;
30016                 srcColors = json.morphColors [ i ].colors;
30017
30018                 for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
30019
30020                     color = new THREE.Color( 0xffaa00 );
30021                     color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
30022                     dstColors.push( color );
30023
30024                 }
30025
30026             }
30027
30028         }
30029
30030     };
30031
30032     callback( geometry );
30033
30034 };
30035 /**
30036  * @author mrdoob / http://mrdoob.com/
30037  */
30038
30039 THREE.LoadingMonitor = function () {
30040
30041     THREE.EventTarget.call( this );
30042
30043     var scope = this;
30044
30045     var loaded = 0;
30046     var total = 0;
30047
30048     var onLoad = function ( event ) {
30049
30050         loaded ++;
30051
30052         scope.dispatchEvent( { type: 'progress', loaded: loaded, total: total } );
30053
30054         if ( loaded === total ) {
30055
30056             scope.dispatchEvent( { type: 'load' } );
30057
30058         }
30059
30060     };
30061
30062     this.add = function ( loader ) {
30063
30064         total ++;
30065
30066         loader.addEventListener( 'load', onLoad, false );
30067
30068     };
30069
30070 };
30071 /**
30072  * @author mrdoob / http://mrdoob.com/
30073  * @author alteredq / http://alteredqualia.com/
30074  */
30075
30076 THREE.GeometryLoader = function () {
30077
30078     THREE.EventTarget.call( this );
30079
30080     this.crossOrigin = null;
30081     this.path = null;
30082
30083
30084 };
30085
30086 THREE.GeometryLoader.prototype = {
30087
30088     constructor: THREE.GeometryLoader,
30089
30090     load: function ( url ) {
30091
30092         var scope = this;
30093         var geometry = null;
30094
30095         if ( scope.path === null ) {
30096
30097             var parts = url.split( '/' ); parts.pop();
30098             scope.path = ( parts.length < 1 ? '.' : parts.join( '/' ) );
30099
30100         }
30101
30102         //
30103
30104         var xhr = new XMLHttpRequest();
30105
30106         xhr.addEventListener( 'load', function ( event ) {
30107
30108             if ( event.target.responseText ) {
30109
30110                 geometry = scope.parse( JSON.parse( event.target.responseText ), monitor );
30111
30112             } else {
30113
30114                 scope.dispatchEvent( { type: 'error', message: 'Invalid file [' + url + ']' } );
30115
30116             }
30117
30118         }, false );
30119
30120         xhr.addEventListener( 'error', function () {
30121
30122             scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
30123
30124         }, false );
30125
30126         xhr.open( 'GET', url, true );
30127         xhr.send( null );
30128
30129         //
30130
30131         var monitor = new THREE.LoadingMonitor();
30132
30133         monitor.addEventListener( 'load', function ( event ) {
30134
30135             scope.dispatchEvent( { type: 'load', content: geometry } );
30136
30137         } );
30138
30139         monitor.add( xhr );
30140
30141     },
30142
30143     parse: function ( data, monitor ) {
30144
30145         var scope = this;
30146         var geometry = new THREE.Geometry();
30147
30148         var scale = ( data.scale !== undefined ) ? 1 / data.scale : 1;
30149
30150         // materials
30151
30152         if ( data.materials ) {
30153
30154             geometry.materials = [];
30155
30156             for ( var i = 0; i < data.materials.length; ++ i ) {
30157
30158                 var m = data.materials[ i ];
30159
30160                 function isPow2( n ) {
30161
30162                     var l = Math.log( n ) / Math.LN2;
30163                     return Math.floor( l ) == l;
30164
30165                 }
30166
30167                 function nearestPow2( n ) {
30168
30169                     var l = Math.log( n ) / Math.LN2;
30170                     return Math.pow( 2, Math.round(  l ) );
30171
30172                 }
30173
30174                 function createTexture( where, name, sourceFile, repeat, offset, wrap ) {
30175
30176                     where[ name ] = new THREE.Texture();
30177                     where[ name ].sourceFile = sourceFile;
30178
30179                     if ( repeat ) {
30180
30181                         where[ name ].repeat.set( repeat[ 0 ], repeat[ 1 ] );
30182
30183                         if ( repeat[ 0 ] !== 1 ) where[ name ].wrapS = THREE.RepeatWrapping;
30184                         if ( repeat[ 1 ] !== 1 ) where[ name ].wrapT = THREE.RepeatWrapping;
30185
30186                     }
30187
30188                     if ( offset ) {
30189
30190                         where[ name ].offset.set( offset[ 0 ], offset[ 1 ] );
30191
30192                     }
30193
30194                     if ( wrap ) {
30195
30196                         var wrapMap = {
30197
30198                             "repeat": THREE.RepeatWrapping,
30199                             "mirror": THREE.MirroredRepeatWrapping
30200
30201                         }
30202
30203                         if ( wrapMap[ wrap[ 0 ] ] !== undefined ) where[ name ].wrapS = wrapMap[ wrap[ 0 ] ];
30204                         if ( wrapMap[ wrap[ 1 ] ] !== undefined ) where[ name ].wrapT = wrapMap[ wrap[ 1 ] ];
30205
30206                     }
30207
30208                     // load image
30209
30210                     var texture = where[ name ];
30211
30212                     var loader = new THREE.ImageLoader();
30213                     loader.addEventListener( 'load', function ( event ) {
30214
30215                         var image = event.content;
30216
30217                         if ( !isPow2( image.width ) || !isPow2( image.height ) ) {
30218
30219                             var width = nearestPow2( image.width );
30220                             var height = nearestPow2( image.height );
30221
30222                             texture.image = document.createElement( 'canvas' );
30223                             texture.image.width = width;
30224                             texture.image.height = height;
30225                             texture.image.getContext( '2d' ).drawImage( image, 0, 0, width, height );
30226
30227                         } else {
30228
30229                             texture.image = image;
30230
30231                         }
30232
30233                         texture.needsUpdate = true;
30234
30235                     } );
30236                     loader.crossOrigin = scope.crossOrigin;
30237                     loader.load( scope.path + '/' + sourceFile );
30238
30239                     if ( monitor ) monitor.add( loader );
30240
30241                 }
30242
30243                 function rgb2hex( rgb ) {
30244
30245                     return ( rgb[ 0 ] * 255 << 16 ) + ( rgb[ 1 ] * 255 << 8 ) + rgb[ 2 ] * 255;
30246
30247                 }
30248
30249                 // defaults
30250
30251                 var mtype = "MeshLambertMaterial";
30252                 var mpars = { color: 0xeeeeee, opacity: 1.0, map: null, lightMap: null, normalMap: null, bumpMap: null, wireframe: false };
30253
30254                 // parameters from model file
30255
30256                 if ( m.shading ) {
30257
30258                     var shading = m.shading.toLowerCase();
30259
30260                     if ( shading === "phong" ) mtype = "MeshPhongMaterial";
30261                     else if ( shading === "basic" ) mtype = "MeshBasicMaterial";
30262
30263                 }
30264
30265                 if ( m.blending !== undefined && THREE[ m.blending ] !== undefined ) {
30266
30267                     mpars.blending = THREE[ m.blending ];
30268
30269                 }
30270
30271                 if ( m.transparent !== undefined || m.opacity < 1.0 ) {
30272
30273                     mpars.transparent = m.transparent;
30274
30275                 }
30276
30277                 if ( m.depthTest !== undefined ) {
30278
30279                     mpars.depthTest = m.depthTest;
30280
30281                 }
30282
30283                 if ( m.depthWrite !== undefined ) {
30284
30285                     mpars.depthWrite = m.depthWrite;
30286
30287                 }
30288
30289                 if ( m.vertexColors !== undefined ) {
30290
30291                     if ( m.vertexColors == "face" ) {
30292
30293                         mpars.vertexColors = THREE.FaceColors;
30294
30295                     } else if ( m.vertexColors ) {
30296
30297                         mpars.vertexColors = THREE.VertexColors;
30298
30299                     }
30300
30301                 }
30302
30303                 // colors
30304
30305                 if ( m.colorDiffuse ) {
30306
30307                     mpars.color = rgb2hex( m.colorDiffuse );
30308
30309                 } else if ( m.DbgColor ) {
30310
30311                     mpars.color = m.DbgColor;
30312
30313                 }
30314
30315                 if ( m.colorSpecular ) {
30316
30317                     mpars.specular = rgb2hex( m.colorSpecular );
30318
30319                 }
30320
30321                 if ( m.colorAmbient ) {
30322
30323                     mpars.ambient = rgb2hex( m.colorAmbient );
30324
30325                 }
30326
30327                 // modifiers
30328
30329                 if ( m.transparency ) {
30330
30331                     mpars.opacity = m.transparency;
30332
30333                 }
30334
30335                 if ( m.specularCoef ) {
30336
30337                     mpars.shininess = m.specularCoef;
30338
30339                 }
30340
30341                 if ( m.visible !== undefined ) {
30342
30343                     mpars.visible = m.visible;
30344
30345                 }
30346
30347                 if ( m.flipSided !== undefined ) {
30348
30349                     mpars.side = THREE.BackSide;
30350
30351                 }
30352
30353                 if ( m.doubleSided !== undefined ) {
30354
30355                     mpars.side = THREE.DoubleSide;
30356
30357                 }
30358
30359                 if ( m.wireframe !== undefined ) {
30360
30361                     mpars.wireframe = m.wireframe;
30362
30363                 }
30364
30365                 // textures
30366
30367                 if ( m.mapDiffuse ) {
30368
30369                     createTexture( mpars, "map", m.mapDiffuse, m.mapDiffuseRepeat, m.mapDiffuseOffset, m.mapDiffuseWrap );
30370
30371                 }
30372
30373                 if ( m.mapLight ) {
30374
30375                     createTexture( mpars, "lightMap", m.mapLight, m.mapLightRepeat, m.mapLightOffset, m.mapLightWrap );
30376
30377                 }
30378
30379                 if ( m.mapBump ) {
30380
30381                     createTexture( mpars, "bumpMap", m.mapBump, m.mapBumpRepeat, m.mapBumpOffset, m.mapBumpWrap );
30382
30383                 }
30384
30385                 if ( m.mapNormal ) {
30386
30387                     createTexture( mpars, "normalMap", m.mapNormal, m.mapNormalRepeat, m.mapNormalOffset, m.mapNormalWrap );
30388
30389                 }
30390
30391                 if ( m.mapSpecular ) {
30392
30393                     createTexture( mpars, "specularMap", m.mapSpecular, m.mapSpecularRepeat, m.mapSpecularOffset, m.mapSpecularWrap );
30394
30395                 }
30396
30397                 // special case for normal mapped material
30398
30399                 if ( m.mapNormal ) {
30400
30401                     var shader = THREE.ShaderUtils.lib[ "normal" ];
30402                     var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
30403
30404                     uniforms[ "tNormal" ].value = mpars.normalMap;
30405
30406                     if ( m.mapNormalFactor ) {
30407
30408                         uniforms[ "uNormalScale" ].value.set( m.mapNormalFactor, m.mapNormalFactor );
30409
30410                     }
30411
30412                     if ( mpars.map ) {
30413
30414                         uniforms[ "tDiffuse" ].value = mpars.map;
30415                         uniforms[ "enableDiffuse" ].value = true;
30416
30417                     }
30418
30419                     if ( mpars.specularMap ) {
30420
30421                         uniforms[ "tSpecular" ].value = mpars.specularMap;
30422                         uniforms[ "enableSpecular" ].value = true;
30423
30424                     }
30425
30426                     if ( mpars.lightMap ) {
30427
30428                         uniforms[ "tAO" ].value = mpars.lightMap;
30429                         uniforms[ "enableAO" ].value = true;
30430
30431                     }
30432
30433                     // for the moment don't handle displacement texture
30434
30435                     uniforms[ "uDiffuseColor" ].value.setHex( mpars.color );
30436                     uniforms[ "uSpecularColor" ].value.setHex( mpars.specular );
30437                     uniforms[ "uAmbientColor" ].value.setHex( mpars.ambient );
30438
30439                     uniforms[ "uShininess" ].value = mpars.shininess;
30440
30441                     if ( mpars.opacity !== undefined ) {
30442
30443                         uniforms[ "uOpacity" ].value = mpars.opacity;
30444
30445                     }
30446
30447                     var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
30448                     var material = new THREE.ShaderMaterial( parameters );
30449
30450                 } else {
30451
30452                     var material = new THREE[ mtype ]( mpars );
30453
30454                 }
30455
30456                 if ( m.DbgName !== undefined ) material.name = m.DbgName;
30457
30458                 geometry.materials[ i ] = material;
30459
30460             }
30461
30462         }
30463
30464         // geometry
30465
30466         function isBitSet( value, position ) {
30467
30468             return value & ( 1 << position );
30469
30470         }
30471
30472         var faces = data.faces;
30473         var vertices = data.vertices;
30474         var normals = data.normals;
30475         var colors = data.colors;
30476         var nUvLayers = 0;
30477
30478         // disregard empty arrays
30479
30480         if ( data.uvs ) {
30481
30482             for ( var i = 0; i < data.uvs.length; i ++ ) {
30483
30484                 if ( data.uvs[ i ].length ) nUvLayers ++;
30485
30486             }
30487
30488         }
30489
30490         for ( var i = 0; i < nUvLayers; i ++ ) {
30491
30492             geometry.faceUvs[ i ] = [];
30493             geometry.faceVertexUvs[ i ] = [];
30494
30495         }
30496
30497         var offset = 0;
30498         var zLength = vertices.length;
30499
30500         while ( offset < zLength ) {
30501
30502             var vertex = new THREE.Vector3();
30503
30504             vertex.x = vertices[ offset ++ ] * scale;
30505             vertex.y = vertices[ offset ++ ] * scale;
30506             vertex.z = vertices[ offset ++ ] * scale;
30507
30508             geometry.vertices.push( vertex );
30509
30510         }
30511
30512         offset = 0;
30513         zLength = faces.length;
30514
30515         while ( offset < zLength ) {
30516
30517             var type = faces[ offset ++ ];
30518
30519             var isQuad = isBitSet( type, 0 );
30520
30521             var hasMaterial = isBitSet( type, 1 );
30522             var hasFaceUv = isBitSet( type, 2 );
30523             var hasFaceVertexUv = isBitSet( type, 3 );
30524             var hasFaceNormal = isBitSet( type, 4 );
30525             var hasFaceVertexNormal = isBitSet( type, 5 );
30526             var hasFaceColor = isBitSet( type, 6 );
30527             var hasFaceVertexColor = isBitSet( type, 7 );
30528
30529             // console.log("type", type, "bits", isQuad, hasMaterial, hasFaceUv, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
30530
30531             if ( isQuad ) {
30532
30533                 var face = new THREE.Face4();
30534
30535                 face.a = faces[ offset ++ ];
30536                 face.b = faces[ offset ++ ];
30537                 face.c = faces[ offset ++ ];
30538                 face.d = faces[ offset ++ ];
30539
30540                 var nVertices = 4;
30541
30542             } else {
30543
30544                 var face = new THREE.Face3();
30545
30546                 face.a = faces[ offset ++ ];
30547                 face.b = faces[ offset ++ ];
30548                 face.c = faces[ offset ++ ];
30549
30550                 var nVertices = 3;
30551
30552             }
30553
30554             if ( hasMaterial ) {
30555
30556                 var materialIndex = faces[ offset ++ ];
30557                 face.materialIndex = materialIndex;
30558
30559             }
30560
30561             // to get face <=> uv index correspondence
30562
30563             var fi = geometry.faces.length;
30564
30565             if ( hasFaceUv ) {
30566
30567                 for ( var i = 0; i < nUvLayers; i ++ ) {
30568
30569                     var uvLayer = data.uvs[ i ];
30570
30571                     var uvIndex = faces[ offset ++ ];
30572
30573                     var u = uvLayer[ uvIndex * 2 ];
30574                     var v = uvLayer[ uvIndex * 2 + 1 ];
30575
30576                     geometry.faceUvs[ i ][ fi ] = new THREE.UV( u, v );
30577
30578                 }
30579
30580             }
30581
30582             if ( hasFaceVertexUv ) {
30583
30584                 for ( var i = 0; i < nUvLayers; i ++ ) {
30585
30586                     var uvLayer = data.uvs[ i ];
30587
30588                     var uvs = [];
30589
30590                     for ( var j = 0; j < nVertices; j ++ ) {
30591
30592                         var uvIndex = faces[ offset ++ ];
30593
30594                         var u = uvLayer[ uvIndex * 2 ];
30595                         var v = uvLayer[ uvIndex * 2 + 1 ];
30596
30597                         uvs[ j ] = new THREE.UV( u, v );
30598
30599                     }
30600
30601                     geometry.faceVertexUvs[ i ][ fi ] = uvs;
30602
30603                 }
30604
30605             }
30606
30607             if ( hasFaceNormal ) {
30608
30609                 var normalIndex = faces[ offset ++ ] * 3;
30610
30611                 var normal = new THREE.Vector3();
30612
30613                 normal.x = normals[ normalIndex ++ ];
30614                 normal.y = normals[ normalIndex ++ ];
30615                 normal.z = normals[ normalIndex ];
30616
30617                 face.normal = normal;
30618
30619             }
30620
30621             if ( hasFaceVertexNormal ) {
30622
30623                 for ( i = 0; i < nVertices; i ++ ) {
30624
30625                     var normalIndex = faces[ offset ++ ] * 3;
30626
30627                     var normal = new THREE.Vector3();
30628
30629                     normal.x = normals[ normalIndex ++ ];
30630                     normal.y = normals[ normalIndex ++ ];
30631                     normal.z = normals[ normalIndex ];
30632
30633                     face.vertexNormals.push( normal );
30634
30635                 }
30636
30637             }
30638
30639
30640             if ( hasFaceColor ) {
30641
30642                 var colorIndex = faces[ offset ++ ];
30643
30644                 face.color = new THREE.Color( colors[ colorIndex ] );
30645
30646             }
30647
30648
30649             if ( hasFaceVertexColor ) {
30650
30651                 for ( var i = 0; i < nVertices; i ++ ) {
30652
30653                     var colorIndex = faces[ offset ++ ];
30654
30655                     face.vertexColors.push( new THREE.Color( colors[ colorIndex ] ) );
30656
30657                 }
30658
30659             }
30660
30661             geometry.faces.push( face );
30662
30663         }
30664
30665
30666         // skin
30667
30668         if ( data.skinWeights ) {
30669
30670             for ( var i = 0, l = data.skinWeights.length; i < l; i += 2 ) {
30671
30672                 var x = data.skinWeights[ i ];
30673                 var y = data.skinWeights[ i + 1 ];
30674                 var z = 0;
30675                 var w = 0;
30676
30677                 geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );
30678
30679             }
30680
30681         }
30682
30683         if ( data.skinIndices ) {
30684
30685             for ( var i = 0, l = data.skinIndices.length; i < l; i += 2 ) {
30686
30687                 var a = data.skinIndices[ i ];
30688                 var b = data.skinIndices[ i + 1 ];
30689                 var c = 0;
30690                 var d = 0;
30691
30692                 geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );
30693
30694             }
30695
30696         }
30697
30698         geometry.bones = data.bones;
30699         geometry.animation = data.animation;
30700
30701
30702         // morphing
30703
30704         if ( data.morphTargets ) {
30705
30706             for ( var i = 0, l = data.morphTargets.length; i < l; i ++ ) {
30707
30708                 geometry.morphTargets[ i ] = {};
30709                 geometry.morphTargets[ i ].name = data.morphTargets[ i ].name;
30710                 geometry.morphTargets[ i ].vertices = [];
30711
30712                 var dstVertices = geometry.morphTargets[ i ].vertices;
30713                 var srcVertices = data.morphTargets [ i ].vertices;
30714
30715                 for( var v = 0, vl = srcVertices.length; v < vl; v += 3 ) {
30716
30717                     var vertex = new THREE.Vector3();
30718                     vertex.x = srcVertices[ v ] * scale;
30719                     vertex.y = srcVertices[ v + 1 ] * scale;
30720                     vertex.z = srcVertices[ v + 2 ] * scale;
30721
30722                     dstVertices.push( vertex );
30723
30724                 }
30725
30726             }
30727
30728         }
30729
30730         if ( data.morphColors ) {
30731
30732             for ( var i = 0, l = data.morphColors.length; i < l; i++ ) {
30733
30734                 geometry.morphColors[ i ] = {};
30735                 geometry.morphColors[ i ].name = data.morphColors[ i ].name;
30736                 geometry.morphColors[ i ].colors = [];
30737
30738                 var dstColors = geometry.morphColors[ i ].colors;
30739                 var srcColors = data.morphColors [ i ].colors;
30740
30741                 for ( var c = 0, cl = srcColors.length; c < cl; c += 3 ) {
30742
30743                     var color = new THREE.Color( 0xffaa00 );
30744                     color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
30745
30746                     dstColors.push( color );
30747
30748                 }
30749
30750             }
30751
30752         }
30753
30754         geometry.computeCentroids();
30755         geometry.computeFaceNormals();
30756
30757         return geometry;
30758
30759     }
30760
30761 };
30762 /**
30763  * @author alteredq / http://alteredqualia.com/
30764  */
30765
30766 THREE.SceneLoader = function () {
30767
30768     this.onLoadStart = function () {};
30769     this.onLoadProgress = function() {};
30770     this.onLoadComplete = function () {};
30771
30772     this.callbackSync = function () {};
30773     this.callbackProgress = function () {};
30774
30775     this.geometryHandlerMap = {};
30776
30777     this.addGeometryHandler( "ascii", THREE.JSONLoader );
30778     this.addGeometryHandler( "binary", THREE.BinaryLoader );
30779
30780 };
30781
30782 THREE.SceneLoader.prototype.constructor = THREE.SceneLoader;
30783
30784 THREE.SceneLoader.prototype.load = function ( url, callbackFinished ) {
30785
30786     var scope = this;
30787
30788     var xhr = new XMLHttpRequest();
30789
30790     xhr.onreadystatechange = function () {
30791
30792         if ( xhr.readyState === 4 ) {
30793
30794             if ( xhr.status === 200 || xhr.status === 0 ) {
30795
30796                 var json = JSON.parse( xhr.responseText );
30797                 scope.parse( json, callbackFinished, url );
30798
30799             } else {
30800
30801                 console.error( "THREE.SceneLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
30802
30803             }
30804
30805         }
30806
30807     };
30808
30809     xhr.open( "GET", url, true );
30810     xhr.send( null );
30811
30812 };
30813
30814 THREE.SceneLoader.prototype.addGeometryHandler = function ( typeID, loaderClass ) {
30815
30816     this.geometryHandlerMap[ typeID ] = { "loaderClass": loaderClass };
30817
30818 };
30819
30820 THREE.SceneLoader.prototype.parse = function ( json, callbackFinished, url ) {
30821
30822     var scope = this;
30823
30824     var urlBase = THREE.Loader.prototype.extractUrlBase( url );
30825
30826     var dg, dm, dl, dc, df, dt,
30827         g, m, l, d, p, r, q, s, c, t, f, tt, pp, u,
30828         geometry, material, camera, fog,
30829         texture, images,
30830         light,
30831         counter_models, counter_textures,
30832         total_models, total_textures,
30833         result;
30834
30835     var data = json;
30836
30837     // async geometry loaders
30838
30839     for ( var typeID in this.geometryHandlerMap ) {
30840
30841         var loaderClass = this.geometryHandlerMap[ typeID ][ "loaderClass" ];
30842         this.geometryHandlerMap[ typeID ][ "loaderObject" ] = new loaderClass();
30843
30844     }
30845
30846     counter_models = 0;
30847     counter_textures = 0;
30848
30849     result = {
30850
30851         scene: new THREE.Scene(),
30852         geometries: {},
30853         materials: {},
30854         textures: {},
30855         objects: {},
30856         cameras: {},
30857         lights: {},
30858         fogs: {},
30859         empties: {}
30860
30861     };
30862
30863     if ( data.transform ) {
30864
30865         var position = data.transform.position,
30866             rotation = data.transform.rotation,
30867             scale = data.transform.scale;
30868
30869         if ( position )
30870             result.scene.position.set( position[ 0 ], position[ 1 ], position [ 2 ] );
30871
30872         if ( rotation )
30873             result.scene.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation [ 2 ] );
30874
30875         if ( scale )
30876             result.scene.scale.set( scale[ 0 ], scale[ 1 ], scale [ 2 ] );
30877
30878         if ( position || rotation || scale ) {
30879
30880             result.scene.updateMatrix();
30881             result.scene.updateMatrixWorld();
30882
30883         }
30884
30885     }
30886
30887     function get_url( source_url, url_type ) {
30888
30889         if ( url_type == "relativeToHTML" ) {
30890
30891             return source_url;
30892
30893         } else {
30894
30895             return urlBase + "/" + source_url;
30896
30897         }
30898
30899     };
30900
30901     // toplevel loader function, delegates to handle_children
30902
30903     function handle_objects() {
30904
30905         handle_children( result.scene, data.objects );
30906
30907     }
30908
30909     // handle all the children from the loaded json and attach them to given parent
30910
30911     function handle_children( parent, children ) {
30912
30913         for ( var dd in children ) {
30914
30915             // check by id if child has already been handled,
30916             // if not, create new object
30917
30918             if ( result.objects[ dd ] === undefined ) {
30919
30920                 var o = children[ dd ];
30921
30922                 var object = null;
30923
30924                 if ( o.geometry !== undefined ) {
30925
30926                     geometry = result.geometries[ o.geometry ];
30927
30928                     // geometry already loaded
30929
30930                     if ( geometry ) {
30931
30932                         var hasNormals = false;
30933
30934                         // not anymore support for multiple materials
30935                         // shouldn't really be array
30936
30937                         material = result.materials[ o.materials[ 0 ] ];
30938                         hasNormals = material instanceof THREE.ShaderMaterial;
30939
30940                         if ( hasNormals ) {
30941
30942                             geometry.computeTangents();
30943
30944                         }
30945
30946                         p = o.position;
30947                         r = o.rotation;
30948                         q = o.quaternion;
30949                         s = o.scale;
30950                         m = o.matrix;
30951
30952                         // turn off quaternions, for the moment
30953
30954                         q = 0;
30955
30956                         if ( o.materials.length === 0 ) {
30957
30958                             material = new THREE.MeshFaceMaterial();
30959
30960                         }
30961
30962                         // dirty hack to handle meshes with multiple materials
30963                         // just use face materials defined in model
30964
30965                         if ( o.materials.length > 1 ) {
30966
30967                             material = new THREE.MeshFaceMaterial();
30968
30969                         }
30970
30971                         if ( o.morph ) {
30972
30973                             object = new THREE.MorphAnimMesh( geometry, material );
30974
30975                             if ( o.duration !== undefined ) {
30976
30977                                 object.duration = o.duration;
30978
30979                             }
30980
30981                             if ( o.time !== undefined ) {
30982
30983                                 object.time = o.time;
30984
30985                             }
30986
30987                             if ( o.mirroredLoop !== undefined ) {
30988
30989                                 object.mirroredLoop = o.mirroredLoop;
30990
30991                             }
30992
30993                             if ( material.morphNormals ) {
30994
30995                                 geometry.computeMorphNormals();
30996
30997                             }
30998
30999                         } else {
31000
31001                             object = new THREE.Mesh( geometry, material );
31002
31003                         }
31004
31005                         object.name = dd;
31006
31007                         if ( m ) {
31008
31009                             object.matrixAutoUpdate = false;
31010                             object.matrix.set(
31011                                 m[0], m[1], m[2], m[3],
31012                                 m[4], m[5], m[6], m[7],
31013                                 m[8], m[9], m[10], m[11],
31014                                 m[12], m[13], m[14], m[15]
31015                             );
31016
31017                         } else {
31018
31019                             object.position.set( p[0], p[1], p[2] );
31020
31021                             if ( q ) {
31022
31023                                 object.quaternion.set( q[0], q[1], q[2], q[3] );
31024                                 object.useQuaternion = true;
31025
31026                             } else {
31027
31028                                 object.rotation.set( r[0], r[1], r[2] );
31029
31030                             }
31031
31032                             object.scale.set( s[0], s[1], s[2] );
31033
31034                         }
31035
31036                         object.visible = o.visible;
31037                         object.castShadow = o.castShadow;
31038                         object.receiveShadow = o.receiveShadow;
31039
31040                         parent.add( object );
31041
31042                         result.objects[ dd ] = object;
31043
31044                     }
31045
31046                 // pure Object3D
31047
31048                 } else {
31049
31050                     p = o.position;
31051                     r = o.rotation;
31052                     q = o.quaternion;
31053                     s = o.scale;
31054
31055                     // turn off quaternions, for the moment
31056
31057                     q = 0;
31058
31059                     object = new THREE.Object3D();
31060                     object.name = dd;
31061                     object.position.set( p[0], p[1], p[2] );
31062
31063                     if ( q ) {
31064
31065                         object.quaternion.set( q[0], q[1], q[2], q[3] );
31066                         object.useQuaternion = true;
31067
31068                     } else {
31069
31070                         object.rotation.set( r[0], r[1], r[2] );
31071
31072                     }
31073
31074                     object.scale.set( s[0], s[1], s[2] );
31075                     object.visible = ( o.visible !== undefined ) ? o.visible : false;
31076
31077                     parent.add( object );
31078
31079                     result.objects[ dd ] = object;
31080                     result.empties[ dd ] = object;
31081
31082                 }
31083
31084                 if ( object ) {
31085
31086                     if ( o.properties !== undefined )  {
31087
31088                         for ( var key in o.properties ) {
31089
31090                             var value = o.properties[ key ];
31091                             object.properties[ key ] = value;
31092
31093                         }
31094
31095                     }
31096
31097                     if ( o.children !== undefined ) {
31098
31099                         handle_children( object, o.children );
31100
31101                     }
31102
31103                 }
31104
31105             }
31106
31107         }
31108
31109     };
31110
31111     function handle_mesh( geo, id ) {
31112
31113         result.geometries[ id ] = geo;
31114         handle_objects();
31115
31116     };
31117
31118     function create_callback( id ) {
31119
31120         return function( geo ) {
31121
31122             handle_mesh( geo, id );
31123
31124             counter_models -= 1;
31125
31126             scope.onLoadComplete();
31127
31128             async_callback_gate();
31129
31130         }
31131
31132     };
31133
31134     function create_callback_embed( id ) {
31135
31136         return function( geo ) {
31137
31138             result.geometries[ id ] = geo;
31139
31140         }
31141
31142     };
31143
31144     function async_callback_gate() {
31145
31146         var progress = {
31147
31148             totalModels : total_models,
31149             totalTextures : total_textures,
31150             loadedModels : total_models - counter_models,
31151             loadedTextures : total_textures - counter_textures
31152
31153         };
31154
31155         scope.callbackProgress( progress, result );
31156
31157         scope.onLoadProgress();
31158
31159         if ( counter_models === 0 && counter_textures === 0 ) {
31160
31161             callbackFinished( result );
31162
31163         }
31164
31165     };
31166
31167     var callbackTexture = function ( count ) {
31168
31169         counter_textures -= count;
31170         async_callback_gate();
31171
31172         scope.onLoadComplete();
31173
31174     };
31175
31176     // must use this instead of just directly calling callbackTexture
31177     // because of closure in the calling context loop
31178
31179     var generateTextureCallback = function ( count ) {
31180
31181         return function() {
31182
31183             callbackTexture( count );
31184
31185         };
31186
31187     };
31188
31189     // first go synchronous elements
31190
31191     // cameras
31192
31193     for( dc in data.cameras ) {
31194
31195         c = data.cameras[ dc ];
31196
31197         if ( c.type === "perspective" ) {
31198
31199             camera = new THREE.PerspectiveCamera( c.fov, c.aspect, c.near, c.far );
31200
31201         } else if ( c.type === "ortho" ) {
31202
31203             camera = new THREE.OrthographicCamera( c.left, c.right, c.top, c.bottom, c.near, c.far );
31204
31205         }
31206
31207         p = c.position;
31208         t = c.target;
31209         u = c.up;
31210
31211         camera.position.set( p[0], p[1], p[2] );
31212         camera.target = new THREE.Vector3( t[0], t[1], t[2] );
31213         if ( u ) camera.up.set( u[0], u[1], u[2] );
31214
31215         result.cameras[ dc ] = camera;
31216
31217     }
31218
31219     // lights
31220
31221     var hex, intensity;
31222
31223     for ( dl in data.lights ) {
31224
31225         l = data.lights[ dl ];
31226
31227         hex = ( l.color !== undefined ) ? l.color : 0xffffff;
31228         intensity = ( l.intensity !== undefined ) ? l.intensity : 1;
31229
31230         if ( l.type === "directional" ) {
31231
31232             p = l.direction;
31233
31234             light = new THREE.DirectionalLight( hex, intensity );
31235             light.position.set( p[0], p[1], p[2] );
31236             light.position.normalize();
31237
31238         } else if ( l.type === "point" ) {
31239
31240             p = l.position;
31241             d = l.distance;
31242
31243             light = new THREE.PointLight( hex, intensity, d );
31244             light.position.set( p[0], p[1], p[2] );
31245
31246         } else if ( l.type === "ambient" ) {
31247
31248             light = new THREE.AmbientLight( hex );
31249
31250         }
31251
31252         result.scene.add( light );
31253
31254         result.lights[ dl ] = light;
31255
31256     }
31257
31258     // fogs
31259
31260     for( df in data.fogs ) {
31261
31262         f = data.fogs[ df ];
31263
31264         if ( f.type === "linear" ) {
31265
31266             fog = new THREE.Fog( 0x000000, f.near, f.far );
31267
31268         } else if ( f.type === "exp2" ) {
31269
31270             fog = new THREE.FogExp2( 0x000000, f.density );
31271
31272         }
31273
31274         c = f.color;
31275         fog.color.setRGB( c[0], c[1], c[2] );
31276
31277         result.fogs[ df ] = fog;
31278
31279     }
31280
31281     // defaults
31282
31283     if ( result.cameras && data.defaults && data.defaults.camera ) {
31284
31285         result.currentCamera = result.cameras[ data.defaults.camera ];
31286
31287     }
31288
31289     if ( result.fogs && data.defaults && data.defaults.fog ) {
31290
31291         result.scene.fog = result.fogs[ data.defaults.fog ];
31292
31293     }
31294
31295     c = data.defaults.bgcolor;
31296     result.bgColor = new THREE.Color();
31297     result.bgColor.setRGB( c[0], c[1], c[2] );
31298
31299     result.bgColorAlpha = data.defaults.bgalpha;
31300
31301     // now come potentially asynchronous elements
31302
31303     // geometries
31304
31305     // count how many models will be loaded asynchronously
31306
31307     for( dg in data.geometries ) {
31308
31309         g = data.geometries[ dg ];
31310
31311         if ( g.type in this.geometryHandlerMap ) {
31312
31313             counter_models += 1;
31314
31315             scope.onLoadStart();
31316
31317         }
31318
31319     }
31320
31321     total_models = counter_models;
31322
31323     for ( dg in data.geometries ) {
31324
31325         g = data.geometries[ dg ];
31326
31327         if ( g.type === "cube" ) {
31328
31329             geometry = new THREE.CubeGeometry( g.width, g.height, g.depth, g.segmentsWidth, g.segmentsHeight, g.segmentsDepth, null, g.flipped, g.sides );
31330             result.geometries[ dg ] = geometry;
31331
31332         } else if ( g.type === "plane" ) {
31333
31334             geometry = new THREE.PlaneGeometry( g.width, g.height, g.segmentsWidth, g.segmentsHeight );
31335             result.geometries[ dg ] = geometry;
31336
31337         } else if ( g.type === "sphere" ) {
31338
31339             geometry = new THREE.SphereGeometry( g.radius, g.segmentsWidth, g.segmentsHeight );
31340             result.geometries[ dg ] = geometry;
31341
31342         } else if ( g.type === "cylinder" ) {
31343
31344             geometry = new THREE.CylinderGeometry( g.topRad, g.botRad, g.height, g.radSegs, g.heightSegs );
31345             result.geometries[ dg ] = geometry;
31346
31347         } else if ( g.type === "torus" ) {
31348
31349             geometry = new THREE.TorusGeometry( g.radius, g.tube, g.segmentsR, g.segmentsT );
31350             result.geometries[ dg ] = geometry;
31351
31352         } else if ( g.type === "icosahedron" ) {
31353
31354             geometry = new THREE.IcosahedronGeometry( g.radius, g.subdivisions );
31355             result.geometries[ dg ] = geometry;
31356
31357         } else if ( g.type in this.geometryHandlerMap ) {
31358
31359             var loaderParameters = {};
31360             for ( var parType in g ) {
31361
31362                 if ( parType !== "type" && parType !== "url" ) {
31363
31364                     loaderParameters[ parType ] = g[ parType ];
31365
31366                 }
31367
31368             }
31369
31370             var loader = this.geometryHandlerMap[ g.type ][ "loaderObject" ];
31371             loader.load( get_url( g.url, data.urlBaseType ), create_callback( dg ), loaderParameters );
31372
31373         } else if ( g.type === "embedded" ) {
31374
31375             var modelJson = data.embeds[ g.id ],
31376                 texture_path = "";
31377
31378             // pass metadata along to jsonLoader so it knows the format version
31379
31380             modelJson.metadata = data.metadata;
31381
31382             if ( modelJson ) {
31383
31384                 var jsonLoader = this.geometryHandlerMap[ "ascii" ][ "loaderObject" ];
31385                 jsonLoader.createModel( modelJson, create_callback_embed( dg ), texture_path );
31386
31387             }
31388
31389         }
31390
31391     }
31392
31393     // textures
31394
31395     // count how many textures will be loaded asynchronously
31396
31397     for( dt in data.textures ) {
31398
31399         tt = data.textures[ dt ];
31400
31401         if( tt.url instanceof Array ) {
31402
31403             counter_textures += tt.url.length;
31404
31405             for( var n = 0; n < tt.url.length; n ++ ) {
31406
31407                 scope.onLoadStart();
31408
31409             }
31410
31411         } else {
31412
31413             counter_textures += 1;
31414
31415             scope.onLoadStart();
31416
31417         }
31418
31419     }
31420
31421     total_textures = counter_textures;
31422
31423     for ( dt in data.textures ) {
31424
31425         tt = data.textures[ dt ];
31426
31427         if ( tt.mapping !== undefined && THREE[ tt.mapping ] !== undefined  ) {
31428
31429             tt.mapping = new THREE[ tt.mapping ]();
31430
31431         }
31432
31433         if ( tt.url instanceof Array ) {
31434
31435             var count = tt.url.length;
31436             var url_array = [];
31437
31438             for( var i = 0; i < count; i ++ ) {
31439
31440                 url_array[ i ] = get_url( tt.url[ i ], data.urlBaseType );
31441
31442             }
31443
31444             var isCompressed = url_array[ 0 ].endsWith( ".dds" );
31445
31446             if ( isCompressed ) {
31447
31448                 texture = THREE.ImageUtils.loadCompressedTextureCube( url_array, tt.mapping, generateTextureCallback( count ) );
31449
31450             } else {
31451
31452                 texture = THREE.ImageUtils.loadTextureCube( url_array, tt.mapping, generateTextureCallback( count ) );
31453
31454             }
31455
31456         } else {
31457
31458             var isCompressed = tt.url.toLowerCase().endsWith( ".dds" );
31459             var fullUrl = get_url( tt.url, data.urlBaseType );
31460             var textureCallback = generateTextureCallback( 1 );
31461
31462             if ( isCompressed ) {
31463
31464                 texture = THREE.ImageUtils.loadCompressedTexture( fullUrl, tt.mapping, textureCallback );
31465
31466             } else {
31467
31468                 texture = THREE.ImageUtils.loadTexture( fullUrl, tt.mapping, textureCallback );
31469
31470             }
31471
31472             if ( THREE[ tt.minFilter ] !== undefined )
31473                 texture.minFilter = THREE[ tt.minFilter ];
31474
31475             if ( THREE[ tt.magFilter ] !== undefined )
31476                 texture.magFilter = THREE[ tt.magFilter ];
31477
31478             if ( tt.anisotropy ) texture.anisotropy = tt.anisotropy;
31479
31480             if ( tt.repeat ) {
31481
31482                 texture.repeat.set( tt.repeat[ 0 ], tt.repeat[ 1 ] );
31483
31484                 if ( tt.repeat[ 0 ] !== 1 ) texture.wrapS = THREE.RepeatWrapping;
31485                 if ( tt.repeat[ 1 ] !== 1 ) texture.wrapT = THREE.RepeatWrapping;
31486
31487             }
31488
31489             if ( tt.offset ) {
31490
31491                 texture.offset.set( tt.offset[ 0 ], tt.offset[ 1 ] );
31492
31493             }
31494
31495             // handle wrap after repeat so that default repeat can be overriden
31496
31497             if ( tt.wrap ) {
31498
31499                 var wrapMap = {
31500                 "repeat"     : THREE.RepeatWrapping,
31501                 "mirror"    : THREE.MirroredRepeatWrapping
31502                 }
31503
31504                 if ( wrapMap[ tt.wrap[ 0 ] ] !== undefined ) texture.wrapS = wrapMap[ tt.wrap[ 0 ] ];
31505                 if ( wrapMap[ tt.wrap[ 1 ] ] !== undefined ) texture.wrapT = wrapMap[ tt.wrap[ 1 ] ];
31506
31507             }
31508
31509         }
31510
31511         result.textures[ dt ] = texture;
31512
31513     }
31514
31515     // materials
31516
31517     for ( dm in data.materials ) {
31518
31519         m = data.materials[ dm ];
31520
31521         for ( pp in m.parameters ) {
31522
31523             if ( pp === "envMap" || pp === "map" || pp === "lightMap" || pp === "bumpMap" ) {
31524
31525                 m.parameters[ pp ] = result.textures[ m.parameters[ pp ] ];
31526
31527             } else if ( pp === "shading" ) {
31528
31529                 m.parameters[ pp ] = ( m.parameters[ pp ] === "flat" ) ? THREE.FlatShading : THREE.SmoothShading;
31530
31531             } else if ( pp === "side" ) {
31532
31533                 if (  m.parameters[ pp ] == "double" ) {
31534
31535                     m.parameters[ pp ] = THREE.DoubleSide;
31536
31537                 } else if ( m.parameters[ pp ] == "back" ) {
31538
31539                     m.parameters[ pp ] = THREE.BackSide;
31540
31541                 } else {
31542
31543                     m.parameters[ pp ] = THREE.FrontSide;
31544
31545                 }
31546
31547             } else if ( pp === "blending" ) {
31548
31549                 m.parameters[ pp ] = m.parameters[ pp ] in THREE ? THREE[ m.parameters[ pp ] ] : THREE.NormalBlending;
31550
31551             } else if ( pp === "combine" ) {
31552
31553                 m.parameters[ pp ] = ( m.parameters[ pp ] == "MixOperation" ) ? THREE.MixOperation : THREE.MultiplyOperation;
31554
31555             } else if ( pp === "vertexColors" ) {
31556
31557                 if ( m.parameters[ pp ] == "face" ) {
31558
31559                     m.parameters[ pp ] = THREE.FaceColors;
31560
31561                 // default to vertex colors if "vertexColors" is anything else face colors or 0 / null / false
31562
31563                 } else if ( m.parameters[ pp ] )   {
31564
31565                     m.parameters[ pp ] = THREE.VertexColors;
31566
31567                 }
31568
31569             } else if ( pp === "wrapRGB" ) {
31570
31571                 var v3 = m.parameters[ pp ];
31572                 m.parameters[ pp ] = new THREE.Vector3( v3[ 0 ], v3[ 1 ], v3[ 2 ] );
31573
31574             }
31575
31576         }
31577
31578         if ( m.parameters.opacity !== undefined && m.parameters.opacity < 1.0 ) {
31579
31580             m.parameters.transparent = true;
31581
31582         }
31583
31584         if ( m.parameters.normalMap ) {
31585
31586             var shader = THREE.ShaderUtils.lib[ "normal" ];
31587             var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
31588
31589             var diffuse = m.parameters.color;
31590             var specular = m.parameters.specular;
31591             var ambient = m.parameters.ambient;
31592             var shininess = m.parameters.shininess;
31593
31594             uniforms[ "tNormal" ].value = result.textures[ m.parameters.normalMap ];
31595
31596             if ( m.parameters.normalScale ) {
31597
31598                 uniforms[ "uNormalScale" ].value.set( m.parameters.normalScale[ 0 ], m.parameters.normalScale[ 1 ] );
31599
31600             }
31601
31602             if ( m.parameters.map ) {
31603
31604                 uniforms[ "tDiffuse" ].value = m.parameters.map;
31605                 uniforms[ "enableDiffuse" ].value = true;
31606
31607             }
31608
31609             if ( m.parameters.envMap ) {
31610
31611                 uniforms[ "tCube" ].value = m.parameters.envMap;
31612                 uniforms[ "enableReflection" ].value = true;
31613                 uniforms[ "uReflectivity" ].value = m.parameters.reflectivity;
31614
31615             }
31616
31617             if ( m.parameters.lightMap ) {
31618
31619                 uniforms[ "tAO" ].value = m.parameters.lightMap;
31620                 uniforms[ "enableAO" ].value = true;
31621
31622             }
31623
31624             if ( m.parameters.specularMap ) {
31625
31626                 uniforms[ "tSpecular" ].value = result.textures[ m.parameters.specularMap ];
31627                 uniforms[ "enableSpecular" ].value = true;
31628
31629             }
31630
31631             if ( m.parameters.displacementMap ) {
31632
31633                 uniforms[ "tDisplacement" ].value = result.textures[ m.parameters.displacementMap ];
31634                 uniforms[ "enableDisplacement" ].value = true;
31635
31636                 uniforms[ "uDisplacementBias" ].value = m.parameters.displacementBias;
31637                 uniforms[ "uDisplacementScale" ].value = m.parameters.displacementScale;
31638
31639             }
31640
31641             uniforms[ "uDiffuseColor" ].value.setHex( diffuse );
31642             uniforms[ "uSpecularColor" ].value.setHex( specular );
31643             uniforms[ "uAmbientColor" ].value.setHex( ambient );
31644
31645             uniforms[ "uShininess" ].value = shininess;
31646
31647             if ( m.parameters.opacity ) {
31648
31649                 uniforms[ "uOpacity" ].value = m.parameters.opacity;
31650
31651             }
31652
31653             var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true, fog: true };
31654
31655             material = new THREE.ShaderMaterial( parameters );
31656
31657         } else {
31658
31659             material = new THREE[ m.type ]( m.parameters );
31660
31661         }
31662
31663         result.materials[ dm ] = material;
31664
31665     }
31666
31667     // objects ( synchronous init of procedural primitives )
31668
31669     handle_objects();
31670
31671     // synchronous callback
31672
31673     scope.callbackSync( result );
31674
31675     // just in case there are no async elements
31676
31677     async_callback_gate();
31678
31679 };
31680 /**
31681  * @author mrdoob / http://mrdoob.com/
31682  */
31683
31684 THREE.TextureLoader = function () {
31685
31686     THREE.EventTarget.call( this );
31687
31688     this.crossOrigin = null;
31689
31690 };
31691
31692 THREE.TextureLoader.prototype = {
31693
31694     constructor: THREE.TextureLoader,
31695
31696     load: function ( url ) {
31697
31698         var scope = this;
31699
31700         var image = new Image();
31701
31702         image.addEventListener( 'load', function () {
31703
31704             var texture = new THREE.Texture( image );
31705             texture.needsUpdate = true;
31706
31707             scope.dispatchEvent( { type: 'load', content: texture } );
31708
31709         }, false );
31710
31711         image.addEventListener( 'error', function () {
31712
31713             scope.dispatchEvent( { type: 'error', message: 'Couldn\'t load URL [' + url + ']' } );
31714
31715         }, false );
31716
31717         if ( scope.crossOrigin ) image.crossOrigin = scope.crossOrigin;
31718
31719         image.src = url;
31720
31721     }
31722
31723 }
31724 /**
31725  * @author mrdoob / http://mrdoob.com/
31726  * @author alteredq / http://alteredqualia.com/
31727  */
31728
31729 THREE.Material = function () {
31730
31731     this.id = THREE.MaterialCount ++;
31732
31733     this.name = '';
31734
31735     this.side = THREE.FrontSide;
31736
31737     this.opacity = 1;
31738     this.transparent = false;
31739
31740     this.blending = THREE.NormalBlending;
31741
31742     this.blendSrc = THREE.SrcAlphaFactor;
31743     this.blendDst = THREE.OneMinusSrcAlphaFactor;
31744     this.blendEquation = THREE.AddEquation;
31745
31746     this.depthTest = true;
31747     this.depthWrite = true;
31748
31749     this.polygonOffset = false;
31750     this.polygonOffsetFactor = 0;
31751     this.polygonOffsetUnits = 0;
31752
31753     this.alphaTest = 0;
31754
31755     this.overdraw = false; // Boolean for fixing antialiasing gaps in CanvasRenderer
31756
31757     this.visible = true;
31758
31759     this.needsUpdate = true;
31760
31761 };
31762
31763 THREE.Material.prototype.setValues = function ( values ) {
31764
31765     if ( values === undefined ) return;
31766
31767     for ( var key in values ) {
31768
31769         var newValue = values[ key ];
31770
31771         if ( newValue === undefined ) {
31772
31773             console.warn( 'THREE.Material: \'' + key + '\' parameter is undefined.' );
31774             continue;
31775
31776         }
31777
31778         if ( key in this ) {
31779
31780             var currentValue = this[ key ];
31781
31782             if ( currentValue instanceof THREE.Color && newValue instanceof THREE.Color ) {
31783
31784                 currentValue.copy( newValue );
31785
31786             } else if ( currentValue instanceof THREE.Color && typeof( newValue ) === "number" ) {
31787
31788                 currentValue.setHex( newValue );
31789
31790             } else if ( currentValue instanceof THREE.Vector3 && newValue instanceof THREE.Vector3 ) {
31791
31792                 currentValue.copy( newValue );
31793
31794             } else {
31795
31796                 this[ key ] = newValue;
31797
31798             }
31799
31800         }
31801
31802     }
31803
31804 };
31805
31806 THREE.Material.prototype.clone = function ( material ) {
31807
31808     if ( material === undefined ) material = new THREE.Material();
31809
31810     material.name = this.name;
31811
31812     material.side = this.side;
31813
31814     material.opacity = this.opacity;
31815     material.transparent = this.transparent;
31816
31817     material.blending = this.blending;
31818
31819     material.blendSrc = this.blendSrc;
31820     material.blendDst = this.blendDst;
31821     material.blendEquation = this.blendEquation;
31822
31823     material.depthTest = this.depthTest;
31824     material.depthWrite = this.depthWrite;
31825
31826     material.polygonOffset = this.polygonOffset;
31827     material.polygonOffsetFactor = this.polygonOffsetFactor;
31828     material.polygonOffsetUnits = this.polygonOffsetUnits;
31829
31830     material.alphaTest = this.alphaTest;
31831
31832     material.overdraw = this.overdraw;
31833
31834     material.visible = this.visible;
31835
31836     return material;
31837
31838 };
31839
31840 THREE.MaterialCount = 0;
31841 /**
31842  * @author mrdoob / http://mrdoob.com/
31843  * @author alteredq / http://alteredqualia.com/
31844  *
31845  * parameters = {
31846  *  color: <hex>,
31847  *  opacity: <float>,
31848  *
31849  *  blending: THREE.NormalBlending,
31850  *  depthTest: <bool>,
31851  *
31852  *  linewidth: <float>,
31853  *  linecap: "round",
31854  *  linejoin: "round",
31855  *
31856  *  vertexColors: <bool>
31857  *
31858  *  fog: <bool>
31859  * }
31860  */
31861
31862 THREE.LineBasicMaterial = function ( parameters ) {
31863
31864     THREE.Material.call( this );
31865
31866     this.color = new THREE.Color( 0xffffff );
31867
31868     this.linewidth = 1;
31869     this.linecap = 'round';
31870     this.linejoin = 'round';
31871
31872     this.vertexColors = false;
31873
31874     this.fog = true;
31875
31876     this.setValues( parameters );
31877
31878 };
31879
31880 THREE.LineBasicMaterial.prototype = Object.create( THREE.Material.prototype );
31881
31882 THREE.LineBasicMaterial.prototype.clone = function () {
31883
31884     var material = new THREE.LineBasicMaterial();
31885
31886     THREE.Material.prototype.clone.call( this, material );
31887
31888     material.color.copy( this.color );
31889
31890     material.linewidth = this.linewidth;
31891     material.linecap = this.linecap;
31892     material.linejoin = this.linejoin;
31893
31894     material.vertexColors = this.vertexColors;
31895
31896     material.fog = this.fog;
31897
31898     return material;
31899
31900 };
31901 /**
31902  * @author mrdoob / http://mrdoob.com/
31903  * @author alteredq / http://alteredqualia.com/
31904  *
31905  * parameters = {
31906  *  color: <hex>,
31907  *  opacity: <float>,
31908  *  map: new THREE.Texture( <Image> ),
31909  *
31910  *  lightMap: new THREE.Texture( <Image> ),
31911  *
31912  *  specularMap: new THREE.Texture( <Image> ),
31913  *
31914  *  envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
31915  *  combine: THREE.Multiply,
31916  *  reflectivity: <float>,
31917  *  refractionRatio: <float>,
31918  *
31919  *  shading: THREE.SmoothShading,
31920  *  blending: THREE.NormalBlending,
31921  *  depthTest: <bool>,
31922  *
31923  *  wireframe: <boolean>,
31924  *  wireframeLinewidth: <float>,
31925  *
31926  *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
31927  *
31928  *  skinning: <bool>,
31929  *  morphTargets: <bool>,
31930  *
31931  *  fog: <bool>
31932  * }
31933  */
31934
31935 THREE.MeshBasicMaterial = function ( parameters ) {
31936
31937     THREE.Material.call( this );
31938
31939     this.color = new THREE.Color( 0xffffff ); // emissive
31940
31941     this.map = null;
31942
31943     this.lightMap = null;
31944
31945     this.specularMap = null;
31946
31947     this.envMap = null;
31948     this.combine = THREE.MultiplyOperation;
31949     this.reflectivity = 1;
31950     this.refractionRatio = 0.98;
31951
31952     this.fog = true;
31953
31954     this.shading = THREE.SmoothShading;
31955
31956     this.wireframe = false;
31957     this.wireframeLinewidth = 1;
31958     this.wireframeLinecap = 'round';
31959     this.wireframeLinejoin = 'round';
31960
31961     this.vertexColors = THREE.NoColors;
31962
31963     this.skinning = false;
31964     this.morphTargets = false;
31965
31966     this.setValues( parameters );
31967
31968 };
31969
31970 THREE.MeshBasicMaterial.prototype = Object.create( THREE.Material.prototype );
31971
31972 THREE.MeshBasicMaterial.prototype.clone = function () {
31973
31974     var material = new THREE.MeshBasicMaterial();
31975
31976     THREE.Material.prototype.clone.call( this, material );
31977
31978     material.color.copy( this.color );
31979
31980     material.map = this.map;
31981
31982     material.lightMap = this.lightMap;
31983
31984     material.specularMap = this.specularMap;
31985
31986     material.envMap = this.envMap;
31987     material.combine = this.combine;
31988     material.reflectivity = this.reflectivity;
31989     material.refractionRatio = this.refractionRatio;
31990
31991     material.fog = this.fog;
31992
31993     material.shading = this.shading;
31994
31995     material.wireframe = this.wireframe;
31996     material.wireframeLinewidth = this.wireframeLinewidth;
31997     material.wireframeLinecap = this.wireframeLinecap;
31998     material.wireframeLinejoin = this.wireframeLinejoin;
31999
32000     material.vertexColors = this.vertexColors;
32001
32002     material.skinning = this.skinning;
32003     material.morphTargets = this.morphTargets;
32004
32005     return material;
32006
32007 };
32008 /**
32009  * @author mrdoob / http://mrdoob.com/
32010  * @author alteredq / http://alteredqualia.com/
32011  *
32012  * parameters = {
32013  *  color: <hex>,
32014  *  ambient: <hex>,
32015  *  emissive: <hex>,
32016  *  opacity: <float>,
32017  *
32018  *  map: new THREE.Texture( <Image> ),
32019  *
32020  *  lightMap: new THREE.Texture( <Image> ),
32021  *
32022  *  specularMap: new THREE.Texture( <Image> ),
32023  *
32024  *  envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
32025  *  combine: THREE.Multiply,
32026  *  reflectivity: <float>,
32027  *  refractionRatio: <float>,
32028  *
32029  *  shading: THREE.SmoothShading,
32030  *  blending: THREE.NormalBlending,
32031  *  depthTest: <bool>,
32032  *
32033  *  wireframe: <boolean>,
32034  *  wireframeLinewidth: <float>,
32035  *
32036  *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
32037  *
32038  *  skinning: <bool>,
32039  *  morphTargets: <bool>,
32040  *  morphNormals: <bool>,
32041  *
32042  *    fog: <bool>
32043  * }
32044  */
32045
32046 THREE.MeshLambertMaterial = function ( parameters ) {
32047
32048     THREE.Material.call( this );
32049
32050     this.color = new THREE.Color( 0xffffff ); // diffuse
32051     this.ambient = new THREE.Color( 0xffffff );
32052     this.emissive = new THREE.Color( 0x000000 );
32053
32054     this.wrapAround = false;
32055     this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
32056
32057     this.map = null;
32058
32059     this.lightMap = null;
32060
32061     this.specularMap = null;
32062
32063     this.envMap = null;
32064     this.combine = THREE.MultiplyOperation;
32065     this.reflectivity = 1;
32066     this.refractionRatio = 0.98;
32067
32068     this.fog = true;
32069
32070     this.shading = THREE.SmoothShading;
32071
32072     this.wireframe = false;
32073     this.wireframeLinewidth = 1;
32074     this.wireframeLinecap = 'round';
32075     this.wireframeLinejoin = 'round';
32076
32077     this.vertexColors = THREE.NoColors;
32078
32079     this.skinning = false;
32080     this.morphTargets = false;
32081     this.morphNormals = false;
32082
32083     this.setValues( parameters );
32084
32085 };
32086
32087 THREE.MeshLambertMaterial.prototype = Object.create( THREE.Material.prototype );
32088
32089 THREE.MeshLambertMaterial.prototype.clone = function () {
32090
32091     var material = new THREE.MeshLambertMaterial();
32092
32093     THREE.Material.prototype.clone.call( this, material );
32094
32095     material.color.copy( this.color );
32096     material.ambient.copy( this.ambient );
32097     material.emissive.copy( this.emissive );
32098
32099     material.wrapAround = this.wrapAround;
32100     material.wrapRGB.copy( this.wrapRGB );
32101
32102     material.map = this.map;
32103
32104     material.lightMap = this.lightMap;
32105
32106     material.specularMap = this.specularMap;
32107
32108     material.envMap = this.envMap;
32109     material.combine = this.combine;
32110     material.reflectivity = this.reflectivity;
32111     material.refractionRatio = this.refractionRatio;
32112
32113     material.fog = this.fog;
32114
32115     material.shading = this.shading;
32116
32117     material.wireframe = this.wireframe;
32118     material.wireframeLinewidth = this.wireframeLinewidth;
32119     material.wireframeLinecap = this.wireframeLinecap;
32120     material.wireframeLinejoin = this.wireframeLinejoin;
32121
32122     material.vertexColors = this.vertexColors;
32123
32124     material.skinning = this.skinning;
32125     material.morphTargets = this.morphTargets;
32126     material.morphNormals = this.morphNormals;
32127
32128     return material;
32129
32130 };
32131 /**
32132  * @author mrdoob / http://mrdoob.com/
32133  * @author alteredq / http://alteredqualia.com/
32134  *
32135  * parameters = {
32136  *  color: <hex>,
32137  *  ambient: <hex>,
32138  *  emissive: <hex>,
32139  *  specular: <hex>,
32140  *  shininess: <float>,
32141  *  opacity: <float>,
32142  *
32143  *  map: new THREE.Texture( <Image> ),
32144  *
32145  *  lightMap: new THREE.Texture( <Image> ),
32146  *
32147  *  bumpMap: new THREE.Texture( <Image> ),
32148  *  bumpScale: <float>,
32149  *
32150  *  normalMap: new THREE.Texture( <Image> ),
32151  *  normalScale: <Vector2>,
32152  *
32153  *  specularMap: new THREE.Texture( <Image> ),
32154  *
32155  *  envMap: new THREE.TextureCube( [posx, negx, posy, negy, posz, negz] ),
32156  *  combine: THREE.Multiply,
32157  *  reflectivity: <float>,
32158  *  refractionRatio: <float>,
32159  *
32160  *  shading: THREE.SmoothShading,
32161  *  blending: THREE.NormalBlending,
32162  *  depthTest: <bool>,
32163  *
32164  *  wireframe: <boolean>,
32165  *  wireframeLinewidth: <float>,
32166  *
32167  *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
32168  *
32169  *  skinning: <bool>,
32170  *  morphTargets: <bool>,
32171  *  morphNormals: <bool>,
32172  *
32173  *    fog: <bool>
32174  * }
32175  */
32176
32177 THREE.MeshPhongMaterial = function ( parameters ) {
32178
32179     THREE.Material.call( this );
32180
32181     this.color = new THREE.Color( 0xffffff ); // diffuse
32182     this.ambient = new THREE.Color( 0xffffff );
32183     this.emissive = new THREE.Color( 0x000000 );
32184     this.specular = new THREE.Color( 0x111111 );
32185     this.shininess = 30;
32186
32187     this.metal = false;
32188     this.perPixel = false;
32189
32190     this.wrapAround = false;
32191     this.wrapRGB = new THREE.Vector3( 1, 1, 1 );
32192
32193     this.map = null;
32194
32195     this.lightMap = null;
32196
32197     this.bumpMap = null;
32198     this.bumpScale = 1;
32199
32200     this.normalMap = null;
32201     this.normalScale = new THREE.Vector2( 1, 1 );
32202
32203     this.specularMap = null;
32204
32205     this.envMap = null;
32206     this.combine = THREE.MultiplyOperation;
32207     this.reflectivity = 1;
32208     this.refractionRatio = 0.98;
32209
32210     this.fog = true;
32211
32212     this.shading = THREE.SmoothShading;
32213
32214     this.wireframe = false;
32215     this.wireframeLinewidth = 1;
32216     this.wireframeLinecap = 'round';
32217     this.wireframeLinejoin = 'round';
32218
32219     this.vertexColors = THREE.NoColors;
32220
32221     this.skinning = false;
32222     this.morphTargets = false;
32223     this.morphNormals = false;
32224
32225     this.setValues( parameters );
32226
32227 };
32228
32229 THREE.MeshPhongMaterial.prototype = Object.create( THREE.Material.prototype );
32230
32231 THREE.MeshPhongMaterial.prototype.clone = function () {
32232
32233     var material = new THREE.MeshPhongMaterial();
32234
32235     THREE.Material.prototype.clone.call( this, material );
32236
32237     material.color.copy( this.color );
32238     material.ambient.copy( this.ambient );
32239     material.emissive.copy( this.emissive );
32240     material.specular.copy( this.specular );
32241     material.shininess = this.shininess;
32242
32243     material.metal = this.metal;
32244     material.perPixel = this.perPixel;
32245
32246     material.wrapAround = this.wrapAround;
32247     material.wrapRGB.copy( this.wrapRGB );
32248
32249     material.map = this.map;
32250
32251     material.lightMap = this.lightMap;
32252
32253     material.bumpMap = this.bumpMap;
32254     material.bumpScale = this.bumpScale;
32255
32256     material.normalMap = this.normalMap;
32257     material.normalScale.copy( this.normalScale );
32258
32259     material.specularMap = this.specularMap;
32260
32261     material.envMap = this.envMap;
32262     material.combine = this.combine;
32263     material.reflectivity = this.reflectivity;
32264     material.refractionRatio = this.refractionRatio;
32265
32266     material.fog = this.fog;
32267
32268     material.shading = this.shading;
32269
32270     material.wireframe = this.wireframe;
32271     material.wireframeLinewidth = this.wireframeLinewidth;
32272     material.wireframeLinecap = this.wireframeLinecap;
32273     material.wireframeLinejoin = this.wireframeLinejoin;
32274
32275     material.vertexColors = this.vertexColors;
32276
32277     material.skinning = this.skinning;
32278     material.morphTargets = this.morphTargets;
32279     material.morphNormals = this.morphNormals;
32280
32281     return material;
32282
32283 };
32284 /**
32285  * @author mrdoob / http://mrdoob.com/
32286  * @author alteredq / http://alteredqualia.com/
32287  *
32288  * parameters = {
32289  *  opacity: <float>,
32290
32291  *  blending: THREE.NormalBlending,
32292  *  depthTest: <bool>,
32293
32294  *  wireframe: <boolean>,
32295  *  wireframeLinewidth: <float>
32296  * }
32297  */
32298
32299 THREE.MeshDepthMaterial = function ( parameters ) {
32300
32301     THREE.Material.call( this );
32302
32303     this.wireframe = false;
32304     this.wireframeLinewidth = 1;
32305
32306     this.setValues( parameters );
32307
32308 };
32309
32310 THREE.MeshDepthMaterial.prototype = Object.create( THREE.Material.prototype );
32311
32312 THREE.MeshDepthMaterial.prototype.clone = function () {
32313
32314     var material = new THREE.LineBasicMaterial();
32315
32316     THREE.Material.prototype.clone.call( this, material );
32317
32318     material.wireframe = this.wireframe;
32319     material.wireframeLinewidth = this.wireframeLinewidth;
32320
32321     return material;
32322
32323 };
32324 /**
32325  * @author mrdoob / http://mrdoob.com/
32326  *
32327  * parameters = {
32328  *  opacity: <float>,
32329
32330  *  shading: THREE.FlatShading,
32331  *  blending: THREE.NormalBlending,
32332  *  depthTest: <bool>,
32333
32334  *  wireframe: <boolean>,
32335  *  wireframeLinewidth: <float>
32336  * }
32337  */
32338
32339 THREE.MeshNormalMaterial = function ( parameters ) {
32340
32341     THREE.Material.call( this, parameters );
32342
32343     this.shading = THREE.FlatShading;
32344
32345     this.wireframe = false;
32346     this.wireframeLinewidth = 1;
32347
32348     this.setValues( parameters );
32349
32350 };
32351
32352 THREE.MeshNormalMaterial.prototype = Object.create( THREE.Material.prototype );
32353
32354 THREE.MeshNormalMaterial.prototype.clone = function () {
32355
32356     var material = new THREE.MeshNormalMaterial();
32357
32358     THREE.Material.prototype.clone.call( this, material );
32359
32360     material.shading = this.shading;
32361
32362     material.wireframe = this.wireframe;
32363     material.wireframeLinewidth = this.wireframeLinewidth;
32364
32365     return material;
32366
32367 };
32368 /**
32369  * @author mrdoob / http://mrdoob.com/
32370  */
32371
32372 THREE.MeshFaceMaterial = function () {};
32373
32374 THREE.MeshFaceMaterial.prototype.clone = function () {
32375
32376     return new THREE.MeshFaceMaterial();
32377
32378 };
32379 /**
32380  * @author mrdoob / http://mrdoob.com/
32381  * @author alteredq / http://alteredqualia.com/
32382  *
32383  * parameters = {
32384  *  color: <hex>,
32385  *  opacity: <float>,
32386  *  map: new THREE.Texture( <Image> ),
32387  *
32388  *  size: <float>,
32389  *
32390  *  blending: THREE.NormalBlending,
32391  *  depthTest: <bool>,
32392  *
32393  *  vertexColors: <bool>,
32394  *
32395  *  fog: <bool>
32396  * }
32397  */
32398
32399 THREE.ParticleBasicMaterial = function ( parameters ) {
32400
32401     THREE.Material.call( this );
32402
32403     this.color = new THREE.Color( 0xffffff );
32404
32405     this.map = null;
32406
32407     this.size = 1;
32408     this.sizeAttenuation = true;
32409
32410     this.vertexColors = false;
32411
32412     this.fog = true;
32413
32414     this.setValues( parameters );
32415
32416 };
32417
32418 THREE.ParticleBasicMaterial.prototype = Object.create( THREE.Material.prototype );
32419
32420 THREE.ParticleBasicMaterial.prototype.clone = function () {
32421
32422     var material = new THREE.ParticleBasicMaterial();
32423
32424     THREE.Material.prototype.clone.call( this, material );
32425
32426     material.color.copy( this.color );
32427
32428     material.map = this.map;
32429
32430     material.size = this.size;
32431     material.sizeAttenuation = this.sizeAttenuation;
32432
32433     material.vertexColors = this.vertexColors;
32434
32435     material.fog = this.fog;
32436
32437     return material;
32438
32439 };
32440 /**
32441  * @author mrdoob / http://mrdoob.com/
32442  *
32443  * parameters = {
32444  *  color: <hex>,
32445  *  program: <function>,
32446  *  opacity: <float>,
32447  *  blending: THREE.NormalBlending
32448  * }
32449  */
32450
32451 THREE.ParticleCanvasMaterial = function ( parameters ) {
32452
32453     THREE.Material.call( this );
32454
32455     this.color = new THREE.Color( 0xffffff );
32456     this.program = function ( context, color ) {};
32457
32458     this.setValues( parameters );
32459
32460 };
32461
32462 THREE.ParticleCanvasMaterial.prototype = Object.create( THREE.Material.prototype );
32463
32464 THREE.ParticleCanvasMaterial.prototype.clone = function () {
32465
32466     var material = new THREE.ParticleCanvasMaterial();
32467
32468     THREE.Material.prototype.clone.call( this, material );
32469
32470     material.color.copy( this.color );
32471     material.program = this.program;
32472
32473     return material;
32474
32475 };
32476 /**
32477  * @author mrdoob / http://mrdoob.com/
32478  */
32479
32480 THREE.ParticleDOMMaterial = function ( element ) {
32481
32482     this.element = element;
32483
32484 };
32485
32486 THREE.ParticleDOMMaterial.prototype.clone = function(){
32487
32488     return new THREE.ParticleDOMMaterial( this.element );
32489
32490 };
32491 /**
32492  * @author alteredq / http://alteredqualia.com/
32493  *
32494  * parameters = {
32495  *  fragmentShader: <string>,
32496  *  vertexShader: <string>,
32497  *
32498  *  uniforms: { "parameter1": { type: "f", value: 1.0 }, "parameter2": { type: "i" value2: 2 } },
32499  *
32500  *  shading: THREE.SmoothShading,
32501  *  blending: THREE.NormalBlending,
32502  *  depthTest: <bool>,
32503  *
32504  *  wireframe: <boolean>,
32505  *  wireframeLinewidth: <float>,
32506  *
32507  *  lights: <bool>,
32508  *
32509  *  vertexColors: THREE.NoColors / THREE.VertexColors / THREE.FaceColors,
32510  *
32511  *  skinning: <bool>,
32512  *  morphTargets: <bool>,
32513  *  morphNormals: <bool>,
32514  *
32515  *    fog: <bool>
32516  * }
32517  */
32518
32519 THREE.ShaderMaterial = function ( parameters ) {
32520
32521     THREE.Material.call( this );
32522
32523     this.fragmentShader = "void main() {}";
32524     this.vertexShader = "void main() {}";
32525     this.uniforms = {};
32526     this.attributes = null;
32527
32528     this.shading = THREE.SmoothShading;
32529
32530     this.wireframe = false;
32531     this.wireframeLinewidth = 1;
32532
32533     this.fog = false; // set to use scene fog
32534
32535     this.lights = false; // set to use scene lights
32536
32537     this.vertexColors = THREE.NoColors; // set to use "color" attribute stream
32538
32539     this.skinning = false; // set to use skinning attribute streams
32540
32541     this.morphTargets = false; // set to use morph targets
32542     this.morphNormals = false; // set to use morph normals
32543
32544     this.setValues( parameters );
32545
32546 };
32547
32548 THREE.ShaderMaterial.prototype = Object.create( THREE.Material.prototype );
32549
32550 THREE.ShaderMaterial.prototype.clone = function () {
32551
32552     var material = new THREE.ShaderMaterial();
32553
32554     THREE.Material.prototype.clone.call( this, material );
32555
32556     material.fragmentShader = this.fragmentShader;
32557     material.vertexShader = this.vertexShader;
32558     material.uniforms = this.uniforms;
32559     material.attributes = this.attributes;
32560
32561     material.shading = this.shading;
32562
32563     material.wireframe = this.wireframe;
32564     material.wireframeLinewidth = this.wireframeLinewidth;
32565
32566     material.fog = this.fog;
32567
32568     material.lights = this.lights;
32569
32570     material.vertexColors = this.vertexColors;
32571
32572     material.skinning = this.skinning;
32573
32574     material.morphTargets = this.morphTargets;
32575     material.morphNormals = this.morphNormals;
32576
32577     return material;
32578
32579 };
32580 /**
32581  * @author mrdoob / http://mrdoob.com/
32582  * @author alteredq / http://alteredqualia.com/
32583  * @author szimek / https://github.com/szimek/
32584  */
32585
32586 THREE.Texture = function ( image, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy ) {
32587
32588     this.id = THREE.TextureCount ++;
32589
32590     this.image = image;
32591
32592     this.mapping = mapping !== undefined ? mapping : new THREE.UVMapping();
32593
32594     this.wrapS = wrapS !== undefined ? wrapS : THREE.ClampToEdgeWrapping;
32595     this.wrapT = wrapT !== undefined ? wrapT : THREE.ClampToEdgeWrapping;
32596
32597     this.magFilter = magFilter !== undefined ? magFilter : THREE.LinearFilter;
32598     this.minFilter = minFilter !== undefined ? minFilter : THREE.LinearMipMapLinearFilter;
32599
32600     this.anisotropy = anisotropy !== undefined ? anisotropy : 1;
32601
32602     this.format = format !== undefined ? format : THREE.RGBAFormat;
32603     this.type = type !== undefined ? type : THREE.UnsignedByteType;
32604
32605     this.offset = new THREE.Vector2( 0, 0 );
32606     this.repeat = new THREE.Vector2( 1, 1 );
32607
32608     this.generateMipmaps = true;
32609     this.premultiplyAlpha = false;
32610     this.flipY = true;
32611
32612     this.needsUpdate = false;
32613     this.onUpdate = null;
32614
32615 };
32616
32617 THREE.Texture.prototype = {
32618
32619     constructor: THREE.Texture,
32620
32621     clone: function () {
32622
32623         var texture = new THREE.Texture();
32624
32625         texture.image = this.image;
32626
32627         texture.mapping = this.mapping;
32628
32629         texture.wrapS = this.wrapS;
32630         texture.wrapT = this.wrapT;
32631
32632         texture.magFilter = this.magFilter;
32633         texture.minFilter = this.minFilter;
32634
32635         texture.anisotropy = this.anisotropy;
32636
32637         texture.format = this.format;
32638         texture.type = this.type;
32639
32640         texture.offset.copy( this.offset );
32641         texture.repeat.copy( this.repeat );
32642
32643         texture.generateMipmaps = this.generateMipmaps;
32644         texture.premultiplyAlpha = this.premultiplyAlpha;
32645         texture.flipY = this.flipY;
32646
32647         return texture;
32648
32649     }
32650
32651 };
32652
32653 THREE.TextureCount = 0;
32654 /**
32655  * @author alteredq / http://alteredqualia.com/
32656  */
32657
32658 THREE.CompressedTexture = function ( mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter ) {
32659
32660     THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type );
32661
32662     this.image = { width: width, height: height };
32663     this.mipmaps = mipmaps;
32664
32665 };
32666
32667 THREE.CompressedTexture.prototype = Object.create( THREE.Texture.prototype );
32668
32669 THREE.CompressedTexture.prototype.clone = function () {
32670
32671     var texture = new THREE.CompressedTexture();
32672
32673     texture.image = this.image;
32674     texture.mipmaps = this.mipmaps;
32675
32676     texture.format = this.format;
32677     texture.type = this.type;
32678
32679     texture.mapping = this.mapping;
32680
32681     texture.wrapS = this.wrapS;
32682     texture.wrapT = this.wrapT;
32683
32684     texture.magFilter = this.magFilter;
32685     texture.minFilter = this.minFilter;
32686
32687     texture.anisotropy = this.anisotropy;
32688
32689     texture.offset.copy( this.offset );
32690     texture.repeat.copy( this.repeat );
32691
32692     return texture;
32693
32694 };
32695 /**
32696  * @author alteredq / http://alteredqualia.com/
32697  */
32698
32699 THREE.DataTexture = function ( data, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter ) {
32700
32701     THREE.Texture.call( this, null, mapping, wrapS, wrapT, magFilter, minFilter, format, type );
32702
32703     this.image = { data: data, width: width, height: height };
32704
32705 };
32706
32707 THREE.DataTexture.prototype = Object.create( THREE.Texture.prototype );
32708
32709 THREE.DataTexture.prototype.clone = function () {
32710
32711     var clonedTexture = new THREE.DataTexture( this.image.data,  this.image.width, this.image.height, this.format, this.type, this.mapping, this.wrapS, this.wrapT, this.magFilter, this.minFilter );
32712
32713     clonedTexture.offset.copy( this.offset );
32714     clonedTexture.repeat.copy( this.repeat );
32715
32716     return clonedTexture;
32717
32718 };
32719 /**
32720  * @author mrdoob / http://mrdoob.com/
32721  */
32722
32723 THREE.Particle = function ( material ) {
32724
32725     THREE.Object3D.call( this );
32726
32727     this.material = material;
32728
32729 };
32730
32731 THREE.Particle.prototype = Object.create( THREE.Object3D.prototype );
32732 /**
32733  * @author alteredq / http://alteredqualia.com/
32734  */
32735
32736 THREE.ParticleSystem = function ( geometry, material ) {
32737
32738     THREE.Object3D.call( this );
32739
32740     this.geometry = geometry;
32741     this.material = ( material !== undefined ) ? material : new THREE.ParticleBasicMaterial( { color: Math.random() * 0xffffff } );
32742
32743     this.sortParticles = false;
32744
32745     if ( this.geometry ) {
32746
32747         // calc bound radius
32748
32749         if( !this.geometry.boundingSphere ) {
32750
32751             this.geometry.computeBoundingSphere();
32752
32753         }
32754
32755         this.boundRadius = geometry.boundingSphere.radius;
32756
32757     }
32758
32759     this.frustumCulled = false;
32760
32761 };
32762
32763 THREE.ParticleSystem.prototype = Object.create( THREE.Object3D.prototype );
32764 /**
32765  * @author mrdoob / http://mrdoob.com/
32766  */
32767
32768 THREE.Line = function ( geometry, material, type ) {
32769
32770     THREE.Object3D.call( this );
32771
32772     this.geometry = geometry;
32773     this.material = ( material !== undefined ) ? material : new THREE.LineBasicMaterial( { color: Math.random() * 0xffffff } );
32774     this.type = ( type !== undefined ) ? type : THREE.LineStrip;
32775
32776     if ( this.geometry ) {
32777
32778         if ( ! this.geometry.boundingSphere ) {
32779
32780             this.geometry.computeBoundingSphere();
32781
32782         }
32783
32784     }
32785
32786 };
32787
32788 THREE.LineStrip = 0;
32789 THREE.LinePieces = 1;
32790
32791 THREE.Line.prototype = Object.create( THREE.Object3D.prototype );
32792 /**
32793  * @author mrdoob / http://mrdoob.com/
32794  * @author alteredq / http://alteredqualia.com/
32795  * @author mikael emtinger / http://gomo.se/
32796  */
32797
32798 THREE.Mesh = function ( geometry, material ) {
32799
32800     THREE.Object3D.call( this );
32801
32802     this.geometry = geometry;
32803     this.material = ( material !== undefined ) ? material : new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, wireframe: true } );
32804
32805     if ( this.geometry ) {
32806
32807         // calc bound radius
32808
32809         if ( ! this.geometry.boundingSphere ) {
32810
32811             this.geometry.computeBoundingSphere();
32812
32813         }
32814
32815         this.boundRadius = geometry.boundingSphere.radius;
32816
32817
32818         // setup morph targets
32819
32820         if( this.geometry.morphTargets.length ) {
32821
32822             this.morphTargetBase = -1;
32823             this.morphTargetForcedOrder = [];
32824             this.morphTargetInfluences = [];
32825             this.morphTargetDictionary = {};
32826
32827             for( var m = 0; m < this.geometry.morphTargets.length; m ++ ) {
32828
32829                 this.morphTargetInfluences.push( 0 );
32830                 this.morphTargetDictionary[ this.geometry.morphTargets[ m ].name ] = m;
32831
32832             }
32833
32834         }
32835
32836     }
32837
32838 }
32839
32840 THREE.Mesh.prototype = Object.create( THREE.Object3D.prototype );
32841
32842
32843 /*
32844  * Get Morph Target Index by Name
32845  */
32846
32847 THREE.Mesh.prototype.getMorphTargetIndexByName = function( name ) {
32848
32849     if ( this.morphTargetDictionary[ name ] !== undefined ) {
32850
32851         return this.morphTargetDictionary[ name ];
32852     }
32853
32854     console.log( "THREE.Mesh.getMorphTargetIndexByName: morph target " + name + " does not exist. Returning 0." );
32855     return 0;
32856
32857 }
32858 /**
32859  * @author mikael emtinger / http://gomo.se/
32860  * @author alteredq / http://alteredqualia.com/
32861  */
32862
32863 THREE.Bone = function( belongsToSkin ) {
32864
32865     THREE.Object3D.call( this );
32866
32867     this.skin = belongsToSkin;
32868     this.skinMatrix = new THREE.Matrix4();
32869
32870 };
32871
32872 THREE.Bone.prototype = Object.create( THREE.Object3D.prototype );
32873
32874 THREE.Bone.prototype.update = function( parentSkinMatrix, forceUpdate ) {
32875
32876     // update local
32877
32878     if ( this.matrixAutoUpdate ) {
32879
32880         forceUpdate |= this.updateMatrix();
32881
32882     }
32883
32884     // update skin matrix
32885
32886     if ( forceUpdate || this.matrixWorldNeedsUpdate ) {
32887
32888         if( parentSkinMatrix ) {
32889
32890             this.skinMatrix.multiply( parentSkinMatrix, this.matrix );
32891
32892         } else {
32893
32894             this.skinMatrix.copy( this.matrix );
32895
32896         }
32897
32898         this.matrixWorldNeedsUpdate = false;
32899         forceUpdate = true;
32900
32901     }
32902
32903     // update children
32904
32905     var child, i, l = this.children.length;
32906
32907     for ( i = 0; i < l; i ++ ) {
32908
32909         this.children[ i ].update( this.skinMatrix, forceUpdate );
32910
32911     }
32912
32913 };
32914
32915 /**
32916  * @author mikael emtinger / http://gomo.se/
32917  * @author alteredq / http://alteredqualia.com/
32918  */
32919
32920 THREE.SkinnedMesh = function ( geometry, material, useVertexTexture ) {
32921
32922     THREE.Mesh.call( this, geometry, material );
32923
32924     //
32925
32926     this.useVertexTexture = useVertexTexture !== undefined ? useVertexTexture : true;
32927
32928     // init bones
32929
32930     this.identityMatrix = new THREE.Matrix4();
32931
32932     this.bones = [];
32933     this.boneMatrices = [];
32934
32935     var b, bone, gbone, p, q, s;
32936
32937     if ( this.geometry.bones !== undefined ) {
32938
32939         for ( b = 0; b < this.geometry.bones.length; b ++ ) {
32940
32941             gbone = this.geometry.bones[ b ];
32942
32943             p = gbone.pos;
32944             q = gbone.rotq;
32945             s = gbone.scl;
32946
32947             bone = this.addBone();
32948
32949             bone.name = gbone.name;
32950             bone.position.set( p[0], p[1], p[2] );
32951             bone.quaternion.set( q[0], q[1], q[2], q[3] );
32952             bone.useQuaternion = true;
32953
32954             if ( s !== undefined ) {
32955
32956                 bone.scale.set( s[0], s[1], s[2] );
32957
32958             } else {
32959
32960                 bone.scale.set( 1, 1, 1 );
32961
32962             }
32963
32964         }
32965
32966         for ( b = 0; b < this.bones.length; b ++ ) {
32967
32968             gbone = this.geometry.bones[ b ];
32969             bone = this.bones[ b ];
32970
32971             if ( gbone.parent === -1 ) {
32972
32973                 this.add( bone );
32974
32975             } else {
32976
32977                 this.bones[ gbone.parent ].add( bone );
32978
32979             }
32980
32981         }
32982
32983         //
32984
32985         var nBones = this.bones.length;
32986
32987         if ( this.useVertexTexture ) {
32988
32989             // layout (1 matrix = 4 pixels)
32990             //    RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
32991             //  with  8x8  pixel texture max   16 bones  (8 * 8  / 4)
32992             //       16x16 pixel texture max   64 bones (16 * 16 / 4)
32993             //       32x32 pixel texture max  256 bones (32 * 32 / 4)
32994             //       64x64 pixel texture max 1024 bones (64 * 64 / 4)
32995
32996             var size;
32997
32998             if ( nBones > 256 )
32999                 size = 64;
33000             else if ( nBones > 64 )
33001                 size = 32;
33002             else if ( nBones > 16 )
33003                 size = 16;
33004             else
33005                 size = 8;
33006
33007             this.boneTextureWidth = size;
33008             this.boneTextureHeight = size;
33009
33010             this.boneMatrices = new Float32Array( this.boneTextureWidth * this.boneTextureHeight * 4 ); // 4 floats per RGBA pixel
33011             this.boneTexture = new THREE.DataTexture( this.boneMatrices, this.boneTextureWidth, this.boneTextureHeight, THREE.RGBAFormat, THREE.FloatType );
33012             this.boneTexture.minFilter = THREE.NearestFilter;
33013             this.boneTexture.magFilter = THREE.NearestFilter;
33014             this.boneTexture.generateMipmaps = false;
33015             this.boneTexture.flipY = false;
33016
33017         } else {
33018
33019             this.boneMatrices = new Float32Array( 16 * nBones );
33020
33021         }
33022
33023         this.pose();
33024
33025     }
33026
33027 };
33028
33029 THREE.SkinnedMesh.prototype = Object.create( THREE.Mesh.prototype );
33030
33031 THREE.SkinnedMesh.prototype.addBone = function( bone ) {
33032
33033     if ( bone === undefined ) {
33034
33035         bone = new THREE.Bone( this );
33036
33037     }
33038
33039     this.bones.push( bone );
33040
33041     return bone;
33042
33043 };
33044
33045 THREE.SkinnedMesh.prototype.updateMatrixWorld = function ( force ) {
33046
33047     this.matrixAutoUpdate && this.updateMatrix();
33048
33049     // update matrixWorld
33050
33051     if ( this.matrixWorldNeedsUpdate || force ) {
33052
33053         if ( this.parent ) {
33054
33055             this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
33056
33057         } else {
33058
33059             this.matrixWorld.copy( this.matrix );
33060
33061         }
33062
33063         this.matrixWorldNeedsUpdate = false;
33064
33065         force = true;
33066
33067     }
33068
33069     // update children
33070
33071     for ( var i = 0, l = this.children.length; i < l; i ++ ) {
33072
33073         var child = this.children[ i ];
33074
33075         if ( child instanceof THREE.Bone ) {
33076
33077             child.update( this.identityMatrix, false );
33078
33079         } else {
33080
33081             child.updateMatrixWorld( true );
33082
33083         }
33084
33085     }
33086
33087     // make a snapshot of the bones' rest position
33088
33089     if ( this.boneInverses == undefined ) {
33090
33091         this.boneInverses = [];
33092
33093         for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
33094
33095             var inverse = new THREE.Matrix4();
33096
33097             inverse.getInverse( this.bones[ b ].skinMatrix );
33098
33099             this.boneInverses.push( inverse );
33100
33101         }
33102
33103     }
33104
33105     // flatten bone matrices to array
33106
33107     for ( var b = 0, bl = this.bones.length; b < bl; b ++ ) {
33108
33109         // compute the offset between the current and the original transform;
33110
33111         //TODO: we could get rid of this multiplication step if the skinMatrix
33112         // was already representing the offset; however, this requires some
33113         // major changes to the animation system
33114
33115         THREE.SkinnedMesh.offsetMatrix.multiply( this.bones[ b ].skinMatrix, this.boneInverses[ b ] );
33116
33117         THREE.SkinnedMesh.offsetMatrix.flattenToArrayOffset( this.boneMatrices, b * 16 );
33118
33119     }
33120
33121     if ( this.useVertexTexture ) {
33122
33123         this.boneTexture.needsUpdate = true;
33124
33125     }
33126
33127 };
33128
33129 /*
33130  * Pose
33131  */
33132
33133 THREE.SkinnedMesh.prototype.pose = function() {
33134
33135     this.updateMatrixWorld( true );
33136
33137     for ( var i = 0; i < this.geometry.skinIndices.length; i ++ ) {
33138
33139         // normalize weights
33140
33141         var sw = this.geometry.skinWeights[ i ];
33142
33143         var scale = 1.0 / sw.lengthManhattan();
33144
33145         if ( scale !== Infinity ) {
33146
33147             sw.multiplyScalar( scale );
33148
33149         } else {
33150
33151             sw.set( 1 ); // this will be normalized by the shader anyway
33152
33153         }
33154
33155     }
33156
33157 };
33158
33159 THREE.SkinnedMesh.offsetMatrix = new THREE.Matrix4();
33160
33161 /**
33162  * @author alteredq / http://alteredqualia.com/
33163  */
33164
33165 THREE.MorphAnimMesh = function ( geometry, material ) {
33166
33167     THREE.Mesh.call( this, geometry, material );
33168
33169     // API
33170
33171     this.duration = 1000; // milliseconds
33172     this.mirroredLoop = false;
33173     this.time = 0;
33174
33175     // internals
33176
33177     this.lastKeyframe = 0;
33178     this.currentKeyframe = 0;
33179
33180     this.direction = 1;
33181     this.directionBackwards = false;
33182
33183     this.setFrameRange( 0, this.geometry.morphTargets.length - 1 );
33184
33185 };
33186
33187 THREE.MorphAnimMesh.prototype = Object.create( THREE.Mesh.prototype );
33188
33189 THREE.MorphAnimMesh.prototype.setFrameRange = function ( start, end ) {
33190
33191     this.startKeyframe = start;
33192     this.endKeyframe = end;
33193
33194     this.length = this.endKeyframe - this.startKeyframe + 1;
33195
33196 };
33197
33198 THREE.MorphAnimMesh.prototype.setDirectionForward = function () {
33199
33200     this.direction = 1;
33201     this.directionBackwards = false;
33202
33203 };
33204
33205 THREE.MorphAnimMesh.prototype.setDirectionBackward = function () {
33206
33207     this.direction = -1;
33208     this.directionBackwards = true;
33209
33210 };
33211
33212 THREE.MorphAnimMesh.prototype.parseAnimations = function () {
33213
33214     var geometry = this.geometry;
33215
33216     if ( ! geometry.animations ) geometry.animations = {};
33217
33218     var firstAnimation, animations = geometry.animations;
33219
33220     var pattern = /([a-z]+)(\d+)/;
33221
33222     for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
33223
33224         var morph = geometry.morphTargets[ i ];
33225         var parts = morph.name.match( pattern );
33226
33227         if ( parts && parts.length > 1 ) {
33228
33229             var label = parts[ 1 ];
33230             var num = parts[ 2 ];
33231
33232             if ( ! animations[ label ] ) animations[ label ] = { start: Infinity, end: -Infinity };
33233
33234             var animation = animations[ label ];
33235
33236             if ( i < animation.start ) animation.start = i;
33237             if ( i > animation.end ) animation.end = i;
33238
33239             if ( ! firstAnimation ) firstAnimation = label;
33240
33241         }
33242
33243     }
33244
33245     geometry.firstAnimation = firstAnimation;
33246
33247 };
33248
33249 THREE.MorphAnimMesh.prototype.setAnimationLabel = function ( label, start, end ) {
33250
33251     if ( ! this.geometry.animations ) this.geometry.animations = {};
33252
33253     this.geometry.animations[ label ] = { start: start, end: end };
33254
33255 };
33256
33257 THREE.MorphAnimMesh.prototype.playAnimation = function ( label, fps ) {
33258
33259     var animation = this.geometry.animations[ label ];
33260
33261     if ( animation ) {
33262
33263         this.setFrameRange( animation.start, animation.end );
33264         this.duration = 1000 * ( ( animation.end - animation.start ) / fps );
33265         this.time = 0;
33266
33267     } else {
33268
33269         console.warn( "animation[" + label + "] undefined" );
33270
33271     }
33272
33273 };
33274
33275 THREE.MorphAnimMesh.prototype.updateAnimation = function ( delta ) {
33276
33277     var frameTime = this.duration / this.length;
33278
33279     this.time += this.direction * delta;
33280
33281     if ( this.mirroredLoop ) {
33282
33283         if ( this.time > this.duration || this.time < 0 ) {
33284
33285             this.direction *= -1;
33286
33287             if ( this.time > this.duration ) {
33288
33289                 this.time = this.duration;
33290                 this.directionBackwards = true;
33291
33292             }
33293
33294             if ( this.time < 0 ) {
33295
33296                 this.time = 0;
33297                 this.directionBackwards = false;
33298
33299             }
33300
33301         }
33302
33303     } else {
33304
33305         this.time = this.time % this.duration;
33306
33307         if ( this.time < 0 ) this.time += this.duration;
33308
33309     }
33310
33311     var keyframe = this.startKeyframe + THREE.Math.clamp( Math.floor( this.time / frameTime ), 0, this.length - 1 );
33312
33313     if ( keyframe !== this.currentKeyframe ) {
33314
33315         this.morphTargetInfluences[ this.lastKeyframe ] = 0;
33316         this.morphTargetInfluences[ this.currentKeyframe ] = 1;
33317
33318         this.morphTargetInfluences[ keyframe ] = 0;
33319
33320         this.lastKeyframe = this.currentKeyframe;
33321         this.currentKeyframe = keyframe;
33322
33323     }
33324
33325     var mix = ( this.time % frameTime ) / frameTime;
33326
33327     if ( this.directionBackwards ) {
33328
33329         mix = 1 - mix;
33330
33331     }
33332
33333     this.morphTargetInfluences[ this.currentKeyframe ] = mix;
33334     this.morphTargetInfluences[ this.lastKeyframe ] = 1 - mix;
33335
33336 };
33337 /**
33338  * @author alteredq / http://alteredqualia.com/
33339  */
33340
33341 THREE.Ribbon = function ( geometry, material ) {
33342
33343     THREE.Object3D.call( this );
33344
33345     this.geometry = geometry;
33346     this.material = material;
33347
33348 };
33349
33350 THREE.Ribbon.prototype = Object.create( THREE.Object3D.prototype );
33351 /**
33352  * @author mikael emtinger / http://gomo.se/
33353  * @author alteredq / http://alteredqualia.com/
33354  * @author mrdoob / http://mrdoob.com/
33355  */
33356
33357 THREE.LOD = function () {
33358
33359     THREE.Object3D.call( this );
33360
33361     this.LODs = [];
33362
33363 };
33364
33365
33366 THREE.LOD.prototype = Object.create( THREE.Object3D.prototype );
33367
33368 THREE.LOD.prototype.addLevel = function ( object3D, visibleAtDistance ) {
33369
33370     if ( visibleAtDistance === undefined ) {
33371
33372         visibleAtDistance = 0;
33373
33374     }
33375
33376     visibleAtDistance = Math.abs( visibleAtDistance );
33377
33378     for ( var l = 0; l < this.LODs.length; l ++ ) {
33379
33380         if ( visibleAtDistance < this.LODs[ l ].visibleAtDistance ) {
33381
33382             break;
33383
33384         }
33385
33386     }
33387
33388     this.LODs.splice( l, 0, { visibleAtDistance: visibleAtDistance, object3D: object3D } );
33389     this.add( object3D );
33390
33391 };
33392
33393 THREE.LOD.prototype.update = function ( camera ) {
33394
33395     if ( this.LODs.length > 1 ) {
33396
33397         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
33398
33399         var inverse  = camera.matrixWorldInverse;
33400         var distance = -( inverse.elements[2] * this.matrixWorld.elements[12] + inverse.elements[6] * this.matrixWorld.elements[13] + inverse.elements[10] * this.matrixWorld.elements[14] + inverse.elements[14] );
33401
33402         this.LODs[ 0 ].object3D.visible = true;
33403
33404         for ( var l = 1; l < this.LODs.length; l ++ ) {
33405
33406             if( distance >= this.LODs[ l ].visibleAtDistance ) {
33407
33408                 this.LODs[ l - 1 ].object3D.visible = false;
33409                 this.LODs[ l     ].object3D.visible = true;
33410
33411             } else {
33412
33413                 break;
33414
33415             }
33416
33417         }
33418
33419         for( ; l < this.LODs.length; l ++ ) {
33420
33421             this.LODs[ l ].object3D.visible = false;
33422
33423         }
33424
33425     }
33426
33427 };
33428 /**
33429  * @author mikael emtinger / http://gomo.se/
33430  */
33431
33432 THREE.Sprite = function ( parameters ) {
33433
33434     THREE.Object3D.call( this );
33435
33436     this.color = ( parameters.color !== undefined ) ? new THREE.Color( parameters.color ) : new THREE.Color( 0xffffff );
33437     this.map = ( parameters.map !== undefined ) ? parameters.map : new THREE.Texture();
33438
33439     this.blending = ( parameters.blending !== undefined ) ? parameters.blending : THREE.NormalBlending;
33440
33441     this.blendSrc = parameters.blendSrc !== undefined ? parameters.blendSrc : THREE.SrcAlphaFactor;
33442     this.blendDst = parameters.blendDst !== undefined ? parameters.blendDst : THREE.OneMinusSrcAlphaFactor;
33443     this.blendEquation = parameters.blendEquation !== undefined ? parameters.blendEquation : THREE.AddEquation;
33444
33445     this.useScreenCoordinates = ( parameters.useScreenCoordinates !== undefined ) ? parameters.useScreenCoordinates : true;
33446     this.mergeWith3D = ( parameters.mergeWith3D !== undefined ) ? parameters.mergeWith3D : !this.useScreenCoordinates;
33447     this.affectedByDistance = ( parameters.affectedByDistance !== undefined ) ? parameters.affectedByDistance : !this.useScreenCoordinates;
33448     this.scaleByViewport = ( parameters.scaleByViewport !== undefined ) ? parameters.scaleByViewport : !this.affectedByDistance;
33449     this.alignment = ( parameters.alignment instanceof THREE.Vector2 ) ? parameters.alignment : THREE.SpriteAlignment.center;
33450
33451     this.rotation3d = this.rotation;
33452     this.rotation = 0;
33453     this.opacity = 1;
33454
33455     this.uvOffset = new THREE.Vector2( 0, 0 );
33456     this.uvScale  = new THREE.Vector2( 1, 1 );
33457
33458 };
33459
33460 THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype );
33461
33462 /*
33463  * Custom update matrix
33464  */
33465
33466 THREE.Sprite.prototype.updateMatrix = function () {
33467
33468     this.matrix.setPosition( this.position );
33469
33470     this.rotation3d.set( 0, 0, this.rotation );
33471     this.matrix.setRotationFromEuler( this.rotation3d );
33472
33473     if ( this.scale.x !== 1 || this.scale.y !== 1 ) {
33474
33475         this.matrix.scale( this.scale );
33476         this.boundRadiusScale = Math.max( this.scale.x, this.scale.y );
33477
33478     }
33479
33480     this.matrixWorldNeedsUpdate = true;
33481
33482 };
33483
33484 /*
33485  * Alignment
33486  */
33487
33488 THREE.SpriteAlignment = {};
33489 THREE.SpriteAlignment.topLeft = new THREE.Vector2( 1, -1 );
33490 THREE.SpriteAlignment.topCenter = new THREE.Vector2( 0, -1 );
33491 THREE.SpriteAlignment.topRight = new THREE.Vector2( -1, -1 );
33492 THREE.SpriteAlignment.centerLeft = new THREE.Vector2( 1, 0 );
33493 THREE.SpriteAlignment.center = new THREE.Vector2( 0, 0 );
33494 THREE.SpriteAlignment.centerRight = new THREE.Vector2( -1, 0 );
33495 THREE.SpriteAlignment.bottomLeft = new THREE.Vector2( 1, 1 );
33496 THREE.SpriteAlignment.bottomCenter = new THREE.Vector2( 0, 1 );
33497 THREE.SpriteAlignment.bottomRight = new THREE.Vector2( -1, 1 );
33498 /**
33499  * @author mrdoob / http://mrdoob.com/
33500  */
33501
33502 THREE.Scene = function () {
33503
33504     THREE.Object3D.call( this );
33505
33506     this.fog = null;
33507     this.overrideMaterial = null;
33508
33509     this.matrixAutoUpdate = false;
33510
33511     this.__objects = [];
33512     this.__lights = [];
33513
33514     this.__objectsAdded = [];
33515     this.__objectsRemoved = [];
33516
33517 };
33518
33519 THREE.Scene.prototype = Object.create( THREE.Object3D.prototype );
33520
33521 THREE.Scene.prototype.__addObject = function ( object ) {
33522
33523     if ( object instanceof THREE.Light ) {
33524
33525         if ( this.__lights.indexOf( object ) === - 1 ) {
33526
33527             this.__lights.push( object );
33528
33529         }
33530
33531         if ( object.target && object.target.parent === undefined ) {
33532
33533             this.add( object.target );
33534
33535         }
33536
33537     } else if ( !( object instanceof THREE.Camera || object instanceof THREE.Bone ) ) {
33538
33539         if ( this.__objects.indexOf( object ) === - 1 ) {
33540
33541             this.__objects.push( object );
33542             this.__objectsAdded.push( object );
33543
33544             // check if previously removed
33545
33546             var i = this.__objectsRemoved.indexOf( object );
33547
33548             if ( i !== -1 ) {
33549
33550                 this.__objectsRemoved.splice( i, 1 );
33551
33552             }
33553
33554         }
33555
33556     }
33557
33558     for ( var c = 0; c < object.children.length; c ++ ) {
33559
33560         this.__addObject( object.children[ c ] );
33561
33562     }
33563
33564 };
33565
33566 THREE.Scene.prototype.__removeObject = function ( object ) {
33567
33568     if ( object instanceof THREE.Light ) {
33569
33570         var i = this.__lights.indexOf( object );
33571
33572         if ( i !== -1 ) {
33573
33574             this.__lights.splice( i, 1 );
33575
33576         }
33577
33578     } else if ( !( object instanceof THREE.Camera ) ) {
33579
33580         var i = this.__objects.indexOf( object );
33581
33582         if( i !== -1 ) {
33583
33584             this.__objects.splice( i, 1 );
33585             this.__objectsRemoved.push( object );
33586
33587             // check if previously added
33588
33589             var ai = this.__objectsAdded.indexOf( object );
33590
33591             if ( ai !== -1 ) {
33592
33593                 this.__objectsAdded.splice( ai, 1 );
33594
33595             }
33596
33597         }
33598
33599     }
33600
33601     for ( var c = 0; c < object.children.length; c ++ ) {
33602
33603         this.__removeObject( object.children[ c ] );
33604
33605     }
33606
33607 };
33608 /**
33609  * @author mrdoob / http://mrdoob.com/
33610  * @author alteredq / http://alteredqualia.com/
33611  */
33612
33613 THREE.Fog = function ( hex, near, far ) {
33614
33615     this.color = new THREE.Color( hex );
33616
33617     this.near = ( near !== undefined ) ? near : 1;
33618     this.far = ( far !== undefined ) ? far : 1000;
33619
33620 };
33621 /**
33622  * @author mrdoob / http://mrdoob.com/
33623  * @author alteredq / http://alteredqualia.com/
33624  */
33625
33626 THREE.FogExp2 = function ( hex, density ) {
33627
33628     this.color = new THREE.Color( hex );
33629     this.density = ( density !== undefined ) ? density : 0.00025;
33630
33631 };
33632 /**
33633  * @author mrdoob / http://mrdoob.com/
33634  */
33635
33636 THREE.CanvasRenderer = function ( parameters ) {
33637
33638     console.log( 'THREE.CanvasRenderer', THREE.REVISION );
33639
33640     parameters = parameters || {};
33641
33642     var _this = this,
33643     _renderData, _elements, _lights,
33644     _projector = new THREE.Projector(),
33645
33646     _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
33647
33648     _canvasWidth, _canvasHeight, _canvasWidthHalf, _canvasHeightHalf,
33649     _context = _canvas.getContext( '2d' ),
33650
33651     _clearColor = new THREE.Color( 0x000000 ),
33652     _clearOpacity = 0,
33653
33654     _contextGlobalAlpha = 1,
33655     _contextGlobalCompositeOperation = 0,
33656     _contextStrokeStyle = null,
33657     _contextFillStyle = null,
33658     _contextLineWidth = null,
33659     _contextLineCap = null,
33660     _contextLineJoin = null,
33661
33662     _v1, _v2, _v3, _v4,
33663     _v5 = new THREE.RenderableVertex(),
33664     _v6 = new THREE.RenderableVertex(),
33665
33666     _v1x, _v1y, _v2x, _v2y, _v3x, _v3y,
33667     _v4x, _v4y, _v5x, _v5y, _v6x, _v6y,
33668
33669     _color = new THREE.Color(),
33670     _color1 = new THREE.Color(),
33671     _color2 = new THREE.Color(),
33672     _color3 = new THREE.Color(),
33673     _color4 = new THREE.Color(),
33674
33675     _patterns = {}, _imagedatas = {},
33676
33677     _near, _far,
33678
33679     _image, _uvs,
33680     _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y,
33681
33682     _clipRect = new THREE.Rectangle(),
33683     _clearRect = new THREE.Rectangle(),
33684     _bboxRect = new THREE.Rectangle(),
33685
33686     _enableLighting = false,
33687     _ambientLight = new THREE.Color(),
33688     _directionalLights = new THREE.Color(),
33689     _pointLights = new THREE.Color(),
33690
33691     _pi2 = Math.PI * 2,
33692     _vector3 = new THREE.Vector3(), // Needed for PointLight
33693
33694     _pixelMap, _pixelMapContext, _pixelMapImage, _pixelMapData,
33695     _gradientMap, _gradientMapContext, _gradientMapQuality = 16;
33696
33697     _pixelMap = document.createElement( 'canvas' );
33698     _pixelMap.width = _pixelMap.height = 2;
33699
33700     _pixelMapContext = _pixelMap.getContext( '2d' );
33701     _pixelMapContext.fillStyle = 'rgba(0,0,0,1)';
33702     _pixelMapContext.fillRect( 0, 0, 2, 2 );
33703
33704     _pixelMapImage = _pixelMapContext.getImageData( 0, 0, 2, 2 );
33705     _pixelMapData = _pixelMapImage.data;
33706
33707     _gradientMap = document.createElement( 'canvas' );
33708     _gradientMap.width = _gradientMap.height = _gradientMapQuality;
33709
33710     _gradientMapContext = _gradientMap.getContext( '2d' );
33711     _gradientMapContext.translate( - _gradientMapQuality / 2, - _gradientMapQuality / 2 );
33712     _gradientMapContext.scale( _gradientMapQuality, _gradientMapQuality );
33713
33714     _gradientMapQuality --; // Fix UVs
33715
33716     this.domElement = _canvas;
33717
33718     this.autoClear = true;
33719     this.sortObjects = true;
33720     this.sortElements = true;
33721
33722     this.info = {
33723
33724         render: {
33725
33726             vertices: 0,
33727             faces: 0
33728
33729         }
33730
33731     }
33732
33733     this.setSize = function ( width, height ) {
33734
33735         _canvasWidth = width;
33736         _canvasHeight = height;
33737         _canvasWidthHalf = Math.floor( _canvasWidth / 2 );
33738         _canvasHeightHalf = Math.floor( _canvasHeight / 2 );
33739
33740         _canvas.width = _canvasWidth;
33741         _canvas.height = _canvasHeight;
33742
33743         _clipRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
33744         _clearRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
33745
33746         _contextGlobalAlpha = 1;
33747         _contextGlobalCompositeOperation = 0;
33748         _contextStrokeStyle = null;
33749         _contextFillStyle = null;
33750         _contextLineWidth = null;
33751         _contextLineCap = null;
33752         _contextLineJoin = null;
33753
33754     };
33755
33756     this.setClearColor = function ( color, opacity ) {
33757
33758         _clearColor.copy( color );
33759         _clearOpacity = opacity !== undefined ? opacity : 1;
33760
33761         _clearRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
33762
33763     };
33764
33765     this.setClearColorHex = function ( hex, opacity ) {
33766
33767         _clearColor.setHex( hex );
33768         _clearOpacity = opacity !== undefined ? opacity : 1;
33769
33770         _clearRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
33771
33772     };
33773
33774     this.getMaxAnisotropy  = function () {
33775
33776         return 0;
33777
33778     };
33779
33780     this.clear = function () {
33781
33782         _context.setTransform( 1, 0, 0, - 1, _canvasWidthHalf, _canvasHeightHalf );
33783
33784         if ( _clearRect.isEmpty() === false ) {
33785
33786             _clearRect.minSelf( _clipRect );
33787             _clearRect.inflate( 2 );
33788
33789             if ( _clearOpacity < 1 ) {
33790
33791                 _context.clearRect( Math.floor( _clearRect.getX() ), Math.floor( _clearRect.getY() ), Math.floor( _clearRect.getWidth() ), Math.floor( _clearRect.getHeight() ) );
33792
33793             }
33794
33795             if ( _clearOpacity > 0 ) {
33796
33797                 setBlending( THREE.NormalBlending );
33798                 setOpacity( 1 );
33799
33800                 setFillStyle( 'rgba(' + Math.floor( _clearColor.r * 255 ) + ',' + Math.floor( _clearColor.g * 255 ) + ',' + Math.floor( _clearColor.b * 255 ) + ',' + _clearOpacity + ')' );
33801
33802                 _context.fillRect( Math.floor( _clearRect.getX() ), Math.floor( _clearRect.getY() ), Math.floor( _clearRect.getWidth() ), Math.floor( _clearRect.getHeight() ) );
33803
33804             }
33805
33806             _clearRect.empty();
33807
33808         }
33809
33810
33811     };
33812
33813     this.render = function ( scene, camera ) {
33814
33815         if ( camera instanceof THREE.Camera === false ) {
33816
33817             console.error( 'THREE.CanvasRenderer.render: camera is not an instance of THREE.Camera.' );
33818             return;
33819
33820         }
33821
33822         var e, el, element, material;
33823
33824         this.autoClear === true ? this.clear() : _context.setTransform( 1, 0, 0, - 1, _canvasWidthHalf, _canvasHeightHalf );
33825
33826         _this.info.render.vertices = 0;
33827         _this.info.render.faces = 0;
33828
33829         _renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );
33830         _elements = _renderData.elements;
33831         _lights = _renderData.lights;
33832
33833         /* DEBUG
33834         _context.fillStyle = 'rgba( 0, 255, 255, 0.5 )';
33835         _context.fillRect( _clipRect.getX(), _clipRect.getY(), _clipRect.getWidth(), _clipRect.getHeight() );
33836         */
33837
33838         _enableLighting = _lights.length > 0;
33839
33840         if ( _enableLighting === true ) {
33841
33842              calculateLights();
33843
33844         }
33845
33846         for ( e = 0, el = _elements.length; e < el; e++ ) {
33847
33848             element = _elements[ e ];
33849
33850             material = element.material;
33851
33852             if ( material === undefined || material.visible === false ) continue;
33853
33854             _bboxRect.empty();
33855
33856             if ( element instanceof THREE.RenderableParticle ) {
33857
33858                 _v1 = element;
33859                 _v1.x *= _canvasWidthHalf; _v1.y *= _canvasHeightHalf;
33860
33861                 renderParticle( _v1, element, material, scene );
33862
33863             } else if ( element instanceof THREE.RenderableLine ) {
33864
33865                 _v1 = element.v1; _v2 = element.v2;
33866
33867                 _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
33868                 _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
33869
33870                 _bboxRect.addPoint( _v1.positionScreen.x, _v1.positionScreen.y );
33871                 _bboxRect.addPoint( _v2.positionScreen.x, _v2.positionScreen.y );
33872
33873                 if ( _clipRect.intersects( _bboxRect ) === true ) {
33874
33875                     renderLine( _v1, _v2, element, material, scene );
33876
33877                 }
33878
33879
33880             } else if ( element instanceof THREE.RenderableFace3 ) {
33881
33882                 _v1 = element.v1; _v2 = element.v2; _v3 = element.v3;
33883
33884                 _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
33885                 _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
33886                 _v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf;
33887
33888                 if ( material.overdraw === true ) {
33889
33890                     expand( _v1.positionScreen, _v2.positionScreen );
33891                     expand( _v2.positionScreen, _v3.positionScreen );
33892                     expand( _v3.positionScreen, _v1.positionScreen );
33893
33894                 }
33895
33896                 _bboxRect.add3Points( _v1.positionScreen.x, _v1.positionScreen.y,
33897                               _v2.positionScreen.x, _v2.positionScreen.y,
33898                               _v3.positionScreen.x, _v3.positionScreen.y );
33899
33900                 if ( _clipRect.intersects( _bboxRect ) === true ) {
33901
33902                     renderFace3( _v1, _v2, _v3, 0, 1, 2, element, material, scene );
33903
33904                 }
33905
33906             } else if ( element instanceof THREE.RenderableFace4 ) {
33907
33908                 _v1 = element.v1; _v2 = element.v2; _v3 = element.v3; _v4 = element.v4;
33909
33910                 _v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
33911                 _v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
33912                 _v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf;
33913                 _v4.positionScreen.x *= _canvasWidthHalf; _v4.positionScreen.y *= _canvasHeightHalf;
33914
33915                 _v5.positionScreen.copy( _v2.positionScreen );
33916                 _v6.positionScreen.copy( _v4.positionScreen );
33917
33918                 if ( material.overdraw === true ) {
33919
33920                     expand( _v1.positionScreen, _v2.positionScreen );
33921                     expand( _v2.positionScreen, _v4.positionScreen );
33922                     expand( _v4.positionScreen, _v1.positionScreen );
33923
33924                     expand( _v3.positionScreen, _v5.positionScreen );
33925                     expand( _v3.positionScreen, _v6.positionScreen );
33926
33927                 }
33928
33929                 _bboxRect.addPoint( _v1.positionScreen.x, _v1.positionScreen.y );
33930                 _bboxRect.addPoint( _v2.positionScreen.x, _v2.positionScreen.y );
33931                 _bboxRect.addPoint( _v3.positionScreen.x, _v3.positionScreen.y );
33932                 _bboxRect.addPoint( _v4.positionScreen.x, _v4.positionScreen.y );
33933
33934                 if ( _clipRect.intersects( _bboxRect ) === true ) {
33935
33936                     renderFace4( _v1, _v2, _v3, _v4, _v5, _v6, element, material, scene );
33937
33938                 }
33939
33940             }
33941
33942             /* DEBUG
33943             _context.lineWidth = 1;
33944             _context.strokeStyle = 'rgba( 0, 255, 0, 0.5 )';
33945             _context.strokeRect( _bboxRect.getX(), _bboxRect.getY(), _bboxRect.getWidth(), _bboxRect.getHeight() );
33946             */
33947
33948             _clearRect.addRectangle( _bboxRect );
33949
33950
33951         }
33952
33953         /* DEBUG
33954         _context.lineWidth = 1;
33955         _context.strokeStyle = 'rgba( 255, 0, 0, 0.5 )';
33956         _context.strokeRect( _clearRect.getX(), _clearRect.getY(), _clearRect.getWidth(), _clearRect.getHeight() );
33957         */
33958
33959         _context.setTransform( 1, 0, 0, 1, 0, 0 );
33960
33961         //
33962
33963         function calculateLights() {
33964
33965             _ambientLight.setRGB( 0, 0, 0 );
33966             _directionalLights.setRGB( 0, 0, 0 );
33967             _pointLights.setRGB( 0, 0, 0 );
33968
33969             for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
33970
33971                 var light = _lights[ l ];
33972                 var lightColor = light.color;
33973
33974                 if ( light instanceof THREE.AmbientLight ) {
33975
33976                     _ambientLight.r += lightColor.r;
33977                     _ambientLight.g += lightColor.g;
33978                     _ambientLight.b += lightColor.b;
33979
33980                 } else if ( light instanceof THREE.DirectionalLight ) {
33981
33982                     // for particles
33983
33984                     _directionalLights.r += lightColor.r;
33985                     _directionalLights.g += lightColor.g;
33986                     _directionalLights.b += lightColor.b;
33987
33988                 } else if ( light instanceof THREE.PointLight ) {
33989
33990                     // for particles
33991
33992                     _pointLights.r += lightColor.r;
33993                     _pointLights.g += lightColor.g;
33994                     _pointLights.b += lightColor.b;
33995
33996                 }
33997
33998             }
33999
34000         }
34001
34002         function calculateLight( position, normal, color ) {
34003
34004             for ( var l = 0, ll = _lights.length; l < ll; l ++ ) {
34005
34006                 var light = _lights[ l ];
34007                 var lightColor = light.color;
34008
34009                 if ( light instanceof THREE.DirectionalLight ) {
34010
34011                     var lightPosition = light.matrixWorld.getPosition().normalize();
34012
34013                     var amount = normal.dot( lightPosition );
34014
34015                     if ( amount <= 0 ) continue;
34016
34017                     amount *= light.intensity;
34018
34019                     color.r += lightColor.r * amount;
34020                     color.g += lightColor.g * amount;
34021                     color.b += lightColor.b * amount;
34022
34023                 } else if ( light instanceof THREE.PointLight ) {
34024
34025                     var lightPosition = light.matrixWorld.getPosition();
34026
34027                     var amount = normal.dot( _vector3.sub( lightPosition, position ).normalize() );
34028
34029                     if ( amount <= 0 ) continue;
34030
34031                     amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
34032
34033                     if ( amount == 0 ) continue;
34034
34035                     amount *= light.intensity;
34036
34037                     color.r += lightColor.r * amount;
34038                     color.g += lightColor.g * amount;
34039                     color.b += lightColor.b * amount;
34040
34041                 }
34042
34043             }
34044
34045         }
34046
34047         function renderParticle( v1, element, material, scene ) {
34048
34049             setOpacity( material.opacity );
34050             setBlending( material.blending );
34051
34052             var width, height, scaleX, scaleY,
34053             bitmap, bitmapWidth, bitmapHeight;
34054
34055             if ( material instanceof THREE.ParticleBasicMaterial ) {
34056
34057                 if ( material.map === null ) {
34058
34059                     scaleX = element.object.scale.x;
34060                     scaleY = element.object.scale.y;
34061
34062                     // TODO: Be able to disable this
34063
34064                     scaleX *= element.scale.x * _canvasWidthHalf;
34065                     scaleY *= element.scale.y * _canvasHeightHalf;
34066
34067                     _bboxRect.set( v1.x - scaleX, v1.y - scaleY, v1.x  + scaleX, v1.y + scaleY );
34068
34069                     if ( _clipRect.intersects( _bboxRect ) === false ) {
34070
34071                         return;
34072
34073                     }
34074
34075                     setFillStyle( material.color.getContextStyle() );
34076
34077                     _context.save();
34078                     _context.translate( v1.x, v1.y );
34079                     _context.rotate( - element.rotation );
34080                     _context.scale( scaleX, scaleY );
34081                     _context.fillRect( -1, -1, 2, 2 );
34082                     _context.restore();
34083
34084                 } else {
34085
34086                     bitmap = material.map.image;
34087                     bitmapWidth = bitmap.width >> 1;
34088                     bitmapHeight = bitmap.height >> 1;
34089
34090                     scaleX = element.scale.x * _canvasWidthHalf;
34091                     scaleY = element.scale.y * _canvasHeightHalf;
34092
34093                     width = scaleX * bitmapWidth;
34094                     height = scaleY * bitmapHeight;
34095
34096                     // TODO: Rotations break this...
34097
34098                     _bboxRect.set( v1.x - width, v1.y - height, v1.x  + width, v1.y + height );
34099
34100                     if ( _clipRect.intersects( _bboxRect ) === false ) {
34101
34102                         return;
34103
34104                     }
34105
34106                     _context.save();
34107                     _context.translate( v1.x, v1.y );
34108                     _context.rotate( - element.rotation );
34109                     _context.scale( scaleX, - scaleY );
34110
34111                     _context.translate( - bitmapWidth, - bitmapHeight );
34112                     _context.drawImage( bitmap, 0, 0 );
34113                     _context.restore();
34114
34115                 }
34116
34117                 /* DEBUG
34118                 setStrokeStyle( 'rgb(255,255,0)' );
34119                 _context.beginPath();
34120                 _context.moveTo( v1.x - 10, v1.y );
34121                 _context.lineTo( v1.x + 10, v1.y );
34122                 _context.moveTo( v1.x, v1.y - 10 );
34123                 _context.lineTo( v1.x, v1.y + 10 );
34124                 _context.stroke();
34125                 */
34126
34127             } else if ( material instanceof THREE.ParticleCanvasMaterial ) {
34128
34129                 width = element.scale.x * _canvasWidthHalf;
34130                 height = element.scale.y * _canvasHeightHalf;
34131
34132                 _bboxRect.set( v1.x - width, v1.y - height, v1.x + width, v1.y + height );
34133
34134                 if ( _clipRect.intersects( _bboxRect ) === false ) {
34135
34136                     return;
34137
34138                 }
34139
34140                 setStrokeStyle( material.color.getContextStyle() );
34141                 setFillStyle( material.color.getContextStyle() );
34142
34143                 _context.save();
34144                 _context.translate( v1.x, v1.y );
34145                 _context.rotate( - element.rotation );
34146                 _context.scale( width, height );
34147
34148                 material.program( _context );
34149
34150                 _context.restore();
34151
34152             }
34153
34154         }
34155
34156         function renderLine( v1, v2, element, material, scene ) {
34157
34158             setOpacity( material.opacity );
34159             setBlending( material.blending );
34160
34161             _context.beginPath();
34162             _context.moveTo( v1.positionScreen.x, v1.positionScreen.y );
34163             _context.lineTo( v2.positionScreen.x, v2.positionScreen.y );
34164
34165             if ( material instanceof THREE.LineBasicMaterial ) {
34166
34167                 setLineWidth( material.linewidth );
34168                 setLineCap( material.linecap );
34169                 setLineJoin( material.linejoin );
34170                 setStrokeStyle( material.color.getContextStyle() );
34171
34172                 _context.stroke();
34173                 _bboxRect.inflate( material.linewidth * 2 );
34174
34175             }
34176
34177         }
34178
34179         function renderFace3( v1, v2, v3, uv1, uv2, uv3, element, material, scene ) {
34180
34181             _this.info.render.vertices += 3;
34182             _this.info.render.faces ++;
34183
34184             setOpacity( material.opacity );
34185             setBlending( material.blending );
34186
34187             _v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
34188             _v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
34189             _v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
34190
34191             drawTriangle( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y );
34192
34193             if ( ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) && material.map === null && material.map === null ) {
34194
34195                 if ( _enableLighting === true ) {
34196
34197                     var diffuse = material.color;
34198                     var emissive = material.emissive;
34199
34200                     if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 3 ) {
34201
34202                         _color1.r = _color2.r = _color3.r = _ambientLight.r;
34203                         _color1.g = _color2.g = _color3.g = _ambientLight.g;
34204                         _color1.b = _color2.b = _color3.b = _ambientLight.b;
34205
34206                         calculateLight( element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
34207                         calculateLight( element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
34208                         calculateLight( element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color3 );
34209
34210                         _color1.r = diffuse.r * _color1.r + emissive.r;
34211                         _color1.g = diffuse.g * _color1.g + emissive.g;
34212                         _color1.b = diffuse.b * _color1.b + emissive.b;
34213
34214                         _color2.r = diffuse.r * _color2.r + emissive.r;
34215                         _color2.g = diffuse.g * _color2.g + emissive.g;
34216                         _color2.b = diffuse.b * _color2.b + emissive.b;
34217
34218                         _color3.r = diffuse.r * _color3.r + emissive.r;
34219                         _color3.g = diffuse.g * _color3.g + emissive.g;
34220                         _color3.b = diffuse.b * _color3.b + emissive.b;
34221
34222                         _color4.r = ( _color2.r + _color3.r ) * 0.5;
34223                         _color4.g = ( _color2.g + _color3.g ) * 0.5;
34224                         _color4.b = ( _color2.b + _color3.b ) * 0.5;
34225
34226                         _image = getGradientTexture( _color1, _color2, _color3, _color4 );
34227
34228                         clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
34229
34230                     } else {
34231
34232                         _color.r = _ambientLight.r;
34233                         _color.g = _ambientLight.g;
34234                         _color.b = _ambientLight.b;
34235
34236                         calculateLight( element.centroidWorld, element.normalWorld, _color );
34237
34238                         _color.r = diffuse.r * _color.r + emissive.r;
34239                         _color.g = diffuse.g * _color.g + emissive.g;
34240                         _color.b = diffuse.b * _color.b + emissive.b;
34241
34242                         material.wireframe === true ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
34243
34244                     }
34245
34246                 } else {
34247
34248                     material.wireframe === true ? strokePath( material.color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( material.color );
34249
34250                 }
34251
34252             } else if ( material instanceof THREE.MeshBasicMaterial || material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) {
34253
34254                 if ( material.map !== null ) {
34255
34256                     if ( material.map.mapping instanceof THREE.UVMapping ) {
34257
34258                         _uvs = element.uvs[ 0 ];
34259                         patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uvs[ uv1 ].u, _uvs[ uv1 ].v, _uvs[ uv2 ].u, _uvs[ uv2 ].v, _uvs[ uv3 ].u, _uvs[ uv3 ].v, material.map );
34260
34261                     }
34262
34263
34264                 } else if ( material.envMap !== null ) {
34265
34266                     if ( material.envMap.mapping instanceof THREE.SphericalReflectionMapping ) {
34267
34268                         var cameraMatrix = camera.matrixWorldInverse;
34269
34270                         _vector3.copy( element.vertexNormalsWorld[ uv1 ] );
34271                         _uv1x = ( _vector3.x * cameraMatrix.elements[0] + _vector3.y * cameraMatrix.elements[4] + _vector3.z * cameraMatrix.elements[8] ) * 0.5 + 0.5;
34272                         _uv1y = ( _vector3.x * cameraMatrix.elements[1] + _vector3.y * cameraMatrix.elements[5] + _vector3.z * cameraMatrix.elements[9] ) * 0.5 + 0.5;
34273
34274                         _vector3.copy( element.vertexNormalsWorld[ uv2 ] );
34275                         _uv2x = ( _vector3.x * cameraMatrix.elements[0] + _vector3.y * cameraMatrix.elements[4] + _vector3.z * cameraMatrix.elements[8] ) * 0.5 + 0.5;
34276                         _uv2y = ( _vector3.x * cameraMatrix.elements[1] + _vector3.y * cameraMatrix.elements[5] + _vector3.z * cameraMatrix.elements[9] ) * 0.5 + 0.5;
34277
34278                         _vector3.copy( element.vertexNormalsWorld[ uv3 ] );
34279                         _uv3x = ( _vector3.x * cameraMatrix.elements[0] + _vector3.y * cameraMatrix.elements[4] + _vector3.z * cameraMatrix.elements[8] ) * 0.5 + 0.5;
34280                         _uv3y = ( _vector3.x * cameraMatrix.elements[1] + _vector3.y * cameraMatrix.elements[5] + _vector3.z * cameraMatrix.elements[9] ) * 0.5 + 0.5;
34281
34282                         patternPath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y, material.envMap );
34283
34284                     }/* else if ( material.envMap.mapping == THREE.SphericalRefractionMapping ) {
34285
34286
34287
34288                     }*/
34289
34290
34291                 } else {
34292
34293                     material.wireframe === true ? strokePath( material.color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( material.color );
34294
34295                 }
34296
34297             } else if ( material instanceof THREE.MeshDepthMaterial ) {
34298
34299                 _near = camera.near;
34300                 _far = camera.far;
34301
34302                 _color1.r = _color1.g = _color1.b = 1 - smoothstep( v1.positionScreen.z, _near, _far );
34303                 _color2.r = _color2.g = _color2.b = 1 - smoothstep( v2.positionScreen.z, _near, _far );
34304                 _color3.r = _color3.g = _color3.b = 1 - smoothstep( v3.positionScreen.z, _near, _far );
34305
34306                 _color4.r = ( _color2.r + _color3.r ) * 0.5;
34307                 _color4.g = ( _color2.g + _color3.g ) * 0.5;
34308                 _color4.b = ( _color2.b + _color3.b ) * 0.5;
34309
34310                 _image = getGradientTexture( _color1, _color2, _color3, _color4 );
34311
34312                 clipImage( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, 0, 0, 1, 0, 0, 1, _image );
34313
34314             } else if ( material instanceof THREE.MeshNormalMaterial ) {
34315
34316                 _color.r = normalToComponent( element.normalWorld.x );
34317                 _color.g = normalToComponent( element.normalWorld.y );
34318                 _color.b = normalToComponent( element.normalWorld.z );
34319
34320                 material.wireframe === true ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
34321
34322             }
34323
34324         }
34325
34326         function renderFace4( v1, v2, v3, v4, v5, v6, element, material, scene ) {
34327
34328             _this.info.render.vertices += 4;
34329             _this.info.render.faces ++;
34330
34331             setOpacity( material.opacity );
34332             setBlending( material.blending );
34333
34334             if ( ( material.map !== undefined && material.map !== null ) || ( material.envMap !== undefined && material.envMap !== null ) ) {
34335
34336                 // Let renderFace3() handle this
34337
34338                 renderFace3( v1, v2, v4, 0, 1, 3, element, material, scene );
34339                 renderFace3( v5, v3, v6, 1, 2, 3, element, material, scene );
34340
34341                 return;
34342
34343             }
34344
34345             _v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
34346             _v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
34347             _v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
34348             _v4x = v4.positionScreen.x; _v4y = v4.positionScreen.y;
34349             _v5x = v5.positionScreen.x; _v5y = v5.positionScreen.y;
34350             _v6x = v6.positionScreen.x; _v6y = v6.positionScreen.y;
34351
34352             if ( material instanceof THREE.MeshLambertMaterial || material instanceof THREE.MeshPhongMaterial ) {
34353
34354                 if ( _enableLighting === true ) {
34355
34356                     var diffuse = material.color;
34357                     var emissive = material.emissive;
34358
34359                     if ( material.wireframe === false && material.shading == THREE.SmoothShading && element.vertexNormalsLength == 4 ) {
34360
34361                         _color1.r = _color2.r = _color3.r = _color4.r = _ambientLight.r;
34362                         _color1.g = _color2.g = _color3.g = _color4.g = _ambientLight.g;
34363                         _color1.b = _color2.b = _color3.b = _color4.b = _ambientLight.b;
34364
34365                         calculateLight( element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
34366                         calculateLight( element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
34367                         calculateLight( element.v4.positionWorld, element.vertexNormalsWorld[ 3 ], _color3 );
34368                         calculateLight( element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color4 );
34369
34370                         _color1.r = diffuse.r * _color1.r + emissive.r;
34371                         _color1.g = diffuse.g * _color1.g + emissive.g;
34372                         _color1.b = diffuse.b * _color1.b + emissive.b;
34373
34374                         _color2.r = diffuse.r * _color2.r + emissive.r;
34375                         _color2.g = diffuse.g * _color2.g + emissive.g;
34376                         _color2.b = diffuse.b * _color2.b + emissive.b;
34377
34378                         _color3.r = diffuse.r * _color3.r + emissive.r;
34379                         _color3.g = diffuse.g * _color3.g + emissive.g;
34380                         _color3.b = diffuse.b * _color3.b + emissive.b;
34381
34382                         _color4.r = diffuse.r * _color4.r + emissive.r;
34383                         _color4.g = diffuse.g * _color4.g + emissive.g;
34384                         _color4.b = diffuse.b * _color4.b + emissive.b;
34385
34386                         _image = getGradientTexture( _color1, _color2, _color3, _color4 );
34387
34388                         // TODO: UVs are incorrect, v4->v3?
34389
34390                         drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
34391                         clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
34392
34393                         drawTriangle( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y );
34394                         clipImage( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, 1, 0, 1, 1, 0, 1, _image );
34395
34396                     } else {
34397
34398                         _color.r = _ambientLight.r;
34399                         _color.g = _ambientLight.g;
34400                         _color.b = _ambientLight.b;
34401
34402                         calculateLight( element.centroidWorld, element.normalWorld, _color );
34403
34404                         _color.r = diffuse.r * _color.r + emissive.r;
34405                         _color.g = diffuse.g * _color.g + emissive.g;
34406                         _color.b = diffuse.b * _color.b + emissive.b;
34407
34408                         drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
34409
34410                         material.wireframe === true ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
34411
34412                     }
34413
34414                 } else {
34415
34416                     drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
34417
34418                     material.wireframe === true ? strokePath( material.color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( material.color );
34419
34420                 }
34421
34422             } else if ( material instanceof THREE.MeshBasicMaterial ) {
34423
34424                 drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
34425
34426                 material.wireframe === true ? strokePath( material.color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( material.color );
34427
34428             } else if ( material instanceof THREE.MeshNormalMaterial ) {
34429
34430                 _color.r = normalToComponent( element.normalWorld.x );
34431                 _color.g = normalToComponent( element.normalWorld.y );
34432                 _color.b = normalToComponent( element.normalWorld.z );
34433
34434                 drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
34435
34436                 material.wireframe === true ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
34437
34438             } else if ( material instanceof THREE.MeshDepthMaterial ) {
34439
34440                 _near = camera.near;
34441                 _far = camera.far;
34442
34443                 _color1.r = _color1.g = _color1.b = 1 - smoothstep( v1.positionScreen.z, _near, _far );
34444                 _color2.r = _color2.g = _color2.b = 1 - smoothstep( v2.positionScreen.z, _near, _far );
34445                 _color3.r = _color3.g = _color3.b = 1 - smoothstep( v4.positionScreen.z, _near, _far );
34446                 _color4.r = _color4.g = _color4.b = 1 - smoothstep( v3.positionScreen.z, _near, _far );
34447
34448                 _image = getGradientTexture( _color1, _color2, _color3, _color4 );
34449
34450                 // TODO: UVs are incorrect, v4->v3?
34451
34452                 drawTriangle( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y );
34453                 clipImage( _v1x, _v1y, _v2x, _v2y, _v4x, _v4y, 0, 0, 1, 0, 0, 1, _image );
34454
34455                 drawTriangle( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y );
34456                 clipImage( _v5x, _v5y, _v3x, _v3y, _v6x, _v6y, 1, 0, 1, 1, 0, 1, _image );
34457
34458             }
34459
34460         }
34461
34462         //
34463
34464         function drawTriangle( x0, y0, x1, y1, x2, y2 ) {
34465
34466             _context.beginPath();
34467             _context.moveTo( x0, y0 );
34468             _context.lineTo( x1, y1 );
34469             _context.lineTo( x2, y2 );
34470             _context.closePath();
34471
34472         }
34473
34474         function drawQuad( x0, y0, x1, y1, x2, y2, x3, y3 ) {
34475
34476             _context.beginPath();
34477             _context.moveTo( x0, y0 );
34478             _context.lineTo( x1, y1 );
34479             _context.lineTo( x2, y2 );
34480             _context.lineTo( x3, y3 );
34481             _context.closePath();
34482
34483         }
34484
34485         function strokePath( color, linewidth, linecap, linejoin ) {
34486
34487             setLineWidth( linewidth );
34488             setLineCap( linecap );
34489             setLineJoin( linejoin );
34490             setStrokeStyle( color.getContextStyle() );
34491
34492             _context.stroke();
34493
34494             _bboxRect.inflate( linewidth * 2 );
34495
34496         }
34497
34498         function fillPath( color ) {
34499
34500             setFillStyle( color.getContextStyle() );
34501             _context.fill();
34502
34503         }
34504
34505         function patternPath( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, texture ) {
34506
34507             if ( texture instanceof THREE.DataTexture || texture.image === undefined || texture.image.width == 0 ) return;
34508
34509             if ( texture.needsUpdate === true ) {
34510
34511                 var repeatX = texture.wrapS == THREE.RepeatWrapping;
34512                 var repeatY = texture.wrapT == THREE.RepeatWrapping;
34513
34514                 _patterns[ texture.id ] = _context.createPattern(
34515                     texture.image, repeatX === true && repeatY === true
34516                         ? 'repeat'
34517                         : repeatX === true && repeatY === false
34518                             ? 'repeat-x'
34519                             : repeatX === false && repeatY === true
34520                                 ? 'repeat-y'
34521                                 : 'no-repeat'
34522                 );
34523
34524                 texture.needsUpdate = false;
34525
34526             }
34527
34528             _patterns[ texture.id ] === undefined
34529                 ? setFillStyle( 'rgba(0,0,0,1)' )
34530                 : setFillStyle( _patterns[ texture.id ] );
34531
34532             // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
34533
34534             var a, b, c, d, e, f, det, idet,
34535             offsetX = texture.offset.x / texture.repeat.x,
34536             offsetY = texture.offset.y / texture.repeat.y,
34537             width = texture.image.width * texture.repeat.x,
34538             height = texture.image.height * texture.repeat.y;
34539
34540             u0 = ( u0 + offsetX ) * width;
34541             v0 = ( 1.0 - v0 + offsetY ) * height;
34542
34543             u1 = ( u1 + offsetX ) * width;
34544             v1 = ( 1.0 - v1 + offsetY ) * height;
34545
34546             u2 = ( u2 + offsetX ) * width;
34547             v2 = ( 1.0 - v2 + offsetY ) * height;
34548
34549             x1 -= x0; y1 -= y0;
34550             x2 -= x0; y2 -= y0;
34551
34552             u1 -= u0; v1 -= v0;
34553             u2 -= u0; v2 -= v0;
34554
34555             det = u1 * v2 - u2 * v1;
34556
34557             if ( det === 0 ) {
34558
34559                 if ( _imagedatas[ texture.id ] === undefined ) {
34560
34561                     var canvas = document.createElement( 'canvas' )
34562                     canvas.width = texture.image.width;
34563                     canvas.height = texture.image.height;
34564
34565                     var context = canvas.getContext( '2d' );
34566                     context.drawImage( texture.image, 0, 0 );
34567
34568                     _imagedatas[ texture.id ] = context.getImageData( 0, 0, texture.image.width, texture.image.height ).data;
34569
34570                 }
34571
34572                 var data = _imagedatas[ texture.id ];
34573                 var index = ( Math.floor( u0 ) + Math.floor( v0 ) * texture.image.width ) * 4;
34574
34575                 _color.setRGB( data[ index ] / 255, data[ index + 1 ] / 255, data[ index + 2 ] / 255 );
34576                 fillPath( _color );
34577
34578                 return;
34579
34580             }
34581
34582             idet = 1 / det;
34583
34584             a = ( v2 * x1 - v1 * x2 ) * idet;
34585             b = ( v2 * y1 - v1 * y2 ) * idet;
34586             c = ( u1 * x2 - u2 * x1 ) * idet;
34587             d = ( u1 * y2 - u2 * y1 ) * idet;
34588
34589             e = x0 - a * u0 - c * v0;
34590             f = y0 - b * u0 - d * v0;
34591
34592             _context.save();
34593             _context.transform( a, b, c, d, e, f );
34594             _context.fill();
34595             _context.restore();
34596
34597         }
34598
34599         function clipImage( x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, u2, v2, image ) {
34600
34601             // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
34602
34603             var a, b, c, d, e, f, det, idet,
34604             width = image.width - 1,
34605             height = image.height - 1;
34606
34607             u0 *= width; v0 *= height;
34608             u1 *= width; v1 *= height;
34609             u2 *= width; v2 *= height;
34610
34611             x1 -= x0; y1 -= y0;
34612             x2 -= x0; y2 -= y0;
34613
34614             u1 -= u0; v1 -= v0;
34615             u2 -= u0; v2 -= v0;
34616
34617             det = u1 * v2 - u2 * v1;
34618
34619             idet = 1 / det;
34620
34621             a = ( v2 * x1 - v1 * x2 ) * idet;
34622             b = ( v2 * y1 - v1 * y2 ) * idet;
34623             c = ( u1 * x2 - u2 * x1 ) * idet;
34624             d = ( u1 * y2 - u2 * y1 ) * idet;
34625
34626             e = x0 - a * u0 - c * v0;
34627             f = y0 - b * u0 - d * v0;
34628
34629             _context.save();
34630             _context.transform( a, b, c, d, e, f );
34631             _context.clip();
34632             _context.drawImage( image, 0, 0 );
34633             _context.restore();
34634
34635         }
34636
34637         function getGradientTexture( color1, color2, color3, color4 ) {
34638
34639             // http://mrdoob.com/blog/post/710
34640
34641             _pixelMapData[ 0 ] = ( color1.r * 255 ) | 0;
34642             _pixelMapData[ 1 ] = ( color1.g * 255 ) | 0;
34643             _pixelMapData[ 2 ] = ( color1.b * 255 ) | 0;
34644
34645             _pixelMapData[ 4 ] = ( color2.r * 255 ) | 0;
34646             _pixelMapData[ 5 ] = ( color2.g * 255 ) | 0;
34647             _pixelMapData[ 6 ] = ( color2.b * 255 ) | 0;
34648
34649             _pixelMapData[ 8 ] = ( color3.r * 255 ) | 0;
34650             _pixelMapData[ 9 ] = ( color3.g * 255 ) | 0;
34651             _pixelMapData[ 10 ] = ( color3.b * 255 ) | 0;
34652
34653             _pixelMapData[ 12 ] = ( color4.r * 255 ) | 0;
34654             _pixelMapData[ 13 ] = ( color4.g * 255 ) | 0;
34655             _pixelMapData[ 14 ] = ( color4.b * 255 ) | 0;
34656
34657             _pixelMapContext.putImageData( _pixelMapImage, 0, 0 );
34658             _gradientMapContext.drawImage( _pixelMap, 0, 0 );
34659
34660             return _gradientMap;
34661
34662         }
34663
34664         function smoothstep( value, min, max ) {
34665
34666             var x = ( value - min ) / ( max - min );
34667             return x * x * ( 3 - 2 * x );
34668
34669         }
34670
34671         function normalToComponent( normal ) {
34672
34673             var component = ( normal + 1 ) * 0.5;
34674             return component < 0 ? 0 : ( component > 1 ? 1 : component );
34675
34676         }
34677
34678         // Hide anti-alias gaps
34679
34680         function expand( v1, v2 ) {
34681
34682             var x = v2.x - v1.x, y =  v2.y - v1.y,
34683             det = x * x + y * y, idet;
34684
34685             if ( det === 0 ) return;
34686
34687             idet = 1 / Math.sqrt( det );
34688
34689             x *= idet; y *= idet;
34690
34691             v2.x += x; v2.y += y;
34692             v1.x -= x; v1.y -= y;
34693
34694         }
34695     };
34696
34697     // Context cached methods.
34698
34699     function setOpacity( value ) {
34700
34701         if ( _contextGlobalAlpha !== value ) {
34702
34703             _context.globalAlpha = value;
34704             _contextGlobalAlpha = value;
34705
34706         }
34707
34708     }
34709
34710     function setBlending( value ) {
34711
34712         if ( _contextGlobalCompositeOperation !== value ) {
34713
34714             if ( value === THREE.NormalBlending ) {
34715
34716                 _context.globalCompositeOperation = 'source-over';
34717
34718             } else if ( value === THREE.AdditiveBlending ) {
34719
34720                 _context.globalCompositeOperation = 'lighter';
34721
34722             } else if ( value === THREE.SubtractiveBlending ) {
34723
34724                 _context.globalCompositeOperation = 'darker';
34725
34726             }
34727
34728             _contextGlobalCompositeOperation = value;
34729
34730         }
34731
34732     }
34733
34734     function setLineWidth( value ) {
34735
34736         if ( _contextLineWidth !== value ) {
34737
34738             _context.lineWidth = value;
34739             _contextLineWidth = value;
34740
34741         }
34742
34743     }
34744
34745     function setLineCap( value ) {
34746
34747         // "butt", "round", "square"
34748
34749         if ( _contextLineCap !== value ) {
34750
34751             _context.lineCap = value;
34752             _contextLineCap = value;
34753
34754         }
34755
34756     }
34757
34758     function setLineJoin( value ) {
34759
34760         // "round", "bevel", "miter"
34761
34762         if ( _contextLineJoin !== value ) {
34763
34764             _context.lineJoin = value;
34765             _contextLineJoin = value;
34766
34767         }
34768
34769     }
34770
34771     function setStrokeStyle( value ) {
34772
34773         if ( _contextStrokeStyle !== value ) {
34774
34775             _context.strokeStyle = value;
34776             _contextStrokeStyle = value;
34777
34778         }
34779
34780     }
34781
34782     function setFillStyle( value ) {
34783
34784         if ( _contextFillStyle !== value ) {
34785
34786             _context.fillStyle = value;
34787             _contextFillStyle = value;
34788
34789         }
34790
34791     }
34792
34793 };
34794 /**
34795  * @author alteredq / http://alteredqualia.com/
34796  * @author mrdoob / http://mrdoob.com/
34797  * @author mikael emtinger / http://gomo.se/
34798  */
34799
34800 THREE.ShaderChunk = {
34801
34802     // FOG
34803
34804     fog_pars_fragment: [
34805
34806         "#ifdef USE_FOG",
34807
34808             "uniform vec3 fogColor;",
34809
34810             "#ifdef FOG_EXP2",
34811
34812                 "uniform float fogDensity;",
34813
34814             "#else",
34815
34816                 "uniform float fogNear;",
34817                 "uniform float fogFar;",
34818
34819             "#endif",
34820
34821         "#endif"
34822
34823     ].join("\n"),
34824
34825     fog_fragment: [
34826
34827         "#ifdef USE_FOG",
34828
34829             "float depth = gl_FragCoord.z / gl_FragCoord.w;",
34830
34831             "#ifdef FOG_EXP2",
34832
34833                 "const float LOG2 = 1.442695;",
34834                 "float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );",
34835                 "fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );",
34836
34837             "#else",
34838
34839                 "float fogFactor = smoothstep( fogNear, fogFar, depth );",
34840
34841             "#endif",
34842
34843             "gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );",
34844
34845         "#endif"
34846
34847     ].join("\n"),
34848
34849     // ENVIRONMENT MAP
34850
34851     envmap_pars_fragment: [
34852
34853         "#ifdef USE_ENVMAP",
34854
34855             "uniform float reflectivity;",
34856             "uniform samplerCube envMap;",
34857             "uniform float flipEnvMap;",
34858             "uniform int combine;",
34859
34860             "#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )",
34861
34862                 "uniform bool useRefract;",
34863                 "uniform float refractionRatio;",
34864
34865             "#else",
34866
34867                 "varying vec3 vReflect;",
34868
34869             "#endif",
34870
34871         "#endif"
34872
34873     ].join("\n"),
34874
34875     envmap_fragment: [
34876
34877         "#ifdef USE_ENVMAP",
34878
34879             "vec3 reflectVec;",
34880
34881             "#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )",
34882
34883                 "vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
34884
34885                 "if ( useRefract ) {",
34886
34887                     "reflectVec = refract( cameraToVertex, normal, refractionRatio );",
34888
34889                 "} else { ",
34890
34891                     "reflectVec = reflect( cameraToVertex, normal );",
34892
34893                 "}",
34894
34895             "#else",
34896
34897                 "reflectVec = vReflect;",
34898
34899             "#endif",
34900
34901             "#ifdef DOUBLE_SIDED",
34902
34903                 "float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
34904                 "vec4 cubeColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
34905
34906             "#else",
34907
34908                 "vec4 cubeColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );",
34909
34910             "#endif",
34911
34912             "#ifdef GAMMA_INPUT",
34913
34914                 "cubeColor.xyz *= cubeColor.xyz;",
34915
34916             "#endif",
34917
34918             "if ( combine == 1 ) {",
34919
34920                 "gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularStrength * reflectivity );",
34921
34922             "} else {",
34923
34924                 "gl_FragColor.xyz = mix( gl_FragColor.xyz, gl_FragColor.xyz * cubeColor.xyz, specularStrength * reflectivity );",
34925
34926             "}",
34927
34928         "#endif"
34929
34930     ].join("\n"),
34931
34932     envmap_pars_vertex: [
34933
34934         "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )",
34935
34936             "varying vec3 vReflect;",
34937
34938             "uniform float refractionRatio;",
34939             "uniform bool useRefract;",
34940
34941         "#endif"
34942
34943     ].join("\n"),
34944
34945     worldpos_vertex : [
34946
34947         "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )",
34948
34949             "#ifdef USE_SKINNING",
34950
34951                 "vec4 mPosition = modelMatrix * skinned;",
34952
34953             "#endif",
34954
34955             "#if defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )",
34956
34957                 "vec4 mPosition = modelMatrix * vec4( morphed, 1.0 );",
34958
34959             "#endif",
34960
34961             "#if ! defined( USE_MORPHTARGETS ) && ! defined( USE_SKINNING )",
34962
34963                 "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
34964
34965             "#endif",
34966
34967         "#endif"
34968
34969     ].join("\n"),
34970
34971     envmap_vertex : [
34972
34973         "#if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP )",
34974
34975             "vec3 nWorld = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * objectNormal;",
34976
34977             "if ( useRefract ) {",
34978
34979                 "vReflect = refract( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ), refractionRatio );",
34980
34981             "} else {",
34982
34983                 "vReflect = reflect( normalize( mPosition.xyz - cameraPosition ), normalize( nWorld.xyz ) );",
34984
34985             "}",
34986
34987         "#endif"
34988
34989     ].join("\n"),
34990
34991     // COLOR MAP (particles)
34992
34993     map_particle_pars_fragment: [
34994
34995         "#ifdef USE_MAP",
34996
34997             "uniform sampler2D map;",
34998
34999         "#endif"
35000
35001     ].join("\n"),
35002
35003
35004     map_particle_fragment: [
35005
35006         "#ifdef USE_MAP",
35007
35008             "gl_FragColor = gl_FragColor * texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );",
35009
35010         "#endif"
35011
35012     ].join("\n"),
35013
35014     // COLOR MAP (triangles)
35015
35016     map_pars_vertex: [
35017
35018         "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",
35019
35020             "varying vec2 vUv;",
35021             "uniform vec4 offsetRepeat;",
35022
35023         "#endif"
35024
35025     ].join("\n"),
35026
35027     map_pars_fragment: [
35028
35029         "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",
35030
35031             "varying vec2 vUv;",
35032
35033         "#endif",
35034
35035         "#ifdef USE_MAP",
35036
35037             "uniform sampler2D map;",
35038
35039         "#endif",
35040
35041     ].join("\n"),
35042
35043     map_vertex: [
35044
35045         "#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP )",
35046
35047             "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
35048
35049         "#endif"
35050
35051     ].join("\n"),
35052
35053     map_fragment: [
35054
35055         "#ifdef USE_MAP",
35056
35057             "#ifdef GAMMA_INPUT",
35058
35059                 "vec4 texelColor = texture2D( map, vUv );",
35060                 "texelColor.xyz *= texelColor.xyz;",
35061
35062                 "gl_FragColor = gl_FragColor * texelColor;",
35063
35064             "#else",
35065
35066                 "gl_FragColor = gl_FragColor * texture2D( map, vUv );",
35067
35068             "#endif",
35069
35070         "#endif"
35071
35072     ].join("\n"),
35073
35074     // LIGHT MAP
35075
35076     lightmap_pars_fragment: [
35077
35078         "#ifdef USE_LIGHTMAP",
35079
35080             "varying vec2 vUv2;",
35081             "uniform sampler2D lightMap;",
35082
35083         "#endif"
35084
35085     ].join("\n"),
35086
35087     lightmap_pars_vertex: [
35088
35089         "#ifdef USE_LIGHTMAP",
35090
35091             "varying vec2 vUv2;",
35092
35093         "#endif"
35094
35095     ].join("\n"),
35096
35097     lightmap_fragment: [
35098
35099         "#ifdef USE_LIGHTMAP",
35100
35101             "gl_FragColor = gl_FragColor * texture2D( lightMap, vUv2 );",
35102
35103         "#endif"
35104
35105     ].join("\n"),
35106
35107     lightmap_vertex: [
35108
35109         "#ifdef USE_LIGHTMAP",
35110
35111             "vUv2 = uv2;",
35112
35113         "#endif"
35114
35115     ].join("\n"),
35116
35117     // BUMP MAP
35118
35119     bumpmap_pars_fragment: [
35120
35121         "#ifdef USE_BUMPMAP",
35122
35123             "uniform sampler2D bumpMap;",
35124             "uniform float bumpScale;",
35125
35126             // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen
35127             //    http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html
35128
35129             // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
35130
35131             "vec2 dHdxy_fwd() {",
35132
35133                 "vec2 dSTdx = dFdx( vUv );",
35134                 "vec2 dSTdy = dFdy( vUv );",
35135
35136                 "float Hll = bumpScale * texture2D( bumpMap, vUv ).x;",
35137                 "float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;",
35138                 "float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;",
35139
35140                 "return vec2( dBx, dBy );",
35141
35142             "}",
35143
35144             "vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {",
35145
35146                 "vec3 vSigmaX = dFdx( surf_pos );",
35147                 "vec3 vSigmaY = dFdy( surf_pos );",
35148                 "vec3 vN = surf_norm;",        // normalized
35149
35150                 "vec3 R1 = cross( vSigmaY, vN );",
35151                 "vec3 R2 = cross( vN, vSigmaX );",
35152
35153                 "float fDet = dot( vSigmaX, R1 );",
35154
35155                 "vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );",
35156                 "return normalize( abs( fDet ) * surf_norm - vGrad );",
35157
35158             "}",
35159
35160         "#endif"
35161
35162     ].join("\n"),
35163
35164     // NORMAL MAP
35165
35166     normalmap_pars_fragment: [
35167
35168         "#ifdef USE_NORMALMAP",
35169
35170             "uniform sampler2D normalMap;",
35171             "uniform vec2 normalScale;",
35172
35173             // Per-Pixel Tangent Space Normal Mapping
35174             // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
35175
35176             "vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {",
35177
35178                 "vec3 q0 = dFdx( eye_pos.xyz );",
35179                 "vec3 q1 = dFdy( eye_pos.xyz );",
35180                 "vec2 st0 = dFdx( vUv.st );",
35181                 "vec2 st1 = dFdy( vUv.st );",
35182
35183                 "vec3 S = normalize(  q0 * st1.t - q1 * st0.t );",
35184                 "vec3 T = normalize( -q0 * st1.s + q1 * st0.s );",
35185                 "vec3 N = normalize( surf_norm );",
35186
35187                 "vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;",
35188                 "mapN.xy = normalScale * mapN.xy;",
35189                 "mat3 tsn = mat3( S, T, N );",
35190                 "return normalize( tsn * mapN );",
35191
35192             "}",
35193
35194         "#endif"
35195
35196     ].join("\n"),
35197
35198     // SPECULAR MAP
35199
35200     specularmap_pars_fragment: [
35201
35202         "#ifdef USE_SPECULARMAP",
35203
35204             "uniform sampler2D specularMap;",
35205
35206         "#endif"
35207
35208     ].join("\n"),
35209
35210     specularmap_fragment: [
35211
35212         "float specularStrength;",
35213
35214         "#ifdef USE_SPECULARMAP",
35215
35216             "vec4 texelSpecular = texture2D( specularMap, vUv );",
35217             "specularStrength = texelSpecular.r;",
35218
35219         "#else",
35220
35221             "specularStrength = 1.0;",
35222
35223         "#endif"
35224
35225     ].join("\n"),
35226
35227     // LIGHTS LAMBERT
35228
35229     lights_lambert_pars_vertex: [
35230
35231         "uniform vec3 ambient;",
35232         "uniform vec3 diffuse;",
35233         "uniform vec3 emissive;",
35234
35235         "uniform vec3 ambientLightColor;",
35236
35237         "#if MAX_DIR_LIGHTS > 0",
35238
35239             "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
35240             "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
35241
35242         "#endif",
35243
35244         "#if MAX_HEMI_LIGHTS > 0",
35245
35246             "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
35247             "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
35248             "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
35249
35250         "#endif",
35251
35252         "#if MAX_POINT_LIGHTS > 0",
35253
35254             "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
35255             "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
35256             "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
35257
35258         "#endif",
35259
35260         "#if MAX_SPOT_LIGHTS > 0",
35261
35262             "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
35263             "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
35264             "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
35265             "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
35266             "uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
35267             "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
35268
35269         "#endif",
35270
35271         "#ifdef WRAP_AROUND",
35272
35273             "uniform vec3 wrapRGB;",
35274
35275         "#endif"
35276
35277     ].join("\n"),
35278
35279     lights_lambert_vertex: [
35280
35281         "vLightFront = vec3( 0.0 );",
35282
35283         "#ifdef DOUBLE_SIDED",
35284
35285             "vLightBack = vec3( 0.0 );",
35286
35287         "#endif",
35288
35289         "transformedNormal = normalize( transformedNormal );",
35290
35291         "#if MAX_DIR_LIGHTS > 0",
35292
35293         "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
35294
35295             "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
35296             "vec3 dirVector = normalize( lDirection.xyz );",
35297
35298             "float dotProduct = dot( transformedNormal, dirVector );",
35299             "vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );",
35300
35301             "#ifdef DOUBLE_SIDED",
35302
35303                 "vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
35304
35305                 "#ifdef WRAP_AROUND",
35306
35307                     "vec3 directionalLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
35308
35309                 "#endif",
35310
35311             "#endif",
35312
35313             "#ifdef WRAP_AROUND",
35314
35315                 "vec3 directionalLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
35316                 "directionalLightWeighting = mix( directionalLightWeighting, directionalLightWeightingHalf, wrapRGB );",
35317
35318                 "#ifdef DOUBLE_SIDED",
35319
35320                     "directionalLightWeightingBack = mix( directionalLightWeightingBack, directionalLightWeightingHalfBack, wrapRGB );",
35321
35322                 "#endif",
35323
35324             "#endif",
35325
35326             "vLightFront += directionalLightColor[ i ] * directionalLightWeighting;",
35327
35328             "#ifdef DOUBLE_SIDED",
35329
35330                 "vLightBack += directionalLightColor[ i ] * directionalLightWeightingBack;",
35331
35332             "#endif",
35333
35334         "}",
35335
35336         "#endif",
35337
35338         "#if MAX_POINT_LIGHTS > 0",
35339
35340             "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
35341
35342                 "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
35343                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35344
35345                 "float lDistance = 1.0;",
35346                 "if ( pointLightDistance[ i ] > 0.0 )",
35347                     "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
35348
35349                 "lVector = normalize( lVector );",
35350                 "float dotProduct = dot( transformedNormal, lVector );",
35351
35352                 "vec3 pointLightWeighting = vec3( max( dotProduct, 0.0 ) );",
35353
35354                 "#ifdef DOUBLE_SIDED",
35355
35356                     "vec3 pointLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
35357
35358                     "#ifdef WRAP_AROUND",
35359
35360                         "vec3 pointLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
35361
35362                     "#endif",
35363
35364                 "#endif",
35365
35366                 "#ifdef WRAP_AROUND",
35367
35368                     "vec3 pointLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
35369                     "pointLightWeighting = mix( pointLightWeighting, pointLightWeightingHalf, wrapRGB );",
35370
35371                     "#ifdef DOUBLE_SIDED",
35372
35373                         "pointLightWeightingBack = mix( pointLightWeightingBack, pointLightWeightingHalfBack, wrapRGB );",
35374
35375                     "#endif",
35376
35377                 "#endif",
35378
35379                 "vLightFront += pointLightColor[ i ] * pointLightWeighting * lDistance;",
35380
35381                 "#ifdef DOUBLE_SIDED",
35382
35383                     "vLightBack += pointLightColor[ i ] * pointLightWeightingBack * lDistance;",
35384
35385                 "#endif",
35386
35387             "}",
35388
35389         "#endif",
35390
35391         "#if MAX_SPOT_LIGHTS > 0",
35392
35393             "for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
35394
35395                 "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
35396                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35397
35398                 "lVector = normalize( lVector );",
35399
35400                 "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - mPosition.xyz ) );",
35401
35402                 "if ( spotEffect > spotLightAngle[ i ] ) {",
35403
35404                     "spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
35405
35406                     "float lDistance = 1.0;",
35407                     "if ( spotLightDistance[ i ] > 0.0 )",
35408                         "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
35409
35410                     "float dotProduct = dot( transformedNormal, lVector );",
35411                     "vec3 spotLightWeighting = vec3( max( dotProduct, 0.0 ) );",
35412
35413                     "#ifdef DOUBLE_SIDED",
35414
35415                         "vec3 spotLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );",
35416
35417                         "#ifdef WRAP_AROUND",
35418
35419                             "vec3 spotLightWeightingHalfBack = vec3( max( -0.5 * dotProduct + 0.5, 0.0 ) );",
35420
35421                         "#endif",
35422
35423                     "#endif",
35424
35425                     "#ifdef WRAP_AROUND",
35426
35427                         "vec3 spotLightWeightingHalf = vec3( max( 0.5 * dotProduct + 0.5, 0.0 ) );",
35428                         "spotLightWeighting = mix( spotLightWeighting, spotLightWeightingHalf, wrapRGB );",
35429
35430                         "#ifdef DOUBLE_SIDED",
35431
35432                             "spotLightWeightingBack = mix( spotLightWeightingBack, spotLightWeightingHalfBack, wrapRGB );",
35433
35434                         "#endif",
35435
35436                     "#endif",
35437
35438                     "vLightFront += spotLightColor[ i ] * spotLightWeighting * lDistance * spotEffect;",
35439
35440                     "#ifdef DOUBLE_SIDED",
35441
35442                         "vLightBack += spotLightColor[ i ] * spotLightWeightingBack * lDistance * spotEffect;",
35443
35444                     "#endif",
35445
35446                 "}",
35447
35448             "}",
35449
35450         "#endif",
35451
35452         "#if MAX_HEMI_LIGHTS > 0",
35453
35454             "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
35455
35456                 "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
35457                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35458
35459                 "lVector = normalize( lVector );",
35460
35461                 "float dotProduct = dot( transformedNormal, lVector );",
35462
35463                 "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
35464                 "float hemiDiffuseWeightBack = -0.5 * dotProduct + 0.5;",
35465
35466                 "vLightFront += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
35467
35468                 "#ifdef DOUBLE_SIDED",
35469
35470                     "vLightBack += mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeightBack );",
35471
35472                 "#endif",
35473
35474             "}",
35475
35476         "#endif",
35477
35478         "vLightFront = vLightFront * diffuse + ambient * ambientLightColor + emissive;",
35479
35480         "#ifdef DOUBLE_SIDED",
35481
35482             "vLightBack = vLightBack * diffuse + ambient * ambientLightColor + emissive;",
35483
35484         "#endif"
35485
35486     ].join("\n"),
35487
35488     // LIGHTS PHONG
35489
35490     lights_phong_pars_vertex: [
35491
35492         "#ifndef PHONG_PER_PIXEL",
35493
35494         "#if MAX_POINT_LIGHTS > 0",
35495
35496             "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
35497             "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
35498
35499             "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
35500
35501         "#endif",
35502
35503         "#if MAX_SPOT_LIGHTS > 0",
35504
35505             "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
35506             "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
35507
35508             "varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",
35509
35510         "#endif",
35511
35512         "#endif",
35513
35514         "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",
35515
35516             "varying vec3 vWorldPosition;",
35517
35518         "#endif"
35519
35520     ].join("\n"),
35521
35522
35523     lights_phong_vertex: [
35524
35525         "#ifndef PHONG_PER_PIXEL",
35526
35527         "#if MAX_POINT_LIGHTS > 0",
35528
35529             "for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
35530
35531                 "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
35532                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35533
35534                 "float lDistance = 1.0;",
35535                 "if ( pointLightDistance[ i ] > 0.0 )",
35536                     "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
35537
35538                 "vPointLight[ i ] = vec4( lVector, lDistance );",
35539
35540             "}",
35541
35542         "#endif",
35543
35544         "#if MAX_SPOT_LIGHTS > 0",
35545
35546             "for( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
35547
35548                 "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
35549                 "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
35550
35551                 "float lDistance = 1.0;",
35552                 "if ( spotLightDistance[ i ] > 0.0 )",
35553                     "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
35554
35555                 "vSpotLight[ i ] = vec4( lVector, lDistance );",
35556
35557             "}",
35558
35559         "#endif",
35560
35561         "#endif",
35562
35563         "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",
35564
35565             "vWorldPosition = mPosition.xyz;",
35566
35567         "#endif"
35568
35569     ].join("\n"),
35570
35571     lights_phong_pars_fragment: [
35572
35573         "uniform vec3 ambientLightColor;",
35574
35575         "#if MAX_DIR_LIGHTS > 0",
35576
35577             "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
35578             "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
35579
35580         "#endif",
35581
35582         "#if MAX_HEMI_LIGHTS > 0",
35583
35584             "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
35585             "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
35586             "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
35587
35588         "#endif",
35589
35590         "#if MAX_POINT_LIGHTS > 0",
35591
35592             "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
35593
35594             "#ifdef PHONG_PER_PIXEL",
35595
35596                 "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
35597                 "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
35598
35599             "#else",
35600
35601                 "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
35602
35603             "#endif",
35604
35605         "#endif",
35606
35607         "#if MAX_SPOT_LIGHTS > 0",
35608
35609             "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
35610             "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
35611             "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
35612             "uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
35613             "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
35614
35615             "#ifdef PHONG_PER_PIXEL",
35616
35617                 "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
35618
35619             "#else",
35620
35621                 "varying vec4 vSpotLight[ MAX_SPOT_LIGHTS ];",
35622
35623             "#endif",
35624
35625         "#endif",
35626
35627         "#if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP )",
35628
35629             "varying vec3 vWorldPosition;",
35630
35631         "#endif",
35632
35633         "#ifdef WRAP_AROUND",
35634
35635             "uniform vec3 wrapRGB;",
35636
35637         "#endif",
35638
35639         "varying vec3 vViewPosition;",
35640         "varying vec3 vNormal;"
35641
35642     ].join("\n"),
35643
35644     lights_phong_fragment: [
35645
35646         "vec3 normal = normalize( vNormal );",
35647         "vec3 viewPosition = normalize( vViewPosition );",
35648
35649         "#ifdef DOUBLE_SIDED",
35650
35651             "normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) );",
35652
35653         "#endif",
35654
35655         "#ifdef USE_NORMALMAP",
35656
35657             "normal = perturbNormal2Arb( -viewPosition, normal );",
35658
35659         "#elif defined( USE_BUMPMAP )",
35660
35661             "normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",
35662
35663         "#endif",
35664
35665         "#if MAX_POINT_LIGHTS > 0",
35666
35667             "vec3 pointDiffuse  = vec3( 0.0 );",
35668             "vec3 pointSpecular = vec3( 0.0 );",
35669
35670             "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
35671
35672                 "#ifdef PHONG_PER_PIXEL",
35673
35674                     "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
35675                     "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
35676
35677                     "float lDistance = 1.0;",
35678                     "if ( pointLightDistance[ i ] > 0.0 )",
35679                         "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
35680
35681                     "lVector = normalize( lVector );",
35682
35683                 "#else",
35684
35685                     "vec3 lVector = normalize( vPointLight[ i ].xyz );",
35686                     "float lDistance = vPointLight[ i ].w;",
35687
35688                 "#endif",
35689
35690                 // diffuse
35691
35692                 "float dotProduct = dot( normal, lVector );",
35693
35694                 "#ifdef WRAP_AROUND",
35695
35696                     "float pointDiffuseWeightFull = max( dotProduct, 0.0 );",
35697                     "float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
35698
35699                     "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );",
35700
35701                 "#else",
35702
35703                     "float pointDiffuseWeight = max( dotProduct, 0.0 );",
35704
35705                 "#endif",
35706
35707                 "pointDiffuse  += diffuse * pointLightColor[ i ] * pointDiffuseWeight * lDistance;",
35708
35709                 // specular
35710
35711                 "vec3 pointHalfVector = normalize( lVector + viewPosition );",
35712                 "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
35713                 "float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 );",
35714
35715                 "#ifdef PHYSICALLY_BASED_SHADING",
35716
35717                     // 2.0 => 2.0001 is hack to work around ANGLE bug
35718
35719                     "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
35720
35721                     "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, pointHalfVector ), 5.0 );",
35722                     "pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance * specularNormalization;",
35723
35724                 "#else",
35725
35726                     "pointSpecular += specular * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * lDistance;",
35727
35728                 "#endif",
35729
35730             "}",
35731
35732         "#endif",
35733
35734         "#if MAX_SPOT_LIGHTS > 0",
35735
35736             "vec3 spotDiffuse  = vec3( 0.0 );",
35737             "vec3 spotSpecular = vec3( 0.0 );",
35738
35739             "for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
35740
35741                 "#ifdef PHONG_PER_PIXEL",
35742
35743                     "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
35744                     "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
35745
35746                     "float lDistance = 1.0;",
35747                     "if ( spotLightDistance[ i ] > 0.0 )",
35748                         "lDistance = 1.0 - min( ( length( lVector ) / spotLightDistance[ i ] ), 1.0 );",
35749
35750                     "lVector = normalize( lVector );",
35751
35752                 "#else",
35753
35754                     "vec3 lVector = normalize( vSpotLight[ i ].xyz );",
35755                     "float lDistance = vSpotLight[ i ].w;",
35756
35757                 "#endif",
35758
35759                 "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );",
35760
35761                 "if ( spotEffect > spotLightAngle[ i ] ) {",
35762
35763                     "spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
35764
35765                     // diffuse
35766
35767                     "float dotProduct = dot( normal, lVector );",
35768
35769                     "#ifdef WRAP_AROUND",
35770
35771                         "float spotDiffuseWeightFull = max( dotProduct, 0.0 );",
35772                         "float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
35773
35774                         "vec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );",
35775
35776                     "#else",
35777
35778                         "float spotDiffuseWeight = max( dotProduct, 0.0 );",
35779
35780                     "#endif",
35781
35782                     "spotDiffuse += diffuse * spotLightColor[ i ] * spotDiffuseWeight * lDistance * spotEffect;",
35783
35784                     // specular
35785
35786                     "vec3 spotHalfVector = normalize( lVector + viewPosition );",
35787                     "float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
35788                     "float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 );",
35789
35790                     "#ifdef PHYSICALLY_BASED_SHADING",
35791
35792                         // 2.0 => 2.0001 is hack to work around ANGLE bug
35793
35794                         "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
35795
35796                         "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, spotHalfVector ), 5.0 );",
35797                         "spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * specularNormalization * spotEffect;",
35798
35799                     "#else",
35800
35801                         "spotSpecular += specular * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * lDistance * spotEffect;",
35802
35803                     "#endif",
35804
35805                 "}",
35806
35807             "}",
35808
35809         "#endif",
35810
35811         "#if MAX_DIR_LIGHTS > 0",
35812
35813             "vec3 dirDiffuse  = vec3( 0.0 );",
35814             "vec3 dirSpecular = vec3( 0.0 );" ,
35815
35816             "for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
35817
35818                 "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
35819                 "vec3 dirVector = normalize( lDirection.xyz );",
35820
35821                 // diffuse
35822
35823                 "float dotProduct = dot( normal, dirVector );",
35824
35825                 "#ifdef WRAP_AROUND",
35826
35827                     "float dirDiffuseWeightFull = max( dotProduct, 0.0 );",
35828                     "float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 );",
35829
35830                     "vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB );",
35831
35832                 "#else",
35833
35834                     "float dirDiffuseWeight = max( dotProduct, 0.0 );",
35835
35836                 "#endif",
35837
35838                 "dirDiffuse  += diffuse * directionalLightColor[ i ] * dirDiffuseWeight;",
35839
35840                 // specular
35841
35842                 "vec3 dirHalfVector = normalize( dirVector + viewPosition );",
35843                 "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
35844                 "float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 );",
35845
35846                 "#ifdef PHYSICALLY_BASED_SHADING",
35847
35848                     /*
35849                     // fresnel term from skin shader
35850                     "const float F0 = 0.128;",
35851
35852                     "float base = 1.0 - dot( viewPosition, dirHalfVector );",
35853                     "float exponential = pow( base, 5.0 );",
35854
35855                     "float fresnel = exponential + F0 * ( 1.0 - exponential );",
35856                     */
35857
35858                     /*
35859                     // fresnel term from fresnel shader
35860                     "const float mFresnelBias = 0.08;",
35861                     "const float mFresnelScale = 0.3;",
35862                     "const float mFresnelPower = 5.0;",
35863
35864                     "float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower );",
35865                     */
35866
35867                     // 2.0 => 2.0001 is hack to work around ANGLE bug
35868
35869                     "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
35870
35871                     //"dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel;",
35872
35873                     "vec3 schlick = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );",
35874                     "dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
35875
35876                 "#else",
35877
35878                     "dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight;",
35879
35880                 "#endif",
35881
35882             "}",
35883
35884         "#endif",
35885
35886         "#if MAX_HEMI_LIGHTS > 0",
35887
35888             "vec3 hemiDiffuse  = vec3( 0.0 );",
35889             "vec3 hemiSpecular = vec3( 0.0 );" ,
35890
35891             "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
35892
35893                 "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
35894                 "vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
35895
35896                 // diffuse
35897
35898                 "float dotProduct = dot( normal, lVector );",
35899                 "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
35900
35901                 "vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
35902
35903                 "hemiDiffuse += diffuse * hemiColor;",
35904
35905                 // specular (sky light)
35906
35907                 "vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
35908                 "float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
35909                 "float hemiSpecularWeightSky = specularStrength * max( pow( hemiDotNormalHalfSky, shininess ), 0.0 );",
35910
35911                 // specular (ground light)
35912
35913                 "vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
35914
35915                 "vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
35916                 "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
35917                 "float hemiSpecularWeightGround = specularStrength * max( pow( hemiDotNormalHalfGround, shininess ), 0.0 );",
35918
35919                 "#ifdef PHYSICALLY_BASED_SHADING",
35920
35921                     "float dotProductGround = dot( normal, lVectorGround );",
35922
35923                     // 2.0 => 2.0001 is hack to work around ANGLE bug
35924
35925                     "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
35926
35927                     "vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );",
35928                     "vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
35929                     "hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
35930
35931                 "#else",
35932
35933                     "hemiSpecular += specular * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;",
35934
35935                 "#endif",
35936
35937             "}",
35938
35939         "#endif",
35940
35941         "vec3 totalDiffuse = vec3( 0.0 );",
35942         "vec3 totalSpecular = vec3( 0.0 );",
35943
35944         "#if MAX_DIR_LIGHTS > 0",
35945
35946             "totalDiffuse += dirDiffuse;",
35947             "totalSpecular += dirSpecular;",
35948
35949         "#endif",
35950
35951         "#if MAX_HEMI_LIGHTS > 0",
35952
35953             "totalDiffuse += hemiDiffuse;",
35954             "totalSpecular += hemiSpecular;",
35955
35956         "#endif",
35957
35958         "#if MAX_POINT_LIGHTS > 0",
35959
35960             "totalDiffuse += pointDiffuse;",
35961             "totalSpecular += pointSpecular;",
35962
35963         "#endif",
35964
35965         "#if MAX_SPOT_LIGHTS > 0",
35966
35967             "totalDiffuse += spotDiffuse;",
35968             "totalSpecular += spotSpecular;",
35969
35970         "#endif",
35971
35972         "#ifdef METAL",
35973
35974             "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient + totalSpecular );",
35975
35976         "#else",
35977
35978             "gl_FragColor.xyz = gl_FragColor.xyz * ( emissive + totalDiffuse + ambientLightColor * ambient ) + totalSpecular;",
35979
35980         "#endif"
35981
35982     ].join("\n"),
35983
35984     // VERTEX COLORS
35985
35986     color_pars_fragment: [
35987
35988         "#ifdef USE_COLOR",
35989
35990             "varying vec3 vColor;",
35991
35992         "#endif"
35993
35994     ].join("\n"),
35995
35996
35997     color_fragment: [
35998
35999         "#ifdef USE_COLOR",
36000
36001             "gl_FragColor = gl_FragColor * vec4( vColor, opacity );",
36002
36003         "#endif"
36004
36005     ].join("\n"),
36006
36007     color_pars_vertex: [
36008
36009         "#ifdef USE_COLOR",
36010
36011             "varying vec3 vColor;",
36012
36013         "#endif"
36014
36015     ].join("\n"),
36016
36017
36018     color_vertex: [
36019
36020         "#ifdef USE_COLOR",
36021
36022             "#ifdef GAMMA_INPUT",
36023
36024                 "vColor = color * color;",
36025
36026             "#else",
36027
36028                 "vColor = color;",
36029
36030             "#endif",
36031
36032         "#endif"
36033
36034     ].join("\n"),
36035
36036     // SKINNING
36037
36038     skinning_pars_vertex: [
36039
36040         "#ifdef USE_SKINNING",
36041
36042             "#ifdef BONE_TEXTURE",
36043
36044                 "uniform sampler2D boneTexture;",
36045
36046                 "mat4 getBoneMatrix( const in float i ) {",
36047
36048                     "float j = i * 4.0;",
36049                     "float x = mod( j, N_BONE_PIXEL_X );",
36050                     "float y = floor( j / N_BONE_PIXEL_X );",
36051
36052                     "const float dx = 1.0 / N_BONE_PIXEL_X;",
36053                     "const float dy = 1.0 / N_BONE_PIXEL_Y;",
36054
36055                     "y = dy * ( y + 0.5 );",
36056
36057                     "vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );",
36058                     "vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );",
36059                     "vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );",
36060                     "vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );",
36061
36062                     "mat4 bone = mat4( v1, v2, v3, v4 );",
36063
36064                     "return bone;",
36065
36066                 "}",
36067
36068             "#else",
36069
36070                 "uniform mat4 boneGlobalMatrices[ MAX_BONES ];",
36071
36072                 "mat4 getBoneMatrix( const in float i ) {",
36073
36074                     "mat4 bone = boneGlobalMatrices[ int(i) ];",
36075                     "return bone;",
36076
36077                 "}",
36078
36079             "#endif",
36080
36081         "#endif"
36082
36083     ].join("\n"),
36084
36085     skinbase_vertex: [
36086
36087         "#ifdef USE_SKINNING",
36088
36089             "mat4 boneMatX = getBoneMatrix( skinIndex.x );",
36090             "mat4 boneMatY = getBoneMatrix( skinIndex.y );",
36091
36092         "#endif"
36093
36094     ].join("\n"),
36095
36096     skinning_vertex: [
36097
36098         "#ifdef USE_SKINNING",
36099
36100             "#ifdef USE_MORPHTARGETS",
36101
36102             "vec4 skinVertex = vec4( morphed, 1.0 );",
36103
36104             "#else",
36105
36106             "vec4 skinVertex = vec4( position, 1.0 );",
36107
36108             "#endif",
36109
36110             "vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
36111             "skinned       += boneMatY * skinVertex * skinWeight.y;",
36112
36113         "#endif"
36114
36115     ].join("\n"),
36116
36117     // MORPHING
36118
36119     morphtarget_pars_vertex: [
36120
36121         "#ifdef USE_MORPHTARGETS",
36122
36123             "#ifndef USE_MORPHNORMALS",
36124
36125             "uniform float morphTargetInfluences[ 8 ];",
36126
36127             "#else",
36128
36129             "uniform float morphTargetInfluences[ 4 ];",
36130
36131             "#endif",
36132
36133         "#endif"
36134
36135     ].join("\n"),
36136
36137     morphtarget_vertex: [
36138
36139         "#ifdef USE_MORPHTARGETS",
36140
36141             "vec3 morphed = vec3( 0.0 );",
36142             "morphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];",
36143             "morphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];",
36144             "morphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];",
36145             "morphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];",
36146
36147             "#ifndef USE_MORPHNORMALS",
36148
36149             "morphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];",
36150             "morphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];",
36151             "morphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];",
36152             "morphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];",
36153
36154             "#endif",
36155
36156             "morphed += position;",
36157
36158         "#endif"
36159
36160     ].join("\n"),
36161
36162     default_vertex : [
36163
36164         "vec4 mvPosition;",
36165
36166         "#ifdef USE_SKINNING",
36167
36168             "mvPosition = modelViewMatrix * skinned;",
36169
36170         "#endif",
36171
36172         "#if !defined( USE_SKINNING ) && defined( USE_MORPHTARGETS )",
36173
36174             "mvPosition = modelViewMatrix * vec4( morphed, 1.0 );",
36175
36176         "#endif",
36177
36178         "#if !defined( USE_SKINNING ) && ! defined( USE_MORPHTARGETS )",
36179
36180             "mvPosition = modelViewMatrix * vec4( position, 1.0 );",
36181
36182         "#endif",
36183
36184         "gl_Position = projectionMatrix * mvPosition;",
36185
36186     ].join("\n"),
36187
36188     morphnormal_vertex: [
36189
36190         "#ifdef USE_MORPHNORMALS",
36191
36192             "vec3 morphedNormal = vec3( 0.0 );",
36193
36194             "morphedNormal +=  ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];",
36195             "morphedNormal +=  ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];",
36196             "morphedNormal +=  ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];",
36197             "morphedNormal +=  ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];",
36198
36199             "morphedNormal += normal;",
36200
36201         "#endif"
36202
36203     ].join("\n"),
36204
36205     skinnormal_vertex: [
36206
36207         "#ifdef USE_SKINNING",
36208
36209             "mat4 skinMatrix = skinWeight.x * boneMatX;",
36210             "skinMatrix     += skinWeight.y * boneMatY;",
36211
36212             "#ifdef USE_MORPHNORMALS",
36213
36214             "vec4 skinnedNormal = skinMatrix * vec4( morphedNormal, 0.0 );",
36215
36216             "#else",
36217
36218             "vec4 skinnedNormal = skinMatrix * vec4( normal, 0.0 );",
36219
36220             "#endif",
36221
36222         "#endif"
36223
36224     ].join("\n"),
36225
36226     defaultnormal_vertex: [
36227
36228         "vec3 objectNormal;",
36229
36230         "#ifdef USE_SKINNING",
36231
36232             "objectNormal = skinnedNormal.xyz;",
36233
36234         "#endif",
36235
36236         "#if !defined( USE_SKINNING ) && defined( USE_MORPHNORMALS )",
36237
36238             "objectNormal = morphedNormal;",
36239
36240         "#endif",
36241
36242         "#if !defined( USE_SKINNING ) && ! defined( USE_MORPHNORMALS )",
36243
36244             "objectNormal = normal;",
36245
36246         "#endif",
36247
36248         "#ifdef FLIP_SIDED",
36249
36250             "objectNormal = -objectNormal;",
36251
36252         "#endif",
36253
36254         "vec3 transformedNormal = normalMatrix * objectNormal;",
36255
36256     ].join("\n"),
36257
36258     // SHADOW MAP
36259
36260     // based on SpiderGL shadow map and Fabien Sanglard's GLSL shadow mapping examples
36261     //  http://spidergl.org/example.php?id=6
36262     //     http://fabiensanglard.net/shadowmapping
36263
36264     shadowmap_pars_fragment: [
36265
36266         "#ifdef USE_SHADOWMAP",
36267
36268             "uniform sampler2D shadowMap[ MAX_SHADOWS ];",
36269             "uniform vec2 shadowMapSize[ MAX_SHADOWS ];",
36270
36271             "uniform float shadowDarkness[ MAX_SHADOWS ];",
36272             "uniform float shadowBias[ MAX_SHADOWS ];",
36273
36274             "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
36275
36276             "float unpackDepth( const in vec4 rgba_depth ) {",
36277
36278                 "const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );",
36279                 "float depth = dot( rgba_depth, bit_shift );",
36280                 "return depth;",
36281
36282             "}",
36283
36284         "#endif"
36285
36286     ].join("\n"),
36287
36288     shadowmap_fragment: [
36289
36290         "#ifdef USE_SHADOWMAP",
36291
36292             "#ifdef SHADOWMAP_DEBUG",
36293
36294                 "vec3 frustumColors[3];",
36295                 "frustumColors[0] = vec3( 1.0, 0.5, 0.0 );",
36296                 "frustumColors[1] = vec3( 0.0, 1.0, 0.8 );",
36297                 "frustumColors[2] = vec3( 0.0, 0.5, 1.0 );",
36298
36299             "#endif",
36300
36301             "#ifdef SHADOWMAP_CASCADE",
36302
36303                 "int inFrustumCount = 0;",
36304
36305             "#endif",
36306
36307             "float fDepth;",
36308             "vec3 shadowColor = vec3( 1.0 );",
36309
36310             "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
36311
36312                 "vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;",
36313
36314                 // "if ( something && something )"          breaks ATI OpenGL shader compiler
36315                 // "if ( all( something, something ) )"  using this instead
36316
36317                 "bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );",
36318                 "bool inFrustum = all( inFrustumVec );",
36319
36320                 // don't shadow pixels outside of light frustum
36321                 // use just first frustum (for cascades)
36322                 // don't shadow pixels behind far plane of light frustum
36323
36324                 "#ifdef SHADOWMAP_CASCADE",
36325
36326                     "inFrustumCount += int( inFrustum );",
36327                     "bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 );",
36328
36329                 "#else",
36330
36331                     "bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );",
36332
36333                 "#endif",
36334
36335                 "bool frustumTest = all( frustumTestVec );",
36336
36337                 "if ( frustumTest ) {",
36338
36339                     "shadowCoord.z += shadowBias[ i ];",
36340
36341                     "#ifdef SHADOWMAP_SOFT",
36342
36343                         // Percentage-close filtering
36344                         // (9 pixel kernel)
36345                         // http://fabiensanglard.net/shadowmappingPCF/
36346
36347                         "float shadow = 0.0;",
36348
36349                         /*
36350                         // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL
36351                         // must enroll loop manually
36352
36353                         "for ( float y = -1.25; y <= 1.25; y += 1.25 )",
36354                             "for ( float x = -1.25; x <= 1.25; x += 1.25 ) {",
36355
36356                                 "vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );",
36357
36358                                 // doesn't seem to produce any noticeable visual difference compared to simple "texture2D" lookup
36359                                 //"vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );",
36360
36361                                 "float fDepth = unpackDepth( rgbaDepth );",
36362
36363                                 "if ( fDepth < shadowCoord.z )",
36364                                     "shadow += 1.0;",
36365
36366                         "}",
36367
36368                         "shadow /= 9.0;",
36369
36370                         */
36371
36372                         "const float shadowDelta = 1.0 / 9.0;",
36373
36374                         "float xPixelOffset = 1.0 / shadowMapSize[ i ].x;",
36375                         "float yPixelOffset = 1.0 / shadowMapSize[ i ].y;",
36376
36377                         "float dx0 = -1.25 * xPixelOffset;",
36378                         "float dy0 = -1.25 * yPixelOffset;",
36379                         "float dx1 = 1.25 * xPixelOffset;",
36380                         "float dy1 = 1.25 * yPixelOffset;",
36381
36382                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) );",
36383                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36384
36385                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) );",
36386                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36387
36388                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) );",
36389                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36390
36391                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) );",
36392                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36393
36394                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) );",
36395                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36396
36397                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) );",
36398                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36399
36400                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) );",
36401                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36402
36403                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) );",
36404                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36405
36406                         "fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) );",
36407                         "if ( fDepth < shadowCoord.z ) shadow += shadowDelta;",
36408
36409                         "shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) );",
36410
36411                     "#else",
36412
36413                         "vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );",
36414                         "float fDepth = unpackDepth( rgbaDepth );",
36415
36416                         "if ( fDepth < shadowCoord.z )",
36417
36418                             // spot with multiple shadows is darker
36419
36420                             "shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] );",
36421
36422                             // spot with multiple shadows has the same color as single shadow spot
36423
36424                             //"shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) );",
36425
36426                     "#endif",
36427
36428                 "}",
36429
36430
36431                 "#ifdef SHADOWMAP_DEBUG",
36432
36433                     "#ifdef SHADOWMAP_CASCADE",
36434
36435                         "if ( inFrustum && inFrustumCount == 1 ) gl_FragColor.xyz *= frustumColors[ i ];",
36436
36437                     "#else",
36438
36439                         "if ( inFrustum ) gl_FragColor.xyz *= frustumColors[ i ];",
36440
36441                     "#endif",
36442
36443                 "#endif",
36444
36445             "}",
36446
36447             "#ifdef GAMMA_OUTPUT",
36448
36449                 "shadowColor *= shadowColor;",
36450
36451             "#endif",
36452
36453             "gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;",
36454
36455         "#endif"
36456
36457     ].join("\n"),
36458
36459     shadowmap_pars_vertex: [
36460
36461         "#ifdef USE_SHADOWMAP",
36462
36463             "varying vec4 vShadowCoord[ MAX_SHADOWS ];",
36464             "uniform mat4 shadowMatrix[ MAX_SHADOWS ];",
36465
36466         "#endif"
36467
36468     ].join("\n"),
36469
36470     shadowmap_vertex: [
36471
36472         "#ifdef USE_SHADOWMAP",
36473
36474             "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
36475
36476                 "vShadowCoord[ i ] = shadowMatrix[ i ] * mPosition;",
36477
36478             "}",
36479
36480         "#endif"
36481
36482     ].join("\n"),
36483
36484     // ALPHATEST
36485
36486     alphatest_fragment: [
36487
36488         "#ifdef ALPHATEST",
36489
36490             "if ( gl_FragColor.a < ALPHATEST ) discard;",
36491
36492         "#endif"
36493
36494     ].join("\n"),
36495
36496     // LINEAR SPACE
36497
36498     linear_to_gamma_fragment: [
36499
36500         "#ifdef GAMMA_OUTPUT",
36501
36502             "gl_FragColor.xyz = sqrt( gl_FragColor.xyz );",
36503
36504         "#endif"
36505
36506     ].join("\n"),
36507
36508
36509 };
36510
36511 THREE.UniformsUtils = {
36512
36513     merge: function ( uniforms ) {
36514
36515         var u, p, tmp, merged = {};
36516
36517         for ( u = 0; u < uniforms.length; u ++ ) {
36518
36519             tmp = this.clone( uniforms[ u ] );
36520
36521             for ( p in tmp ) {
36522
36523                 merged[ p ] = tmp[ p ];
36524
36525             }
36526
36527         }
36528
36529         return merged;
36530
36531     },
36532
36533     clone: function ( uniforms_src ) {
36534
36535         var u, p, parameter, parameter_src, uniforms_dst = {};
36536
36537         for ( u in uniforms_src ) {
36538
36539             uniforms_dst[ u ] = {};
36540
36541             for ( p in uniforms_src[ u ] ) {
36542
36543                 parameter_src = uniforms_src[ u ][ p ];
36544
36545                 if ( parameter_src instanceof THREE.Color ||
36546                      parameter_src instanceof THREE.Vector2 ||
36547                      parameter_src instanceof THREE.Vector3 ||
36548                      parameter_src instanceof THREE.Vector4 ||
36549                      parameter_src instanceof THREE.Matrix4 ||
36550                      parameter_src instanceof THREE.Texture ) {
36551
36552                     uniforms_dst[ u ][ p ] = parameter_src.clone();
36553
36554                 } else if ( parameter_src instanceof Array ) {
36555
36556                     uniforms_dst[ u ][ p ] = parameter_src.slice();
36557
36558                 } else {
36559
36560                     uniforms_dst[ u ][ p ] = parameter_src;
36561
36562                 }
36563
36564             }
36565
36566         }
36567
36568         return uniforms_dst;
36569
36570     }
36571
36572 };
36573
36574 THREE.UniformsLib = {
36575
36576     common: {
36577
36578         "diffuse" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
36579         "opacity" : { type: "f", value: 1.0 },
36580
36581         "map" : { type: "t", value: null },
36582         "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
36583
36584         "lightMap" : { type: "t", value: null },
36585         "specularMap" : { type: "t", value: null },
36586
36587         "envMap" : { type: "t", value: null },
36588         "flipEnvMap" : { type: "f", value: -1 },
36589         "useRefract" : { type: "i", value: 0 },
36590         "reflectivity" : { type: "f", value: 1.0 },
36591         "refractionRatio" : { type: "f", value: 0.98 },
36592         "combine" : { type: "i", value: 0 },
36593
36594         "morphTargetInfluences" : { type: "f", value: 0 }
36595
36596     },
36597
36598     bump: {
36599
36600         "bumpMap" : { type: "t", value: null },
36601         "bumpScale" : { type: "f", value: 1 }
36602
36603     },
36604
36605     normalmap: {
36606
36607         "normalMap" : { type: "t", value: null },
36608         "normalScale" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }
36609     },
36610
36611     fog : {
36612
36613         "fogDensity" : { type: "f", value: 0.00025 },
36614         "fogNear" : { type: "f", value: 1 },
36615         "fogFar" : { type: "f", value: 2000 },
36616         "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
36617
36618     },
36619
36620     lights: {
36621
36622         "ambientLightColor" : { type: "fv", value: [] },
36623
36624         "directionalLightDirection" : { type: "fv", value: [] },
36625         "directionalLightColor" : { type: "fv", value: [] },
36626
36627         "hemisphereLightPosition" : { type: "fv", value: [] },
36628         "hemisphereLightSkyColor" : { type: "fv", value: [] },
36629         "hemisphereLightGroundColor" : { type: "fv", value: [] },
36630
36631         "pointLightColor" : { type: "fv", value: [] },
36632         "pointLightPosition" : { type: "fv", value: [] },
36633         "pointLightDistance" : { type: "fv1", value: [] },
36634
36635         "spotLightColor" : { type: "fv", value: [] },
36636         "spotLightPosition" : { type: "fv", value: [] },
36637         "spotLightDirection" : { type: "fv", value: [] },
36638         "spotLightDistance" : { type: "fv1", value: [] },
36639         "spotLightAngle" : { type: "fv1", value: [] },
36640         "spotLightExponent" : { type: "fv1", value: [] }
36641
36642     },
36643
36644     particle: {
36645
36646         "psColor" : { type: "c", value: new THREE.Color( 0xeeeeee ) },
36647         "opacity" : { type: "f", value: 1.0 },
36648         "size" : { type: "f", value: 1.0 },
36649         "scale" : { type: "f", value: 1.0 },
36650         "map" : { type: "t", value: null },
36651
36652         "fogDensity" : { type: "f", value: 0.00025 },
36653         "fogNear" : { type: "f", value: 1 },
36654         "fogFar" : { type: "f", value: 2000 },
36655         "fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
36656
36657     },
36658
36659     shadowmap: {
36660
36661         "shadowMap": { type: "tv", value: [] },
36662         "shadowMapSize": { type: "v2v", value: [] },
36663
36664         "shadowBias" : { type: "fv1", value: [] },
36665         "shadowDarkness": { type: "fv1", value: [] },
36666
36667         "shadowMatrix" : { type: "m4v", value: [] },
36668
36669     }
36670
36671 };
36672
36673 THREE.ShaderLib = {
36674
36675     'depth': {
36676
36677         uniforms: {
36678
36679             "mNear": { type: "f", value: 1.0 },
36680             "mFar" : { type: "f", value: 2000.0 },
36681             "opacity" : { type: "f", value: 1.0 }
36682
36683         },
36684
36685         vertexShader: [
36686
36687             "void main() {",
36688
36689                 "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
36690
36691             "}"
36692
36693         ].join("\n"),
36694
36695         fragmentShader: [
36696
36697             "uniform float mNear;",
36698             "uniform float mFar;",
36699             "uniform float opacity;",
36700
36701             "void main() {",
36702
36703                 "float depth = gl_FragCoord.z / gl_FragCoord.w;",
36704                 "float color = 1.0 - smoothstep( mNear, mFar, depth );",
36705                 "gl_FragColor = vec4( vec3( color ), opacity );",
36706
36707             "}"
36708
36709         ].join("\n")
36710
36711     },
36712
36713     'normal': {
36714
36715         uniforms: {
36716
36717             "opacity" : { type: "f", value: 1.0 }
36718
36719         },
36720
36721         vertexShader: [
36722
36723             "varying vec3 vNormal;",
36724
36725             "void main() {",
36726
36727                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
36728                 "vNormal = normalMatrix * normal;",
36729
36730                 "gl_Position = projectionMatrix * mvPosition;",
36731
36732             "}"
36733
36734         ].join("\n"),
36735
36736         fragmentShader: [
36737
36738             "uniform float opacity;",
36739             "varying vec3 vNormal;",
36740
36741             "void main() {",
36742
36743                 "gl_FragColor = vec4( 0.5 * normalize( vNormal ) + 0.5, opacity );",
36744
36745             "}"
36746
36747         ].join("\n")
36748
36749     },
36750
36751     'basic': {
36752
36753         uniforms: THREE.UniformsUtils.merge( [
36754
36755             THREE.UniformsLib[ "common" ],
36756             THREE.UniformsLib[ "fog" ],
36757             THREE.UniformsLib[ "shadowmap" ]
36758
36759         ] ),
36760
36761         vertexShader: [
36762
36763             THREE.ShaderChunk[ "map_pars_vertex" ],
36764             THREE.ShaderChunk[ "lightmap_pars_vertex" ],
36765             THREE.ShaderChunk[ "envmap_pars_vertex" ],
36766             THREE.ShaderChunk[ "color_pars_vertex" ],
36767             THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
36768             THREE.ShaderChunk[ "skinning_pars_vertex" ],
36769             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
36770
36771             "void main() {",
36772
36773                 THREE.ShaderChunk[ "map_vertex" ],
36774                 THREE.ShaderChunk[ "lightmap_vertex" ],
36775                 THREE.ShaderChunk[ "color_vertex" ],
36776
36777                 "#ifdef USE_ENVMAP",
36778
36779                 THREE.ShaderChunk[ "morphnormal_vertex" ],
36780                 THREE.ShaderChunk[ "skinbase_vertex" ],
36781                 THREE.ShaderChunk[ "skinnormal_vertex" ],
36782                 THREE.ShaderChunk[ "defaultnormal_vertex" ],
36783
36784                 "#endif",
36785
36786                 THREE.ShaderChunk[ "morphtarget_vertex" ],
36787                 THREE.ShaderChunk[ "skinning_vertex" ],
36788                 THREE.ShaderChunk[ "default_vertex" ],
36789
36790                 THREE.ShaderChunk[ "worldpos_vertex" ],
36791                 THREE.ShaderChunk[ "envmap_vertex" ],
36792                 THREE.ShaderChunk[ "shadowmap_vertex" ],
36793
36794             "}"
36795
36796         ].join("\n"),
36797
36798         fragmentShader: [
36799
36800             "uniform vec3 diffuse;",
36801             "uniform float opacity;",
36802
36803             THREE.ShaderChunk[ "color_pars_fragment" ],
36804             THREE.ShaderChunk[ "map_pars_fragment" ],
36805             THREE.ShaderChunk[ "lightmap_pars_fragment" ],
36806             THREE.ShaderChunk[ "envmap_pars_fragment" ],
36807             THREE.ShaderChunk[ "fog_pars_fragment" ],
36808             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
36809             THREE.ShaderChunk[ "specularmap_pars_fragment" ],
36810
36811             "void main() {",
36812
36813                 "gl_FragColor = vec4( diffuse, opacity );",
36814
36815                 THREE.ShaderChunk[ "map_fragment" ],
36816                 THREE.ShaderChunk[ "alphatest_fragment" ],
36817                 THREE.ShaderChunk[ "specularmap_fragment" ],
36818                 THREE.ShaderChunk[ "lightmap_fragment" ],
36819                 THREE.ShaderChunk[ "color_fragment" ],
36820                 THREE.ShaderChunk[ "envmap_fragment" ],
36821                 THREE.ShaderChunk[ "shadowmap_fragment" ],
36822
36823                 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
36824
36825                 THREE.ShaderChunk[ "fog_fragment" ],
36826
36827             "}"
36828
36829         ].join("\n")
36830
36831     },
36832
36833     'lambert': {
36834
36835         uniforms: THREE.UniformsUtils.merge( [
36836
36837             THREE.UniformsLib[ "common" ],
36838             THREE.UniformsLib[ "fog" ],
36839             THREE.UniformsLib[ "lights" ],
36840             THREE.UniformsLib[ "shadowmap" ],
36841
36842             {
36843                 "ambient"  : { type: "c", value: new THREE.Color( 0xffffff ) },
36844                 "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
36845                 "wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
36846             }
36847
36848         ] ),
36849
36850         vertexShader: [
36851
36852             "#define LAMBERT",
36853
36854             "varying vec3 vLightFront;",
36855
36856             "#ifdef DOUBLE_SIDED",
36857
36858                 "varying vec3 vLightBack;",
36859
36860             "#endif",
36861
36862             THREE.ShaderChunk[ "map_pars_vertex" ],
36863             THREE.ShaderChunk[ "lightmap_pars_vertex" ],
36864             THREE.ShaderChunk[ "envmap_pars_vertex" ],
36865             THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
36866             THREE.ShaderChunk[ "color_pars_vertex" ],
36867             THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
36868             THREE.ShaderChunk[ "skinning_pars_vertex" ],
36869             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
36870
36871             "void main() {",
36872
36873                 THREE.ShaderChunk[ "map_vertex" ],
36874                 THREE.ShaderChunk[ "lightmap_vertex" ],
36875                 THREE.ShaderChunk[ "color_vertex" ],
36876
36877                 THREE.ShaderChunk[ "morphnormal_vertex" ],
36878                 THREE.ShaderChunk[ "skinbase_vertex" ],
36879                 THREE.ShaderChunk[ "skinnormal_vertex" ],
36880                 THREE.ShaderChunk[ "defaultnormal_vertex" ],
36881
36882                 THREE.ShaderChunk[ "morphtarget_vertex" ],
36883                 THREE.ShaderChunk[ "skinning_vertex" ],
36884                 THREE.ShaderChunk[ "default_vertex" ],
36885
36886                 THREE.ShaderChunk[ "worldpos_vertex" ],
36887                 THREE.ShaderChunk[ "envmap_vertex" ],
36888                 THREE.ShaderChunk[ "lights_lambert_vertex" ],
36889                 THREE.ShaderChunk[ "shadowmap_vertex" ],
36890
36891             "}"
36892
36893         ].join("\n"),
36894
36895         fragmentShader: [
36896
36897             "uniform float opacity;",
36898
36899             "varying vec3 vLightFront;",
36900
36901             "#ifdef DOUBLE_SIDED",
36902
36903                 "varying vec3 vLightBack;",
36904
36905             "#endif",
36906
36907             THREE.ShaderChunk[ "color_pars_fragment" ],
36908             THREE.ShaderChunk[ "map_pars_fragment" ],
36909             THREE.ShaderChunk[ "lightmap_pars_fragment" ],
36910             THREE.ShaderChunk[ "envmap_pars_fragment" ],
36911             THREE.ShaderChunk[ "fog_pars_fragment" ],
36912             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
36913             THREE.ShaderChunk[ "specularmap_pars_fragment" ],
36914
36915             "void main() {",
36916
36917                 "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
36918
36919                 THREE.ShaderChunk[ "map_fragment" ],
36920                 THREE.ShaderChunk[ "alphatest_fragment" ],
36921                 THREE.ShaderChunk[ "specularmap_fragment" ],
36922
36923                 "#ifdef DOUBLE_SIDED",
36924
36925                     //"float isFront = float( gl_FrontFacing );",
36926                     //"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;",
36927
36928                     "if ( gl_FrontFacing )",
36929                         "gl_FragColor.xyz *= vLightFront;",
36930                     "else",
36931                         "gl_FragColor.xyz *= vLightBack;",
36932
36933                 "#else",
36934
36935                     "gl_FragColor.xyz *= vLightFront;",
36936
36937                 "#endif",
36938
36939                 THREE.ShaderChunk[ "lightmap_fragment" ],
36940                 THREE.ShaderChunk[ "color_fragment" ],
36941                 THREE.ShaderChunk[ "envmap_fragment" ],
36942                 THREE.ShaderChunk[ "shadowmap_fragment" ],
36943
36944                 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
36945
36946                 THREE.ShaderChunk[ "fog_fragment" ],
36947
36948             "}"
36949
36950         ].join("\n")
36951
36952     },
36953
36954     'phong': {
36955
36956         uniforms: THREE.UniformsUtils.merge( [
36957
36958             THREE.UniformsLib[ "common" ],
36959             THREE.UniformsLib[ "bump" ],
36960             THREE.UniformsLib[ "normalmap" ],
36961             THREE.UniformsLib[ "fog" ],
36962             THREE.UniformsLib[ "lights" ],
36963             THREE.UniformsLib[ "shadowmap" ],
36964
36965             {
36966                 "ambient"  : { type: "c", value: new THREE.Color( 0xffffff ) },
36967                 "emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
36968                 "specular" : { type: "c", value: new THREE.Color( 0x111111 ) },
36969                 "shininess": { type: "f", value: 30 },
36970                 "wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
36971             }
36972
36973         ] ),
36974
36975         vertexShader: [
36976
36977             "#define PHONG",
36978
36979             "varying vec3 vViewPosition;",
36980             "varying vec3 vNormal;",
36981
36982             THREE.ShaderChunk[ "map_pars_vertex" ],
36983             THREE.ShaderChunk[ "lightmap_pars_vertex" ],
36984             THREE.ShaderChunk[ "envmap_pars_vertex" ],
36985             THREE.ShaderChunk[ "lights_phong_pars_vertex" ],
36986             THREE.ShaderChunk[ "color_pars_vertex" ],
36987             THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
36988             THREE.ShaderChunk[ "skinning_pars_vertex" ],
36989             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
36990
36991             "void main() {",
36992
36993                 THREE.ShaderChunk[ "map_vertex" ],
36994                 THREE.ShaderChunk[ "lightmap_vertex" ],
36995                 THREE.ShaderChunk[ "color_vertex" ],
36996
36997                 THREE.ShaderChunk[ "morphnormal_vertex" ],
36998                 THREE.ShaderChunk[ "skinbase_vertex" ],
36999                 THREE.ShaderChunk[ "skinnormal_vertex" ],
37000                 THREE.ShaderChunk[ "defaultnormal_vertex" ],
37001
37002                 "vNormal = transformedNormal;",
37003
37004                 THREE.ShaderChunk[ "morphtarget_vertex" ],
37005                 THREE.ShaderChunk[ "skinning_vertex" ],
37006                 THREE.ShaderChunk[ "default_vertex" ],
37007
37008                 "vViewPosition = -mvPosition.xyz;",
37009
37010                 THREE.ShaderChunk[ "worldpos_vertex" ],
37011                 THREE.ShaderChunk[ "envmap_vertex" ],
37012                 THREE.ShaderChunk[ "lights_phong_vertex" ],
37013                 THREE.ShaderChunk[ "shadowmap_vertex" ],
37014
37015             "}"
37016
37017         ].join("\n"),
37018
37019         fragmentShader: [
37020
37021             "uniform vec3 diffuse;",
37022             "uniform float opacity;",
37023
37024             "uniform vec3 ambient;",
37025             "uniform vec3 emissive;",
37026             "uniform vec3 specular;",
37027             "uniform float shininess;",
37028
37029             THREE.ShaderChunk[ "color_pars_fragment" ],
37030             THREE.ShaderChunk[ "map_pars_fragment" ],
37031             THREE.ShaderChunk[ "lightmap_pars_fragment" ],
37032             THREE.ShaderChunk[ "envmap_pars_fragment" ],
37033             THREE.ShaderChunk[ "fog_pars_fragment" ],
37034             THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
37035             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
37036             THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
37037             THREE.ShaderChunk[ "normalmap_pars_fragment" ],
37038             THREE.ShaderChunk[ "specularmap_pars_fragment" ],
37039
37040             "void main() {",
37041
37042                 "gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",
37043
37044                 THREE.ShaderChunk[ "map_fragment" ],
37045                 THREE.ShaderChunk[ "alphatest_fragment" ],
37046                 THREE.ShaderChunk[ "specularmap_fragment" ],
37047
37048                 THREE.ShaderChunk[ "lights_phong_fragment" ],
37049
37050                 THREE.ShaderChunk[ "lightmap_fragment" ],
37051                 THREE.ShaderChunk[ "color_fragment" ],
37052                 THREE.ShaderChunk[ "envmap_fragment" ],
37053                 THREE.ShaderChunk[ "shadowmap_fragment" ],
37054
37055                 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
37056
37057                 THREE.ShaderChunk[ "fog_fragment" ],
37058
37059             "}"
37060
37061         ].join("\n")
37062
37063     },
37064
37065     'particle_basic': {
37066
37067         uniforms:  THREE.UniformsUtils.merge( [
37068
37069             THREE.UniformsLib[ "particle" ],
37070             THREE.UniformsLib[ "shadowmap" ]
37071
37072         ] ),
37073
37074         vertexShader: [
37075
37076             "uniform float size;",
37077             "uniform float scale;",
37078
37079             THREE.ShaderChunk[ "color_pars_vertex" ],
37080             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
37081
37082             "void main() {",
37083
37084                 THREE.ShaderChunk[ "color_vertex" ],
37085
37086                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
37087
37088                 "#ifdef USE_SIZEATTENUATION",
37089                     "gl_PointSize = size * ( scale / length( mvPosition.xyz ) );",
37090                 "#else",
37091                     "gl_PointSize = size;",
37092                 "#endif",
37093
37094                 "gl_Position = projectionMatrix * mvPosition;",
37095
37096                 THREE.ShaderChunk[ "worldpos_vertex" ],
37097                 THREE.ShaderChunk[ "shadowmap_vertex" ],
37098
37099             "}"
37100
37101         ].join("\n"),
37102
37103         fragmentShader: [
37104
37105             "uniform vec3 psColor;",
37106             "uniform float opacity;",
37107
37108             THREE.ShaderChunk[ "color_pars_fragment" ],
37109             THREE.ShaderChunk[ "map_particle_pars_fragment" ],
37110             THREE.ShaderChunk[ "fog_pars_fragment" ],
37111             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
37112
37113             "void main() {",
37114
37115                 "gl_FragColor = vec4( psColor, opacity );",
37116
37117                 THREE.ShaderChunk[ "map_particle_fragment" ],
37118                 THREE.ShaderChunk[ "alphatest_fragment" ],
37119                 THREE.ShaderChunk[ "color_fragment" ],
37120                 THREE.ShaderChunk[ "shadowmap_fragment" ],
37121                 THREE.ShaderChunk[ "fog_fragment" ],
37122
37123             "}"
37124
37125         ].join("\n")
37126
37127     },
37128
37129     // Depth encoding into RGBA texture
37130     //     based on SpiderGL shadow map example
37131     //         http://spidergl.org/example.php?id=6
37132     //     originally from
37133     //        http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
37134     //     see also here:
37135     //        http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
37136
37137     'depthRGBA': {
37138
37139         uniforms: {},
37140
37141         vertexShader: [
37142
37143             THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
37144             THREE.ShaderChunk[ "skinning_pars_vertex" ],
37145
37146             "void main() {",
37147
37148                 THREE.ShaderChunk[ "skinbase_vertex" ],
37149                 THREE.ShaderChunk[ "morphtarget_vertex" ],
37150                 THREE.ShaderChunk[ "skinning_vertex" ],
37151                 THREE.ShaderChunk[ "default_vertex" ],
37152
37153             "}"
37154
37155         ].join("\n"),
37156
37157         fragmentShader: [
37158
37159             "vec4 pack_depth( const in float depth ) {",
37160
37161                 "const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
37162                 "const vec4 bit_mask  = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
37163                 "vec4 res = fract( depth * bit_shift );",
37164                 "res -= res.xxyz * bit_mask;",
37165                 "return res;",
37166
37167             "}",
37168
37169             "void main() {",
37170
37171                 "gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );",
37172
37173                 //"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z / gl_FragCoord.w );",
37174                 //"float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );",
37175                 //"gl_FragData[ 0 ] = pack_depth( z );",
37176                 //"gl_FragData[ 0 ] = vec4( z, z, z, 1.0 );",
37177
37178             "}"
37179
37180         ].join("\n")
37181
37182     }
37183
37184 };
37185 /**
37186  * @author supereggbert / http://www.paulbrunt.co.uk/
37187  * @author mrdoob / http://mrdoob.com/
37188  * @author alteredq / http://alteredqualia.com/
37189  * @author szimek / https://github.com/szimek/
37190  */
37191
37192 THREE.WebGLRenderer = function ( parameters ) {
37193
37194     console.log( 'THREE.WebGLRenderer', THREE.REVISION );
37195
37196     parameters = parameters || {};
37197
37198     var _canvas = parameters.canvas !== undefined ? parameters.canvas : document.createElement( 'canvas' ),
37199
37200     _precision = parameters.precision !== undefined ? parameters.precision : 'highp',
37201
37202     _alpha = parameters.alpha !== undefined ? parameters.alpha : true,
37203     _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
37204     _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
37205     _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
37206     _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
37207
37208     _clearColor = parameters.clearColor !== undefined ? new THREE.Color( parameters.clearColor ) : new THREE.Color( 0x000000 ),
37209     _clearAlpha = parameters.clearAlpha !== undefined ? parameters.clearAlpha : 0,
37210
37211     _maxLights = parameters.maxLights !== undefined ? parameters.maxLights : 4;
37212
37213     // public properties
37214
37215     this.domElement = _canvas;
37216     this.context = null;
37217
37218     // clearing
37219
37220     this.autoClear = true;
37221     this.autoClearColor = true;
37222     this.autoClearDepth = true;
37223     this.autoClearStencil = true;
37224
37225     // scene graph
37226
37227     this.sortObjects = true;
37228
37229     this.autoUpdateObjects = true;
37230     this.autoUpdateScene = true;
37231
37232     // physically based shading
37233
37234     this.gammaInput = false;
37235     this.gammaOutput = false;
37236     this.physicallyBasedShading = false;
37237
37238     // shadow map
37239
37240     this.shadowMapEnabled = false;
37241     this.shadowMapAutoUpdate = true;
37242     this.shadowMapSoft = true;
37243     this.shadowMapCullFrontFaces = true;
37244     this.shadowMapDebug = false;
37245     this.shadowMapCascade = false;
37246
37247     // morphs
37248
37249     this.maxMorphTargets = 8;
37250     this.maxMorphNormals = 4;
37251
37252     // flags
37253
37254     this.autoScaleCubemaps = true;
37255
37256     // custom render plugins
37257
37258     this.renderPluginsPre = [];
37259     this.renderPluginsPost = [];
37260
37261     // info
37262
37263     this.info = {
37264
37265         memory: {
37266
37267             programs: 0,
37268             geometries: 0,
37269             textures: 0
37270
37271         },
37272
37273         render: {
37274
37275             calls: 0,
37276             vertices: 0,
37277             faces: 0,
37278             points: 0
37279
37280         }
37281
37282     };
37283
37284     // internal properties
37285
37286     var _this = this,
37287
37288     _programs = [],
37289     _programs_counter = 0,
37290
37291     // internal state cache
37292
37293     _currentProgram = null,
37294     _currentFramebuffer = null,
37295     _currentMaterialId = -1,
37296     _currentGeometryGroupHash = null,
37297     _currentCamera = null,
37298     _geometryGroupCounter = 0,
37299
37300     _usedTextureUnits = 0,
37301
37302     // GL state cache
37303
37304     _oldDoubleSided = -1,
37305     _oldFlipSided = -1,
37306
37307     _oldBlending = -1,
37308
37309     _oldBlendEquation = -1,
37310     _oldBlendSrc = -1,
37311     _oldBlendDst = -1,
37312
37313     _oldDepthTest = -1,
37314     _oldDepthWrite = -1,
37315
37316     _oldPolygonOffset = null,
37317     _oldPolygonOffsetFactor = null,
37318     _oldPolygonOffsetUnits = null,
37319
37320     _oldLineWidth = null,
37321
37322     _viewportX = 0,
37323     _viewportY = 0,
37324     _viewportWidth = 0,
37325     _viewportHeight = 0,
37326     _currentWidth = 0,
37327     _currentHeight = 0,
37328
37329     // frustum
37330
37331     _frustum = new THREE.Frustum(),
37332
37333      // camera matrices cache
37334
37335     _projScreenMatrix = new THREE.Matrix4(),
37336     _projScreenMatrixPS = new THREE.Matrix4(),
37337
37338     _vector3 = new THREE.Vector4(),
37339
37340     // light arrays cache
37341
37342     _direction = new THREE.Vector3(),
37343
37344     _lightsNeedUpdate = true,
37345
37346     _lights = {
37347
37348         ambient: [ 0, 0, 0 ],
37349         directional: { length: 0, colors: new Array(), positions: new Array() },
37350         point: { length: 0, colors: new Array(), positions: new Array(), distances: new Array() },
37351         spot: { length: 0, colors: new Array(), positions: new Array(), distances: new Array(), directions: new Array(), angles: new Array(), exponents: new Array() },
37352         hemi: { length: 0, skyColors: new Array(), groundColors: new Array(), positions: new Array() }
37353
37354     };
37355
37356     // initialize
37357
37358     var _gl;
37359
37360     var _glExtensionTextureFloat;
37361     var _glExtensionStandardDerivatives;
37362     var _glExtensionTextureFilterAnisotropic;
37363     var _glExtensionCompressedTextureS3TC;
37364
37365     initGL();
37366
37367     setDefaultGLState();
37368
37369     this.context = _gl;
37370
37371     // GPU capabilities
37372
37373     var _maxTextures = _gl.getParameter( _gl.MAX_TEXTURE_IMAGE_UNITS );
37374     var _maxVertexTextures = _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
37375     var _maxTextureSize = _gl.getParameter( _gl.MAX_TEXTURE_SIZE );
37376     var _maxCubemapSize = _gl.getParameter( _gl.MAX_CUBE_MAP_TEXTURE_SIZE );
37377
37378     var _maxAnisotropy = _glExtensionTextureFilterAnisotropic ? _gl.getParameter( _glExtensionTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT ) : 0;
37379
37380     var _supportsVertexTextures = ( _maxVertexTextures > 0 );
37381     var _supportsBoneTextures = _supportsVertexTextures && _glExtensionTextureFloat;
37382
37383     var _compressedTextureFormats = _glExtensionCompressedTextureS3TC ? _gl.getParameter( _gl.COMPRESSED_TEXTURE_FORMATS ) : [];
37384
37385     // API
37386
37387     this.getContext = function () {
37388
37389         return _gl;
37390
37391     };
37392
37393     this.supportsVertexTextures = function () {
37394
37395         return _supportsVertexTextures;
37396
37397     };
37398
37399     this.getMaxAnisotropy  = function () {
37400
37401         return _maxAnisotropy;
37402
37403     };
37404
37405     this.setSize = function ( width, height ) {
37406
37407         _canvas.width = width;
37408         _canvas.height = height;
37409
37410         this.setViewport( 0, 0, _canvas.width, _canvas.height );
37411
37412     };
37413
37414     this.setViewport = function ( x, y, width, height ) {
37415
37416         _viewportX = x !== undefined ? x : 0;
37417         _viewportY = y !== undefined ? y : 0;
37418
37419         _viewportWidth = width !== undefined ? width : _canvas.width;
37420         _viewportHeight = height !== undefined ? height : _canvas.height;
37421
37422         _gl.viewport( _viewportX, _viewportY, _viewportWidth, _viewportHeight );
37423
37424     };
37425
37426     this.setScissor = function ( x, y, width, height ) {
37427
37428         _gl.scissor( x, y, width, height );
37429
37430     };
37431
37432     this.enableScissorTest = function ( enable ) {
37433
37434         enable ? _gl.enable( _gl.SCISSOR_TEST ) : _gl.disable( _gl.SCISSOR_TEST );
37435
37436     };
37437
37438     // Clearing
37439
37440     this.setClearColorHex = function ( hex, alpha ) {
37441
37442         _clearColor.setHex( hex );
37443         _clearAlpha = alpha;
37444
37445         _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
37446
37447     };
37448
37449     this.setClearColor = function ( color, alpha ) {
37450
37451         _clearColor.copy( color );
37452         _clearAlpha = alpha;
37453
37454         _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
37455
37456     };
37457
37458     this.getClearColor = function () {
37459
37460         return _clearColor;
37461
37462     };
37463
37464     this.getClearAlpha = function () {
37465
37466         return _clearAlpha;
37467
37468     };
37469
37470     this.clear = function ( color, depth, stencil ) {
37471
37472         var bits = 0;
37473
37474         if ( color === undefined || color ) bits |= _gl.COLOR_BUFFER_BIT;
37475         if ( depth === undefined || depth ) bits |= _gl.DEPTH_BUFFER_BIT;
37476         if ( stencil === undefined || stencil ) bits |= _gl.STENCIL_BUFFER_BIT;
37477
37478         _gl.clear( bits );
37479
37480     };
37481
37482     this.clearTarget = function ( renderTarget, color, depth, stencil ) {
37483
37484         this.setRenderTarget( renderTarget );
37485         this.clear( color, depth, stencil );
37486
37487     };
37488
37489     // Plugins
37490
37491     this.addPostPlugin = function ( plugin ) {
37492
37493         plugin.init( this );
37494         this.renderPluginsPost.push( plugin );
37495
37496     };
37497
37498     this.addPrePlugin = function ( plugin ) {
37499
37500         plugin.init( this );
37501         this.renderPluginsPre.push( plugin );
37502
37503     };
37504
37505     // Deallocation
37506
37507     this.deallocateObject = function ( object ) {
37508
37509         if ( ! object.__webglInit ) return;
37510
37511         object.__webglInit = false;
37512
37513         delete object._modelViewMatrix;
37514         delete object._normalMatrix;
37515
37516         delete object._normalMatrixArray;
37517         delete object._modelViewMatrixArray;
37518         delete object._modelMatrixArray;
37519
37520         if ( object instanceof THREE.Mesh ) {
37521
37522             for ( var g in object.geometry.geometryGroups ) {
37523
37524                 deleteMeshBuffers( object.geometry.geometryGroups[ g ] );
37525
37526             }
37527
37528         } else if ( object instanceof THREE.Ribbon ) {
37529
37530             deleteRibbonBuffers( object.geometry );
37531
37532         } else if ( object instanceof THREE.Line ) {
37533
37534             deleteLineBuffers( object.geometry );
37535
37536         } else if ( object instanceof THREE.ParticleSystem ) {
37537
37538             deleteParticleBuffers( object.geometry );
37539
37540         }
37541
37542     };
37543
37544     this.deallocateTexture = function ( texture ) {
37545
37546         if ( ! texture.__webglInit ) return;
37547
37548         texture.__webglInit = false;
37549         _gl.deleteTexture( texture.__webglTexture );
37550
37551         _this.info.memory.textures --;
37552
37553     };
37554
37555     this.deallocateRenderTarget = function ( renderTarget ) {
37556
37557         if ( !renderTarget || ! renderTarget.__webglTexture ) return;
37558
37559         _gl.deleteTexture( renderTarget.__webglTexture );
37560
37561         if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
37562
37563             for ( var i = 0; i < 6; i ++ ) {
37564
37565                 _gl.deleteFramebuffer( renderTarget.__webglFramebuffer[ i ] );
37566                 _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer[ i ] );
37567
37568             }
37569
37570         } else {
37571
37572             _gl.deleteFramebuffer( renderTarget.__webglFramebuffer );
37573             _gl.deleteRenderbuffer( renderTarget.__webglRenderbuffer );
37574
37575         }
37576
37577     };
37578
37579     this.deallocateMaterial = function ( material ) {
37580
37581         var program = material.program;
37582
37583         if ( ! program ) return;
37584
37585         material.program = undefined;
37586
37587         // only deallocate GL program if this was the last use of shared program
37588         // assumed there is only single copy of any program in the _programs list
37589         // (that's how it's constructed)
37590
37591         var i, il, programInfo;
37592         var deleteProgram = false;
37593
37594         for ( i = 0, il = _programs.length; i < il; i ++ ) {
37595
37596             programInfo = _programs[ i ];
37597
37598             if ( programInfo.program === program ) {
37599
37600                 programInfo.usedTimes --;
37601
37602                 if ( programInfo.usedTimes === 0 ) {
37603
37604                     deleteProgram = true;
37605
37606                 }
37607
37608                 break;
37609
37610             }
37611
37612         }
37613
37614         if ( deleteProgram ) {
37615
37616             // avoid using array.splice, this is costlier than creating new array from scratch
37617
37618             var newPrograms = [];
37619
37620             for ( i = 0, il = _programs.length; i < il; i ++ ) {
37621
37622                 programInfo = _programs[ i ];
37623
37624                 if ( programInfo.program !== program ) {
37625
37626                     newPrograms.push( programInfo );
37627
37628                 }
37629
37630             }
37631
37632             _programs = newPrograms;
37633
37634             _gl.deleteProgram( program );
37635
37636             _this.info.memory.programs --;
37637
37638         }
37639
37640     };
37641
37642     // Rendering
37643
37644     this.updateShadowMap = function ( scene, camera ) {
37645
37646         _currentProgram = null;
37647         _oldBlending = -1;
37648         _oldDepthTest = -1;
37649         _oldDepthWrite = -1;
37650         _currentGeometryGroupHash = -1;
37651         _currentMaterialId = -1;
37652         _lightsNeedUpdate = true;
37653         _oldDoubleSided = -1;
37654         _oldFlipSided = -1;
37655
37656         this.shadowMapPlugin.update( scene, camera );
37657
37658     };
37659
37660     // Internal functions
37661
37662     // Buffer allocation
37663
37664     function createParticleBuffers ( geometry ) {
37665
37666         geometry.__webglVertexBuffer = _gl.createBuffer();
37667         geometry.__webglColorBuffer = _gl.createBuffer();
37668
37669         _this.info.memory.geometries ++;
37670
37671     };
37672
37673     function createLineBuffers ( geometry ) {
37674
37675         geometry.__webglVertexBuffer = _gl.createBuffer();
37676         geometry.__webglColorBuffer = _gl.createBuffer();
37677
37678         _this.info.memory.geometries ++;
37679
37680     };
37681
37682     function createRibbonBuffers ( geometry ) {
37683
37684         geometry.__webglVertexBuffer = _gl.createBuffer();
37685         geometry.__webglColorBuffer = _gl.createBuffer();
37686
37687         _this.info.memory.geometries ++;
37688
37689     };
37690
37691     function createMeshBuffers ( geometryGroup ) {
37692
37693         geometryGroup.__webglVertexBuffer = _gl.createBuffer();
37694         geometryGroup.__webglNormalBuffer = _gl.createBuffer();
37695         geometryGroup.__webglTangentBuffer = _gl.createBuffer();
37696         geometryGroup.__webglColorBuffer = _gl.createBuffer();
37697         geometryGroup.__webglUVBuffer = _gl.createBuffer();
37698         geometryGroup.__webglUV2Buffer = _gl.createBuffer();
37699
37700         geometryGroup.__webglSkinIndicesBuffer = _gl.createBuffer();
37701         geometryGroup.__webglSkinWeightsBuffer = _gl.createBuffer();
37702
37703         geometryGroup.__webglFaceBuffer = _gl.createBuffer();
37704         geometryGroup.__webglLineBuffer = _gl.createBuffer();
37705
37706         var m, ml;
37707
37708         if ( geometryGroup.numMorphTargets ) {
37709
37710             geometryGroup.__webglMorphTargetsBuffers = [];
37711
37712             for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
37713
37714                 geometryGroup.__webglMorphTargetsBuffers.push( _gl.createBuffer() );
37715
37716             }
37717
37718         }
37719
37720         if ( geometryGroup.numMorphNormals ) {
37721
37722             geometryGroup.__webglMorphNormalsBuffers = [];
37723
37724             for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
37725
37726                 geometryGroup.__webglMorphNormalsBuffers.push( _gl.createBuffer() );
37727
37728             }
37729
37730         }
37731
37732         _this.info.memory.geometries ++;
37733
37734     };
37735
37736     // Buffer deallocation
37737
37738     function deleteParticleBuffers ( geometry ) {
37739
37740         _gl.deleteBuffer( geometry.__webglVertexBuffer );
37741         _gl.deleteBuffer( geometry.__webglColorBuffer );
37742
37743         _this.info.memory.geometries --;
37744
37745     };
37746
37747     function deleteLineBuffers ( geometry ) {
37748
37749         _gl.deleteBuffer( geometry.__webglVertexBuffer );
37750         _gl.deleteBuffer( geometry.__webglColorBuffer );
37751
37752         _this.info.memory.geometries --;
37753
37754     };
37755
37756     function deleteRibbonBuffers ( geometry ) {
37757
37758         _gl.deleteBuffer( geometry.__webglVertexBuffer );
37759         _gl.deleteBuffer( geometry.__webglColorBuffer );
37760
37761         _this.info.memory.geometries --;
37762
37763     };
37764
37765     function deleteMeshBuffers ( geometryGroup ) {
37766
37767         _gl.deleteBuffer( geometryGroup.__webglVertexBuffer );
37768         _gl.deleteBuffer( geometryGroup.__webglNormalBuffer );
37769         _gl.deleteBuffer( geometryGroup.__webglTangentBuffer );
37770         _gl.deleteBuffer( geometryGroup.__webglColorBuffer );
37771         _gl.deleteBuffer( geometryGroup.__webglUVBuffer );
37772         _gl.deleteBuffer( geometryGroup.__webglUV2Buffer );
37773
37774         _gl.deleteBuffer( geometryGroup.__webglSkinIndicesBuffer );
37775         _gl.deleteBuffer( geometryGroup.__webglSkinWeightsBuffer );
37776
37777         _gl.deleteBuffer( geometryGroup.__webglFaceBuffer );
37778         _gl.deleteBuffer( geometryGroup.__webglLineBuffer );
37779
37780         var m, ml;
37781
37782         if ( geometryGroup.numMorphTargets ) {
37783
37784             for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
37785
37786                 _gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
37787
37788             }
37789
37790         }
37791
37792         if ( geometryGroup.numMorphNormals ) {
37793
37794             for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
37795
37796                 _gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
37797
37798             }
37799
37800         }
37801
37802
37803         if ( geometryGroup.__webglCustomAttributesList ) {
37804
37805             for ( var id in geometryGroup.__webglCustomAttributesList ) {
37806
37807                 _gl.deleteBuffer( geometryGroup.__webglCustomAttributesList[ id ].buffer );
37808
37809             }
37810
37811         }
37812
37813         _this.info.memory.geometries --;
37814
37815     };
37816
37817     // Buffer initialization
37818
37819     function initCustomAttributes ( geometry, object ) {
37820
37821         var nvertices = geometry.vertices.length;
37822
37823         var material = object.material;
37824
37825         if ( material.attributes ) {
37826
37827             if ( geometry.__webglCustomAttributesList === undefined ) {
37828
37829                 geometry.__webglCustomAttributesList = [];
37830
37831             }
37832
37833             for ( var a in material.attributes ) {
37834
37835                 var attribute = material.attributes[ a ];
37836
37837                 if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
37838
37839                     attribute.__webglInitialized = true;
37840
37841                     var size = 1;        // "f" and "i"
37842
37843                     if ( attribute.type === "v2" ) size = 2;
37844                     else if ( attribute.type === "v3" ) size = 3;
37845                     else if ( attribute.type === "v4" ) size = 4;
37846                     else if ( attribute.type === "c"  ) size = 3;
37847
37848                     attribute.size = size;
37849
37850                     attribute.array = new Float32Array( nvertices * size );
37851
37852                     attribute.buffer = _gl.createBuffer();
37853                     attribute.buffer.belongsToAttribute = a;
37854
37855                     attribute.needsUpdate = true;
37856
37857                 }
37858
37859                 geometry.__webglCustomAttributesList.push( attribute );
37860
37861             }
37862
37863         }
37864
37865     };
37866
37867     function initParticleBuffers ( geometry, object ) {
37868
37869         var nvertices = geometry.vertices.length;
37870
37871         geometry.__vertexArray = new Float32Array( nvertices * 3 );
37872         geometry.__colorArray = new Float32Array( nvertices * 3 );
37873
37874         geometry.__sortArray = [];
37875
37876         geometry.__webglParticleCount = nvertices;
37877
37878         initCustomAttributes ( geometry, object );
37879
37880     };
37881
37882     function initLineBuffers ( geometry, object ) {
37883
37884         var nvertices = geometry.vertices.length;
37885
37886         geometry.__vertexArray = new Float32Array( nvertices * 3 );
37887         geometry.__colorArray = new Float32Array( nvertices * 3 );
37888
37889         geometry.__webglLineCount = nvertices;
37890
37891         initCustomAttributes ( geometry, object );
37892
37893     };
37894
37895     function initRibbonBuffers ( geometry ) {
37896
37897         var nvertices = geometry.vertices.length;
37898
37899         geometry.__vertexArray = new Float32Array( nvertices * 3 );
37900         geometry.__colorArray = new Float32Array( nvertices * 3 );
37901
37902         geometry.__webglVertexCount = nvertices;
37903
37904     };
37905
37906     function initMeshBuffers ( geometryGroup, object ) {
37907
37908         var geometry = object.geometry,
37909             faces3 = geometryGroup.faces3,
37910             faces4 = geometryGroup.faces4,
37911
37912             nvertices = faces3.length * 3 + faces4.length * 4,
37913             ntris     = faces3.length * 1 + faces4.length * 2,
37914             nlines    = faces3.length * 3 + faces4.length * 4,
37915
37916             material = getBufferMaterial( object, geometryGroup ),
37917
37918             uvType = bufferGuessUVType( material ),
37919             normalType = bufferGuessNormalType( material ),
37920             vertexColorType = bufferGuessVertexColorType( material );
37921
37922         //console.log( "uvType", uvType, "normalType", normalType, "vertexColorType", vertexColorType, object, geometryGroup, material );
37923
37924         geometryGroup.__vertexArray = new Float32Array( nvertices * 3 );
37925
37926         if ( normalType ) {
37927
37928             geometryGroup.__normalArray = new Float32Array( nvertices * 3 );
37929
37930         }
37931
37932         if ( geometry.hasTangents ) {
37933
37934             geometryGroup.__tangentArray = new Float32Array( nvertices * 4 );
37935
37936         }
37937
37938         if ( vertexColorType ) {
37939
37940             geometryGroup.__colorArray = new Float32Array( nvertices * 3 );
37941
37942         }
37943
37944         if ( uvType ) {
37945
37946             if ( geometry.faceUvs.length > 0 || geometry.faceVertexUvs.length > 0 ) {
37947
37948                 geometryGroup.__uvArray = new Float32Array( nvertices * 2 );
37949
37950             }
37951
37952             if ( geometry.faceUvs.length > 1 || geometry.faceVertexUvs.length > 1 ) {
37953
37954                 geometryGroup.__uv2Array = new Float32Array( nvertices * 2 );
37955
37956             }
37957
37958         }
37959
37960         if ( object.geometry.skinWeights.length && object.geometry.skinIndices.length ) {
37961
37962             geometryGroup.__skinIndexArray = new Float32Array( nvertices * 4 );
37963             geometryGroup.__skinWeightArray = new Float32Array( nvertices * 4 );
37964
37965         }
37966
37967         geometryGroup.__faceArray = new Uint16Array( ntris * 3 );
37968         geometryGroup.__lineArray = new Uint16Array( nlines * 2 );
37969
37970         var m, ml;
37971
37972         if ( geometryGroup.numMorphTargets ) {
37973
37974             geometryGroup.__morphTargetsArrays = [];
37975
37976             for ( m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
37977
37978                 geometryGroup.__morphTargetsArrays.push( new Float32Array( nvertices * 3 ) );
37979
37980             }
37981
37982         }
37983
37984         if ( geometryGroup.numMorphNormals ) {
37985
37986             geometryGroup.__morphNormalsArrays = [];
37987
37988             for ( m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
37989
37990                 geometryGroup.__morphNormalsArrays.push( new Float32Array( nvertices * 3 ) );
37991
37992             }
37993
37994         }
37995
37996         geometryGroup.__webglFaceCount = ntris * 3;
37997         geometryGroup.__webglLineCount = nlines * 2;
37998
37999
38000         // custom attributes
38001
38002         if ( material.attributes ) {
38003
38004             if ( geometryGroup.__webglCustomAttributesList === undefined ) {
38005
38006                 geometryGroup.__webglCustomAttributesList = [];
38007
38008             }
38009
38010             for ( var a in material.attributes ) {
38011
38012                 // Do a shallow copy of the attribute object so different geometryGroup chunks use different
38013                 // attribute buffers which are correctly indexed in the setMeshBuffers function
38014
38015                 var originalAttribute = material.attributes[ a ];
38016
38017                 var attribute = {};
38018
38019                 for ( var property in originalAttribute ) {
38020
38021                     attribute[ property ] = originalAttribute[ property ];
38022
38023                 }
38024
38025                 if( !attribute.__webglInitialized || attribute.createUniqueBuffers ) {
38026
38027                     attribute.__webglInitialized = true;
38028
38029                     var size = 1;        // "f" and "i"
38030
38031                     if( attribute.type === "v2" ) size = 2;
38032                     else if( attribute.type === "v3" ) size = 3;
38033                     else if( attribute.type === "v4" ) size = 4;
38034                     else if( attribute.type === "c"  ) size = 3;
38035
38036                     attribute.size = size;
38037
38038                     attribute.array = new Float32Array( nvertices * size );
38039
38040                     attribute.buffer = _gl.createBuffer();
38041                     attribute.buffer.belongsToAttribute = a;
38042
38043                     originalAttribute.needsUpdate = true;
38044                     attribute.__original = originalAttribute;
38045
38046                 }
38047
38048                 geometryGroup.__webglCustomAttributesList.push( attribute );
38049
38050             }
38051
38052         }
38053
38054         geometryGroup.__inittedArrays = true;
38055
38056     };
38057
38058     function getBufferMaterial( object, geometryGroup ) {
38059
38060         if ( object.material && ! ( object.material instanceof THREE.MeshFaceMaterial ) ) {
38061
38062             return object.material;
38063
38064         } else if ( geometryGroup.materialIndex >= 0 ) {
38065
38066             return object.geometry.materials[ geometryGroup.materialIndex ];
38067
38068         }
38069
38070     };
38071
38072     function materialNeedsSmoothNormals ( material ) {
38073
38074         return material && material.shading !== undefined && material.shading === THREE.SmoothShading;
38075
38076     };
38077
38078     function bufferGuessNormalType ( material ) {
38079
38080         // only MeshBasicMaterial and MeshDepthMaterial don't need normals
38081
38082         if ( ( material instanceof THREE.MeshBasicMaterial && !material.envMap ) || material instanceof THREE.MeshDepthMaterial ) {
38083
38084             return false;
38085
38086         }
38087
38088         if ( materialNeedsSmoothNormals( material ) ) {
38089
38090             return THREE.SmoothShading;
38091
38092         } else {
38093
38094             return THREE.FlatShading;
38095
38096         }
38097
38098     };
38099
38100     function bufferGuessVertexColorType ( material ) {
38101
38102         if ( material.vertexColors ) {
38103
38104             return material.vertexColors;
38105
38106         }
38107
38108         return false;
38109
38110     };
38111
38112     function bufferGuessUVType ( material ) {
38113
38114         // material must use some texture to require uvs
38115
38116         if ( material.map || material.lightMap || material.bumpMap || material.normalMap || material.specularMap || material instanceof THREE.ShaderMaterial ) {
38117
38118             return true;
38119
38120         }
38121
38122         return false;
38123
38124     };
38125
38126     //
38127
38128     function initDirectBuffers( geometry ) {
38129
38130         var a, attribute, type;
38131
38132         for ( a in geometry.attributes ) {
38133
38134             if ( a === "index" ) {
38135
38136                 type = _gl.ELEMENT_ARRAY_BUFFER;
38137
38138             } else {
38139
38140                 type = _gl.ARRAY_BUFFER;
38141
38142             }
38143
38144             attribute = geometry.attributes[ a ];
38145
38146             attribute.buffer = _gl.createBuffer();
38147
38148             _gl.bindBuffer( type, attribute.buffer );
38149             _gl.bufferData( type, attribute.array, _gl.STATIC_DRAW );
38150
38151         }
38152
38153     };
38154
38155     // Buffer setting
38156
38157     function setParticleBuffers ( geometry, hint, object ) {
38158
38159         var v, c, vertex, offset, index, color,
38160
38161         vertices = geometry.vertices,
38162         vl = vertices.length,
38163
38164         colors = geometry.colors,
38165         cl = colors.length,
38166
38167         vertexArray = geometry.__vertexArray,
38168         colorArray = geometry.__colorArray,
38169
38170         sortArray = geometry.__sortArray,
38171
38172         dirtyVertices = geometry.verticesNeedUpdate,
38173         dirtyElements = geometry.elementsNeedUpdate,
38174         dirtyColors = geometry.colorsNeedUpdate,
38175
38176         customAttributes = geometry.__webglCustomAttributesList,
38177         i, il,
38178         a, ca, cal, value,
38179         customAttribute;
38180
38181         if ( object.sortParticles ) {
38182
38183             _projScreenMatrixPS.copy( _projScreenMatrix );
38184             _projScreenMatrixPS.multiplySelf( object.matrixWorld );
38185
38186             for ( v = 0; v < vl; v ++ ) {
38187
38188                 vertex = vertices[ v ];
38189
38190                 _vector3.copy( vertex );
38191                 _projScreenMatrixPS.multiplyVector3( _vector3 );
38192
38193                 sortArray[ v ] = [ _vector3.z, v ];
38194
38195             }
38196
38197             sortArray.sort( function( a, b ) { return b[ 0 ] - a[ 0 ]; } );
38198
38199             for ( v = 0; v < vl; v ++ ) {
38200
38201                 vertex = vertices[ sortArray[v][1] ];
38202
38203                 offset = v * 3;
38204
38205                 vertexArray[ offset ]     = vertex.x;
38206                 vertexArray[ offset + 1 ] = vertex.y;
38207                 vertexArray[ offset + 2 ] = vertex.z;
38208
38209             }
38210
38211             for ( c = 0; c < cl; c ++ ) {
38212
38213                 offset = c * 3;
38214
38215                 color = colors[ sortArray[c][1] ];
38216
38217                 colorArray[ offset ]     = color.r;
38218                 colorArray[ offset + 1 ] = color.g;
38219                 colorArray[ offset + 2 ] = color.b;
38220
38221             }
38222
38223             if ( customAttributes ) {
38224
38225                 for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
38226
38227                     customAttribute = customAttributes[ i ];
38228
38229                     if ( ! ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) ) continue;
38230
38231                     offset = 0;
38232
38233                     cal = customAttribute.value.length;
38234
38235                     if ( customAttribute.size === 1 ) {
38236
38237                         for ( ca = 0; ca < cal; ca ++ ) {
38238
38239                             index = sortArray[ ca ][ 1 ];
38240
38241                             customAttribute.array[ ca ] = customAttribute.value[ index ];
38242
38243                         }
38244
38245                     } else if ( customAttribute.size === 2 ) {
38246
38247                         for ( ca = 0; ca < cal; ca ++ ) {
38248
38249                             index = sortArray[ ca ][ 1 ];
38250
38251                             value = customAttribute.value[ index ];
38252
38253                             customAttribute.array[ offset ]     = value.x;
38254                             customAttribute.array[ offset + 1 ] = value.y;
38255
38256                             offset += 2;
38257
38258                         }
38259
38260                     } else if ( customAttribute.size === 3 ) {
38261
38262                         if ( customAttribute.type === "c" ) {
38263
38264                             for ( ca = 0; ca < cal; ca ++ ) {
38265
38266                                 index = sortArray[ ca ][ 1 ];
38267
38268                                 value = customAttribute.value[ index ];
38269
38270                                 customAttribute.array[ offset ]     = value.r;
38271                                 customAttribute.array[ offset + 1 ] = value.g;
38272                                 customAttribute.array[ offset + 2 ] = value.b;
38273
38274                                 offset += 3;
38275
38276                             }
38277
38278                         } else {
38279
38280                             for ( ca = 0; ca < cal; ca ++ ) {
38281
38282                                 index = sortArray[ ca ][ 1 ];
38283
38284                                 value = customAttribute.value[ index ];
38285
38286                                 customAttribute.array[ offset ]     = value.x;
38287                                 customAttribute.array[ offset + 1 ] = value.y;
38288                                 customAttribute.array[ offset + 2 ] = value.z;
38289
38290                                 offset += 3;
38291
38292                             }
38293
38294                         }
38295
38296                     } else if ( customAttribute.size === 4 ) {
38297
38298                         for ( ca = 0; ca < cal; ca ++ ) {
38299
38300                             index = sortArray[ ca ][ 1 ];
38301
38302                             value = customAttribute.value[ index ];
38303
38304                             customAttribute.array[ offset ]      = value.x;
38305                             customAttribute.array[ offset + 1  ] = value.y;
38306                             customAttribute.array[ offset + 2  ] = value.z;
38307                             customAttribute.array[ offset + 3  ] = value.w;
38308
38309                             offset += 4;
38310
38311                         }
38312
38313                     }
38314
38315                 }
38316
38317             }
38318
38319         } else {
38320
38321             if ( dirtyVertices ) {
38322
38323                 for ( v = 0; v < vl; v ++ ) {
38324
38325                     vertex = vertices[ v ];
38326
38327                     offset = v * 3;
38328
38329                     vertexArray[ offset ]     = vertex.x;
38330                     vertexArray[ offset + 1 ] = vertex.y;
38331                     vertexArray[ offset + 2 ] = vertex.z;
38332
38333                 }
38334
38335             }
38336
38337             if ( dirtyColors ) {
38338
38339                 for ( c = 0; c < cl; c ++ ) {
38340
38341                     color = colors[ c ];
38342
38343                     offset = c * 3;
38344
38345                     colorArray[ offset ]     = color.r;
38346                     colorArray[ offset + 1 ] = color.g;
38347                     colorArray[ offset + 2 ] = color.b;
38348
38349                 }
38350
38351             }
38352
38353             if ( customAttributes ) {
38354
38355                 for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
38356
38357                     customAttribute = customAttributes[ i ];
38358
38359                     if ( customAttribute.needsUpdate &&
38360                          ( customAttribute.boundTo === undefined ||
38361                            customAttribute.boundTo === "vertices") ) {
38362
38363                         cal = customAttribute.value.length;
38364
38365                         offset = 0;
38366
38367                         if ( customAttribute.size === 1 ) {
38368
38369                             for ( ca = 0; ca < cal; ca ++ ) {
38370
38371                                 customAttribute.array[ ca ] = customAttribute.value[ ca ];
38372
38373                             }
38374
38375                         } else if ( customAttribute.size === 2 ) {
38376
38377                             for ( ca = 0; ca < cal; ca ++ ) {
38378
38379                                 value = customAttribute.value[ ca ];
38380
38381                                 customAttribute.array[ offset ]     = value.x;
38382                                 customAttribute.array[ offset + 1 ] = value.y;
38383
38384                                 offset += 2;
38385
38386                             }
38387
38388                         } else if ( customAttribute.size === 3 ) {
38389
38390                             if ( customAttribute.type === "c" ) {
38391
38392                                 for ( ca = 0; ca < cal; ca ++ ) {
38393
38394                                     value = customAttribute.value[ ca ];
38395
38396                                     customAttribute.array[ offset ]     = value.r;
38397                                     customAttribute.array[ offset + 1 ] = value.g;
38398                                     customAttribute.array[ offset + 2 ] = value.b;
38399
38400                                     offset += 3;
38401
38402                                 }
38403
38404                             } else {
38405
38406                                 for ( ca = 0; ca < cal; ca ++ ) {
38407
38408                                     value = customAttribute.value[ ca ];
38409
38410                                     customAttribute.array[ offset ]     = value.x;
38411                                     customAttribute.array[ offset + 1 ] = value.y;
38412                                     customAttribute.array[ offset + 2 ] = value.z;
38413
38414                                     offset += 3;
38415
38416                                 }
38417
38418                             }
38419
38420                         } else if ( customAttribute.size === 4 ) {
38421
38422                             for ( ca = 0; ca < cal; ca ++ ) {
38423
38424                                 value = customAttribute.value[ ca ];
38425
38426                                 customAttribute.array[ offset ]      = value.x;
38427                                 customAttribute.array[ offset + 1  ] = value.y;
38428                                 customAttribute.array[ offset + 2  ] = value.z;
38429                                 customAttribute.array[ offset + 3  ] = value.w;
38430
38431                                 offset += 4;
38432
38433                             }
38434
38435                         }
38436
38437                     }
38438
38439                 }
38440
38441             }
38442
38443         }
38444
38445         if ( dirtyVertices || object.sortParticles ) {
38446
38447             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
38448             _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
38449
38450         }
38451
38452         if ( dirtyColors || object.sortParticles ) {
38453
38454             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
38455             _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
38456
38457         }
38458
38459         if ( customAttributes ) {
38460
38461             for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
38462
38463                 customAttribute = customAttributes[ i ];
38464
38465                 if ( customAttribute.needsUpdate || object.sortParticles ) {
38466
38467                     _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
38468                     _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
38469
38470                 }
38471
38472             }
38473
38474         }
38475
38476
38477     };
38478
38479     function setLineBuffers ( geometry, hint ) {
38480
38481         var v, c, vertex, offset, color,
38482
38483         vertices = geometry.vertices,
38484         colors = geometry.colors,
38485         vl = vertices.length,
38486         cl = colors.length,
38487
38488         vertexArray = geometry.__vertexArray,
38489         colorArray = geometry.__colorArray,
38490
38491         dirtyVertices = geometry.verticesNeedUpdate,
38492         dirtyColors = geometry.colorsNeedUpdate,
38493
38494         customAttributes = geometry.__webglCustomAttributesList,
38495
38496         i, il,
38497         a, ca, cal, value,
38498         customAttribute;
38499
38500         if ( dirtyVertices ) {
38501
38502             for ( v = 0; v < vl; v ++ ) {
38503
38504                 vertex = vertices[ v ];
38505
38506                 offset = v * 3;
38507
38508                 vertexArray[ offset ]     = vertex.x;
38509                 vertexArray[ offset + 1 ] = vertex.y;
38510                 vertexArray[ offset + 2 ] = vertex.z;
38511
38512             }
38513
38514             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
38515             _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
38516
38517         }
38518
38519         if ( dirtyColors ) {
38520
38521             for ( c = 0; c < cl; c ++ ) {
38522
38523                 color = colors[ c ];
38524
38525                 offset = c * 3;
38526
38527                 colorArray[ offset ]     = color.r;
38528                 colorArray[ offset + 1 ] = color.g;
38529                 colorArray[ offset + 2 ] = color.b;
38530
38531             }
38532
38533             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
38534             _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
38535
38536         }
38537
38538         if ( customAttributes ) {
38539
38540             for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
38541
38542                 customAttribute = customAttributes[ i ];
38543
38544                 if ( customAttribute.needsUpdate &&
38545                      ( customAttribute.boundTo === undefined ||
38546                        customAttribute.boundTo === "vertices" ) ) {
38547
38548                     offset = 0;
38549
38550                     cal = customAttribute.value.length;
38551
38552                     if ( customAttribute.size === 1 ) {
38553
38554                         for ( ca = 0; ca < cal; ca ++ ) {
38555
38556                             customAttribute.array[ ca ] = customAttribute.value[ ca ];
38557
38558                         }
38559
38560                     } else if ( customAttribute.size === 2 ) {
38561
38562                         for ( ca = 0; ca < cal; ca ++ ) {
38563
38564                             value = customAttribute.value[ ca ];
38565
38566                             customAttribute.array[ offset ]     = value.x;
38567                             customAttribute.array[ offset + 1 ] = value.y;
38568
38569                             offset += 2;
38570
38571                         }
38572
38573                     } else if ( customAttribute.size === 3 ) {
38574
38575                         if ( customAttribute.type === "c" ) {
38576
38577                             for ( ca = 0; ca < cal; ca ++ ) {
38578
38579                                 value = customAttribute.value[ ca ];
38580
38581                                 customAttribute.array[ offset ]     = value.r;
38582                                 customAttribute.array[ offset + 1 ] = value.g;
38583                                 customAttribute.array[ offset + 2 ] = value.b;
38584
38585                                 offset += 3;
38586
38587                             }
38588
38589                         } else {
38590
38591                             for ( ca = 0; ca < cal; ca ++ ) {
38592
38593                                 value = customAttribute.value[ ca ];
38594
38595                                 customAttribute.array[ offset ]     = value.x;
38596                                 customAttribute.array[ offset + 1 ] = value.y;
38597                                 customAttribute.array[ offset + 2 ] = value.z;
38598
38599                                 offset += 3;
38600
38601                             }
38602
38603                         }
38604
38605                     } else if ( customAttribute.size === 4 ) {
38606
38607                         for ( ca = 0; ca < cal; ca ++ ) {
38608
38609                             value = customAttribute.value[ ca ];
38610
38611                             customAttribute.array[ offset ]      = value.x;
38612                             customAttribute.array[ offset + 1  ] = value.y;
38613                             customAttribute.array[ offset + 2  ] = value.z;
38614                             customAttribute.array[ offset + 3  ] = value.w;
38615
38616                             offset += 4;
38617
38618                         }
38619
38620                     }
38621
38622                     _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
38623                     _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
38624
38625                 }
38626
38627             }
38628
38629         }
38630
38631     };
38632
38633     function setRibbonBuffers ( geometry, hint ) {
38634
38635         var v, c, vertex, offset, color,
38636
38637         vertices = geometry.vertices,
38638         colors = geometry.colors,
38639         vl = vertices.length,
38640         cl = colors.length,
38641
38642         vertexArray = geometry.__vertexArray,
38643         colorArray = geometry.__colorArray,
38644
38645         dirtyVertices = geometry.verticesNeedUpdate,
38646         dirtyColors = geometry.colorsNeedUpdate;
38647
38648         if ( dirtyVertices ) {
38649
38650             for ( v = 0; v < vl; v ++ ) {
38651
38652                 vertex = vertices[ v ];
38653
38654                 offset = v * 3;
38655
38656                 vertexArray[ offset ]     = vertex.x;
38657                 vertexArray[ offset + 1 ] = vertex.y;
38658                 vertexArray[ offset + 2 ] = vertex.z;
38659
38660             }
38661
38662             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglVertexBuffer );
38663             _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
38664
38665         }
38666
38667         if ( dirtyColors ) {
38668
38669             for ( c = 0; c < cl; c ++ ) {
38670
38671                 color = colors[ c ];
38672
38673                 offset = c * 3;
38674
38675                 colorArray[ offset ]     = color.r;
38676                 colorArray[ offset + 1 ] = color.g;
38677                 colorArray[ offset + 2 ] = color.b;
38678
38679             }
38680
38681             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometry.__webglColorBuffer );
38682             _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
38683
38684         }
38685
38686     };
38687
38688     function setMeshBuffers( geometryGroup, object, hint, dispose, material ) {
38689
38690         if ( ! geometryGroup.__inittedArrays ) {
38691
38692             // console.log( object );
38693             return;
38694
38695         }
38696
38697         var normalType = bufferGuessNormalType( material ),
38698         vertexColorType = bufferGuessVertexColorType( material ),
38699         uvType = bufferGuessUVType( material ),
38700
38701         needsSmoothNormals = ( normalType === THREE.SmoothShading );
38702
38703         var f, fl, fi, face,
38704         vertexNormals, faceNormal, normal,
38705         vertexColors, faceColor,
38706         vertexTangents,
38707         uv, uv2, v1, v2, v3, v4, t1, t2, t3, t4, n1, n2, n3, n4,
38708         c1, c2, c3, c4,
38709         sw1, sw2, sw3, sw4,
38710         si1, si2, si3, si4,
38711         sa1, sa2, sa3, sa4,
38712         sb1, sb2, sb3, sb4,
38713         m, ml, i, il,
38714         vn, uvi, uv2i,
38715         vk, vkl, vka,
38716         nka, chf, faceVertexNormals,
38717         a,
38718
38719         vertexIndex = 0,
38720
38721         offset = 0,
38722         offset_uv = 0,
38723         offset_uv2 = 0,
38724         offset_face = 0,
38725         offset_normal = 0,
38726         offset_tangent = 0,
38727         offset_line = 0,
38728         offset_color = 0,
38729         offset_skin = 0,
38730         offset_morphTarget = 0,
38731         offset_custom = 0,
38732         offset_customSrc = 0,
38733
38734         value,
38735
38736         vertexArray = geometryGroup.__vertexArray,
38737         uvArray = geometryGroup.__uvArray,
38738         uv2Array = geometryGroup.__uv2Array,
38739         normalArray = geometryGroup.__normalArray,
38740         tangentArray = geometryGroup.__tangentArray,
38741         colorArray = geometryGroup.__colorArray,
38742
38743         skinIndexArray = geometryGroup.__skinIndexArray,
38744         skinWeightArray = geometryGroup.__skinWeightArray,
38745
38746         morphTargetsArrays = geometryGroup.__morphTargetsArrays,
38747         morphNormalsArrays = geometryGroup.__morphNormalsArrays,
38748
38749         customAttributes = geometryGroup.__webglCustomAttributesList,
38750         customAttribute,
38751
38752         faceArray = geometryGroup.__faceArray,
38753         lineArray = geometryGroup.__lineArray,
38754
38755         geometry = object.geometry, // this is shared for all chunks
38756
38757         dirtyVertices = geometry.verticesNeedUpdate,
38758         dirtyElements = geometry.elementsNeedUpdate,
38759         dirtyUvs = geometry.uvsNeedUpdate,
38760         dirtyNormals = geometry.normalsNeedUpdate,
38761         dirtyTangents = geometry.tangentsNeedUpdate,
38762         dirtyColors = geometry.colorsNeedUpdate,
38763         dirtyMorphTargets = geometry.morphTargetsNeedUpdate,
38764
38765         vertices = geometry.vertices,
38766         chunk_faces3 = geometryGroup.faces3,
38767         chunk_faces4 = geometryGroup.faces4,
38768         obj_faces = geometry.faces,
38769
38770         obj_uvs  = geometry.faceVertexUvs[ 0 ],
38771         obj_uvs2 = geometry.faceVertexUvs[ 1 ],
38772
38773         obj_colors = geometry.colors,
38774
38775         obj_skinIndices = geometry.skinIndices,
38776         obj_skinWeights = geometry.skinWeights,
38777
38778         morphTargets = geometry.morphTargets,
38779         morphNormals = geometry.morphNormals;
38780
38781         if ( dirtyVertices ) {
38782
38783             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
38784
38785                 face = obj_faces[ chunk_faces3[ f ] ];
38786
38787                 v1 = vertices[ face.a ];
38788                 v2 = vertices[ face.b ];
38789                 v3 = vertices[ face.c ];
38790
38791                 vertexArray[ offset ]     = v1.x;
38792                 vertexArray[ offset + 1 ] = v1.y;
38793                 vertexArray[ offset + 2 ] = v1.z;
38794
38795                 vertexArray[ offset + 3 ] = v2.x;
38796                 vertexArray[ offset + 4 ] = v2.y;
38797                 vertexArray[ offset + 5 ] = v2.z;
38798
38799                 vertexArray[ offset + 6 ] = v3.x;
38800                 vertexArray[ offset + 7 ] = v3.y;
38801                 vertexArray[ offset + 8 ] = v3.z;
38802
38803                 offset += 9;
38804
38805             }
38806
38807             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
38808
38809                 face = obj_faces[ chunk_faces4[ f ] ];
38810
38811                 v1 = vertices[ face.a ];
38812                 v2 = vertices[ face.b ];
38813                 v3 = vertices[ face.c ];
38814                 v4 = vertices[ face.d ];
38815
38816                 vertexArray[ offset ]     = v1.x;
38817                 vertexArray[ offset + 1 ] = v1.y;
38818                 vertexArray[ offset + 2 ] = v1.z;
38819
38820                 vertexArray[ offset + 3 ] = v2.x;
38821                 vertexArray[ offset + 4 ] = v2.y;
38822                 vertexArray[ offset + 5 ] = v2.z;
38823
38824                 vertexArray[ offset + 6 ] = v3.x;
38825                 vertexArray[ offset + 7 ] = v3.y;
38826                 vertexArray[ offset + 8 ] = v3.z;
38827
38828                 vertexArray[ offset + 9 ]  = v4.x;
38829                 vertexArray[ offset + 10 ] = v4.y;
38830                 vertexArray[ offset + 11 ] = v4.z;
38831
38832                 offset += 12;
38833
38834             }
38835
38836             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
38837             _gl.bufferData( _gl.ARRAY_BUFFER, vertexArray, hint );
38838
38839         }
38840
38841         if ( dirtyMorphTargets ) {
38842
38843             for ( vk = 0, vkl = morphTargets.length; vk < vkl; vk ++ ) {
38844
38845                 offset_morphTarget = 0;
38846
38847                 for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
38848
38849                     chf = chunk_faces3[ f ];
38850                     face = obj_faces[ chf ];
38851
38852                     // morph positions
38853
38854                     v1 = morphTargets[ vk ].vertices[ face.a ];
38855                     v2 = morphTargets[ vk ].vertices[ face.b ];
38856                     v3 = morphTargets[ vk ].vertices[ face.c ];
38857
38858                     vka = morphTargetsArrays[ vk ];
38859
38860                     vka[ offset_morphTarget ]       = v1.x;
38861                     vka[ offset_morphTarget + 1 ] = v1.y;
38862                     vka[ offset_morphTarget + 2 ] = v1.z;
38863
38864                     vka[ offset_morphTarget + 3 ] = v2.x;
38865                     vka[ offset_morphTarget + 4 ] = v2.y;
38866                     vka[ offset_morphTarget + 5 ] = v2.z;
38867
38868                     vka[ offset_morphTarget + 6 ] = v3.x;
38869                     vka[ offset_morphTarget + 7 ] = v3.y;
38870                     vka[ offset_morphTarget + 8 ] = v3.z;
38871
38872                     // morph normals
38873
38874                     if ( material.morphNormals ) {
38875
38876                         if ( needsSmoothNormals ) {
38877
38878                             faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
38879
38880                             n1 = faceVertexNormals.a;
38881                             n2 = faceVertexNormals.b;
38882                             n3 = faceVertexNormals.c;
38883
38884                         } else {
38885
38886                             n1 = morphNormals[ vk ].faceNormals[ chf ];
38887                             n2 = n1;
38888                             n3 = n1;
38889
38890                         }
38891
38892                         nka = morphNormalsArrays[ vk ];
38893
38894                         nka[ offset_morphTarget ]       = n1.x;
38895                         nka[ offset_morphTarget + 1 ] = n1.y;
38896                         nka[ offset_morphTarget + 2 ] = n1.z;
38897
38898                         nka[ offset_morphTarget + 3 ] = n2.x;
38899                         nka[ offset_morphTarget + 4 ] = n2.y;
38900                         nka[ offset_morphTarget + 5 ] = n2.z;
38901
38902                         nka[ offset_morphTarget + 6 ] = n3.x;
38903                         nka[ offset_morphTarget + 7 ] = n3.y;
38904                         nka[ offset_morphTarget + 8 ] = n3.z;
38905
38906                     }
38907
38908                     //
38909
38910                     offset_morphTarget += 9;
38911
38912                 }
38913
38914                 for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
38915
38916                     chf = chunk_faces4[ f ];
38917                     face = obj_faces[ chf ];
38918
38919                     // morph positions
38920
38921                     v1 = morphTargets[ vk ].vertices[ face.a ];
38922                     v2 = morphTargets[ vk ].vertices[ face.b ];
38923                     v3 = morphTargets[ vk ].vertices[ face.c ];
38924                     v4 = morphTargets[ vk ].vertices[ face.d ];
38925
38926                     vka = morphTargetsArrays[ vk ];
38927
38928                     vka[ offset_morphTarget ]       = v1.x;
38929                     vka[ offset_morphTarget + 1 ] = v1.y;
38930                     vka[ offset_morphTarget + 2 ] = v1.z;
38931
38932                     vka[ offset_morphTarget + 3 ] = v2.x;
38933                     vka[ offset_morphTarget + 4 ] = v2.y;
38934                     vka[ offset_morphTarget + 5 ] = v2.z;
38935
38936                     vka[ offset_morphTarget + 6 ] = v3.x;
38937                     vka[ offset_morphTarget + 7 ] = v3.y;
38938                     vka[ offset_morphTarget + 8 ] = v3.z;
38939
38940                     vka[ offset_morphTarget + 9 ]  = v4.x;
38941                     vka[ offset_morphTarget + 10 ] = v4.y;
38942                     vka[ offset_morphTarget + 11 ] = v4.z;
38943
38944                     // morph normals
38945
38946                     if ( material.morphNormals ) {
38947
38948                         if ( needsSmoothNormals ) {
38949
38950                             faceVertexNormals = morphNormals[ vk ].vertexNormals[ chf ];
38951
38952                             n1 = faceVertexNormals.a;
38953                             n2 = faceVertexNormals.b;
38954                             n3 = faceVertexNormals.c;
38955                             n4 = faceVertexNormals.d;
38956
38957                         } else {
38958
38959                             n1 = morphNormals[ vk ].faceNormals[ chf ];
38960                             n2 = n1;
38961                             n3 = n1;
38962                             n4 = n1;
38963
38964                         }
38965
38966                         nka = morphNormalsArrays[ vk ];
38967
38968                         nka[ offset_morphTarget ]       = n1.x;
38969                         nka[ offset_morphTarget + 1 ] = n1.y;
38970                         nka[ offset_morphTarget + 2 ] = n1.z;
38971
38972                         nka[ offset_morphTarget + 3 ] = n2.x;
38973                         nka[ offset_morphTarget + 4 ] = n2.y;
38974                         nka[ offset_morphTarget + 5 ] = n2.z;
38975
38976                         nka[ offset_morphTarget + 6 ] = n3.x;
38977                         nka[ offset_morphTarget + 7 ] = n3.y;
38978                         nka[ offset_morphTarget + 8 ] = n3.z;
38979
38980                         nka[ offset_morphTarget + 9 ]  = n4.x;
38981                         nka[ offset_morphTarget + 10 ] = n4.y;
38982                         nka[ offset_morphTarget + 11 ] = n4.z;
38983
38984                     }
38985
38986                     //
38987
38988                     offset_morphTarget += 12;
38989
38990                 }
38991
38992                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ vk ] );
38993                 _gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
38994
38995                 if ( material.morphNormals ) {
38996
38997                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ vk ] );
38998                     _gl.bufferData( _gl.ARRAY_BUFFER, morphNormalsArrays[ vk ], hint );
38999
39000                 }
39001
39002             }
39003
39004         }
39005
39006         if ( obj_skinWeights.length ) {
39007
39008             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39009
39010                 face = obj_faces[ chunk_faces3[ f ]    ];
39011
39012                 // weights
39013
39014                 sw1 = obj_skinWeights[ face.a ];
39015                 sw2 = obj_skinWeights[ face.b ];
39016                 sw3 = obj_skinWeights[ face.c ];
39017
39018                 skinWeightArray[ offset_skin ]     = sw1.x;
39019                 skinWeightArray[ offset_skin + 1 ] = sw1.y;
39020                 skinWeightArray[ offset_skin + 2 ] = sw1.z;
39021                 skinWeightArray[ offset_skin + 3 ] = sw1.w;
39022
39023                 skinWeightArray[ offset_skin + 4 ] = sw2.x;
39024                 skinWeightArray[ offset_skin + 5 ] = sw2.y;
39025                 skinWeightArray[ offset_skin + 6 ] = sw2.z;
39026                 skinWeightArray[ offset_skin + 7 ] = sw2.w;
39027
39028                 skinWeightArray[ offset_skin + 8 ]  = sw3.x;
39029                 skinWeightArray[ offset_skin + 9 ]  = sw3.y;
39030                 skinWeightArray[ offset_skin + 10 ] = sw3.z;
39031                 skinWeightArray[ offset_skin + 11 ] = sw3.w;
39032
39033                 // indices
39034
39035                 si1 = obj_skinIndices[ face.a ];
39036                 si2 = obj_skinIndices[ face.b ];
39037                 si3 = obj_skinIndices[ face.c ];
39038
39039                 skinIndexArray[ offset_skin ]     = si1.x;
39040                 skinIndexArray[ offset_skin + 1 ] = si1.y;
39041                 skinIndexArray[ offset_skin + 2 ] = si1.z;
39042                 skinIndexArray[ offset_skin + 3 ] = si1.w;
39043
39044                 skinIndexArray[ offset_skin + 4 ] = si2.x;
39045                 skinIndexArray[ offset_skin + 5 ] = si2.y;
39046                 skinIndexArray[ offset_skin + 6 ] = si2.z;
39047                 skinIndexArray[ offset_skin + 7 ] = si2.w;
39048
39049                 skinIndexArray[ offset_skin + 8 ]  = si3.x;
39050                 skinIndexArray[ offset_skin + 9 ]  = si3.y;
39051                 skinIndexArray[ offset_skin + 10 ] = si3.z;
39052                 skinIndexArray[ offset_skin + 11 ] = si3.w;
39053
39054                 offset_skin += 12;
39055
39056             }
39057
39058             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39059
39060                 face = obj_faces[ chunk_faces4[ f ] ];
39061
39062                 // weights
39063
39064                 sw1 = obj_skinWeights[ face.a ];
39065                 sw2 = obj_skinWeights[ face.b ];
39066                 sw3 = obj_skinWeights[ face.c ];
39067                 sw4 = obj_skinWeights[ face.d ];
39068
39069                 skinWeightArray[ offset_skin ]     = sw1.x;
39070                 skinWeightArray[ offset_skin + 1 ] = sw1.y;
39071                 skinWeightArray[ offset_skin + 2 ] = sw1.z;
39072                 skinWeightArray[ offset_skin + 3 ] = sw1.w;
39073
39074                 skinWeightArray[ offset_skin + 4 ] = sw2.x;
39075                 skinWeightArray[ offset_skin + 5 ] = sw2.y;
39076                 skinWeightArray[ offset_skin + 6 ] = sw2.z;
39077                 skinWeightArray[ offset_skin + 7 ] = sw2.w;
39078
39079                 skinWeightArray[ offset_skin + 8 ]  = sw3.x;
39080                 skinWeightArray[ offset_skin + 9 ]  = sw3.y;
39081                 skinWeightArray[ offset_skin + 10 ] = sw3.z;
39082                 skinWeightArray[ offset_skin + 11 ] = sw3.w;
39083
39084                 skinWeightArray[ offset_skin + 12 ] = sw4.x;
39085                 skinWeightArray[ offset_skin + 13 ] = sw4.y;
39086                 skinWeightArray[ offset_skin + 14 ] = sw4.z;
39087                 skinWeightArray[ offset_skin + 15 ] = sw4.w;
39088
39089                 // indices
39090
39091                 si1 = obj_skinIndices[ face.a ];
39092                 si2 = obj_skinIndices[ face.b ];
39093                 si3 = obj_skinIndices[ face.c ];
39094                 si4 = obj_skinIndices[ face.d ];
39095
39096                 skinIndexArray[ offset_skin ]     = si1.x;
39097                 skinIndexArray[ offset_skin + 1 ] = si1.y;
39098                 skinIndexArray[ offset_skin + 2 ] = si1.z;
39099                 skinIndexArray[ offset_skin + 3 ] = si1.w;
39100
39101                 skinIndexArray[ offset_skin + 4 ] = si2.x;
39102                 skinIndexArray[ offset_skin + 5 ] = si2.y;
39103                 skinIndexArray[ offset_skin + 6 ] = si2.z;
39104                 skinIndexArray[ offset_skin + 7 ] = si2.w;
39105
39106                 skinIndexArray[ offset_skin + 8 ]  = si3.x;
39107                 skinIndexArray[ offset_skin + 9 ]  = si3.y;
39108                 skinIndexArray[ offset_skin + 10 ] = si3.z;
39109                 skinIndexArray[ offset_skin + 11 ] = si3.w;
39110
39111                 skinIndexArray[ offset_skin + 12 ] = si4.x;
39112                 skinIndexArray[ offset_skin + 13 ] = si4.y;
39113                 skinIndexArray[ offset_skin + 14 ] = si4.z;
39114                 skinIndexArray[ offset_skin + 15 ] = si4.w;
39115
39116                 offset_skin += 16;
39117
39118             }
39119
39120             if ( offset_skin > 0 ) {
39121
39122                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
39123                 _gl.bufferData( _gl.ARRAY_BUFFER, skinIndexArray, hint );
39124
39125                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
39126                 _gl.bufferData( _gl.ARRAY_BUFFER, skinWeightArray, hint );
39127
39128             }
39129
39130         }
39131
39132         if ( dirtyColors && vertexColorType ) {
39133
39134             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39135
39136                 face = obj_faces[ chunk_faces3[ f ]    ];
39137
39138                 vertexColors = face.vertexColors;
39139                 faceColor = face.color;
39140
39141                 if ( vertexColors.length === 3 && vertexColorType === THREE.VertexColors ) {
39142
39143                     c1 = vertexColors[ 0 ];
39144                     c2 = vertexColors[ 1 ];
39145                     c3 = vertexColors[ 2 ];
39146
39147                 } else {
39148
39149                     c1 = faceColor;
39150                     c2 = faceColor;
39151                     c3 = faceColor;
39152
39153                 }
39154
39155                 colorArray[ offset_color ]     = c1.r;
39156                 colorArray[ offset_color + 1 ] = c1.g;
39157                 colorArray[ offset_color + 2 ] = c1.b;
39158
39159                 colorArray[ offset_color + 3 ] = c2.r;
39160                 colorArray[ offset_color + 4 ] = c2.g;
39161                 colorArray[ offset_color + 5 ] = c2.b;
39162
39163                 colorArray[ offset_color + 6 ] = c3.r;
39164                 colorArray[ offset_color + 7 ] = c3.g;
39165                 colorArray[ offset_color + 8 ] = c3.b;
39166
39167                 offset_color += 9;
39168
39169             }
39170
39171             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39172
39173                 face = obj_faces[ chunk_faces4[ f ] ];
39174
39175                 vertexColors = face.vertexColors;
39176                 faceColor = face.color;
39177
39178                 if ( vertexColors.length === 4 && vertexColorType === THREE.VertexColors ) {
39179
39180                     c1 = vertexColors[ 0 ];
39181                     c2 = vertexColors[ 1 ];
39182                     c3 = vertexColors[ 2 ];
39183                     c4 = vertexColors[ 3 ];
39184
39185                 } else {
39186
39187                     c1 = faceColor;
39188                     c2 = faceColor;
39189                     c3 = faceColor;
39190                     c4 = faceColor;
39191
39192                 }
39193
39194                 colorArray[ offset_color ]     = c1.r;
39195                 colorArray[ offset_color + 1 ] = c1.g;
39196                 colorArray[ offset_color + 2 ] = c1.b;
39197
39198                 colorArray[ offset_color + 3 ] = c2.r;
39199                 colorArray[ offset_color + 4 ] = c2.g;
39200                 colorArray[ offset_color + 5 ] = c2.b;
39201
39202                 colorArray[ offset_color + 6 ] = c3.r;
39203                 colorArray[ offset_color + 7 ] = c3.g;
39204                 colorArray[ offset_color + 8 ] = c3.b;
39205
39206                 colorArray[ offset_color + 9 ]  = c4.r;
39207                 colorArray[ offset_color + 10 ] = c4.g;
39208                 colorArray[ offset_color + 11 ] = c4.b;
39209
39210                 offset_color += 12;
39211
39212             }
39213
39214             if ( offset_color > 0 ) {
39215
39216                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
39217                 _gl.bufferData( _gl.ARRAY_BUFFER, colorArray, hint );
39218
39219             }
39220
39221         }
39222
39223         if ( dirtyTangents && geometry.hasTangents ) {
39224
39225             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39226
39227                 face = obj_faces[ chunk_faces3[ f ]    ];
39228
39229                 vertexTangents = face.vertexTangents;
39230
39231                 t1 = vertexTangents[ 0 ];
39232                 t2 = vertexTangents[ 1 ];
39233                 t3 = vertexTangents[ 2 ];
39234
39235                 tangentArray[ offset_tangent ]     = t1.x;
39236                 tangentArray[ offset_tangent + 1 ] = t1.y;
39237                 tangentArray[ offset_tangent + 2 ] = t1.z;
39238                 tangentArray[ offset_tangent + 3 ] = t1.w;
39239
39240                 tangentArray[ offset_tangent + 4 ] = t2.x;
39241                 tangentArray[ offset_tangent + 5 ] = t2.y;
39242                 tangentArray[ offset_tangent + 6 ] = t2.z;
39243                 tangentArray[ offset_tangent + 7 ] = t2.w;
39244
39245                 tangentArray[ offset_tangent + 8 ]  = t3.x;
39246                 tangentArray[ offset_tangent + 9 ]  = t3.y;
39247                 tangentArray[ offset_tangent + 10 ] = t3.z;
39248                 tangentArray[ offset_tangent + 11 ] = t3.w;
39249
39250                 offset_tangent += 12;
39251
39252             }
39253
39254             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39255
39256                 face = obj_faces[ chunk_faces4[ f ] ];
39257
39258                 vertexTangents = face.vertexTangents;
39259
39260                 t1 = vertexTangents[ 0 ];
39261                 t2 = vertexTangents[ 1 ];
39262                 t3 = vertexTangents[ 2 ];
39263                 t4 = vertexTangents[ 3 ];
39264
39265                 tangentArray[ offset_tangent ]     = t1.x;
39266                 tangentArray[ offset_tangent + 1 ] = t1.y;
39267                 tangentArray[ offset_tangent + 2 ] = t1.z;
39268                 tangentArray[ offset_tangent + 3 ] = t1.w;
39269
39270                 tangentArray[ offset_tangent + 4 ] = t2.x;
39271                 tangentArray[ offset_tangent + 5 ] = t2.y;
39272                 tangentArray[ offset_tangent + 6 ] = t2.z;
39273                 tangentArray[ offset_tangent + 7 ] = t2.w;
39274
39275                 tangentArray[ offset_tangent + 8 ]  = t3.x;
39276                 tangentArray[ offset_tangent + 9 ]  = t3.y;
39277                 tangentArray[ offset_tangent + 10 ] = t3.z;
39278                 tangentArray[ offset_tangent + 11 ] = t3.w;
39279
39280                 tangentArray[ offset_tangent + 12 ] = t4.x;
39281                 tangentArray[ offset_tangent + 13 ] = t4.y;
39282                 tangentArray[ offset_tangent + 14 ] = t4.z;
39283                 tangentArray[ offset_tangent + 15 ] = t4.w;
39284
39285                 offset_tangent += 16;
39286
39287             }
39288
39289             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
39290             _gl.bufferData( _gl.ARRAY_BUFFER, tangentArray, hint );
39291
39292         }
39293
39294         if ( dirtyNormals && normalType ) {
39295
39296             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39297
39298                 face = obj_faces[ chunk_faces3[ f ]    ];
39299
39300                 vertexNormals = face.vertexNormals;
39301                 faceNormal = face.normal;
39302
39303                 if ( vertexNormals.length === 3 && needsSmoothNormals ) {
39304
39305                     for ( i = 0; i < 3; i ++ ) {
39306
39307                         vn = vertexNormals[ i ];
39308
39309                         normalArray[ offset_normal ]     = vn.x;
39310                         normalArray[ offset_normal + 1 ] = vn.y;
39311                         normalArray[ offset_normal + 2 ] = vn.z;
39312
39313                         offset_normal += 3;
39314
39315                     }
39316
39317                 } else {
39318
39319                     for ( i = 0; i < 3; i ++ ) {
39320
39321                         normalArray[ offset_normal ]     = faceNormal.x;
39322                         normalArray[ offset_normal + 1 ] = faceNormal.y;
39323                         normalArray[ offset_normal + 2 ] = faceNormal.z;
39324
39325                         offset_normal += 3;
39326
39327                     }
39328
39329                 }
39330
39331             }
39332
39333             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39334
39335                 face = obj_faces[ chunk_faces4[ f ] ];
39336
39337                 vertexNormals = face.vertexNormals;
39338                 faceNormal = face.normal;
39339
39340                 if ( vertexNormals.length === 4 && needsSmoothNormals ) {
39341
39342                     for ( i = 0; i < 4; i ++ ) {
39343
39344                         vn = vertexNormals[ i ];
39345
39346                         normalArray[ offset_normal ]     = vn.x;
39347                         normalArray[ offset_normal + 1 ] = vn.y;
39348                         normalArray[ offset_normal + 2 ] = vn.z;
39349
39350                         offset_normal += 3;
39351
39352                     }
39353
39354                 } else {
39355
39356                     for ( i = 0; i < 4; i ++ ) {
39357
39358                         normalArray[ offset_normal ]     = faceNormal.x;
39359                         normalArray[ offset_normal + 1 ] = faceNormal.y;
39360                         normalArray[ offset_normal + 2 ] = faceNormal.z;
39361
39362                         offset_normal += 3;
39363
39364                     }
39365
39366                 }
39367
39368             }
39369
39370             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
39371             _gl.bufferData( _gl.ARRAY_BUFFER, normalArray, hint );
39372
39373         }
39374
39375         if ( dirtyUvs && obj_uvs && uvType ) {
39376
39377             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39378
39379                 fi = chunk_faces3[ f ];
39380
39381                 face = obj_faces[ fi ];
39382                 uv = obj_uvs[ fi ];
39383
39384                 if ( uv === undefined ) continue;
39385
39386                 for ( i = 0; i < 3; i ++ ) {
39387
39388                     uvi = uv[ i ];
39389
39390                     uvArray[ offset_uv ]     = uvi.u;
39391                     uvArray[ offset_uv + 1 ] = uvi.v;
39392
39393                     offset_uv += 2;
39394
39395                 }
39396
39397             }
39398
39399             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39400
39401                 fi = chunk_faces4[ f ];
39402
39403                 face = obj_faces[ fi ];
39404                 uv = obj_uvs[ fi ];
39405
39406                 if ( uv === undefined ) continue;
39407
39408                 for ( i = 0; i < 4; i ++ ) {
39409
39410                     uvi = uv[ i ];
39411
39412                     uvArray[ offset_uv ]     = uvi.u;
39413                     uvArray[ offset_uv + 1 ] = uvi.v;
39414
39415                     offset_uv += 2;
39416
39417                 }
39418
39419             }
39420
39421             if ( offset_uv > 0 ) {
39422
39423                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
39424                 _gl.bufferData( _gl.ARRAY_BUFFER, uvArray, hint );
39425
39426             }
39427
39428         }
39429
39430         if ( dirtyUvs && obj_uvs2 && uvType ) {
39431
39432             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39433
39434                 fi = chunk_faces3[ f ];
39435
39436                 face = obj_faces[ fi ];
39437                 uv2 = obj_uvs2[ fi ];
39438
39439                 if ( uv2 === undefined ) continue;
39440
39441                 for ( i = 0; i < 3; i ++ ) {
39442
39443                     uv2i = uv2[ i ];
39444
39445                     uv2Array[ offset_uv2 ]     = uv2i.u;
39446                     uv2Array[ offset_uv2 + 1 ] = uv2i.v;
39447
39448                     offset_uv2 += 2;
39449
39450                 }
39451
39452             }
39453
39454             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39455
39456                 fi = chunk_faces4[ f ];
39457
39458                 face = obj_faces[ fi ];
39459                 uv2 = obj_uvs2[ fi ];
39460
39461                 if ( uv2 === undefined ) continue;
39462
39463                 for ( i = 0; i < 4; i ++ ) {
39464
39465                     uv2i = uv2[ i ];
39466
39467                     uv2Array[ offset_uv2 ]     = uv2i.u;
39468                     uv2Array[ offset_uv2 + 1 ] = uv2i.v;
39469
39470                     offset_uv2 += 2;
39471
39472                 }
39473
39474             }
39475
39476             if ( offset_uv2 > 0 ) {
39477
39478                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
39479                 _gl.bufferData( _gl.ARRAY_BUFFER, uv2Array, hint );
39480
39481             }
39482
39483         }
39484
39485         if ( dirtyElements ) {
39486
39487             for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39488
39489                 face = obj_faces[ chunk_faces3[ f ]    ];
39490
39491                 faceArray[ offset_face ]      = vertexIndex;
39492                 faceArray[ offset_face + 1 ] = vertexIndex + 1;
39493                 faceArray[ offset_face + 2 ] = vertexIndex + 2;
39494
39495                 offset_face += 3;
39496
39497                 lineArray[ offset_line ]     = vertexIndex;
39498                 lineArray[ offset_line + 1 ] = vertexIndex + 1;
39499
39500                 lineArray[ offset_line + 2 ] = vertexIndex;
39501                 lineArray[ offset_line + 3 ] = vertexIndex + 2;
39502
39503                 lineArray[ offset_line + 4 ] = vertexIndex + 1;
39504                 lineArray[ offset_line + 5 ] = vertexIndex + 2;
39505
39506                 offset_line += 6;
39507
39508                 vertexIndex += 3;
39509
39510             }
39511
39512             for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39513
39514                 face = obj_faces[ chunk_faces4[ f ] ];
39515
39516                 faceArray[ offset_face ]     = vertexIndex;
39517                 faceArray[ offset_face + 1 ] = vertexIndex + 1;
39518                 faceArray[ offset_face + 2 ] = vertexIndex + 3;
39519
39520                 faceArray[ offset_face + 3 ] = vertexIndex + 1;
39521                 faceArray[ offset_face + 4 ] = vertexIndex + 2;
39522                 faceArray[ offset_face + 5 ] = vertexIndex + 3;
39523
39524                 offset_face += 6;
39525
39526                 lineArray[ offset_line ]     = vertexIndex;
39527                 lineArray[ offset_line + 1 ] = vertexIndex + 1;
39528
39529                 lineArray[ offset_line + 2 ] = vertexIndex;
39530                 lineArray[ offset_line + 3 ] = vertexIndex + 3;
39531
39532                 lineArray[ offset_line + 4 ] = vertexIndex + 1;
39533                 lineArray[ offset_line + 5 ] = vertexIndex + 2;
39534
39535                 lineArray[ offset_line + 6 ] = vertexIndex + 2;
39536                 lineArray[ offset_line + 7 ] = vertexIndex + 3;
39537
39538                 offset_line += 8;
39539
39540                 vertexIndex += 4;
39541
39542             }
39543
39544             _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
39545             _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faceArray, hint );
39546
39547             _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
39548             _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, lineArray, hint );
39549
39550         }
39551
39552         if ( customAttributes ) {
39553
39554             for ( i = 0, il = customAttributes.length; i < il; i ++ ) {
39555
39556                 customAttribute = customAttributes[ i ];
39557
39558                 if ( ! customAttribute.__original.needsUpdate ) continue;
39559
39560                 offset_custom = 0;
39561                 offset_customSrc = 0;
39562
39563                 if ( customAttribute.size === 1 ) {
39564
39565                     if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
39566
39567                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39568
39569                             face = obj_faces[ chunk_faces3[ f ]    ];
39570
39571                             customAttribute.array[ offset_custom ]        = customAttribute.value[ face.a ];
39572                             customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
39573                             customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
39574
39575                             offset_custom += 3;
39576
39577                         }
39578
39579                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39580
39581                             face = obj_faces[ chunk_faces4[ f ] ];
39582
39583                             customAttribute.array[ offset_custom ]        = customAttribute.value[ face.a ];
39584                             customAttribute.array[ offset_custom + 1 ] = customAttribute.value[ face.b ];
39585                             customAttribute.array[ offset_custom + 2 ] = customAttribute.value[ face.c ];
39586                             customAttribute.array[ offset_custom + 3 ] = customAttribute.value[ face.d ];
39587
39588                             offset_custom += 4;
39589
39590                         }
39591
39592                     } else if ( customAttribute.boundTo === "faces" ) {
39593
39594                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39595
39596                             value = customAttribute.value[ chunk_faces3[ f ] ];
39597
39598                             customAttribute.array[ offset_custom ]        = value;
39599                             customAttribute.array[ offset_custom + 1 ] = value;
39600                             customAttribute.array[ offset_custom + 2 ] = value;
39601
39602                             offset_custom += 3;
39603
39604                         }
39605
39606                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39607
39608                             value = customAttribute.value[ chunk_faces4[ f ] ];
39609
39610                             customAttribute.array[ offset_custom ]        = value;
39611                             customAttribute.array[ offset_custom + 1 ] = value;
39612                             customAttribute.array[ offset_custom + 2 ] = value;
39613                             customAttribute.array[ offset_custom + 3 ] = value;
39614
39615                             offset_custom += 4;
39616
39617                         }
39618
39619                     }
39620
39621                 } else if ( customAttribute.size === 2 ) {
39622
39623                     if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
39624
39625                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39626
39627                             face = obj_faces[ chunk_faces3[ f ]    ];
39628
39629                             v1 = customAttribute.value[ face.a ];
39630                             v2 = customAttribute.value[ face.b ];
39631                             v3 = customAttribute.value[ face.c ];
39632
39633                             customAttribute.array[ offset_custom ]        = v1.x;
39634                             customAttribute.array[ offset_custom + 1 ] = v1.y;
39635
39636                             customAttribute.array[ offset_custom + 2 ] = v2.x;
39637                             customAttribute.array[ offset_custom + 3 ] = v2.y;
39638
39639                             customAttribute.array[ offset_custom + 4 ] = v3.x;
39640                             customAttribute.array[ offset_custom + 5 ] = v3.y;
39641
39642                             offset_custom += 6;
39643
39644                         }
39645
39646                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39647
39648                             face = obj_faces[ chunk_faces4[ f ] ];
39649
39650                             v1 = customAttribute.value[ face.a ];
39651                             v2 = customAttribute.value[ face.b ];
39652                             v3 = customAttribute.value[ face.c ];
39653                             v4 = customAttribute.value[ face.d ];
39654
39655                             customAttribute.array[ offset_custom ]        = v1.x;
39656                             customAttribute.array[ offset_custom + 1 ] = v1.y;
39657
39658                             customAttribute.array[ offset_custom + 2 ] = v2.x;
39659                             customAttribute.array[ offset_custom + 3 ] = v2.y;
39660
39661                             customAttribute.array[ offset_custom + 4 ] = v3.x;
39662                             customAttribute.array[ offset_custom + 5 ] = v3.y;
39663
39664                             customAttribute.array[ offset_custom + 6 ] = v4.x;
39665                             customAttribute.array[ offset_custom + 7 ] = v4.y;
39666
39667                             offset_custom += 8;
39668
39669                         }
39670
39671                     } else if ( customAttribute.boundTo === "faces" ) {
39672
39673                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39674
39675                             value = customAttribute.value[ chunk_faces3[ f ] ];
39676
39677                             v1 = value;
39678                             v2 = value;
39679                             v3 = value;
39680
39681                             customAttribute.array[ offset_custom ]        = v1.x;
39682                             customAttribute.array[ offset_custom + 1 ] = v1.y;
39683
39684                             customAttribute.array[ offset_custom + 2 ] = v2.x;
39685                             customAttribute.array[ offset_custom + 3 ] = v2.y;
39686
39687                             customAttribute.array[ offset_custom + 4 ] = v3.x;
39688                             customAttribute.array[ offset_custom + 5 ] = v3.y;
39689
39690                             offset_custom += 6;
39691
39692                         }
39693
39694                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39695
39696                             value = customAttribute.value[ chunk_faces4[ f ] ];
39697
39698                             v1 = value;
39699                             v2 = value;
39700                             v3 = value;
39701                             v4 = value;
39702
39703                             customAttribute.array[ offset_custom ]        = v1.x;
39704                             customAttribute.array[ offset_custom + 1 ] = v1.y;
39705
39706                             customAttribute.array[ offset_custom + 2 ] = v2.x;
39707                             customAttribute.array[ offset_custom + 3 ] = v2.y;
39708
39709                             customAttribute.array[ offset_custom + 4 ] = v3.x;
39710                             customAttribute.array[ offset_custom + 5 ] = v3.y;
39711
39712                             customAttribute.array[ offset_custom + 6 ] = v4.x;
39713                             customAttribute.array[ offset_custom + 7 ] = v4.y;
39714
39715                             offset_custom += 8;
39716
39717                         }
39718
39719                     }
39720
39721                 } else if ( customAttribute.size === 3 ) {
39722
39723                     var pp;
39724
39725                     if ( customAttribute.type === "c" ) {
39726
39727                         pp = [ "r", "g", "b" ];
39728
39729                     } else {
39730
39731                         pp = [ "x", "y", "z" ];
39732
39733                     }
39734
39735                     if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
39736
39737                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39738
39739                             face = obj_faces[ chunk_faces3[ f ]    ];
39740
39741                             v1 = customAttribute.value[ face.a ];
39742                             v2 = customAttribute.value[ face.b ];
39743                             v3 = customAttribute.value[ face.c ];
39744
39745                             customAttribute.array[ offset_custom ]        = v1[ pp[ 0 ] ];
39746                             customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
39747                             customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
39748
39749                             customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
39750                             customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
39751                             customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
39752
39753                             customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
39754                             customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
39755                             customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
39756
39757                             offset_custom += 9;
39758
39759                         }
39760
39761                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39762
39763                             face = obj_faces[ chunk_faces4[ f ] ];
39764
39765                             v1 = customAttribute.value[ face.a ];
39766                             v2 = customAttribute.value[ face.b ];
39767                             v3 = customAttribute.value[ face.c ];
39768                             v4 = customAttribute.value[ face.d ];
39769
39770                             customAttribute.array[ offset_custom  ]     = v1[ pp[ 0 ] ];
39771                             customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
39772                             customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
39773
39774                             customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
39775                             customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
39776                             customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
39777
39778                             customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
39779                             customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
39780                             customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
39781
39782                             customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
39783                             customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
39784                             customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
39785
39786                             offset_custom += 12;
39787
39788                         }
39789
39790                     } else if ( customAttribute.boundTo === "faces" ) {
39791
39792                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39793
39794                             value = customAttribute.value[ chunk_faces3[ f ] ];
39795
39796                             v1 = value;
39797                             v2 = value;
39798                             v3 = value;
39799
39800                             customAttribute.array[ offset_custom ]        = v1[ pp[ 0 ] ];
39801                             customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
39802                             customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
39803
39804                             customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
39805                             customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
39806                             customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
39807
39808                             customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
39809                             customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
39810                             customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
39811
39812                             offset_custom += 9;
39813
39814                         }
39815
39816                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39817
39818                             value = customAttribute.value[ chunk_faces4[ f ] ];
39819
39820                             v1 = value;
39821                             v2 = value;
39822                             v3 = value;
39823                             v4 = value;
39824
39825                             customAttribute.array[ offset_custom  ]     = v1[ pp[ 0 ] ];
39826                             customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
39827                             customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
39828
39829                             customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
39830                             customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
39831                             customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
39832
39833                             customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
39834                             customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
39835                             customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
39836
39837                             customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
39838                             customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
39839                             customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
39840
39841                             offset_custom += 12;
39842
39843                         }
39844
39845                     } else if ( customAttribute.boundTo === "faceVertices" ) {
39846
39847                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39848
39849                             value = customAttribute.value[ chunk_faces3[ f ] ];
39850
39851                             v1 = value[ 0 ];
39852                             v2 = value[ 1 ];
39853                             v3 = value[ 2 ];
39854
39855                             customAttribute.array[ offset_custom ]        = v1[ pp[ 0 ] ];
39856                             customAttribute.array[ offset_custom + 1 ] = v1[ pp[ 1 ] ];
39857                             customAttribute.array[ offset_custom + 2 ] = v1[ pp[ 2 ] ];
39858
39859                             customAttribute.array[ offset_custom + 3 ] = v2[ pp[ 0 ] ];
39860                             customAttribute.array[ offset_custom + 4 ] = v2[ pp[ 1 ] ];
39861                             customAttribute.array[ offset_custom + 5 ] = v2[ pp[ 2 ] ];
39862
39863                             customAttribute.array[ offset_custom + 6 ] = v3[ pp[ 0 ] ];
39864                             customAttribute.array[ offset_custom + 7 ] = v3[ pp[ 1 ] ];
39865                             customAttribute.array[ offset_custom + 8 ] = v3[ pp[ 2 ] ];
39866
39867                             offset_custom += 9;
39868
39869                         }
39870
39871                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39872
39873                             value = customAttribute.value[ chunk_faces4[ f ] ];
39874
39875                             v1 = value[ 0 ];
39876                             v2 = value[ 1 ];
39877                             v3 = value[ 2 ];
39878                             v4 = value[ 3 ];
39879
39880                             customAttribute.array[ offset_custom  ]     = v1[ pp[ 0 ] ];
39881                             customAttribute.array[ offset_custom + 1  ] = v1[ pp[ 1 ] ];
39882                             customAttribute.array[ offset_custom + 2  ] = v1[ pp[ 2 ] ];
39883
39884                             customAttribute.array[ offset_custom + 3  ] = v2[ pp[ 0 ] ];
39885                             customAttribute.array[ offset_custom + 4  ] = v2[ pp[ 1 ] ];
39886                             customAttribute.array[ offset_custom + 5  ] = v2[ pp[ 2 ] ];
39887
39888                             customAttribute.array[ offset_custom + 6  ] = v3[ pp[ 0 ] ];
39889                             customAttribute.array[ offset_custom + 7  ] = v3[ pp[ 1 ] ];
39890                             customAttribute.array[ offset_custom + 8  ] = v3[ pp[ 2 ] ];
39891
39892                             customAttribute.array[ offset_custom + 9  ] = v4[ pp[ 0 ] ];
39893                             customAttribute.array[ offset_custom + 10 ] = v4[ pp[ 1 ] ];
39894                             customAttribute.array[ offset_custom + 11 ] = v4[ pp[ 2 ] ];
39895
39896                             offset_custom += 12;
39897
39898                         }
39899
39900                     }
39901
39902                 } else if ( customAttribute.size === 4 ) {
39903
39904                     if ( customAttribute.boundTo === undefined || customAttribute.boundTo === "vertices" ) {
39905
39906                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39907
39908                             face = obj_faces[ chunk_faces3[ f ]    ];
39909
39910                             v1 = customAttribute.value[ face.a ];
39911                             v2 = customAttribute.value[ face.b ];
39912                             v3 = customAttribute.value[ face.c ];
39913
39914                             customAttribute.array[ offset_custom  ]     = v1.x;
39915                             customAttribute.array[ offset_custom + 1  ] = v1.y;
39916                             customAttribute.array[ offset_custom + 2  ] = v1.z;
39917                             customAttribute.array[ offset_custom + 3  ] = v1.w;
39918
39919                             customAttribute.array[ offset_custom + 4  ] = v2.x;
39920                             customAttribute.array[ offset_custom + 5  ] = v2.y;
39921                             customAttribute.array[ offset_custom + 6  ] = v2.z;
39922                             customAttribute.array[ offset_custom + 7  ] = v2.w;
39923
39924                             customAttribute.array[ offset_custom + 8  ] = v3.x;
39925                             customAttribute.array[ offset_custom + 9  ] = v3.y;
39926                             customAttribute.array[ offset_custom + 10 ] = v3.z;
39927                             customAttribute.array[ offset_custom + 11 ] = v3.w;
39928
39929                             offset_custom += 12;
39930
39931                         }
39932
39933                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39934
39935                             face = obj_faces[ chunk_faces4[ f ] ];
39936
39937                             v1 = customAttribute.value[ face.a ];
39938                             v2 = customAttribute.value[ face.b ];
39939                             v3 = customAttribute.value[ face.c ];
39940                             v4 = customAttribute.value[ face.d ];
39941
39942                             customAttribute.array[ offset_custom  ]     = v1.x;
39943                             customAttribute.array[ offset_custom + 1  ] = v1.y;
39944                             customAttribute.array[ offset_custom + 2  ] = v1.z;
39945                             customAttribute.array[ offset_custom + 3  ] = v1.w;
39946
39947                             customAttribute.array[ offset_custom + 4  ] = v2.x;
39948                             customAttribute.array[ offset_custom + 5  ] = v2.y;
39949                             customAttribute.array[ offset_custom + 6  ] = v2.z;
39950                             customAttribute.array[ offset_custom + 7  ] = v2.w;
39951
39952                             customAttribute.array[ offset_custom + 8  ] = v3.x;
39953                             customAttribute.array[ offset_custom + 9  ] = v3.y;
39954                             customAttribute.array[ offset_custom + 10 ] = v3.z;
39955                             customAttribute.array[ offset_custom + 11 ] = v3.w;
39956
39957                             customAttribute.array[ offset_custom + 12 ] = v4.x;
39958                             customAttribute.array[ offset_custom + 13 ] = v4.y;
39959                             customAttribute.array[ offset_custom + 14 ] = v4.z;
39960                             customAttribute.array[ offset_custom + 15 ] = v4.w;
39961
39962                             offset_custom += 16;
39963
39964                         }
39965
39966                     } else if ( customAttribute.boundTo === "faces" ) {
39967
39968                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
39969
39970                             value = customAttribute.value[ chunk_faces3[ f ] ];
39971
39972                             v1 = value;
39973                             v2 = value;
39974                             v3 = value;
39975
39976                             customAttribute.array[ offset_custom  ]     = v1.x;
39977                             customAttribute.array[ offset_custom + 1  ] = v1.y;
39978                             customAttribute.array[ offset_custom + 2  ] = v1.z;
39979                             customAttribute.array[ offset_custom + 3  ] = v1.w;
39980
39981                             customAttribute.array[ offset_custom + 4  ] = v2.x;
39982                             customAttribute.array[ offset_custom + 5  ] = v2.y;
39983                             customAttribute.array[ offset_custom + 6  ] = v2.z;
39984                             customAttribute.array[ offset_custom + 7  ] = v2.w;
39985
39986                             customAttribute.array[ offset_custom + 8  ] = v3.x;
39987                             customAttribute.array[ offset_custom + 9  ] = v3.y;
39988                             customAttribute.array[ offset_custom + 10 ] = v3.z;
39989                             customAttribute.array[ offset_custom + 11 ] = v3.w;
39990
39991                             offset_custom += 12;
39992
39993                         }
39994
39995                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
39996
39997                             value = customAttribute.value[ chunk_faces4[ f ] ];
39998
39999                             v1 = value;
40000                             v2 = value;
40001                             v3 = value;
40002                             v4 = value;
40003
40004                             customAttribute.array[ offset_custom  ]     = v1.x;
40005                             customAttribute.array[ offset_custom + 1  ] = v1.y;
40006                             customAttribute.array[ offset_custom + 2  ] = v1.z;
40007                             customAttribute.array[ offset_custom + 3  ] = v1.w;
40008
40009                             customAttribute.array[ offset_custom + 4  ] = v2.x;
40010                             customAttribute.array[ offset_custom + 5  ] = v2.y;
40011                             customAttribute.array[ offset_custom + 6  ] = v2.z;
40012                             customAttribute.array[ offset_custom + 7  ] = v2.w;
40013
40014                             customAttribute.array[ offset_custom + 8  ] = v3.x;
40015                             customAttribute.array[ offset_custom + 9  ] = v3.y;
40016                             customAttribute.array[ offset_custom + 10 ] = v3.z;
40017                             customAttribute.array[ offset_custom + 11 ] = v3.w;
40018
40019                             customAttribute.array[ offset_custom + 12 ] = v4.x;
40020                             customAttribute.array[ offset_custom + 13 ] = v4.y;
40021                             customAttribute.array[ offset_custom + 14 ] = v4.z;
40022                             customAttribute.array[ offset_custom + 15 ] = v4.w;
40023
40024                             offset_custom += 16;
40025
40026                         }
40027
40028                     } else if ( customAttribute.boundTo === "faceVertices" ) {
40029
40030                         for ( f = 0, fl = chunk_faces3.length; f < fl; f ++ ) {
40031
40032                             value = customAttribute.value[ chunk_faces3[ f ] ];
40033
40034                             v1 = value[ 0 ];
40035                             v2 = value[ 1 ];
40036                             v3 = value[ 2 ];
40037
40038                             customAttribute.array[ offset_custom  ]     = v1.x;
40039                             customAttribute.array[ offset_custom + 1  ] = v1.y;
40040                             customAttribute.array[ offset_custom + 2  ] = v1.z;
40041                             customAttribute.array[ offset_custom + 3  ] = v1.w;
40042
40043                             customAttribute.array[ offset_custom + 4  ] = v2.x;
40044                             customAttribute.array[ offset_custom + 5  ] = v2.y;
40045                             customAttribute.array[ offset_custom + 6  ] = v2.z;
40046                             customAttribute.array[ offset_custom + 7  ] = v2.w;
40047
40048                             customAttribute.array[ offset_custom + 8  ] = v3.x;
40049                             customAttribute.array[ offset_custom + 9  ] = v3.y;
40050                             customAttribute.array[ offset_custom + 10 ] = v3.z;
40051                             customAttribute.array[ offset_custom + 11 ] = v3.w;
40052
40053                             offset_custom += 12;
40054
40055                         }
40056
40057                         for ( f = 0, fl = chunk_faces4.length; f < fl; f ++ ) {
40058
40059                             value = customAttribute.value[ chunk_faces4[ f ] ];
40060
40061                             v1 = value[ 0 ];
40062                             v2 = value[ 1 ];
40063                             v3 = value[ 2 ];
40064                             v4 = value[ 3 ];
40065
40066                             customAttribute.array[ offset_custom  ]     = v1.x;
40067                             customAttribute.array[ offset_custom + 1  ] = v1.y;
40068                             customAttribute.array[ offset_custom + 2  ] = v1.z;
40069                             customAttribute.array[ offset_custom + 3  ] = v1.w;
40070
40071                             customAttribute.array[ offset_custom + 4  ] = v2.x;
40072                             customAttribute.array[ offset_custom + 5  ] = v2.y;
40073                             customAttribute.array[ offset_custom + 6  ] = v2.z;
40074                             customAttribute.array[ offset_custom + 7  ] = v2.w;
40075
40076                             customAttribute.array[ offset_custom + 8  ] = v3.x;
40077                             customAttribute.array[ offset_custom + 9  ] = v3.y;
40078                             customAttribute.array[ offset_custom + 10 ] = v3.z;
40079                             customAttribute.array[ offset_custom + 11 ] = v3.w;
40080
40081                             customAttribute.array[ offset_custom + 12 ] = v4.x;
40082                             customAttribute.array[ offset_custom + 13 ] = v4.y;
40083                             customAttribute.array[ offset_custom + 14 ] = v4.z;
40084                             customAttribute.array[ offset_custom + 15 ] = v4.w;
40085
40086                             offset_custom += 16;
40087
40088                         }
40089
40090                     }
40091
40092                 }
40093
40094                 _gl.bindBuffer( _gl.ARRAY_BUFFER, customAttribute.buffer );
40095                 _gl.bufferData( _gl.ARRAY_BUFFER, customAttribute.array, hint );
40096
40097             }
40098
40099         }
40100
40101         if ( dispose ) {
40102
40103             delete geometryGroup.__inittedArrays;
40104             delete geometryGroup.__colorArray;
40105             delete geometryGroup.__normalArray;
40106             delete geometryGroup.__tangentArray;
40107             delete geometryGroup.__uvArray;
40108             delete geometryGroup.__uv2Array;
40109             delete geometryGroup.__faceArray;
40110             delete geometryGroup.__vertexArray;
40111             delete geometryGroup.__lineArray;
40112             delete geometryGroup.__skinIndexArray;
40113             delete geometryGroup.__skinWeightArray;
40114
40115         }
40116
40117     };
40118
40119     function setDirectBuffers ( geometry, hint, dispose ) {
40120
40121         var attributes = geometry.attributes;
40122
40123         var index = attributes[ "index" ];
40124         var position = attributes[ "position" ];
40125         var normal = attributes[ "normal" ];
40126         var uv = attributes[ "uv" ];
40127         var color = attributes[ "color" ];
40128         var tangent = attributes[ "tangent" ];
40129
40130         if ( geometry.elementsNeedUpdate && index !== undefined ) {
40131
40132             _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
40133             _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, index.array, hint );
40134
40135         }
40136
40137         if ( geometry.verticesNeedUpdate && position !== undefined ) {
40138
40139             _gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
40140             _gl.bufferData( _gl.ARRAY_BUFFER, position.array, hint );
40141
40142         }
40143
40144         if ( geometry.normalsNeedUpdate && normal !== undefined ) {
40145
40146             _gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
40147             _gl.bufferData( _gl.ARRAY_BUFFER, normal.array, hint );
40148
40149         }
40150
40151         if ( geometry.uvsNeedUpdate && uv !== undefined ) {
40152
40153             _gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
40154             _gl.bufferData( _gl.ARRAY_BUFFER, uv.array, hint );
40155
40156         }
40157
40158         if ( geometry.colorsNeedUpdate && color !== undefined ) {
40159
40160             _gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
40161             _gl.bufferData( _gl.ARRAY_BUFFER, color.array, hint );
40162
40163         }
40164
40165         if ( geometry.tangentsNeedUpdate && tangent !== undefined ) {
40166
40167             _gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
40168             _gl.bufferData( _gl.ARRAY_BUFFER, tangent.array, hint );
40169
40170         }
40171
40172         if ( dispose ) {
40173
40174             for ( var i in geometry.attributes ) {
40175
40176                 delete geometry.attributes[ i ].array;
40177
40178             }
40179
40180         }
40181
40182     };
40183
40184     // Buffer rendering
40185
40186     this.renderBufferImmediate = function ( object, program, material ) {
40187
40188         if ( object.hasPositions && ! object.__webglVertexBuffer ) object.__webglVertexBuffer = _gl.createBuffer();
40189         if ( object.hasNormals && ! object.__webglNormalBuffer ) object.__webglNormalBuffer = _gl.createBuffer();
40190         if ( object.hasUvs && ! object.__webglUvBuffer ) object.__webglUvBuffer = _gl.createBuffer();
40191         if ( object.hasColors && ! object.__webglColorBuffer ) object.__webglColorBuffer = _gl.createBuffer();
40192
40193         if ( object.hasPositions ) {
40194
40195             _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglVertexBuffer );
40196             _gl.bufferData( _gl.ARRAY_BUFFER, object.positionArray, _gl.DYNAMIC_DRAW );
40197             _gl.enableVertexAttribArray( program.attributes.position );
40198             _gl.vertexAttribPointer( program.attributes.position, 3, _gl.FLOAT, false, 0, 0 );
40199
40200         }
40201
40202         if ( object.hasNormals ) {
40203
40204             _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglNormalBuffer );
40205
40206             if ( material.shading === THREE.FlatShading ) {
40207
40208                 var nx, ny, nz,
40209                     nax, nbx, ncx, nay, nby, ncy, naz, nbz, ncz,
40210                     normalArray,
40211                     i, il = object.count * 3;
40212
40213                 for( i = 0; i < il; i += 9 ) {
40214
40215                     normalArray = object.normalArray;
40216
40217                     nax  = normalArray[ i ];
40218                     nay  = normalArray[ i + 1 ];
40219                     naz  = normalArray[ i + 2 ];
40220
40221                     nbx  = normalArray[ i + 3 ];
40222                     nby  = normalArray[ i + 4 ];
40223                     nbz  = normalArray[ i + 5 ];
40224
40225                     ncx  = normalArray[ i + 6 ];
40226                     ncy  = normalArray[ i + 7 ];
40227                     ncz  = normalArray[ i + 8 ];
40228
40229                     nx = ( nax + nbx + ncx ) / 3;
40230                     ny = ( nay + nby + ncy ) / 3;
40231                     nz = ( naz + nbz + ncz ) / 3;
40232
40233                     normalArray[ i ]      = nx;
40234                     normalArray[ i + 1 ] = ny;
40235                     normalArray[ i + 2 ] = nz;
40236
40237                     normalArray[ i + 3 ] = nx;
40238                     normalArray[ i + 4 ] = ny;
40239                     normalArray[ i + 5 ] = nz;
40240
40241                     normalArray[ i + 6 ] = nx;
40242                     normalArray[ i + 7 ] = ny;
40243                     normalArray[ i + 8 ] = nz;
40244
40245                 }
40246
40247             }
40248
40249             _gl.bufferData( _gl.ARRAY_BUFFER, object.normalArray, _gl.DYNAMIC_DRAW );
40250             _gl.enableVertexAttribArray( program.attributes.normal );
40251             _gl.vertexAttribPointer( program.attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
40252
40253         }
40254
40255         if ( object.hasUvs && material.map ) {
40256
40257             _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglUvBuffer );
40258             _gl.bufferData( _gl.ARRAY_BUFFER, object.uvArray, _gl.DYNAMIC_DRAW );
40259             _gl.enableVertexAttribArray( program.attributes.uv );
40260             _gl.vertexAttribPointer( program.attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
40261
40262         }
40263
40264         if ( object.hasColors && material.vertexColors !== THREE.NoColors ) {
40265
40266             _gl.bindBuffer( _gl.ARRAY_BUFFER, object.__webglColorBuffer );
40267             _gl.bufferData( _gl.ARRAY_BUFFER, object.colorArray, _gl.DYNAMIC_DRAW );
40268             _gl.enableVertexAttribArray( program.attributes.color );
40269             _gl.vertexAttribPointer( program.attributes.color, 3, _gl.FLOAT, false, 0, 0 );
40270
40271         }
40272
40273         _gl.drawArrays( _gl.TRIANGLES, 0, object.count );
40274
40275         object.count = 0;
40276
40277     };
40278
40279     this.renderBufferDirect = function ( camera, lights, fog, material, geometry, object ) {
40280
40281         if ( material.visible === false ) return;
40282
40283         var program, attributes, linewidth, primitives, a, attribute;
40284
40285         program = setProgram( camera, lights, fog, material, object );
40286
40287         attributes = program.attributes;
40288
40289         var updateBuffers = false,
40290             wireframeBit = material.wireframe ? 1 : 0,
40291             geometryHash = ( geometry.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
40292
40293         if ( geometryHash !== _currentGeometryGroupHash ) {
40294
40295             _currentGeometryGroupHash = geometryHash;
40296             updateBuffers = true;
40297
40298         }
40299
40300         // render mesh
40301
40302         if ( object instanceof THREE.Mesh ) {
40303
40304             var offsets = geometry.offsets;
40305
40306             // if there is more than 1 chunk
40307             // must set attribute pointers to use new offsets for each chunk
40308             // even if geometry and materials didn't change
40309
40310             if ( offsets.length > 1 ) updateBuffers = true;
40311
40312             for ( var i = 0, il = offsets.length; i < il; ++ i ) {
40313
40314                 var startIndex = offsets[ i ].index;
40315
40316                 if ( updateBuffers ) {
40317
40318                     // vertices
40319
40320                     var position = geometry.attributes[ "position" ];
40321                     var positionSize = position.itemSize;
40322
40323                     _gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
40324                     _gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, startIndex * positionSize * 4 ); // 4 bytes per Float32
40325
40326                     // normals
40327
40328                     var normal = geometry.attributes[ "normal" ];
40329
40330                     if ( attributes.normal >= 0 && normal ) {
40331
40332                         var normalSize = normal.itemSize;
40333
40334                         _gl.bindBuffer( _gl.ARRAY_BUFFER, normal.buffer );
40335                         _gl.vertexAttribPointer( attributes.normal, normalSize, _gl.FLOAT, false, 0, startIndex * normalSize * 4 );
40336
40337                     }
40338
40339                     // uvs
40340
40341                     var uv = geometry.attributes[ "uv" ];
40342
40343                     if ( attributes.uv >= 0 && uv ) {
40344
40345                         if ( uv.buffer ) {
40346
40347                             var uvSize = uv.itemSize;
40348
40349                             _gl.bindBuffer( _gl.ARRAY_BUFFER, uv.buffer );
40350                             _gl.vertexAttribPointer( attributes.uv, uvSize, _gl.FLOAT, false, 0, startIndex * uvSize * 4 );
40351
40352                             _gl.enableVertexAttribArray( attributes.uv );
40353
40354                         } else {
40355
40356                             _gl.disableVertexAttribArray( attributes.uv );
40357
40358                         }
40359
40360                     }
40361
40362                     // colors
40363
40364                     var color = geometry.attributes[ "color" ];
40365
40366                     if ( attributes.color >= 0 && color ) {
40367
40368                         var colorSize = color.itemSize;
40369
40370                         _gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
40371                         _gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, startIndex * colorSize * 4 );
40372
40373                     }
40374
40375                     // tangents
40376
40377                     var tangent = geometry.attributes[ "tangent" ];
40378
40379                     if ( attributes.tangent >= 0 && tangent ) {
40380
40381                         var tangentSize = tangent.itemSize;
40382
40383                         _gl.bindBuffer( _gl.ARRAY_BUFFER, tangent.buffer );
40384                         _gl.vertexAttribPointer( attributes.tangent, tangentSize, _gl.FLOAT, false, 0, startIndex * tangentSize * 4 );
40385
40386                     }
40387
40388                     // indices
40389
40390                     var index = geometry.attributes[ "index" ];
40391
40392                     _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, index.buffer );
40393
40394                 }
40395
40396                 // render indexed triangles
40397
40398                 _gl.drawElements( _gl.TRIANGLES, offsets[ i ].count, _gl.UNSIGNED_SHORT, offsets[ i ].start * 2 ); // 2 bytes per Uint16
40399
40400                 _this.info.render.calls ++;
40401                 _this.info.render.vertices += offsets[ i ].count; // not really true, here vertices can be shared
40402                 _this.info.render.faces += offsets[ i ].count / 3;
40403
40404             }
40405
40406         // render particles
40407
40408         } else if ( object instanceof THREE.ParticleSystem ) {
40409
40410             if ( updateBuffers ) {
40411
40412                 // vertices
40413
40414                 var position = geometry.attributes[ "position" ];
40415                 var positionSize = position.itemSize;
40416
40417                 _gl.bindBuffer( _gl.ARRAY_BUFFER, position.buffer );
40418                 _gl.vertexAttribPointer( attributes.position, positionSize, _gl.FLOAT, false, 0, 0 );
40419
40420                 // colors
40421
40422                 var color = geometry.attributes[ "color" ];
40423
40424                 if ( attributes.color >= 0 && color ) {
40425
40426                     var colorSize = color.itemSize;
40427
40428                     _gl.bindBuffer( _gl.ARRAY_BUFFER, color.buffer );
40429                     _gl.vertexAttribPointer( attributes.color, colorSize, _gl.FLOAT, false, 0, 0 );
40430
40431                 }
40432
40433                 // render particles
40434
40435                 _gl.drawArrays( _gl.POINTS, 0, position.numItems / 3 );
40436
40437                 _this.info.render.calls ++;
40438                 _this.info.render.points += position.numItems / 3;
40439
40440             }
40441
40442         }
40443
40444     };
40445
40446     this.renderBuffer = function ( camera, lights, fog, material, geometryGroup, object ) {
40447
40448         if ( material.visible === false ) return;
40449
40450         var program, attributes, linewidth, primitives, a, attribute, i, il;
40451
40452         program = setProgram( camera, lights, fog, material, object );
40453
40454         attributes = program.attributes;
40455
40456         var updateBuffers = false,
40457             wireframeBit = material.wireframe ? 1 : 0,
40458             geometryGroupHash = ( geometryGroup.id * 0xffffff ) + ( program.id * 2 ) + wireframeBit;
40459
40460         if ( geometryGroupHash !== _currentGeometryGroupHash ) {
40461
40462             _currentGeometryGroupHash = geometryGroupHash;
40463             updateBuffers = true;
40464
40465         }
40466
40467         // vertices
40468
40469         if ( !material.morphTargets && attributes.position >= 0 ) {
40470
40471             if ( updateBuffers ) {
40472
40473                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
40474                 _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
40475
40476             }
40477
40478         } else {
40479
40480             if ( object.morphTargetBase ) {
40481
40482                 setupMorphTargets( material, geometryGroup, object );
40483
40484             }
40485
40486         }
40487
40488
40489         if ( updateBuffers ) {
40490
40491             // custom attributes
40492
40493             // Use the per-geometryGroup custom attribute arrays which are setup in initMeshBuffers
40494
40495             if ( geometryGroup.__webglCustomAttributesList ) {
40496
40497                 for ( i = 0, il = geometryGroup.__webglCustomAttributesList.length; i < il; i ++ ) {
40498
40499                     attribute = geometryGroup.__webglCustomAttributesList[ i ];
40500
40501                     if( attributes[ attribute.buffer.belongsToAttribute ] >= 0 ) {
40502
40503                         _gl.bindBuffer( _gl.ARRAY_BUFFER, attribute.buffer );
40504                         _gl.vertexAttribPointer( attributes[ attribute.buffer.belongsToAttribute ], attribute.size, _gl.FLOAT, false, 0, 0 );
40505
40506                     }
40507
40508                 }
40509
40510             }
40511
40512
40513             // colors
40514
40515             if ( attributes.color >= 0 ) {
40516
40517                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglColorBuffer );
40518                 _gl.vertexAttribPointer( attributes.color, 3, _gl.FLOAT, false, 0, 0 );
40519
40520             }
40521
40522             // normals
40523
40524             if ( attributes.normal >= 0 ) {
40525
40526                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglNormalBuffer );
40527                 _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
40528
40529             }
40530
40531             // tangents
40532
40533             if ( attributes.tangent >= 0 ) {
40534
40535                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglTangentBuffer );
40536                 _gl.vertexAttribPointer( attributes.tangent, 4, _gl.FLOAT, false, 0, 0 );
40537
40538             }
40539
40540             // uvs
40541
40542             if ( attributes.uv >= 0 ) {
40543
40544                 if ( geometryGroup.__webglUVBuffer ) {
40545
40546                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUVBuffer );
40547                     _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 0, 0 );
40548
40549                     _gl.enableVertexAttribArray( attributes.uv );
40550
40551                 } else {
40552
40553                     _gl.disableVertexAttribArray( attributes.uv );
40554
40555                 }
40556
40557             }
40558
40559             if ( attributes.uv2 >= 0 ) {
40560
40561                 if ( geometryGroup.__webglUV2Buffer ) {
40562
40563                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglUV2Buffer );
40564                     _gl.vertexAttribPointer( attributes.uv2, 2, _gl.FLOAT, false, 0, 0 );
40565
40566                     _gl.enableVertexAttribArray( attributes.uv2 );
40567
40568                 } else {
40569
40570                     _gl.disableVertexAttribArray( attributes.uv2 );
40571
40572                 }
40573
40574             }
40575
40576             if ( material.skinning &&
40577                  attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
40578
40579                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinIndicesBuffer );
40580                 _gl.vertexAttribPointer( attributes.skinIndex, 4, _gl.FLOAT, false, 0, 0 );
40581
40582                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglSkinWeightsBuffer );
40583                 _gl.vertexAttribPointer( attributes.skinWeight, 4, _gl.FLOAT, false, 0, 0 );
40584
40585             }
40586
40587         }
40588
40589         // render mesh
40590
40591         if ( object instanceof THREE.Mesh ) {
40592
40593             // wireframe
40594
40595             if ( material.wireframe ) {
40596
40597                 setLineWidth( material.wireframeLinewidth );
40598
40599                 if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglLineBuffer );
40600                 _gl.drawElements( _gl.LINES, geometryGroup.__webglLineCount, _gl.UNSIGNED_SHORT, 0 );
40601
40602             // triangles
40603
40604             } else {
40605
40606                 if ( updateBuffers ) _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webglFaceBuffer );
40607                 _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webglFaceCount, _gl.UNSIGNED_SHORT, 0 );
40608
40609             }
40610
40611             _this.info.render.calls ++;
40612             _this.info.render.vertices += geometryGroup.__webglFaceCount;
40613             _this.info.render.faces += geometryGroup.__webglFaceCount / 3;
40614
40615         // render lines
40616
40617         } else if ( object instanceof THREE.Line ) {
40618
40619             primitives = ( object.type === THREE.LineStrip ) ? _gl.LINE_STRIP : _gl.LINES;
40620
40621             setLineWidth( material.linewidth );
40622
40623             _gl.drawArrays( primitives, 0, geometryGroup.__webglLineCount );
40624
40625             _this.info.render.calls ++;
40626
40627         // render particles
40628
40629         } else if ( object instanceof THREE.ParticleSystem ) {
40630
40631             _gl.drawArrays( _gl.POINTS, 0, geometryGroup.__webglParticleCount );
40632
40633             _this.info.render.calls ++;
40634             _this.info.render.points += geometryGroup.__webglParticleCount;
40635
40636         // render ribbon
40637
40638         } else if ( object instanceof THREE.Ribbon ) {
40639
40640             _gl.drawArrays( _gl.TRIANGLE_STRIP, 0, geometryGroup.__webglVertexCount );
40641
40642             _this.info.render.calls ++;
40643
40644         }
40645
40646     };
40647
40648     function setupMorphTargets ( material, geometryGroup, object ) {
40649
40650         // set base
40651
40652         var attributes = material.program.attributes;
40653
40654         if ( object.morphTargetBase !== -1 ) {
40655
40656             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ object.morphTargetBase ] );
40657             _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
40658
40659         } else if ( attributes.position >= 0 ) {
40660
40661             _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglVertexBuffer );
40662             _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
40663
40664         }
40665
40666         if ( object.morphTargetForcedOrder.length ) {
40667
40668             // set forced order
40669
40670             var m = 0;
40671             var order = object.morphTargetForcedOrder;
40672             var influences = object.morphTargetInfluences;
40673
40674             while ( m < material.numSupportedMorphTargets && m < order.length ) {
40675
40676                 _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ order[ m ] ] );
40677                 _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
40678
40679                 if ( material.morphNormals ) {
40680
40681                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ order[ m ] ] );
40682                     _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
40683
40684                 }
40685
40686                 object.__webglMorphTargetInfluences[ m ] = influences[ order[ m ] ];
40687
40688                 m ++;
40689             }
40690
40691         } else {
40692
40693             // find the most influencing
40694
40695             var influence, activeInfluenceIndices = [];
40696             var influences = object.morphTargetInfluences;
40697             var i, il = influences.length;
40698
40699             for ( i = 0; i < il; i ++ ) {
40700
40701                 influence = influences[ i ];
40702
40703                 if ( influence > 0 ) {
40704
40705                     activeInfluenceIndices.push( [ i, influence ] );
40706
40707                 }
40708
40709             }
40710
40711             if ( activeInfluenceIndices.length > material.numSupportedMorphTargets ) {
40712
40713                 activeInfluenceIndices.sort( numericalSort );
40714                 activeInfluenceIndices.length = material.numSupportedMorphTargets;
40715
40716             } else if ( activeInfluenceIndices.length > material.numSupportedMorphNormals ) {
40717
40718                 activeInfluenceIndices.sort( numericalSort );
40719
40720             } else if ( activeInfluenceIndices.length === 0 ) {
40721
40722                 activeInfluenceIndices.push( [ 0, 0 ] );
40723
40724             };
40725
40726             var influenceIndex, m = 0;
40727
40728             while ( m < material.numSupportedMorphTargets ) {
40729
40730                 if ( activeInfluenceIndices[ m ] ) {
40731
40732                     influenceIndex = activeInfluenceIndices[ m ][ 0 ];
40733
40734                     _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ influenceIndex ] );
40735
40736                     _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
40737
40738                     if ( material.morphNormals ) {
40739
40740                         _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphNormalsBuffers[ influenceIndex ] );
40741                         _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
40742
40743                     }
40744
40745                     object.__webglMorphTargetInfluences[ m ] = influences[ influenceIndex ];
40746
40747                 } else {
40748
40749                     _gl.vertexAttribPointer( attributes[ "morphTarget" + m ], 3, _gl.FLOAT, false, 0, 0 );
40750
40751                     if ( material.morphNormals ) {
40752
40753                         _gl.vertexAttribPointer( attributes[ "morphNormal" + m ], 3, _gl.FLOAT, false, 0, 0 );
40754
40755                     }
40756
40757                     object.__webglMorphTargetInfluences[ m ] = 0;
40758
40759                 }
40760
40761                 m ++;
40762
40763             }
40764
40765         }
40766
40767         // load updated influences uniform
40768
40769         if ( material.program.uniforms.morphTargetInfluences !== null ) {
40770
40771             _gl.uniform1fv( material.program.uniforms.morphTargetInfluences, object.__webglMorphTargetInfluences );
40772
40773         }
40774
40775     };
40776
40777     // Sorting
40778
40779     function painterSort ( a, b ) {
40780
40781         return b.z - a.z;
40782
40783     };
40784
40785     function numericalSort ( a, b ) {
40786
40787         return b[ 1 ] - a[ 1 ];
40788
40789     };
40790
40791
40792     // Rendering
40793
40794     this.render = function ( scene, camera, renderTarget, forceClear ) {
40795
40796         if ( camera instanceof THREE.Camera === false ) {
40797
40798             console.error( 'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.' );
40799             return;
40800
40801         }
40802
40803         var i, il,
40804
40805         webglObject, object,
40806         renderList,
40807
40808         lights = scene.__lights,
40809         fog = scene.fog;
40810
40811         // reset caching for this frame
40812
40813         _currentMaterialId = -1;
40814         _lightsNeedUpdate = true;
40815
40816         // update scene graph
40817
40818         if ( this.autoUpdateScene ) scene.updateMatrixWorld();
40819
40820         // update camera matrices and frustum
40821
40822         if ( camera.parent === undefined ) camera.updateMatrixWorld();
40823
40824         if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
40825         if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
40826
40827         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
40828
40829         camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
40830         camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
40831
40832         _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
40833         _frustum.setFromMatrix( _projScreenMatrix );
40834
40835         // update WebGL objects
40836
40837         if ( this.autoUpdateObjects ) this.initWebGLObjects( scene );
40838
40839         // custom render plugins (pre pass)
40840
40841         renderPlugins( this.renderPluginsPre, scene, camera );
40842
40843         //
40844
40845         _this.info.render.calls = 0;
40846         _this.info.render.vertices = 0;
40847         _this.info.render.faces = 0;
40848         _this.info.render.points = 0;
40849
40850         this.setRenderTarget( renderTarget );
40851
40852         if ( this.autoClear || forceClear ) {
40853
40854             this.clear( this.autoClearColor, this.autoClearDepth, this.autoClearStencil );
40855
40856         }
40857
40858         // set matrices for regular objects (frustum culled)
40859
40860         renderList = scene.__webglObjects;
40861
40862         for ( i = 0, il = renderList.length; i < il; i ++ ) {
40863
40864             webglObject = renderList[ i ];
40865             object = webglObject.object;
40866
40867             webglObject.render = false;
40868
40869             if ( object.visible ) {
40870
40871                 if ( ! ( object instanceof THREE.Mesh || object instanceof THREE.ParticleSystem ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
40872
40873                     //object.matrixWorld.flattenToArray( object._modelMatrixArray );
40874
40875                     setupMatrices( object, camera );
40876
40877                     unrollBufferMaterial( webglObject );
40878
40879                     webglObject.render = true;
40880
40881                     if ( this.sortObjects === true ) {
40882
40883                         if ( object.renderDepth !== null ) {
40884
40885                             webglObject.z = object.renderDepth;
40886
40887                         } else {
40888
40889                             _vector3.copy( object.matrixWorld.getPosition() );
40890                             _projScreenMatrix.multiplyVector3( _vector3 );
40891
40892                             webglObject.z = _vector3.z;
40893
40894                         }
40895
40896                     }
40897
40898                 }
40899
40900             }
40901
40902         }
40903
40904         if ( this.sortObjects ) {
40905
40906             renderList.sort( painterSort );
40907
40908         }
40909
40910         // set matrices for immediate objects
40911
40912         renderList = scene.__webglObjectsImmediate;
40913
40914         for ( i = 0, il = renderList.length; i < il; i ++ ) {
40915
40916             webglObject = renderList[ i ];
40917             object = webglObject.object;
40918
40919             if ( object.visible ) {
40920
40921                 /*
40922                 if ( object.matrixAutoUpdate ) {
40923
40924                     object.matrixWorld.flattenToArray( object._modelMatrixArray );
40925
40926                 }
40927                 */
40928
40929                 setupMatrices( object, camera );
40930
40931                 unrollImmediateBufferMaterial( webglObject );
40932
40933             }
40934
40935         }
40936
40937         if ( scene.overrideMaterial ) {
40938
40939             var material = scene.overrideMaterial;
40940
40941             this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
40942             this.setDepthTest( material.depthTest );
40943             this.setDepthWrite( material.depthWrite );
40944             setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
40945
40946             renderObjects( scene.__webglObjects, false, "", camera, lights, fog, true, material );
40947             renderObjectsImmediate( scene.__webglObjectsImmediate, "", camera, lights, fog, false, material );
40948
40949         } else {
40950
40951             // opaque pass (front-to-back order)
40952
40953             this.setBlending( THREE.NormalBlending );
40954
40955             renderObjects( scene.__webglObjects, true, "opaque", camera, lights, fog, false );
40956             renderObjectsImmediate( scene.__webglObjectsImmediate, "opaque", camera, lights, fog, false );
40957
40958             // transparent pass (back-to-front order)
40959
40960             renderObjects( scene.__webglObjects, false, "transparent", camera, lights, fog, true );
40961             renderObjectsImmediate( scene.__webglObjectsImmediate, "transparent", camera, lights, fog, true );
40962
40963         }
40964
40965         // custom render plugins (post pass)
40966
40967         renderPlugins( this.renderPluginsPost, scene, camera );
40968
40969
40970         // Generate mipmap if we're using any kind of mipmap filtering
40971
40972         if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
40973
40974             updateRenderTargetMipmap( renderTarget );
40975
40976         }
40977
40978         // Ensure depth buffer writing is enabled so it can be cleared on next render
40979
40980         this.setDepthTest( true );
40981         this.setDepthWrite( true );
40982
40983         // _gl.finish();
40984
40985     };
40986
40987     function renderPlugins( plugins, scene, camera ) {
40988
40989         if ( ! plugins.length ) return;
40990
40991         for ( var i = 0, il = plugins.length; i < il; i ++ ) {
40992
40993             // reset state for plugin (to start from clean slate)
40994
40995             _currentProgram = null;
40996             _currentCamera = null;
40997
40998             _oldBlending = -1;
40999             _oldDepthTest = -1;
41000             _oldDepthWrite = -1;
41001             _oldDoubleSided = -1;
41002             _oldFlipSided = -1;
41003             _currentGeometryGroupHash = -1;
41004             _currentMaterialId = -1;
41005
41006             _lightsNeedUpdate = true;
41007
41008             plugins[ i ].render( scene, camera, _currentWidth, _currentHeight );
41009
41010             // reset state after plugin (anything could have changed)
41011
41012             _currentProgram = null;
41013             _currentCamera = null;
41014
41015             _oldBlending = -1;
41016             _oldDepthTest = -1;
41017             _oldDepthWrite = -1;
41018             _oldDoubleSided = -1;
41019             _oldFlipSided = -1;
41020             _currentGeometryGroupHash = -1;
41021             _currentMaterialId = -1;
41022
41023             _lightsNeedUpdate = true;
41024
41025         }
41026
41027     };
41028
41029     function renderObjects ( renderList, reverse, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
41030
41031         var webglObject, object, buffer, material, start, end, delta;
41032
41033         if ( reverse ) {
41034
41035             start = renderList.length - 1;
41036             end = -1;
41037             delta = -1;
41038
41039         } else {
41040
41041             start = 0;
41042             end = renderList.length;
41043             delta = 1;
41044         }
41045
41046         for ( var i = start; i !== end; i += delta ) {
41047
41048             webglObject = renderList[ i ];
41049
41050             if ( webglObject.render ) {
41051
41052                 object = webglObject.object;
41053                 buffer = webglObject.buffer;
41054
41055                 if ( overrideMaterial ) {
41056
41057                     material = overrideMaterial;
41058
41059                 } else {
41060
41061                     material = webglObject[ materialType ];
41062
41063                     if ( ! material ) continue;
41064
41065                     if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
41066
41067                     _this.setDepthTest( material.depthTest );
41068                     _this.setDepthWrite( material.depthWrite );
41069                     setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
41070
41071                 }
41072
41073                 _this.setMaterialFaces( material );
41074
41075                 if ( buffer instanceof THREE.BufferGeometry ) {
41076
41077                     _this.renderBufferDirect( camera, lights, fog, material, buffer, object );
41078
41079                 } else {
41080
41081                     _this.renderBuffer( camera, lights, fog, material, buffer, object );
41082
41083                 }
41084
41085             }
41086
41087         }
41088
41089     };
41090
41091     function renderObjectsImmediate ( renderList, materialType, camera, lights, fog, useBlending, overrideMaterial ) {
41092
41093         var webglObject, object, material, program;
41094
41095         for ( var i = 0, il = renderList.length; i < il; i ++ ) {
41096
41097             webglObject = renderList[ i ];
41098             object = webglObject.object;
41099
41100             if ( object.visible ) {
41101
41102                 if ( overrideMaterial ) {
41103
41104                     material = overrideMaterial;
41105
41106                 } else {
41107
41108                     material = webglObject[ materialType ];
41109
41110                     if ( ! material ) continue;
41111
41112                     if ( useBlending ) _this.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
41113
41114                     _this.setDepthTest( material.depthTest );
41115                     _this.setDepthWrite( material.depthWrite );
41116                     setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
41117
41118                 }
41119
41120                 _this.renderImmediateObject( camera, lights, fog, material, object );
41121
41122             }
41123
41124         }
41125
41126     };
41127
41128     this.renderImmediateObject = function ( camera, lights, fog, material, object ) {
41129
41130         var program = setProgram( camera, lights, fog, material, object );
41131
41132         _currentGeometryGroupHash = -1;
41133
41134         _this.setMaterialFaces( material );
41135
41136         if ( object.immediateRenderCallback ) {
41137
41138             object.immediateRenderCallback( program, _gl, _frustum );
41139
41140         } else {
41141
41142             object.render( function( object ) { _this.renderBufferImmediate( object, program, material ); } );
41143
41144         }
41145
41146     };
41147
41148     function unrollImmediateBufferMaterial ( globject ) {
41149
41150         var object = globject.object,
41151             material = object.material;
41152
41153         if ( material.transparent ) {
41154
41155             globject.transparent = material;
41156             globject.opaque = null;
41157
41158         } else {
41159
41160             globject.opaque = material;
41161             globject.transparent = null;
41162
41163         }
41164
41165     };
41166
41167     function unrollBufferMaterial ( globject ) {
41168
41169         var object = globject.object,
41170             buffer = globject.buffer,
41171             material, materialIndex, meshMaterial;
41172
41173         meshMaterial = object.material;
41174
41175         if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
41176
41177             materialIndex = buffer.materialIndex;
41178
41179             if ( materialIndex >= 0 ) {
41180
41181                 material = object.geometry.materials[ materialIndex ];
41182
41183                 if ( material.transparent ) {
41184
41185                     globject.transparent = material;
41186                     globject.opaque = null;
41187
41188                 } else {
41189
41190                     globject.opaque = material;
41191                     globject.transparent = null;
41192
41193                 }
41194
41195             }
41196
41197         } else {
41198
41199             material = meshMaterial;
41200
41201             if ( material ) {
41202
41203                 if ( material.transparent ) {
41204
41205                     globject.transparent = material;
41206                     globject.opaque = null;
41207
41208                 } else {
41209
41210                     globject.opaque = material;
41211                     globject.transparent = null;
41212
41213                 }
41214
41215             }
41216
41217         }
41218
41219     };
41220
41221     // Geometry splitting
41222
41223     function sortFacesByMaterial ( geometry ) {
41224
41225         var f, fl, face, materialIndex, vertices,
41226             materialHash, groupHash,
41227             hash_map = {};
41228
41229         var numMorphTargets = geometry.morphTargets.length;
41230         var numMorphNormals = geometry.morphNormals.length;
41231
41232         geometry.geometryGroups = {};
41233
41234         for ( f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
41235
41236             face = geometry.faces[ f ];
41237             materialIndex = face.materialIndex;
41238
41239             materialHash = ( materialIndex !== undefined ) ? materialIndex : -1;
41240
41241             if ( hash_map[ materialHash ] === undefined ) {
41242
41243                 hash_map[ materialHash ] = { 'hash': materialHash, 'counter': 0 };
41244
41245             }
41246
41247             groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
41248
41249             if ( geometry.geometryGroups[ groupHash ] === undefined ) {
41250
41251                 geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
41252
41253             }
41254
41255             vertices = face instanceof THREE.Face3 ? 3 : 4;
41256
41257             if ( geometry.geometryGroups[ groupHash ].vertices + vertices > 65535 ) {
41258
41259                 hash_map[ materialHash ].counter += 1;
41260                 groupHash = hash_map[ materialHash ].hash + '_' + hash_map[ materialHash ].counter;
41261
41262                 if ( geometry.geometryGroups[ groupHash ] === undefined ) {
41263
41264                     geometry.geometryGroups[ groupHash ] = { 'faces3': [], 'faces4': [], 'materialIndex': materialIndex, 'vertices': 0, 'numMorphTargets': numMorphTargets, 'numMorphNormals': numMorphNormals };
41265
41266                 }
41267
41268             }
41269
41270             if ( face instanceof THREE.Face3 ) {
41271
41272                 geometry.geometryGroups[ groupHash ].faces3.push( f );
41273
41274             } else {
41275
41276                 geometry.geometryGroups[ groupHash ].faces4.push( f );
41277
41278             }
41279
41280             geometry.geometryGroups[ groupHash ].vertices += vertices;
41281
41282         }
41283
41284         geometry.geometryGroupsList = [];
41285
41286         for ( var g in geometry.geometryGroups ) {
41287
41288             geometry.geometryGroups[ g ].id = _geometryGroupCounter ++;
41289
41290             geometry.geometryGroupsList.push( geometry.geometryGroups[ g ] );
41291
41292         }
41293
41294     };
41295
41296     // Objects refresh
41297
41298     this.initWebGLObjects = function ( scene ) {
41299
41300         if ( !scene.__webglObjects ) {
41301
41302             scene.__webglObjects = [];
41303             scene.__webglObjectsImmediate = [];
41304             scene.__webglSprites = [];
41305             scene.__webglFlares = [];
41306
41307         }
41308
41309         while ( scene.__objectsAdded.length ) {
41310
41311             addObject( scene.__objectsAdded[ 0 ], scene );
41312             scene.__objectsAdded.splice( 0, 1 );
41313
41314         }
41315
41316         while ( scene.__objectsRemoved.length ) {
41317
41318             removeObject( scene.__objectsRemoved[ 0 ], scene );
41319             scene.__objectsRemoved.splice( 0, 1 );
41320
41321         }
41322
41323         // update must be called after objects adding / removal
41324
41325         for ( var o = 0, ol = scene.__webglObjects.length; o < ol; o ++ ) {
41326
41327             updateObject( scene.__webglObjects[ o ].object );
41328
41329         }
41330
41331     };
41332
41333     // Objects adding
41334
41335     function addObject ( object, scene ) {
41336
41337         var g, geometry, geometryGroup;
41338
41339         if ( ! object.__webglInit ) {
41340
41341             object.__webglInit = true;
41342
41343             object._modelViewMatrix = new THREE.Matrix4();
41344             object._normalMatrix = new THREE.Matrix3();
41345
41346             if ( object instanceof THREE.Mesh ) {
41347
41348                 geometry = object.geometry;
41349
41350                 if ( geometry instanceof THREE.Geometry ) {
41351
41352                     if ( geometry.geometryGroups === undefined ) {
41353
41354                         sortFacesByMaterial( geometry );
41355
41356                     }
41357
41358                     // create separate VBOs per geometry chunk
41359
41360                     for ( g in geometry.geometryGroups ) {
41361
41362                         geometryGroup = geometry.geometryGroups[ g ];
41363
41364                         // initialise VBO on the first access
41365
41366                         if ( ! geometryGroup.__webglVertexBuffer ) {
41367
41368                             createMeshBuffers( geometryGroup );
41369                             initMeshBuffers( geometryGroup, object );
41370
41371                             geometry.verticesNeedUpdate = true;
41372                             geometry.morphTargetsNeedUpdate = true;
41373                             geometry.elementsNeedUpdate = true;
41374                             geometry.uvsNeedUpdate = true;
41375                             geometry.normalsNeedUpdate = true;
41376                             geometry.tangentsNeedUpdate = true;
41377                             geometry.colorsNeedUpdate = true;
41378
41379                         }
41380
41381                     }
41382
41383                 } else if ( geometry instanceof THREE.BufferGeometry ) {
41384
41385                     initDirectBuffers( geometry );
41386
41387                 }
41388
41389             } else if ( object instanceof THREE.Ribbon ) {
41390
41391                 geometry = object.geometry;
41392
41393                 if( ! geometry.__webglVertexBuffer ) {
41394
41395                     createRibbonBuffers( geometry );
41396                     initRibbonBuffers( geometry );
41397
41398                     geometry.verticesNeedUpdate = true;
41399                     geometry.colorsNeedUpdate = true;
41400
41401                 }
41402
41403             } else if ( object instanceof THREE.Line ) {
41404
41405                 geometry = object.geometry;
41406
41407                 if( ! geometry.__webglVertexBuffer ) {
41408
41409                     createLineBuffers( geometry );
41410                     initLineBuffers( geometry, object );
41411
41412                     geometry.verticesNeedUpdate = true;
41413                     geometry.colorsNeedUpdate = true;
41414
41415                 }
41416
41417             } else if ( object instanceof THREE.ParticleSystem ) {
41418
41419                 geometry = object.geometry;
41420
41421                 if ( ! geometry.__webglVertexBuffer ) {
41422
41423                     if ( geometry instanceof THREE.Geometry ) {
41424
41425                         createParticleBuffers( geometry );
41426                         initParticleBuffers( geometry, object );
41427
41428                         geometry.verticesNeedUpdate = true;
41429                         geometry.colorsNeedUpdate = true;
41430
41431                     } else if ( geometry instanceof THREE.BufferGeometry ) {
41432
41433                         initDirectBuffers( geometry );
41434
41435                     }
41436
41437
41438                 }
41439
41440             }
41441
41442         }
41443
41444         if ( ! object.__webglActive ) {
41445
41446             if ( object instanceof THREE.Mesh ) {
41447
41448                 geometry = object.geometry;
41449
41450                 if ( geometry instanceof THREE.BufferGeometry ) {
41451
41452                     addBuffer( scene.__webglObjects, geometry, object );
41453
41454                 } else {
41455
41456                     for ( g in geometry.geometryGroups ) {
41457
41458                         geometryGroup = geometry.geometryGroups[ g ];
41459
41460                         addBuffer( scene.__webglObjects, geometryGroup, object );
41461
41462                     }
41463
41464                 }
41465
41466             } else if ( object instanceof THREE.Ribbon ||
41467                         object instanceof THREE.Line ||
41468                         object instanceof THREE.ParticleSystem ) {
41469
41470                 geometry = object.geometry;
41471                 addBuffer( scene.__webglObjects, geometry, object );
41472
41473             } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
41474
41475                 addBufferImmediate( scene.__webglObjectsImmediate, object );
41476
41477             } else if ( object instanceof THREE.Sprite ) {
41478
41479                 scene.__webglSprites.push( object );
41480
41481             } else if ( object instanceof THREE.LensFlare ) {
41482
41483                 scene.__webglFlares.push( object );
41484
41485             }
41486
41487             object.__webglActive = true;
41488
41489         }
41490
41491     };
41492
41493     function addBuffer ( objlist, buffer, object ) {
41494
41495         objlist.push(
41496             {
41497                 buffer: buffer,
41498                 object: object,
41499                 opaque: null,
41500                 transparent: null
41501             }
41502         );
41503
41504     };
41505
41506     function addBufferImmediate ( objlist, object ) {
41507
41508         objlist.push(
41509             {
41510                 object: object,
41511                 opaque: null,
41512                 transparent: null
41513             }
41514         );
41515
41516     };
41517
41518     // Objects updates
41519
41520     function updateObject ( object ) {
41521
41522         var geometry = object.geometry,
41523             geometryGroup, customAttributesDirty, material;
41524
41525         if ( object instanceof THREE.Mesh ) {
41526
41527             if ( geometry instanceof THREE.BufferGeometry ) {
41528
41529                 if ( geometry.verticesNeedUpdate || geometry.elementsNeedUpdate ||
41530                      geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
41531                      geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate ) {
41532
41533                     setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
41534
41535                 }
41536
41537                 geometry.verticesNeedUpdate = false;
41538                 geometry.elementsNeedUpdate = false;
41539                 geometry.uvsNeedUpdate = false;
41540                 geometry.normalsNeedUpdate = false;
41541                 geometry.colorsNeedUpdate = false;
41542                 geometry.tangentsNeedUpdate = false;
41543
41544             } else {
41545
41546                 // check all geometry groups
41547
41548                 for( var i = 0, il = geometry.geometryGroupsList.length; i < il; i ++ ) {
41549
41550                     geometryGroup = geometry.geometryGroupsList[ i ];
41551
41552                     material = getBufferMaterial( object, geometryGroup );
41553
41554                     customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
41555
41556                     if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
41557                          geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
41558                          geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
41559
41560                         setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, !geometry.dynamic, material );
41561
41562                     }
41563
41564                 }
41565
41566                 geometry.verticesNeedUpdate = false;
41567                 geometry.morphTargetsNeedUpdate = false;
41568                 geometry.elementsNeedUpdate = false;
41569                 geometry.uvsNeedUpdate = false;
41570                 geometry.normalsNeedUpdate = false;
41571                 geometry.colorsNeedUpdate = false;
41572                 geometry.tangentsNeedUpdate = false;
41573
41574                 material.attributes && clearCustomAttributes( material );
41575
41576             }
41577
41578         } else if ( object instanceof THREE.Ribbon ) {
41579
41580             if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
41581
41582                 setRibbonBuffers( geometry, _gl.DYNAMIC_DRAW );
41583
41584             }
41585
41586             geometry.verticesNeedUpdate = false;
41587             geometry.colorsNeedUpdate = false;
41588
41589         } else if ( object instanceof THREE.Line ) {
41590
41591             material = getBufferMaterial( object, geometryGroup );
41592
41593             customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
41594
41595             if ( geometry.verticesNeedUpdate ||  geometry.colorsNeedUpdate || customAttributesDirty ) {
41596
41597                 setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
41598
41599             }
41600
41601             geometry.verticesNeedUpdate = false;
41602             geometry.colorsNeedUpdate = false;
41603
41604             material.attributes && clearCustomAttributes( material );
41605
41606         } else if ( object instanceof THREE.ParticleSystem ) {
41607
41608             if ( geometry instanceof THREE.BufferGeometry ) {
41609
41610                 if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate ) {
41611
41612                     setDirectBuffers( geometry, _gl.DYNAMIC_DRAW, !geometry.dynamic );
41613
41614                 }
41615
41616                 geometry.verticesNeedUpdate = false;
41617                 geometry.colorsNeedUpdate = false;
41618
41619             } else {
41620
41621                 material = getBufferMaterial( object, geometryGroup );
41622
41623                 customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
41624
41625                 if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || object.sortParticles || customAttributesDirty ) {
41626
41627                     setParticleBuffers( geometry, _gl.DYNAMIC_DRAW, object );
41628
41629                 }
41630
41631                 geometry.verticesNeedUpdate = false;
41632                 geometry.colorsNeedUpdate = false;
41633
41634                 material.attributes && clearCustomAttributes( material );
41635
41636             }
41637
41638         }
41639
41640     };
41641
41642     // Objects updates - custom attributes check
41643
41644     function areCustomAttributesDirty ( material ) {
41645
41646         for ( var a in material.attributes ) {
41647
41648             if ( material.attributes[ a ].needsUpdate ) return true;
41649
41650         }
41651
41652         return false;
41653
41654     };
41655
41656     function clearCustomAttributes ( material ) {
41657
41658         for ( var a in material.attributes ) {
41659
41660             material.attributes[ a ].needsUpdate = false;
41661
41662         }
41663
41664     };
41665
41666     // Objects removal
41667
41668     function removeObject ( object, scene ) {
41669
41670         if ( object instanceof THREE.Mesh  ||
41671              object instanceof THREE.ParticleSystem ||
41672              object instanceof THREE.Ribbon ||
41673              object instanceof THREE.Line ) {
41674
41675             removeInstances( scene.__webglObjects, object );
41676
41677         } else if ( object instanceof THREE.Sprite ) {
41678
41679             removeInstancesDirect( scene.__webglSprites, object );
41680
41681         } else if ( object instanceof THREE.LensFlare ) {
41682
41683             removeInstancesDirect( scene.__webglFlares, object );
41684
41685         } else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
41686
41687             removeInstances( scene.__webglObjectsImmediate, object );
41688
41689         }
41690
41691         object.__webglActive = false;
41692
41693     };
41694
41695     function removeInstances ( objlist, object ) {
41696
41697         for ( var o = objlist.length - 1; o >= 0; o -- ) {
41698
41699             if ( objlist[ o ].object === object ) {
41700
41701                 objlist.splice( o, 1 );
41702
41703             }
41704
41705         }
41706
41707     };
41708
41709     function removeInstancesDirect ( objlist, object ) {
41710
41711         for ( var o = objlist.length - 1; o >= 0; o -- ) {
41712
41713             if ( objlist[ o ] === object ) {
41714
41715                 objlist.splice( o, 1 );
41716
41717             }
41718
41719         }
41720
41721     };
41722
41723     // Materials
41724
41725     this.initMaterial = function ( material, lights, fog, object ) {
41726
41727         var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
41728
41729         if ( material instanceof THREE.MeshDepthMaterial ) {
41730
41731             shaderID = 'depth';
41732
41733         } else if ( material instanceof THREE.MeshNormalMaterial ) {
41734
41735             shaderID = 'normal';
41736
41737         } else if ( material instanceof THREE.MeshBasicMaterial ) {
41738
41739             shaderID = 'basic';
41740
41741         } else if ( material instanceof THREE.MeshLambertMaterial ) {
41742
41743             shaderID = 'lambert';
41744
41745         } else if ( material instanceof THREE.MeshPhongMaterial ) {
41746
41747             shaderID = 'phong';
41748
41749         } else if ( material instanceof THREE.LineBasicMaterial ) {
41750
41751             shaderID = 'basic';
41752
41753         } else if ( material instanceof THREE.ParticleBasicMaterial ) {
41754
41755             shaderID = 'particle_basic';
41756
41757         }
41758
41759         if ( shaderID ) {
41760
41761             setMaterialShaders( material, THREE.ShaderLib[ shaderID ] );
41762
41763         }
41764
41765         // heuristics to create shader parameters according to lights in the scene
41766         // (not to blow over maxLights budget)
41767
41768         maxLightCount = allocateLights( lights );
41769
41770         maxShadows = allocateShadows( lights );
41771
41772         maxBones = allocateBones( object );
41773
41774         parameters = {
41775
41776             map: !!material.map,
41777             envMap: !!material.envMap,
41778             lightMap: !!material.lightMap,
41779             bumpMap: !!material.bumpMap,
41780             normalMap: !!material.normalMap,
41781             specularMap: !!material.specularMap,
41782
41783             vertexColors: material.vertexColors,
41784
41785             fog: fog,
41786             useFog: material.fog,
41787
41788             sizeAttenuation: material.sizeAttenuation,
41789
41790             skinning: material.skinning,
41791             maxBones: maxBones,
41792             useVertexTexture: _supportsBoneTextures && object && object.useVertexTexture,
41793             boneTextureWidth: object && object.boneTextureWidth,
41794             boneTextureHeight: object && object.boneTextureHeight,
41795
41796             morphTargets: material.morphTargets,
41797             morphNormals: material.morphNormals,
41798             maxMorphTargets: this.maxMorphTargets,
41799             maxMorphNormals: this.maxMorphNormals,
41800
41801             maxDirLights: maxLightCount.directional,
41802             maxPointLights: maxLightCount.point,
41803             maxSpotLights: maxLightCount.spot,
41804             maxHemiLights: maxLightCount.hemi,
41805
41806             maxShadows: maxShadows,
41807             shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
41808             shadowMapSoft: this.shadowMapSoft,
41809             shadowMapDebug: this.shadowMapDebug,
41810             shadowMapCascade: this.shadowMapCascade,
41811
41812             alphaTest: material.alphaTest,
41813             metal: material.metal,
41814             perPixel: material.perPixel,
41815             wrapAround: material.wrapAround,
41816             doubleSided: material.side === THREE.DoubleSide,
41817             flipSided: material.side === THREE.BackSide
41818
41819         };
41820
41821         material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
41822
41823         var attributes = material.program.attributes;
41824
41825         if ( attributes.position >= 0 ) _gl.enableVertexAttribArray( attributes.position );
41826         if ( attributes.color >= 0 ) _gl.enableVertexAttribArray( attributes.color );
41827         if ( attributes.normal >= 0 ) _gl.enableVertexAttribArray( attributes.normal );
41828         if ( attributes.tangent >= 0 ) _gl.enableVertexAttribArray( attributes.tangent );
41829
41830         if ( material.skinning &&
41831              attributes.skinIndex >= 0 && attributes.skinWeight >= 0 ) {
41832
41833             _gl.enableVertexAttribArray( attributes.skinIndex );
41834             _gl.enableVertexAttribArray( attributes.skinWeight );
41835
41836         }
41837
41838         if ( material.attributes ) {
41839
41840             for ( a in material.attributes ) {
41841
41842                 if( attributes[ a ] !== undefined && attributes[ a ] >= 0 ) _gl.enableVertexAttribArray( attributes[ a ] );
41843
41844             }
41845
41846         }
41847
41848         if ( material.morphTargets ) {
41849
41850             material.numSupportedMorphTargets = 0;
41851
41852             var id, base = "morphTarget";
41853
41854             for ( i = 0; i < this.maxMorphTargets; i ++ ) {
41855
41856                 id = base + i;
41857
41858                 if ( attributes[ id ] >= 0 ) {
41859
41860                     _gl.enableVertexAttribArray( attributes[ id ] );
41861                     material.numSupportedMorphTargets ++;
41862
41863                 }
41864
41865             }
41866
41867         }
41868
41869         if ( material.morphNormals ) {
41870
41871             material.numSupportedMorphNormals = 0;
41872
41873             var id, base = "morphNormal";
41874
41875             for ( i = 0; i < this.maxMorphNormals; i ++ ) {
41876
41877                 id = base + i;
41878
41879                 if ( attributes[ id ] >= 0 ) {
41880
41881                     _gl.enableVertexAttribArray( attributes[ id ] );
41882                     material.numSupportedMorphNormals ++;
41883
41884                 }
41885
41886             }
41887
41888         }
41889
41890         material.uniformsList = [];
41891
41892         for ( u in material.uniforms ) {
41893
41894             material.uniformsList.push( [ material.uniforms[ u ], u ] );
41895
41896         }
41897
41898     };
41899
41900     function setMaterialShaders( material, shaders ) {
41901
41902         material.uniforms = THREE.UniformsUtils.clone( shaders.uniforms );
41903         material.vertexShader = shaders.vertexShader;
41904         material.fragmentShader = shaders.fragmentShader;
41905
41906     };
41907
41908     function setProgram( camera, lights, fog, material, object ) {
41909
41910         _usedTextureUnits = 0;
41911
41912         if ( material.needsUpdate ) {
41913
41914             if ( material.program ) _this.deallocateMaterial( material );
41915
41916             _this.initMaterial( material, lights, fog, object );
41917             material.needsUpdate = false;
41918
41919         }
41920
41921         if ( material.morphTargets ) {
41922
41923             if ( ! object.__webglMorphTargetInfluences ) {
41924
41925                 object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
41926
41927             }
41928
41929         }
41930
41931         var refreshMaterial = false;
41932
41933         var program = material.program,
41934             p_uniforms = program.uniforms,
41935             m_uniforms = material.uniforms;
41936
41937         if ( program !== _currentProgram ) {
41938
41939             _gl.useProgram( program );
41940             _currentProgram = program;
41941
41942             refreshMaterial = true;
41943
41944         }
41945
41946         if ( material.id !== _currentMaterialId ) {
41947
41948             _currentMaterialId = material.id;
41949             refreshMaterial = true;
41950
41951         }
41952
41953         if ( refreshMaterial || camera !== _currentCamera ) {
41954
41955             _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, camera._projectionMatrixArray );
41956
41957             if ( camera !== _currentCamera ) _currentCamera = camera;
41958
41959         }
41960
41961         // skinning uniforms must be set even if material didn't change
41962         // auto-setting of texture unit for bone texture must go before other textures
41963         // not sure why, but otherwise weird things happen
41964
41965         if ( material.skinning ) {
41966
41967             if ( _supportsBoneTextures && object.useVertexTexture ) {
41968
41969                 if ( p_uniforms.boneTexture !== null ) {
41970
41971                     var textureUnit = getTextureUnit();
41972
41973                     _gl.uniform1i( p_uniforms.boneTexture, textureUnit );
41974                     _this.setTexture( object.boneTexture, textureUnit );
41975
41976                 }
41977
41978             } else {
41979
41980                 if ( p_uniforms.boneGlobalMatrices !== null ) {
41981
41982                     _gl.uniformMatrix4fv( p_uniforms.boneGlobalMatrices, false, object.boneMatrices );
41983
41984                 }
41985
41986             }
41987
41988         }
41989
41990         if ( refreshMaterial ) {
41991
41992             // refresh uniforms common to several materials
41993
41994             if ( fog && material.fog ) {
41995
41996                 refreshUniformsFog( m_uniforms, fog );
41997
41998             }
41999
42000             if ( material instanceof THREE.MeshPhongMaterial ||
42001                  material instanceof THREE.MeshLambertMaterial ||
42002                  material.lights ) {
42003
42004                 if ( _lightsNeedUpdate ) {
42005
42006                     setupLights( program, lights );
42007                     _lightsNeedUpdate = false;
42008
42009                 }
42010
42011                 refreshUniformsLights( m_uniforms, _lights );
42012
42013             }
42014
42015             if ( material instanceof THREE.MeshBasicMaterial ||
42016                  material instanceof THREE.MeshLambertMaterial ||
42017                  material instanceof THREE.MeshPhongMaterial ) {
42018
42019                 refreshUniformsCommon( m_uniforms, material );
42020
42021             }
42022
42023             // refresh single material specific uniforms
42024
42025             if ( material instanceof THREE.LineBasicMaterial ) {
42026
42027                 refreshUniformsLine( m_uniforms, material );
42028
42029             } else if ( material instanceof THREE.ParticleBasicMaterial ) {
42030
42031                 refreshUniformsParticle( m_uniforms, material );
42032
42033             } else if ( material instanceof THREE.MeshPhongMaterial ) {
42034
42035                 refreshUniformsPhong( m_uniforms, material );
42036
42037             } else if ( material instanceof THREE.MeshLambertMaterial ) {
42038
42039                 refreshUniformsLambert( m_uniforms, material );
42040
42041             } else if ( material instanceof THREE.MeshDepthMaterial ) {
42042
42043                 m_uniforms.mNear.value = camera.near;
42044                 m_uniforms.mFar.value = camera.far;
42045                 m_uniforms.opacity.value = material.opacity;
42046
42047             } else if ( material instanceof THREE.MeshNormalMaterial ) {
42048
42049                 m_uniforms.opacity.value = material.opacity;
42050
42051             }
42052
42053             if ( object.receiveShadow && ! material._shadowPass ) {
42054
42055                 refreshUniformsShadow( m_uniforms, lights );
42056
42057             }
42058
42059             // load common uniforms
42060
42061             loadUniformsGeneric( program, material.uniformsList );
42062
42063             // load material specific uniforms
42064             // (shader material also gets them for the sake of genericity)
42065
42066             if ( material instanceof THREE.ShaderMaterial ||
42067                  material instanceof THREE.MeshPhongMaterial ||
42068                  material.envMap ) {
42069
42070                 if ( p_uniforms.cameraPosition !== null ) {
42071
42072                     var position = camera.matrixWorld.getPosition();
42073                     _gl.uniform3f( p_uniforms.cameraPosition, position.x, position.y, position.z );
42074
42075                 }
42076
42077             }
42078
42079             if ( material instanceof THREE.MeshPhongMaterial ||
42080                  material instanceof THREE.MeshLambertMaterial ||
42081                  material instanceof THREE.ShaderMaterial ||
42082                  material.skinning ) {
42083
42084                 if ( p_uniforms.viewMatrix !== null ) {
42085
42086                     _gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, camera._viewMatrixArray );
42087
42088                 }
42089
42090             }
42091
42092         }
42093
42094         loadUniformsMatrices( p_uniforms, object );
42095
42096         if ( p_uniforms.modelMatrix !== null ) {
42097
42098             _gl.uniformMatrix4fv( p_uniforms.modelMatrix, false, object.matrixWorld.elements );
42099
42100         }
42101
42102         return program;
42103
42104     };
42105
42106     // Uniforms (refresh uniforms objects)
42107
42108     function refreshUniformsCommon ( uniforms, material ) {
42109
42110         uniforms.opacity.value = material.opacity;
42111
42112         if ( _this.gammaInput ) {
42113
42114             uniforms.diffuse.value.copyGammaToLinear( material.color );
42115
42116         } else {
42117
42118             uniforms.diffuse.value = material.color;
42119
42120         }
42121
42122         uniforms.map.value = material.map;
42123         uniforms.lightMap.value = material.lightMap;
42124         uniforms.specularMap.value = material.specularMap;
42125
42126         if ( material.bumpMap ) {
42127
42128             uniforms.bumpMap.value = material.bumpMap;
42129             uniforms.bumpScale.value = material.bumpScale;
42130
42131         }
42132
42133         if ( material.normalMap ) {
42134
42135             uniforms.normalMap.value = material.normalMap;
42136             uniforms.normalScale.value.copy( material.normalScale );
42137
42138         }
42139
42140         // uv repeat and offset setting priorities
42141         //    1. color map
42142         //    2. specular map
42143         //    3. normal map
42144         //    4. bump map
42145
42146         var uvScaleMap;
42147
42148         if ( material.map ) {
42149
42150             uvScaleMap = material.map;
42151
42152         } else if ( material.specularMap ) {
42153
42154             uvScaleMap = material.specularMap;
42155
42156         } else if ( material.normalMap ) {
42157
42158             uvScaleMap = material.normalMap;
42159
42160         } else if ( material.bumpMap ) {
42161
42162             uvScaleMap = material.bumpMap;
42163
42164         }
42165
42166         if ( uvScaleMap !== undefined ) {
42167
42168             var offset = uvScaleMap.offset;
42169             var repeat = uvScaleMap.repeat;
42170
42171             uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
42172
42173         }
42174
42175         uniforms.envMap.value = material.envMap;
42176         uniforms.flipEnvMap.value = ( material.envMap instanceof THREE.WebGLRenderTargetCube ) ? 1 : -1;
42177
42178         if ( _this.gammaInput ) {
42179
42180             //uniforms.reflectivity.value = material.reflectivity * material.reflectivity;
42181             uniforms.reflectivity.value = material.reflectivity;
42182
42183         } else {
42184
42185             uniforms.reflectivity.value = material.reflectivity;
42186
42187         }
42188
42189         uniforms.refractionRatio.value = material.refractionRatio;
42190         uniforms.combine.value = material.combine;
42191         uniforms.useRefract.value = material.envMap && material.envMap.mapping instanceof THREE.CubeRefractionMapping;
42192
42193     };
42194
42195     function refreshUniformsLine ( uniforms, material ) {
42196
42197         uniforms.diffuse.value = material.color;
42198         uniforms.opacity.value = material.opacity;
42199
42200     };
42201
42202     function refreshUniformsParticle ( uniforms, material ) {
42203
42204         uniforms.psColor.value = material.color;
42205         uniforms.opacity.value = material.opacity;
42206         uniforms.size.value = material.size;
42207         uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.
42208
42209         uniforms.map.value = material.map;
42210
42211     };
42212
42213     function refreshUniformsFog ( uniforms, fog ) {
42214
42215         uniforms.fogColor.value = fog.color;
42216
42217         if ( fog instanceof THREE.Fog ) {
42218
42219             uniforms.fogNear.value = fog.near;
42220             uniforms.fogFar.value = fog.far;
42221
42222         } else if ( fog instanceof THREE.FogExp2 ) {
42223
42224             uniforms.fogDensity.value = fog.density;
42225
42226         }
42227
42228     };
42229
42230     function refreshUniformsPhong ( uniforms, material ) {
42231
42232         uniforms.shininess.value = material.shininess;
42233
42234         if ( _this.gammaInput ) {
42235
42236             uniforms.ambient.value.copyGammaToLinear( material.ambient );
42237             uniforms.emissive.value.copyGammaToLinear( material.emissive );
42238             uniforms.specular.value.copyGammaToLinear( material.specular );
42239
42240         } else {
42241
42242             uniforms.ambient.value = material.ambient;
42243             uniforms.emissive.value = material.emissive;
42244             uniforms.specular.value = material.specular;
42245
42246         }
42247
42248         if ( material.wrapAround ) {
42249
42250             uniforms.wrapRGB.value.copy( material.wrapRGB );
42251
42252         }
42253
42254     };
42255
42256     function refreshUniformsLambert ( uniforms, material ) {
42257
42258         if ( _this.gammaInput ) {
42259
42260             uniforms.ambient.value.copyGammaToLinear( material.ambient );
42261             uniforms.emissive.value.copyGammaToLinear( material.emissive );
42262
42263         } else {
42264
42265             uniforms.ambient.value = material.ambient;
42266             uniforms.emissive.value = material.emissive;
42267
42268         }
42269
42270         if ( material.wrapAround ) {
42271
42272             uniforms.wrapRGB.value.copy( material.wrapRGB );
42273
42274         }
42275
42276     };
42277
42278     function refreshUniformsLights ( uniforms, lights ) {
42279
42280         uniforms.ambientLightColor.value = lights.ambient;
42281
42282         uniforms.directionalLightColor.value = lights.directional.colors;
42283         uniforms.directionalLightDirection.value = lights.directional.positions;
42284
42285         uniforms.pointLightColor.value = lights.point.colors;
42286         uniforms.pointLightPosition.value = lights.point.positions;
42287         uniforms.pointLightDistance.value = lights.point.distances;
42288
42289         uniforms.spotLightColor.value = lights.spot.colors;
42290         uniforms.spotLightPosition.value = lights.spot.positions;
42291         uniforms.spotLightDistance.value = lights.spot.distances;
42292         uniforms.spotLightDirection.value = lights.spot.directions;
42293         uniforms.spotLightAngle.value = lights.spot.angles;
42294         uniforms.spotLightExponent.value = lights.spot.exponents;
42295
42296         uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
42297         uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
42298         uniforms.hemisphereLightPosition.value = lights.hemi.positions;
42299
42300     };
42301
42302     function refreshUniformsShadow ( uniforms, lights ) {
42303
42304         if ( uniforms.shadowMatrix ) {
42305
42306             var j = 0;
42307
42308             for ( var i = 0, il = lights.length; i < il; i ++ ) {
42309
42310                 var light = lights[ i ];
42311
42312                 if ( ! light.castShadow ) continue;
42313
42314                 if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) ) {
42315
42316                     uniforms.shadowMap.value[ j ] = light.shadowMap;
42317                     uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
42318
42319                     uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
42320
42321                     uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
42322                     uniforms.shadowBias.value[ j ] = light.shadowBias;
42323
42324                     j ++;
42325
42326                 }
42327
42328             }
42329
42330         }
42331
42332     };
42333
42334     // Uniforms (load to GPU)
42335
42336     function loadUniformsMatrices ( uniforms, object ) {
42337
42338         _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrix.elements );
42339
42340         if ( uniforms.normalMatrix ) {
42341
42342             _gl.uniformMatrix3fv( uniforms.normalMatrix, false, object._normalMatrix.elements );
42343
42344         }
42345
42346     };
42347
42348     function getTextureUnit() {
42349
42350         var textureUnit = _usedTextureUnits;
42351
42352         if ( textureUnit >= _maxTextures ) {
42353
42354             console.warn( "Trying to use " + textureUnit + " texture units while this GPU supports only " + _maxTextures );
42355
42356         }
42357
42358         _usedTextureUnits += 1;
42359
42360         return textureUnit;
42361
42362     };
42363
42364     function loadUniformsGeneric ( program, uniforms ) {
42365
42366         var uniform, value, type, location, texture, textureUnit, i, il, j, jl, offset;
42367
42368         for ( j = 0, jl = uniforms.length; j < jl; j ++ ) {
42369
42370             location = program.uniforms[ uniforms[ j ][ 1 ] ];
42371             if ( !location ) continue;
42372
42373             uniform = uniforms[ j ][ 0 ];
42374
42375             type = uniform.type;
42376             value = uniform.value;
42377
42378             if ( type === "i" ) { // single integer
42379
42380                 _gl.uniform1i( location, value );
42381
42382             } else if ( type === "f" ) { // single float
42383
42384                 _gl.uniform1f( location, value );
42385
42386             } else if ( type === "v2" ) { // single THREE.Vector2
42387
42388                 _gl.uniform2f( location, value.x, value.y );
42389
42390             } else if ( type === "v3" ) { // single THREE.Vector3
42391
42392                 _gl.uniform3f( location, value.x, value.y, value.z );
42393
42394             } else if ( type === "v4" ) { // single THREE.Vector4
42395
42396                 _gl.uniform4f( location, value.x, value.y, value.z, value.w );
42397
42398             } else if ( type === "c" ) { // single THREE.Color
42399
42400                 _gl.uniform3f( location, value.r, value.g, value.b );
42401
42402             } else if ( type === "iv1" ) { // flat array of integers (JS or typed array)
42403
42404                 _gl.uniform1iv( location, value );
42405
42406             } else if ( type === "iv" ) { // flat array of integers with 3 x N size (JS or typed array)
42407
42408                 _gl.uniform3iv( location, value );
42409
42410             } else if ( type === "fv1" ) { // flat array of floats (JS or typed array)
42411
42412                 _gl.uniform1fv( location, value );
42413
42414             } else if ( type === "fv" ) { // flat array of floats with 3 x N size (JS or typed array)
42415
42416                 _gl.uniform3fv( location, value );
42417
42418             } else if ( type === "v2v" ) { // array of THREE.Vector2
42419
42420                 if ( uniform._array === undefined ) {
42421
42422                     uniform._array = new Float32Array( 2 * value.length );
42423
42424                 }
42425
42426                 for ( i = 0, il = value.length; i < il; i ++ ) {
42427
42428                     offset = i * 2;
42429
42430                     uniform._array[ offset ]      = value[ i ].x;
42431                     uniform._array[ offset + 1 ] = value[ i ].y;
42432
42433                 }
42434
42435                 _gl.uniform2fv( location, uniform._array );
42436
42437             } else if ( type === "v3v" ) { // array of THREE.Vector3
42438
42439                 if ( uniform._array === undefined ) {
42440
42441                     uniform._array = new Float32Array( 3 * value.length );
42442
42443                 }
42444
42445                 for ( i = 0, il = value.length; i < il; i ++ ) {
42446
42447                     offset = i * 3;
42448
42449                     uniform._array[ offset ]      = value[ i ].x;
42450                     uniform._array[ offset + 1 ] = value[ i ].y;
42451                     uniform._array[ offset + 2 ] = value[ i ].z;
42452
42453                 }
42454
42455                 _gl.uniform3fv( location, uniform._array );
42456
42457             } else if ( type === "v4v" ) { // array of THREE.Vector4
42458
42459                 if ( uniform._array === undefined ) {
42460
42461                     uniform._array = new Float32Array( 4 * value.length );
42462
42463                 }
42464
42465                 for ( i = 0, il = value.length; i < il; i ++ ) {
42466
42467                     offset = i * 4;
42468
42469                     uniform._array[ offset ]      = value[ i ].x;
42470                     uniform._array[ offset + 1 ] = value[ i ].y;
42471                     uniform._array[ offset + 2 ] = value[ i ].z;
42472                     uniform._array[ offset + 3 ] = value[ i ].w;
42473
42474                 }
42475
42476                 _gl.uniform4fv( location, uniform._array );
42477
42478             } else if ( type === "m4") { // single THREE.Matrix4
42479
42480                 if ( uniform._array === undefined ) {
42481
42482                     uniform._array = new Float32Array( 16 );
42483
42484                 }
42485
42486                 value.flattenToArray( uniform._array );
42487                 _gl.uniformMatrix4fv( location, false, uniform._array );
42488
42489             } else if ( type === "m4v" ) { // array of THREE.Matrix4
42490
42491                 if ( uniform._array === undefined ) {
42492
42493                     uniform._array = new Float32Array( 16 * value.length );
42494
42495                 }
42496
42497                 for ( i = 0, il = value.length; i < il; i ++ ) {
42498
42499                     value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
42500
42501                 }
42502
42503                 _gl.uniformMatrix4fv( location, false, uniform._array );
42504
42505             } else if ( type === "t" ) { // single THREE.Texture (2d or cube)
42506
42507                 texture = value;
42508                 textureUnit = getTextureUnit();
42509
42510                 _gl.uniform1i( location, textureUnit );
42511
42512                 if ( !texture ) continue;
42513
42514                 if ( texture.image instanceof Array && texture.image.length === 6 ) {
42515
42516                     setCubeTexture( texture, textureUnit );
42517
42518                 } else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
42519
42520                     setCubeTextureDynamic( texture, textureUnit );
42521
42522                 } else {
42523
42524                     _this.setTexture( texture, textureUnit );
42525
42526                 }
42527
42528             } else if ( type === "tv" ) { // array of THREE.Texture (2d)
42529
42530                 if ( uniform._array === undefined ) {
42531
42532                     uniform._array = [];
42533
42534                 }
42535
42536                 for( i = 0, il = uniform.value.length; i < il; i ++ ) {
42537
42538                     uniform._array[ i ] = getTextureUnit();
42539
42540                 }
42541
42542                 _gl.uniform1iv( location, uniform._array );
42543
42544                 for( i = 0, il = uniform.value.length; i < il; i ++ ) {
42545
42546                     texture = uniform.value[ i ];
42547                     textureUnit = uniform._array[ i ];
42548
42549                     if ( !texture ) continue;
42550
42551                     _this.setTexture( texture, textureUnit );
42552
42553                 }
42554
42555             }
42556
42557         }
42558
42559     };
42560
42561     function setupMatrices ( object, camera ) {
42562
42563         object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld );
42564
42565         object._normalMatrix.getInverse( object._modelViewMatrix );
42566         object._normalMatrix.transpose();
42567
42568     };
42569
42570     //
42571
42572     function setColorGamma( array, offset, color, intensitySq ) {
42573
42574         array[ offset ]     = color.r * color.r * intensitySq;
42575         array[ offset + 1 ] = color.g * color.g * intensitySq;
42576         array[ offset + 2 ] = color.b * color.b * intensitySq;
42577
42578     };
42579
42580     function setColorLinear( array, offset, color, intensity ) {
42581
42582         array[ offset ]     = color.r * intensity;
42583         array[ offset + 1 ] = color.g * intensity;
42584         array[ offset + 2 ] = color.b * intensity;
42585
42586     };
42587
42588     function setupLights ( program, lights ) {
42589
42590         var l, ll, light, n,
42591         r = 0, g = 0, b = 0,
42592         color, skyColor, groundColor,
42593         intensity,  intensitySq,
42594         position,
42595         distance,
42596
42597         zlights = _lights,
42598
42599         dirColors = zlights.directional.colors,
42600         dirPositions = zlights.directional.positions,
42601
42602         pointColors = zlights.point.colors,
42603         pointPositions = zlights.point.positions,
42604         pointDistances = zlights.point.distances,
42605
42606         spotColors = zlights.spot.colors,
42607         spotPositions = zlights.spot.positions,
42608         spotDistances = zlights.spot.distances,
42609         spotDirections = zlights.spot.directions,
42610         spotAngles = zlights.spot.angles,
42611         spotExponents = zlights.spot.exponents,
42612
42613         hemiSkyColors = zlights.hemi.skyColors,
42614         hemiGroundColors = zlights.hemi.groundColors,
42615         hemiPositions = zlights.hemi.positions,
42616
42617         dirLength = 0,
42618         pointLength = 0,
42619         spotLength = 0,
42620         hemiLength = 0,
42621
42622         dirOffset = 0,
42623         pointOffset = 0,
42624         spotOffset = 0,
42625         hemiOffset = 0;
42626
42627         for ( l = 0, ll = lights.length; l < ll; l ++ ) {
42628
42629             light = lights[ l ];
42630
42631             if ( light.onlyShadow || ! light.visible ) continue;
42632
42633             color = light.color;
42634             intensity = light.intensity;
42635             distance = light.distance;
42636
42637             if ( light instanceof THREE.AmbientLight ) {
42638
42639                 if ( _this.gammaInput ) {
42640
42641                     r += color.r * color.r;
42642                     g += color.g * color.g;
42643                     b += color.b * color.b;
42644
42645                 } else {
42646
42647                     r += color.r;
42648                     g += color.g;
42649                     b += color.b;
42650
42651                 }
42652
42653             } else if ( light instanceof THREE.DirectionalLight ) {
42654
42655                 dirOffset = dirLength * 3;
42656
42657                 if ( _this.gammaInput ) {
42658
42659                     setColorGamma( dirColors, dirOffset, color, intensity * intensity );
42660
42661                 } else {
42662
42663                     setColorLinear( dirColors, dirOffset, color, intensity );
42664
42665                 }
42666
42667                 _direction.copy( light.matrixWorld.getPosition() );
42668                 _direction.subSelf( light.target.matrixWorld.getPosition() );
42669                 _direction.normalize();
42670
42671                 dirPositions[ dirOffset ]     = _direction.x;
42672                 dirPositions[ dirOffset + 1 ] = _direction.y;
42673                 dirPositions[ dirOffset + 2 ] = _direction.z;
42674
42675                 dirLength += 1;
42676
42677             } else if( light instanceof THREE.PointLight ) {
42678
42679                 pointOffset = pointLength * 3;
42680
42681                 if ( _this.gammaInput ) {
42682
42683                     setColorGamma( pointColors, pointOffset, color, intensity * intensity );
42684
42685                 } else {
42686
42687                     setColorLinear( pointColors, pointOffset, color, intensity );
42688
42689                 }
42690
42691                 position = light.matrixWorld.getPosition();
42692
42693                 pointPositions[ pointOffset ]     = position.x;
42694                 pointPositions[ pointOffset + 1 ] = position.y;
42695                 pointPositions[ pointOffset + 2 ] = position.z;
42696
42697                 pointDistances[ pointLength ] = distance;
42698
42699                 pointLength += 1;
42700
42701             } else if( light instanceof THREE.SpotLight ) {
42702
42703                 spotOffset = spotLength * 3;
42704
42705                 if ( _this.gammaInput ) {
42706
42707                     setColorGamma( spotColors, spotOffset, color, intensity * intensity );
42708
42709                 } else {
42710
42711                     setColorLinear( spotColors, spotOffset, color, intensity );
42712
42713                 }
42714
42715                 position = light.matrixWorld.getPosition();
42716
42717                 spotPositions[ spotOffset ]     = position.x;
42718                 spotPositions[ spotOffset + 1 ] = position.y;
42719                 spotPositions[ spotOffset + 2 ] = position.z;
42720
42721                 spotDistances[ spotLength ] = distance;
42722
42723                 _direction.copy( position );
42724                 _direction.subSelf( light.target.matrixWorld.getPosition() );
42725                 _direction.normalize();
42726
42727                 spotDirections[ spotOffset ]     = _direction.x;
42728                 spotDirections[ spotOffset + 1 ] = _direction.y;
42729                 spotDirections[ spotOffset + 2 ] = _direction.z;
42730
42731                 spotAngles[ spotLength ] = Math.cos( light.angle );
42732                 spotExponents[ spotLength ] = light.exponent;
42733
42734                 spotLength += 1;
42735
42736             } else if ( light instanceof THREE.HemisphereLight ) {
42737
42738                 skyColor = light.color;
42739                 groundColor = light.groundColor;
42740
42741                 hemiOffset = hemiLength * 3;
42742
42743                 if ( _this.gammaInput ) {
42744
42745                     intensitySq = intensity * intensity;
42746
42747                     setColorGamma( hemiSkyColors, hemiOffset, skyColor, intensitySq );
42748                     setColorGamma( hemiGroundColors, hemiOffset, groundColor, intensitySq );
42749
42750                 } else {
42751
42752                     setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
42753                     setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );
42754
42755                 }
42756
42757                 position = light.matrixWorld.getPosition();
42758
42759                 hemiPositions[ hemiOffset ]     = position.x;
42760                 hemiPositions[ hemiOffset + 1 ] = position.y;
42761                 hemiPositions[ hemiOffset + 2 ] = position.z;
42762
42763                 hemiLength += 1;
42764
42765             }
42766
42767         }
42768
42769         // null eventual remains from removed lights
42770         // (this is to avoid if in shader)
42771
42772         for ( l = dirLength * 3, ll = dirColors.length; l < ll; l ++ ) dirColors[ l ] = 0.0;
42773         for ( l = pointLength * 3, ll = pointColors.length; l < ll; l ++ ) pointColors[ l ] = 0.0;
42774         for ( l = spotLength * 3, ll = spotColors.length; l < ll; l ++ ) spotColors[ l ] = 0.0;
42775         for ( l = hemiLength * 3, ll = hemiSkyColors.length; l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
42776         for ( l = hemiLength * 3, ll = hemiGroundColors.length; l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
42777
42778         zlights.directional.length = dirLength;
42779         zlights.point.length = pointLength;
42780         zlights.spot.length = spotLength;
42781         zlights.hemi.length = hemiLength;
42782
42783         zlights.ambient[ 0 ] = r;
42784         zlights.ambient[ 1 ] = g;
42785         zlights.ambient[ 2 ] = b;
42786
42787     };
42788
42789     // GL state setting
42790
42791     this.setFaceCulling = function ( cullFace, frontFace ) {
42792
42793         if ( cullFace ) {
42794
42795             if ( !frontFace || frontFace === "ccw" ) {
42796
42797                 _gl.frontFace( _gl.CCW );
42798
42799             } else {
42800
42801                 _gl.frontFace( _gl.CW );
42802
42803             }
42804
42805             if( cullFace === "back" ) {
42806
42807                 _gl.cullFace( _gl.BACK );
42808
42809             } else if( cullFace === "front" ) {
42810
42811                 _gl.cullFace( _gl.FRONT );
42812
42813             } else {
42814
42815                 _gl.cullFace( _gl.FRONT_AND_BACK );
42816
42817             }
42818
42819             _gl.enable( _gl.CULL_FACE );
42820
42821         } else {
42822
42823             _gl.disable( _gl.CULL_FACE );
42824
42825         }
42826
42827     };
42828
42829     this.setMaterialFaces = function ( material ) {
42830
42831         var doubleSided = material.side === THREE.DoubleSide;
42832         var flipSided = material.side === THREE.BackSide;
42833
42834         if ( _oldDoubleSided !== doubleSided ) {
42835
42836             if ( doubleSided ) {
42837
42838                 _gl.disable( _gl.CULL_FACE );
42839
42840             } else {
42841
42842                 _gl.enable( _gl.CULL_FACE );
42843
42844             }
42845
42846             _oldDoubleSided = doubleSided;
42847
42848         }
42849
42850         if ( _oldFlipSided !== flipSided ) {
42851
42852             if ( flipSided ) {
42853
42854                 _gl.frontFace( _gl.CW );
42855
42856             } else {
42857
42858                 _gl.frontFace( _gl.CCW );
42859
42860             }
42861
42862             _oldFlipSided = flipSided;
42863
42864         }
42865
42866     };
42867
42868     this.setDepthTest = function ( depthTest ) {
42869
42870         if ( _oldDepthTest !== depthTest ) {
42871
42872             if ( depthTest ) {
42873
42874                 _gl.enable( _gl.DEPTH_TEST );
42875
42876             } else {
42877
42878                 _gl.disable( _gl.DEPTH_TEST );
42879
42880             }
42881
42882             _oldDepthTest = depthTest;
42883
42884         }
42885
42886     };
42887
42888     this.setDepthWrite = function ( depthWrite ) {
42889
42890         if ( _oldDepthWrite !== depthWrite ) {
42891
42892             _gl.depthMask( depthWrite );
42893             _oldDepthWrite = depthWrite;
42894
42895         }
42896
42897     };
42898
42899     function setLineWidth ( width ) {
42900
42901         if ( width !== _oldLineWidth ) {
42902
42903             _gl.lineWidth( width );
42904
42905             _oldLineWidth = width;
42906
42907         }
42908
42909     };
42910
42911     function setPolygonOffset ( polygonoffset, factor, units ) {
42912
42913         if ( _oldPolygonOffset !== polygonoffset ) {
42914
42915             if ( polygonoffset ) {
42916
42917                 _gl.enable( _gl.POLYGON_OFFSET_FILL );
42918
42919             } else {
42920
42921                 _gl.disable( _gl.POLYGON_OFFSET_FILL );
42922
42923             }
42924
42925             _oldPolygonOffset = polygonoffset;
42926
42927         }
42928
42929         if ( polygonoffset && ( _oldPolygonOffsetFactor !== factor || _oldPolygonOffsetUnits !== units ) ) {
42930
42931             _gl.polygonOffset( factor, units );
42932
42933             _oldPolygonOffsetFactor = factor;
42934             _oldPolygonOffsetUnits = units;
42935
42936         }
42937
42938     };
42939
42940     this.setBlending = function ( blending, blendEquation, blendSrc, blendDst ) {
42941
42942         if ( blending !== _oldBlending ) {
42943
42944             if ( blending === THREE.NoBlending ) {
42945
42946                 _gl.disable( _gl.BLEND );
42947
42948             } else if ( blending === THREE.AdditiveBlending ) {
42949
42950                 _gl.enable( _gl.BLEND );
42951                 _gl.blendEquation( _gl.FUNC_ADD );
42952                 _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE );
42953
42954             } else if ( blending === THREE.SubtractiveBlending ) {
42955
42956                 // TODO: Find blendFuncSeparate() combination
42957                 _gl.enable( _gl.BLEND );
42958                 _gl.blendEquation( _gl.FUNC_ADD );
42959                 _gl.blendFunc( _gl.ZERO, _gl.ONE_MINUS_SRC_COLOR );
42960
42961             } else if ( blending === THREE.MultiplyBlending ) {
42962
42963                 // TODO: Find blendFuncSeparate() combination
42964                 _gl.enable( _gl.BLEND );
42965                 _gl.blendEquation( _gl.FUNC_ADD );
42966                 _gl.blendFunc( _gl.ZERO, _gl.SRC_COLOR );
42967
42968             } else if ( blending === THREE.CustomBlending ) {
42969
42970                 _gl.enable( _gl.BLEND );
42971
42972             } else {
42973
42974                 _gl.enable( _gl.BLEND );
42975                 _gl.blendEquationSeparate( _gl.FUNC_ADD, _gl.FUNC_ADD );
42976                 _gl.blendFuncSeparate( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA, _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
42977
42978             }
42979
42980             _oldBlending = blending;
42981
42982         }
42983
42984         if ( blending === THREE.CustomBlending ) {
42985
42986             if ( blendEquation !== _oldBlendEquation ) {
42987
42988                 _gl.blendEquation( paramThreeToGL( blendEquation ) );
42989
42990                 _oldBlendEquation = blendEquation;
42991
42992             }
42993
42994             if ( blendSrc !== _oldBlendSrc || blendDst !== _oldBlendDst ) {
42995
42996                 _gl.blendFunc( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ) );
42997
42998                 _oldBlendSrc = blendSrc;
42999                 _oldBlendDst = blendDst;
43000
43001             }
43002
43003         } else {
43004
43005             _oldBlendEquation = null;
43006             _oldBlendSrc = null;
43007             _oldBlendDst = null;
43008
43009         }
43010
43011     };
43012
43013     // Shaders
43014
43015     function buildProgram ( shaderID, fragmentShader, vertexShader, uniforms, attributes, parameters ) {
43016
43017         var p, pl, program, code;
43018         var chunks = [];
43019
43020         // Generate code
43021
43022         if ( shaderID ) {
43023
43024             chunks.push( shaderID );
43025
43026         } else {
43027
43028             chunks.push( fragmentShader );
43029             chunks.push( vertexShader );
43030
43031         }
43032
43033         for ( p in parameters ) {
43034
43035             chunks.push( p );
43036             chunks.push( parameters[ p ] );
43037
43038         }
43039
43040         code = chunks.join();
43041
43042         // Check if code has been already compiled
43043
43044         for ( p = 0, pl = _programs.length; p < pl; p ++ ) {
43045
43046             var programInfo = _programs[ p ];
43047
43048             if ( programInfo.code === code ) {
43049
43050                 // console.log( "Code already compiled." /*: \n\n" + code*/ );
43051
43052                 programInfo.usedTimes ++;
43053
43054                 return programInfo.program;
43055
43056             }
43057
43058         }
43059
43060         //console.log( "building new program " );
43061
43062         //
43063
43064         program = _gl.createProgram();
43065
43066         var prefix_vertex = [
43067
43068             "precision " + _precision + " float;",
43069
43070             _supportsVertexTextures ? "#define VERTEX_TEXTURES" : "",
43071
43072             _this.gammaInput ? "#define GAMMA_INPUT" : "",
43073             _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
43074             _this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",
43075
43076             "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
43077             "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
43078             "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
43079             "#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
43080
43081             "#define MAX_SHADOWS " + parameters.maxShadows,
43082
43083             "#define MAX_BONES " + parameters.maxBones,
43084
43085             parameters.map ? "#define USE_MAP" : "",
43086             parameters.envMap ? "#define USE_ENVMAP" : "",
43087             parameters.lightMap ? "#define USE_LIGHTMAP" : "",
43088             parameters.bumpMap ? "#define USE_BUMPMAP" : "",
43089             parameters.normalMap ? "#define USE_NORMALMAP" : "",
43090             parameters.specularMap ? "#define USE_SPECULARMAP" : "",
43091             parameters.vertexColors ? "#define USE_COLOR" : "",
43092
43093             parameters.skinning ? "#define USE_SKINNING" : "",
43094             parameters.useVertexTexture ? "#define BONE_TEXTURE" : "",
43095             parameters.boneTextureWidth ? "#define N_BONE_PIXEL_X " + parameters.boneTextureWidth.toFixed( 1 ) : "",
43096             parameters.boneTextureHeight ? "#define N_BONE_PIXEL_Y " + parameters.boneTextureHeight.toFixed( 1 ) : "",
43097
43098             parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
43099             parameters.morphNormals ? "#define USE_MORPHNORMALS" : "",
43100             parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
43101             parameters.wrapAround ? "#define WRAP_AROUND" : "",
43102             parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
43103             parameters.flipSided ? "#define FLIP_SIDED" : "",
43104
43105             parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
43106             parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
43107             parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
43108             parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
43109
43110             parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",
43111
43112             "uniform mat4 modelMatrix;",
43113             "uniform mat4 modelViewMatrix;",
43114             "uniform mat4 projectionMatrix;",
43115             "uniform mat4 viewMatrix;",
43116             "uniform mat3 normalMatrix;",
43117             "uniform vec3 cameraPosition;",
43118
43119             "attribute vec3 position;",
43120             "attribute vec3 normal;",
43121             "attribute vec2 uv;",
43122             "attribute vec2 uv2;",
43123
43124             "#ifdef USE_COLOR",
43125
43126                 "attribute vec3 color;",
43127
43128             "#endif",
43129
43130             "#ifdef USE_MORPHTARGETS",
43131
43132                 "attribute vec3 morphTarget0;",
43133                 "attribute vec3 morphTarget1;",
43134                 "attribute vec3 morphTarget2;",
43135                 "attribute vec3 morphTarget3;",
43136
43137                 "#ifdef USE_MORPHNORMALS",
43138
43139                     "attribute vec3 morphNormal0;",
43140                     "attribute vec3 morphNormal1;",
43141                     "attribute vec3 morphNormal2;",
43142                     "attribute vec3 morphNormal3;",
43143
43144                 "#else",
43145
43146                     "attribute vec3 morphTarget4;",
43147                     "attribute vec3 morphTarget5;",
43148                     "attribute vec3 morphTarget6;",
43149                     "attribute vec3 morphTarget7;",
43150
43151                 "#endif",
43152
43153             "#endif",
43154
43155             "#ifdef USE_SKINNING",
43156
43157                 "attribute vec4 skinIndex;",
43158                 "attribute vec4 skinWeight;",
43159
43160             "#endif",
43161
43162             ""
43163
43164         ].join("\n");
43165
43166         var prefix_fragment = [
43167
43168             "precision " + _precision + " float;",
43169
43170             ( parameters.bumpMap || parameters.normalMap ) ? "#extension GL_OES_standard_derivatives : enable" : "",
43171
43172             "#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
43173             "#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
43174             "#define MAX_SPOT_LIGHTS " + parameters.maxSpotLights,
43175             "#define MAX_HEMI_LIGHTS " + parameters.maxHemiLights,
43176
43177             "#define MAX_SHADOWS " + parameters.maxShadows,
43178
43179             parameters.alphaTest ? "#define ALPHATEST " + parameters.alphaTest: "",
43180
43181             _this.gammaInput ? "#define GAMMA_INPUT" : "",
43182             _this.gammaOutput ? "#define GAMMA_OUTPUT" : "",
43183             _this.physicallyBasedShading ? "#define PHYSICALLY_BASED_SHADING" : "",
43184
43185             ( parameters.useFog && parameters.fog ) ? "#define USE_FOG" : "",
43186             ( parameters.useFog && parameters.fog instanceof THREE.FogExp2 ) ? "#define FOG_EXP2" : "",
43187
43188             parameters.map ? "#define USE_MAP" : "",
43189             parameters.envMap ? "#define USE_ENVMAP" : "",
43190             parameters.lightMap ? "#define USE_LIGHTMAP" : "",
43191             parameters.bumpMap ? "#define USE_BUMPMAP" : "",
43192             parameters.normalMap ? "#define USE_NORMALMAP" : "",
43193             parameters.specularMap ? "#define USE_SPECULARMAP" : "",
43194             parameters.vertexColors ? "#define USE_COLOR" : "",
43195
43196             parameters.metal ? "#define METAL" : "",
43197             parameters.perPixel ? "#define PHONG_PER_PIXEL" : "",
43198             parameters.wrapAround ? "#define WRAP_AROUND" : "",
43199             parameters.doubleSided ? "#define DOUBLE_SIDED" : "",
43200             parameters.flipSided ? "#define FLIP_SIDED" : "",
43201
43202             parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
43203             parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
43204             parameters.shadowMapDebug ? "#define SHADOWMAP_DEBUG" : "",
43205             parameters.shadowMapCascade ? "#define SHADOWMAP_CASCADE" : "",
43206
43207             "uniform mat4 viewMatrix;",
43208             "uniform vec3 cameraPosition;",
43209             ""
43210
43211         ].join("\n");
43212
43213         var glFragmentShader = getShader( "fragment", prefix_fragment + fragmentShader );
43214         var glVertexShader = getShader( "vertex", prefix_vertex + vertexShader );
43215
43216         _gl.attachShader( program, glVertexShader );
43217         _gl.attachShader( program, glFragmentShader );
43218
43219         _gl.linkProgram( program );
43220
43221         if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
43222
43223             console.error( "Could not initialise shader\n" + "VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
43224
43225         }
43226
43227         // clean up
43228
43229         _gl.deleteShader( glFragmentShader );
43230         _gl.deleteShader( glVertexShader );
43231
43232         //console.log( prefix_fragment + fragmentShader );
43233         //console.log( prefix_vertex + vertexShader );
43234
43235         program.uniforms = {};
43236         program.attributes = {};
43237
43238         var identifiers, u, a, i;
43239
43240         // cache uniform locations
43241
43242         identifiers = [
43243
43244             'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'modelMatrix', 'cameraPosition',
43245             'morphTargetInfluences'
43246
43247         ];
43248
43249         if ( parameters.useVertexTexture ) {
43250
43251             identifiers.push( 'boneTexture' );
43252
43253         } else {
43254
43255             identifiers.push( 'boneGlobalMatrices' );
43256
43257         }
43258
43259         for ( u in uniforms ) {
43260
43261             identifiers.push( u );
43262
43263         }
43264
43265         cacheUniformLocations( program, identifiers );
43266
43267         // cache attributes locations
43268
43269         identifiers = [
43270
43271             "position", "normal", "uv", "uv2", "tangent", "color",
43272             "skinIndex", "skinWeight"
43273
43274         ];
43275
43276         for ( i = 0; i < parameters.maxMorphTargets; i ++ ) {
43277
43278             identifiers.push( "morphTarget" + i );
43279
43280         }
43281
43282         for ( i = 0; i < parameters.maxMorphNormals; i ++ ) {
43283
43284             identifiers.push( "morphNormal" + i );
43285
43286         }
43287
43288         for ( a in attributes ) {
43289
43290             identifiers.push( a );
43291
43292         }
43293
43294         cacheAttributeLocations( program, identifiers );
43295
43296         program.id = _programs_counter ++;
43297
43298         _programs.push( { program: program, code: code, usedTimes: 1 } );
43299
43300         _this.info.memory.programs = _programs.length;
43301
43302         return program;
43303
43304     };
43305
43306     // Shader parameters cache
43307
43308     function cacheUniformLocations ( program, identifiers ) {
43309
43310         var i, l, id;
43311
43312         for( i = 0, l = identifiers.length; i < l; i ++ ) {
43313
43314             id = identifiers[ i ];
43315             program.uniforms[ id ] = _gl.getUniformLocation( program, id );
43316
43317         }
43318
43319     };
43320
43321     function cacheAttributeLocations ( program, identifiers ) {
43322
43323         var i, l, id;
43324
43325         for( i = 0, l = identifiers.length; i < l; i ++ ) {
43326
43327             id = identifiers[ i ];
43328             program.attributes[ id ] = _gl.getAttribLocation( program, id );
43329
43330         }
43331
43332     };
43333
43334     function addLineNumbers ( string ) {
43335
43336         var chunks = string.split( "\n" );
43337
43338         for ( var i = 0, il = chunks.length; i < il; i ++ ) {
43339
43340             // Chrome reports shader errors on lines
43341             // starting counting from 1
43342
43343             chunks[ i ] = ( i + 1 ) + ": " + chunks[ i ];
43344
43345         }
43346
43347         return chunks.join( "\n" );
43348
43349     };
43350
43351     function getShader ( type, string ) {
43352
43353         var shader;
43354
43355         if ( type === "fragment" ) {
43356
43357             shader = _gl.createShader( _gl.FRAGMENT_SHADER );
43358
43359         } else if ( type === "vertex" ) {
43360
43361             shader = _gl.createShader( _gl.VERTEX_SHADER );
43362
43363         }
43364
43365         _gl.shaderSource( shader, string );
43366         _gl.compileShader( shader );
43367
43368         if ( !_gl.getShaderParameter( shader, _gl.COMPILE_STATUS ) ) {
43369
43370             console.error( _gl.getShaderInfoLog( shader ) );
43371             console.error( addLineNumbers( string ) );
43372             return null;
43373
43374         }
43375
43376         return shader;
43377
43378     };
43379
43380     // Textures
43381
43382
43383     function isPowerOfTwo ( value ) {
43384
43385         return ( value & ( value - 1 ) ) === 0;
43386
43387     };
43388
43389     function setTextureParameters ( textureType, texture, isImagePowerOfTwo ) {
43390
43391         if ( isImagePowerOfTwo ) {
43392
43393             _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
43394             _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
43395
43396             _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
43397             _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
43398
43399         } else {
43400
43401             _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
43402             _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
43403
43404             _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
43405             _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
43406
43407         }
43408
43409         if ( _glExtensionTextureFilterAnisotropic && texture.type !== THREE.FloatType ) {
43410
43411             if ( texture.anisotropy > 1 || texture.__oldAnisotropy ) {
43412
43413                 _gl.texParameterf( textureType, _glExtensionTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _maxAnisotropy ) );
43414                 texture.__oldAnisotropy = texture.anisotropy;
43415
43416             }
43417
43418         }
43419
43420     };
43421
43422     this.setTexture = function ( texture, slot ) {
43423
43424         if ( texture.needsUpdate ) {
43425
43426             if ( ! texture.__webglInit ) {
43427
43428                 texture.__webglInit = true;
43429                 texture.__webglTexture = _gl.createTexture();
43430
43431                 _this.info.memory.textures ++;
43432
43433             }
43434
43435             _gl.activeTexture( _gl.TEXTURE0 + slot );
43436             _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
43437
43438             _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
43439             _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
43440
43441             var image = texture.image,
43442             isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
43443             glFormat = paramThreeToGL( texture.format ),
43444             glType = paramThreeToGL( texture.type );
43445
43446             setTextureParameters( _gl.TEXTURE_2D, texture, isImagePowerOfTwo );
43447
43448             if ( texture instanceof THREE.CompressedTexture ) {
43449
43450                 var mipmap, mipmaps = texture.mipmaps;
43451
43452                 for( var i = 0, il = mipmaps.length; i < il; i ++ ) {
43453
43454                     mipmap = mipmaps[ i ];
43455                     _gl.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
43456
43457                 }
43458
43459             } else if ( texture instanceof THREE.DataTexture ) {
43460
43461                 _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
43462
43463             } else {
43464
43465                 _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, texture.image );
43466
43467             }
43468
43469             if ( texture.generateMipmaps && isImagePowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
43470
43471             texture.needsUpdate = false;
43472
43473             if ( texture.onUpdate ) texture.onUpdate();
43474
43475         } else {
43476
43477             _gl.activeTexture( _gl.TEXTURE0 + slot );
43478             _gl.bindTexture( _gl.TEXTURE_2D, texture.__webglTexture );
43479
43480         }
43481
43482     };
43483
43484     function clampToMaxSize ( image, maxSize ) {
43485
43486         if ( image.width <= maxSize && image.height <= maxSize ) {
43487
43488             return image;
43489
43490         }
43491
43492         // Warning: Scaling through the canvas will only work with images that use
43493         // premultiplied alpha.
43494
43495         var maxDimension = Math.max( image.width, image.height );
43496         var newWidth = Math.floor( image.width * maxSize / maxDimension );
43497         var newHeight = Math.floor( image.height * maxSize / maxDimension );
43498
43499         var canvas = document.createElement( 'canvas' );
43500         canvas.width = newWidth;
43501         canvas.height = newHeight;
43502
43503         var ctx = canvas.getContext( "2d" );
43504         ctx.drawImage( image, 0, 0, image.width, image.height, 0, 0, newWidth, newHeight );
43505
43506         return canvas;
43507
43508     }
43509
43510     function setCubeTexture ( texture, slot ) {
43511
43512         if ( texture.image.length === 6 ) {
43513
43514             if ( texture.needsUpdate ) {
43515
43516                 if ( ! texture.image.__webglTextureCube ) {
43517
43518                     texture.image.__webglTextureCube = _gl.createTexture();
43519
43520                 }
43521
43522                 _gl.activeTexture( _gl.TEXTURE0 + slot );
43523                 _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
43524
43525                 _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
43526
43527                 var isCompressed = texture instanceof THREE.CompressedTexture;
43528
43529                 var cubeImage = [];
43530
43531                 for ( var i = 0; i < 6; i ++ ) {
43532
43533                     if ( _this.autoScaleCubemaps && ! isCompressed ) {
43534
43535                         cubeImage[ i ] = clampToMaxSize( texture.image[ i ], _maxCubemapSize );
43536
43537                     } else {
43538
43539                         cubeImage[ i ] = texture.image[ i ];
43540
43541                     }
43542
43543                 }
43544
43545                 var image = cubeImage[ 0 ],
43546                 isImagePowerOfTwo = isPowerOfTwo( image.width ) && isPowerOfTwo( image.height ),
43547                 glFormat = paramThreeToGL( texture.format ),
43548                 glType = paramThreeToGL( texture.type );
43549
43550                 setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isImagePowerOfTwo );
43551
43552                 for ( var i = 0; i < 6; i ++ ) {
43553
43554                     if ( isCompressed ) {
43555
43556                         var mipmap, mipmaps = cubeImage[ i ].mipmaps;
43557
43558                         for( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
43559
43560                             mipmap = mipmaps[ j ];
43561                             _gl.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
43562
43563                         }
43564
43565                     } else {
43566
43567                         _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
43568
43569                     }
43570
43571                 }
43572
43573                 if ( texture.generateMipmaps && isImagePowerOfTwo ) {
43574
43575                     _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
43576
43577                 }
43578
43579                 texture.needsUpdate = false;
43580
43581                 if ( texture.onUpdate ) texture.onUpdate();
43582
43583             } else {
43584
43585                 _gl.activeTexture( _gl.TEXTURE0 + slot );
43586                 _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webglTextureCube );
43587
43588             }
43589
43590         }
43591
43592     };
43593
43594     function setCubeTextureDynamic ( texture, slot ) {
43595
43596         _gl.activeTexture( _gl.TEXTURE0 + slot );
43597         _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.__webglTexture );
43598
43599     };
43600
43601     // Render targets
43602
43603     function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
43604
43605         _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
43606         _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, renderTarget.__webglTexture, 0 );
43607
43608     };
43609
43610     function setupRenderBuffer ( renderbuffer, renderTarget  ) {
43611
43612         _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
43613
43614         if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
43615
43616             _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
43617             _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
43618
43619         /* For some reason this is not working. Defaulting to RGBA4.
43620         } else if( ! renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
43621
43622             _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.STENCIL_INDEX8, renderTarget.width, renderTarget.height );
43623             _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
43624         */
43625         } else if( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
43626
43627             _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
43628             _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
43629
43630         } else {
43631
43632             _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
43633
43634         }
43635
43636     };
43637
43638     this.setRenderTarget = function ( renderTarget ) {
43639
43640         var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
43641
43642         if ( renderTarget && ! renderTarget.__webglFramebuffer ) {
43643
43644             if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
43645             if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
43646
43647             renderTarget.__webglTexture = _gl.createTexture();
43648
43649             // Setup texture, create render and frame buffers
43650
43651             var isTargetPowerOfTwo = isPowerOfTwo( renderTarget.width ) && isPowerOfTwo( renderTarget.height ),
43652                 glFormat = paramThreeToGL( renderTarget.format ),
43653                 glType = paramThreeToGL( renderTarget.type );
43654
43655             if ( isCube ) {
43656
43657                 renderTarget.__webglFramebuffer = [];
43658                 renderTarget.__webglRenderbuffer = [];
43659
43660                 _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
43661                 setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
43662
43663                 for ( var i = 0; i < 6; i ++ ) {
43664
43665                     renderTarget.__webglFramebuffer[ i ] = _gl.createFramebuffer();
43666                     renderTarget.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
43667
43668                     _gl.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
43669
43670                     setupFrameBuffer( renderTarget.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
43671                     setupRenderBuffer( renderTarget.__webglRenderbuffer[ i ], renderTarget );
43672
43673                 }
43674
43675                 if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
43676
43677             } else {
43678
43679                 renderTarget.__webglFramebuffer = _gl.createFramebuffer();
43680                 renderTarget.__webglRenderbuffer = _gl.createRenderbuffer();
43681
43682                 _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
43683                 setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
43684
43685                 _gl.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
43686
43687                 setupFrameBuffer( renderTarget.__webglFramebuffer, renderTarget, _gl.TEXTURE_2D );
43688                 setupRenderBuffer( renderTarget.__webglRenderbuffer, renderTarget );
43689
43690                 if ( isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
43691
43692             }
43693
43694             // Release everything
43695
43696             if ( isCube ) {
43697
43698                 _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
43699
43700             } else {
43701
43702                 _gl.bindTexture( _gl.TEXTURE_2D, null );
43703
43704             }
43705
43706             _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
43707             _gl.bindFramebuffer( _gl.FRAMEBUFFER, null);
43708
43709         }
43710
43711         var framebuffer, width, height, vx, vy;
43712
43713         if ( renderTarget ) {
43714
43715             if ( isCube ) {
43716
43717                 framebuffer = renderTarget.__webglFramebuffer[ renderTarget.activeCubeFace ];
43718
43719             } else {
43720
43721                 framebuffer = renderTarget.__webglFramebuffer;
43722
43723             }
43724
43725             width = renderTarget.width;
43726             height = renderTarget.height;
43727
43728             vx = 0;
43729             vy = 0;
43730
43731         } else {
43732
43733             framebuffer = null;
43734
43735             width = _viewportWidth;
43736             height = _viewportHeight;
43737
43738             vx = _viewportX;
43739             vy = _viewportY;
43740
43741         }
43742
43743         if ( framebuffer !== _currentFramebuffer ) {
43744
43745             _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
43746             _gl.viewport( vx, vy, width, height );
43747
43748             _currentFramebuffer = framebuffer;
43749
43750         }
43751
43752         _currentWidth = width;
43753         _currentHeight = height;
43754
43755     };
43756
43757     function updateRenderTargetMipmap ( renderTarget ) {
43758
43759         if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
43760
43761             _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTarget.__webglTexture );
43762             _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
43763             _gl.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
43764
43765         } else {
43766
43767             _gl.bindTexture( _gl.TEXTURE_2D, renderTarget.__webglTexture );
43768             _gl.generateMipmap( _gl.TEXTURE_2D );
43769             _gl.bindTexture( _gl.TEXTURE_2D, null );
43770
43771         }
43772
43773     };
43774
43775     // Fallback filters for non-power-of-2 textures
43776
43777     function filterFallback ( f ) {
43778
43779         if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
43780
43781             return _gl.NEAREST;
43782
43783         }
43784
43785         return _gl.LINEAR;
43786
43787     };
43788
43789     // Map three.js constants to WebGL constants
43790
43791     function paramThreeToGL ( p ) {
43792
43793         if ( p === THREE.RepeatWrapping ) return _gl.REPEAT;
43794         if ( p === THREE.ClampToEdgeWrapping ) return _gl.CLAMP_TO_EDGE;
43795         if ( p === THREE.MirroredRepeatWrapping ) return _gl.MIRRORED_REPEAT;
43796
43797         if ( p === THREE.NearestFilter ) return _gl.NEAREST;
43798         if ( p === THREE.NearestMipMapNearestFilter ) return _gl.NEAREST_MIPMAP_NEAREST;
43799         if ( p === THREE.NearestMipMapLinearFilter ) return _gl.NEAREST_MIPMAP_LINEAR;
43800
43801         if ( p === THREE.LinearFilter ) return _gl.LINEAR;
43802         if ( p === THREE.LinearMipMapNearestFilter ) return _gl.LINEAR_MIPMAP_NEAREST;
43803         if ( p === THREE.LinearMipMapLinearFilter ) return _gl.LINEAR_MIPMAP_LINEAR;
43804
43805         if ( p === THREE.UnsignedByteType ) return _gl.UNSIGNED_BYTE;
43806         if ( p === THREE.UnsignedShort4444Type ) return _gl.UNSIGNED_SHORT_4_4_4_4;
43807         if ( p === THREE.UnsignedShort5551Type ) return _gl.UNSIGNED_SHORT_5_5_5_1;
43808         if ( p === THREE.UnsignedShort565Type ) return _gl.UNSIGNED_SHORT_5_6_5;
43809
43810         if ( p === THREE.ByteType ) return _gl.BYTE;
43811         if ( p === THREE.ShortType ) return _gl.SHORT;
43812         if ( p === THREE.UnsignedShortType ) return _gl.UNSIGNED_SHORT;
43813         if ( p === THREE.IntType ) return _gl.INT;
43814         if ( p === THREE.UnsignedIntType ) return _gl.UNSIGNED_INT;
43815         if ( p === THREE.FloatType ) return _gl.FLOAT;
43816
43817         if ( p === THREE.AlphaFormat ) return _gl.ALPHA;
43818         if ( p === THREE.RGBFormat ) return _gl.RGB;
43819         if ( p === THREE.RGBAFormat ) return _gl.RGBA;
43820         if ( p === THREE.LuminanceFormat ) return _gl.LUMINANCE;
43821         if ( p === THREE.LuminanceAlphaFormat ) return _gl.LUMINANCE_ALPHA;
43822
43823         if ( p === THREE.AddEquation ) return _gl.FUNC_ADD;
43824         if ( p === THREE.SubtractEquation ) return _gl.FUNC_SUBTRACT;
43825         if ( p === THREE.ReverseSubtractEquation ) return _gl.FUNC_REVERSE_SUBTRACT;
43826
43827         if ( p === THREE.ZeroFactor ) return _gl.ZERO;
43828         if ( p === THREE.OneFactor ) return _gl.ONE;
43829         if ( p === THREE.SrcColorFactor ) return _gl.SRC_COLOR;
43830         if ( p === THREE.OneMinusSrcColorFactor ) return _gl.ONE_MINUS_SRC_COLOR;
43831         if ( p === THREE.SrcAlphaFactor ) return _gl.SRC_ALPHA;
43832         if ( p === THREE.OneMinusSrcAlphaFactor ) return _gl.ONE_MINUS_SRC_ALPHA;
43833         if ( p === THREE.DstAlphaFactor ) return _gl.DST_ALPHA;
43834         if ( p === THREE.OneMinusDstAlphaFactor ) return _gl.ONE_MINUS_DST_ALPHA;
43835
43836         if ( p === THREE.DstColorFactor ) return _gl.DST_COLOR;
43837         if ( p === THREE.OneMinusDstColorFactor ) return _gl.ONE_MINUS_DST_COLOR;
43838         if ( p === THREE.SrcAlphaSaturateFactor ) return _gl.SRC_ALPHA_SATURATE;
43839
43840         if ( _glExtensionCompressedTextureS3TC !== undefined ) {
43841
43842             if ( p === THREE.RGB_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGB_S3TC_DXT1_EXT;
43843             if ( p === THREE.RGBA_S3TC_DXT1_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT1_EXT;
43844             if ( p === THREE.RGBA_S3TC_DXT3_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT3_EXT;
43845             if ( p === THREE.RGBA_S3TC_DXT5_Format ) return _glExtensionCompressedTextureS3TC.COMPRESSED_RGBA_S3TC_DXT5_EXT;
43846
43847         }
43848
43849         return 0;
43850
43851     };
43852
43853     // Allocations
43854
43855     function allocateBones ( object ) {
43856
43857         if ( _supportsBoneTextures && object && object.useVertexTexture ) {
43858
43859             return 1024;
43860
43861         } else {
43862
43863             // default for when object is not specified
43864             // ( for example when prebuilding shader
43865             //   to be used with multiple objects )
43866             //
43867             //     - leave some extra space for other uniforms
43868             //  - limit here is ANGLE's 254 max uniform vectors
43869             //    (up to 54 should be safe)
43870
43871             var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
43872             var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );
43873
43874             var maxBones = nVertexMatrices;
43875
43876             if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {
43877
43878                 maxBones = Math.min( object.bones.length, maxBones );
43879
43880                 if ( maxBones < object.bones.length ) {
43881
43882                     console.warn( "WebGLRenderer: too many bones - " + object.bones.length + ", this GPU supports just " + maxBones + " (try OpenGL instead of ANGLE)" );
43883
43884                 }
43885
43886             }
43887
43888             return maxBones;
43889
43890         }
43891
43892     };
43893
43894     function allocateLights ( lights ) {
43895
43896         var l, ll, light, dirLights, pointLights, spotLights, hemiLights, maxDirLights, maxPointLights, maxSpotLights, maxHemiLights;
43897
43898         dirLights = pointLights = spotLights = hemiLights = maxDirLights = maxPointLights = maxSpotLights = maxHemiLights = 0;
43899
43900         for ( l = 0, ll = lights.length; l < ll; l ++ ) {
43901
43902             light = lights[ l ];
43903
43904             if ( light.onlyShadow ) continue;
43905
43906             if ( light instanceof THREE.DirectionalLight ) dirLights ++;
43907             if ( light instanceof THREE.PointLight ) pointLights ++;
43908             if ( light instanceof THREE.SpotLight ) spotLights ++;
43909             if ( light instanceof THREE.HemisphereLight ) hemiLights ++;
43910
43911         }
43912
43913         if ( ( pointLights + spotLights + dirLights + hemiLights) <= _maxLights ) {
43914
43915             maxDirLights = dirLights;
43916             maxPointLights = pointLights;
43917             maxSpotLights = spotLights;
43918             maxHemiLights = hemiLights;
43919
43920         } else {
43921
43922             maxDirLights = Math.ceil( _maxLights * dirLights / ( pointLights + dirLights ) );
43923             maxPointLights = _maxLights - maxDirLights;
43924
43925             // these are not really correct
43926
43927             maxSpotLights = maxPointLights;
43928             maxHemiLights = maxDirLights;
43929
43930         }
43931
43932         return { 'directional' : maxDirLights, 'point' : maxPointLights, 'spot': maxSpotLights, 'hemi': maxHemiLights };
43933
43934     };
43935
43936     function allocateShadows ( lights ) {
43937
43938         var l, ll, light, maxShadows = 0;
43939
43940         for ( l = 0, ll = lights.length; l < ll; l++ ) {
43941
43942             light = lights[ l ];
43943
43944             if ( ! light.castShadow ) continue;
43945
43946             if ( light instanceof THREE.SpotLight ) maxShadows ++;
43947             if ( light instanceof THREE.DirectionalLight && ! light.shadowCascade ) maxShadows ++;
43948
43949         }
43950
43951         return maxShadows;
43952
43953     };
43954
43955     // Initialization
43956
43957     function initGL () {
43958
43959         try {
43960
43961             if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { alpha: _alpha, premultipliedAlpha: _premultipliedAlpha, antialias: _antialias, stencil: _stencil, preserveDrawingBuffer: _preserveDrawingBuffer } ) ) ) {
43962
43963                 throw 'Error creating WebGL context.';
43964
43965             }
43966
43967         } catch ( error ) {
43968
43969             console.error( error );
43970
43971         }
43972
43973         _glExtensionTextureFloat = _gl.getExtension( 'OES_texture_float' );
43974         _glExtensionStandardDerivatives = _gl.getExtension( 'OES_standard_derivatives' );
43975
43976         _glExtensionTextureFilterAnisotropic = _gl.getExtension( 'EXT_texture_filter_anisotropic' ) ||
43977                                                _gl.getExtension( 'MOZ_EXT_texture_filter_anisotropic' ) ||
43978                                                _gl.getExtension( 'WEBKIT_EXT_texture_filter_anisotropic' );
43979
43980
43981         _glExtensionCompressedTextureS3TC = _gl.getExtension( 'WEBGL_compressed_texture_s3tc' ) ||
43982                                             _gl.getExtension( 'MOZ_WEBGL_compressed_texture_s3tc' ) ||
43983                                             _gl.getExtension( 'WEBKIT_WEBGL_compressed_texture_s3tc' );
43984
43985         if ( ! _glExtensionTextureFloat ) {
43986
43987             console.log( 'THREE.WebGLRenderer: Float textures not supported.' );
43988
43989         }
43990
43991         if ( ! _glExtensionStandardDerivatives ) {
43992
43993             console.log( 'THREE.WebGLRenderer: Standard derivatives not supported.' );
43994
43995         }
43996
43997         if ( ! _glExtensionTextureFilterAnisotropic ) {
43998
43999             console.log( 'THREE.WebGLRenderer: Anisotropic texture filtering not supported.' );
44000
44001         }
44002
44003         if ( ! _glExtensionCompressedTextureS3TC ) {
44004
44005             console.log( 'THREE.WebGLRenderer: S3TC compressed textures not supported.' );
44006
44007         }
44008
44009     };
44010
44011     function setDefaultGLState () {
44012
44013         _gl.clearColor( 0, 0, 0, 1 );
44014         _gl.clearDepth( 1 );
44015         _gl.clearStencil( 0 );
44016
44017         _gl.enable( _gl.DEPTH_TEST );
44018         _gl.depthFunc( _gl.LEQUAL );
44019
44020         _gl.frontFace( _gl.CCW );
44021         _gl.cullFace( _gl.BACK );
44022         _gl.enable( _gl.CULL_FACE );
44023
44024         _gl.enable( _gl.BLEND );
44025         _gl.blendEquation( _gl.FUNC_ADD );
44026         _gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
44027
44028         _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
44029
44030     };
44031
44032     // default plugins (order is important)
44033
44034     this.shadowMapPlugin = new THREE.ShadowMapPlugin();
44035     this.addPrePlugin( this.shadowMapPlugin );
44036
44037     this.addPostPlugin( new THREE.SpritePlugin() );
44038     this.addPostPlugin( new THREE.LensFlarePlugin() );
44039
44040 };
44041 /**
44042  * @author szimek / https://github.com/szimek/
44043  * @author alteredq / http://alteredqualia.com/
44044  */
44045
44046 THREE.WebGLRenderTarget = function ( width, height, options ) {
44047
44048     this.width = width;
44049     this.height = height;
44050
44051     options = options || {};
44052
44053     this.wrapS = options.wrapS !== undefined ? options.wrapS : THREE.ClampToEdgeWrapping;
44054     this.wrapT = options.wrapT !== undefined ? options.wrapT : THREE.ClampToEdgeWrapping;
44055
44056     this.magFilter = options.magFilter !== undefined ? options.magFilter : THREE.LinearFilter;
44057     this.minFilter = options.minFilter !== undefined ? options.minFilter : THREE.LinearMipMapLinearFilter;
44058
44059     this.anisotropy = options.anisotropy !== undefined ? options.anisotropy : 1;
44060
44061     this.offset = new THREE.Vector2( 0, 0 );
44062     this.repeat = new THREE.Vector2( 1, 1 );
44063
44064     this.format = options.format !== undefined ? options.format : THREE.RGBAFormat;
44065     this.type = options.type !== undefined ? options.type : THREE.UnsignedByteType;
44066
44067     this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
44068     this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : true;
44069
44070     this.generateMipmaps = true;
44071
44072 };
44073
44074 THREE.WebGLRenderTarget.prototype.clone = function() {
44075
44076     var tmp = new THREE.WebGLRenderTarget( this.width, this.height );
44077
44078     tmp.wrapS = this.wrapS;
44079     tmp.wrapT = this.wrapT;
44080
44081     tmp.magFilter = this.magFilter;
44082     tmp.anisotropy = this.anisotropy;
44083
44084     tmp.minFilter = this.minFilter;
44085
44086     tmp.offset.copy( this.offset );
44087     tmp.repeat.copy( this.repeat );
44088
44089     tmp.format = this.format;
44090     tmp.type = this.type;
44091
44092     tmp.depthBuffer = this.depthBuffer;
44093     tmp.stencilBuffer = this.stencilBuffer;
44094
44095     tmp.generateMipmaps = this.generateMipmaps;
44096
44097     return tmp;
44098
44099 };
44100 /**
44101  * @author alteredq / http://alteredqualia.com
44102  */
44103
44104 THREE.WebGLRenderTargetCube = function ( width, height, options ) {
44105
44106     THREE.WebGLRenderTarget.call( this, width, height, options );
44107
44108     this.activeCubeFace = 0; // PX 0, NX 1, PY 2, NY 3, PZ 4, NZ 5
44109
44110 };
44111
44112 THREE.WebGLRenderTargetCube.prototype = Object.create( THREE.WebGLRenderTarget.prototype );
44113 /**
44114  * @author mrdoob / http://mrdoob.com/
44115  */
44116
44117 THREE.RenderableVertex = function () {
44118
44119     this.positionWorld = new THREE.Vector3();
44120     this.positionScreen = new THREE.Vector4();
44121
44122     this.visible = true;
44123
44124 };
44125
44126 THREE.RenderableVertex.prototype.copy = function ( vertex ) {
44127
44128     this.positionWorld.copy( vertex.positionWorld );
44129     this.positionScreen.copy( vertex.positionScreen );
44130
44131 }
44132 /**
44133  * @author mrdoob / http://mrdoob.com/
44134  */
44135
44136 THREE.RenderableFace3 = function () {
44137
44138     this.v1 = new THREE.RenderableVertex();
44139     this.v2 = new THREE.RenderableVertex();
44140     this.v3 = new THREE.RenderableVertex();
44141
44142     this.centroidWorld = new THREE.Vector3();
44143     this.centroidScreen = new THREE.Vector3();
44144
44145     this.normalWorld = new THREE.Vector3();
44146     this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
44147     this.vertexNormalsLength = 0;
44148
44149     this.material = null;
44150     this.uvs = [[]];
44151
44152     this.z = null;
44153
44154 };
44155 /**
44156  * @author mrdoob / http://mrdoob.com/
44157  */
44158
44159 THREE.RenderableFace4 = function () {
44160
44161     this.v1 = new THREE.RenderableVertex();
44162     this.v2 = new THREE.RenderableVertex();
44163     this.v3 = new THREE.RenderableVertex();
44164     this.v4 = new THREE.RenderableVertex();
44165
44166     this.centroidWorld = new THREE.Vector3();
44167     this.centroidScreen = new THREE.Vector3();
44168
44169     this.normalWorld = new THREE.Vector3();
44170     this.vertexNormalsWorld = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
44171     this.vertexNormalsLength = 0;
44172
44173     this.material = null;
44174     this.uvs = [[]];
44175
44176     this.z = null;
44177
44178 };
44179 /**
44180  * @author mrdoob / http://mrdoob.com/
44181  */
44182
44183 THREE.RenderableObject = function () {
44184
44185     this.object = null;
44186     this.z = null;
44187
44188 };
44189 /**
44190  * @author mrdoob / http://mrdoob.com/
44191  */
44192
44193 THREE.RenderableParticle = function () {
44194
44195     this.object = null;
44196
44197     this.x = null;
44198     this.y = null;
44199     this.z = null;
44200
44201     this.rotation = null;
44202     this.scale = new THREE.Vector2();
44203
44204     this.material = null;
44205
44206 };
44207 /**
44208  * @author mrdoob / http://mrdoob.com/
44209  */
44210
44211 THREE.RenderableLine = function () {
44212
44213     this.z = null;
44214
44215     this.v1 = new THREE.RenderableVertex();
44216     this.v2 = new THREE.RenderableVertex();
44217
44218     this.material = null;
44219
44220 };
44221 /**
44222  * @author alteredq / http://alteredqualia.com/
44223  */
44224
44225 THREE.ColorUtils = {
44226
44227     adjustHSV : function ( color, h, s, v ) {
44228
44229         var hsv = THREE.ColorUtils.__hsv;
44230
44231         THREE.ColorUtils.rgbToHsv( color, hsv );
44232
44233         hsv.h = THREE.Math.clamp( hsv.h + h, 0, 1 );
44234         hsv.s = THREE.Math.clamp( hsv.s + s, 0, 1 );
44235         hsv.v = THREE.Math.clamp( hsv.v + v, 0, 1 );
44236
44237         color.setHSV( hsv.h, hsv.s, hsv.v );
44238
44239     },
44240
44241     // based on MochiKit implementation by Bob Ippolito
44242
44243     rgbToHsv : function ( color, hsv ) {
44244
44245         var r = color.r;
44246         var g = color.g;
44247         var b = color.b;
44248
44249         var max = Math.max( Math.max( r, g ), b );
44250         var min = Math.min( Math.min( r, g ), b );
44251
44252         var hue;
44253         var saturation;
44254         var value = max;
44255
44256         if ( min === max )    {
44257
44258             hue = 0;
44259             saturation = 0;
44260
44261         } else {
44262
44263             var delta = ( max - min );
44264             saturation = delta / max;
44265
44266             if ( r === max ) {
44267
44268                 hue = ( g - b ) / delta;
44269
44270             } else if ( g === max ) {
44271
44272                 hue = 2 + ( ( b - r ) / delta );
44273
44274             } else    {
44275
44276                 hue = 4 + ( ( r - g ) / delta );
44277             }
44278
44279             hue /= 6;
44280
44281             if ( hue < 0 ) {
44282
44283                 hue += 1;
44284
44285             }
44286
44287             if ( hue > 1 ) {
44288
44289                 hue -= 1;
44290
44291             }
44292
44293         }
44294
44295         if ( hsv === undefined ) {
44296
44297             hsv = { h: 0, s: 0, v: 0 };
44298
44299         }
44300
44301         hsv.h = hue;
44302         hsv.s = saturation;
44303         hsv.v = value;
44304
44305         return hsv;
44306
44307     }
44308
44309 };
44310
44311 THREE.ColorUtils.__hsv = { h: 0, s: 0, v: 0 };/**
44312  * @author mrdoob / http://mrdoob.com/
44313  * @author alteredq / http://alteredqualia.com/
44314  */
44315
44316 THREE.GeometryUtils = {
44317
44318     // Merge two geometries or geometry and geometry from object (using object's transform)
44319
44320     merge: function ( geometry1, object2 /* mesh | geometry */ ) {
44321
44322         var matrix, matrixRotation,
44323         vertexOffset = geometry1.vertices.length,
44324         uvPosition = geometry1.faceVertexUvs[ 0 ].length,
44325         geometry2 = object2 instanceof THREE.Mesh ? object2.geometry : object2,
44326         vertices1 = geometry1.vertices,
44327         vertices2 = geometry2.vertices,
44328         faces1 = geometry1.faces,
44329         faces2 = geometry2.faces,
44330         uvs1 = geometry1.faceVertexUvs[ 0 ],
44331         uvs2 = geometry2.faceVertexUvs[ 0 ];
44332
44333         var geo1MaterialsMap = {};
44334
44335         for ( var i = 0; i < geometry1.materials.length; i ++ ) {
44336
44337             var id = geometry1.materials[ i ].id;
44338
44339             geo1MaterialsMap[ id ] = i;
44340
44341         }
44342
44343         if ( object2 instanceof THREE.Mesh ) {
44344
44345             object2.matrixAutoUpdate && object2.updateMatrix();
44346
44347             matrix = object2.matrix;
44348             matrixRotation = new THREE.Matrix4();
44349             matrixRotation.extractRotation( matrix, object2.scale );
44350
44351         }
44352
44353         // vertices
44354
44355         for ( var i = 0, il = vertices2.length; i < il; i ++ ) {
44356
44357             var vertex = vertices2[ i ];
44358
44359             var vertexCopy = vertex.clone();
44360
44361             if ( matrix ) matrix.multiplyVector3( vertexCopy );
44362
44363             vertices1.push( vertexCopy );
44364
44365         }
44366
44367         // faces
44368
44369         for ( i = 0, il = faces2.length; i < il; i ++ ) {
44370
44371             var face = faces2[ i ], faceCopy, normal, color,
44372             faceVertexNormals = face.vertexNormals,
44373             faceVertexColors = face.vertexColors;
44374
44375             if ( face instanceof THREE.Face3 ) {
44376
44377                 faceCopy = new THREE.Face3( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset );
44378
44379             } else if ( face instanceof THREE.Face4 ) {
44380
44381                 faceCopy = new THREE.Face4( face.a + vertexOffset, face.b + vertexOffset, face.c + vertexOffset, face.d + vertexOffset );
44382
44383             }
44384
44385             faceCopy.normal.copy( face.normal );
44386
44387             if ( matrixRotation ) matrixRotation.multiplyVector3( faceCopy.normal );
44388
44389             for ( var j = 0, jl = faceVertexNormals.length; j < jl; j ++ ) {
44390
44391                 normal = faceVertexNormals[ j ].clone();
44392
44393                 if ( matrixRotation ) matrixRotation.multiplyVector3( normal );
44394
44395                 faceCopy.vertexNormals.push( normal );
44396
44397             }
44398
44399             faceCopy.color.copy( face.color );
44400
44401             for ( var j = 0, jl = faceVertexColors.length; j < jl; j ++ ) {
44402
44403                 color = faceVertexColors[ j ];
44404                 faceCopy.vertexColors.push( color.clone() );
44405
44406             }
44407
44408             if ( face.materialIndex !== undefined ) {
44409
44410                 var material2 = geometry2.materials[ face.materialIndex ];
44411                 var materialId2 = material2.id;
44412
44413                 var materialIndex = geo1MaterialsMap[ materialId2 ];
44414
44415                 if ( materialIndex === undefined ) {
44416
44417                     materialIndex = geometry1.materials.length;
44418                     geo1MaterialsMap[ materialId2 ] = materialIndex;
44419
44420                     geometry1.materials.push( material2 );
44421
44422                 }
44423
44424                 faceCopy.materialIndex = materialIndex;
44425
44426             }
44427
44428             faceCopy.centroid.copy( face.centroid );
44429             if ( matrix ) matrix.multiplyVector3( faceCopy.centroid );
44430
44431             faces1.push( faceCopy );
44432
44433         }
44434
44435         // uvs
44436
44437         for ( i = 0, il = uvs2.length; i < il; i ++ ) {
44438
44439             var uv = uvs2[ i ], uvCopy = [];
44440
44441             for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
44442
44443                 uvCopy.push( new THREE.UV( uv[ j ].u, uv[ j ].v ) );
44444
44445             }
44446
44447             uvs1.push( uvCopy );
44448
44449         }
44450
44451     },
44452
44453     clone: function ( geometry ) {
44454
44455         var cloneGeo = new THREE.Geometry();
44456
44457         var i, il;
44458
44459         var vertices = geometry.vertices,
44460             faces = geometry.faces,
44461             uvs = geometry.faceVertexUvs[ 0 ];
44462
44463         // materials
44464
44465         if ( geometry.materials ) {
44466
44467             cloneGeo.materials = geometry.materials.slice();
44468
44469         }
44470
44471         // vertices
44472
44473         for ( i = 0, il = vertices.length; i < il; i ++ ) {
44474
44475             var vertex = vertices[ i ];
44476
44477             cloneGeo.vertices.push( vertex.clone() );
44478
44479         }
44480
44481         // faces
44482
44483         for ( i = 0, il = faces.length; i < il; i ++ ) {
44484
44485             var face = faces[ i ];
44486
44487             cloneGeo.faces.push( face.clone() );
44488
44489         }
44490
44491         // uvs
44492
44493         for ( i = 0, il = uvs.length; i < il; i ++ ) {
44494
44495             var uv = uvs[ i ], uvCopy = [];
44496
44497             for ( var j = 0, jl = uv.length; j < jl; j ++ ) {
44498
44499                 uvCopy.push( new THREE.UV( uv[ j ].u, uv[ j ].v ) );
44500
44501             }
44502
44503             cloneGeo.faceVertexUvs[ 0 ].push( uvCopy );
44504
44505         }
44506
44507         return cloneGeo;
44508
44509     },
44510
44511     // Get random point in triangle (via barycentric coordinates)
44512     //     (uniform distribution)
44513     //     http://www.cgafaq.info/wiki/Random_Point_In_Triangle
44514
44515     randomPointInTriangle: function ( vectorA, vectorB, vectorC ) {
44516
44517         var a, b, c,
44518             point = new THREE.Vector3(),
44519             tmp = THREE.GeometryUtils.__v1;
44520
44521         a = THREE.GeometryUtils.random();
44522         b = THREE.GeometryUtils.random();
44523
44524         if ( ( a + b ) > 1 ) {
44525
44526             a = 1 - a;
44527             b = 1 - b;
44528
44529         }
44530
44531         c = 1 - a - b;
44532
44533         point.copy( vectorA );
44534         point.multiplyScalar( a );
44535
44536         tmp.copy( vectorB );
44537         tmp.multiplyScalar( b );
44538
44539         point.addSelf( tmp );
44540
44541         tmp.copy( vectorC );
44542         tmp.multiplyScalar( c );
44543
44544         point.addSelf( tmp );
44545
44546         return point;
44547
44548     },
44549
44550     // Get random point in face (triangle / quad)
44551     // (uniform distribution)
44552
44553     randomPointInFace: function ( face, geometry, useCachedAreas ) {
44554
44555         var vA, vB, vC, vD;
44556
44557         if ( face instanceof THREE.Face3 ) {
44558
44559             vA = geometry.vertices[ face.a ];
44560             vB = geometry.vertices[ face.b ];
44561             vC = geometry.vertices[ face.c ];
44562
44563             return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC );
44564
44565         } else if ( face instanceof THREE.Face4 ) {
44566
44567             vA = geometry.vertices[ face.a ];
44568             vB = geometry.vertices[ face.b ];
44569             vC = geometry.vertices[ face.c ];
44570             vD = geometry.vertices[ face.d ];
44571
44572             var area1, area2;
44573
44574             if ( useCachedAreas ) {
44575
44576                 if ( face._area1 && face._area2 ) {
44577
44578                     area1 = face._area1;
44579                     area2 = face._area2;
44580
44581                 } else {
44582
44583                     area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD );
44584                     area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
44585
44586                     face._area1 = area1;
44587                     face._area2 = area2;
44588
44589                 }
44590
44591             } else {
44592
44593                 area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD ),
44594                 area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
44595
44596             }
44597
44598             var r = THREE.GeometryUtils.random() * ( area1 + area2 );
44599
44600             if ( r < area1 ) {
44601
44602                 return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vD );
44603
44604             } else {
44605
44606                 return THREE.GeometryUtils.randomPointInTriangle( vB, vC, vD );
44607
44608             }
44609
44610         }
44611
44612     },
44613
44614     // Get uniformly distributed random points in mesh
44615     //     - create array with cumulative sums of face areas
44616     //  - pick random number from 0 to total area
44617     //  - find corresponding place in area array by binary search
44618     //    - get random point in face
44619
44620     randomPointsInGeometry: function ( geometry, n ) {
44621
44622         var face, i,
44623             faces = geometry.faces,
44624             vertices = geometry.vertices,
44625             il = faces.length,
44626             totalArea = 0,
44627             cumulativeAreas = [],
44628             vA, vB, vC, vD;
44629
44630         // precompute face areas
44631
44632         for ( i = 0; i < il; i ++ ) {
44633
44634             face = faces[ i ];
44635
44636             if ( face instanceof THREE.Face3 ) {
44637
44638                 vA = vertices[ face.a ];
44639                 vB = vertices[ face.b ];
44640                 vC = vertices[ face.c ];
44641
44642                 face._area = THREE.GeometryUtils.triangleArea( vA, vB, vC );
44643
44644             } else if ( face instanceof THREE.Face4 ) {
44645
44646                 vA = vertices[ face.a ];
44647                 vB = vertices[ face.b ];
44648                 vC = vertices[ face.c ];
44649                 vD = vertices[ face.d ];
44650
44651                 face._area1 = THREE.GeometryUtils.triangleArea( vA, vB, vD );
44652                 face._area2 = THREE.GeometryUtils.triangleArea( vB, vC, vD );
44653
44654                 face._area = face._area1 + face._area2;
44655
44656             }
44657
44658             totalArea += face._area;
44659
44660             cumulativeAreas[ i ] = totalArea;
44661
44662         }
44663
44664         // binary search cumulative areas array
44665
44666         function binarySearchIndices( value ) {
44667
44668             function binarySearch( start, end ) {
44669
44670                 // return closest larger index
44671                 // if exact number is not found
44672
44673                 if ( end < start )
44674                     return start;
44675
44676                 var mid = start + Math.floor( ( end - start ) / 2 );
44677
44678                 if ( cumulativeAreas[ mid ] > value ) {
44679
44680                     return binarySearch( start, mid - 1 );
44681
44682                 } else if ( cumulativeAreas[ mid ] < value ) {
44683
44684                     return binarySearch( mid + 1, end );
44685
44686                 } else {
44687
44688                     return mid;
44689
44690                 }
44691
44692             }
44693
44694             var result = binarySearch( 0, cumulativeAreas.length - 1 )
44695             return result;
44696
44697         }
44698
44699         // pick random face weighted by face area
44700
44701         var r, index,
44702             result = [];
44703
44704         var stats = {};
44705
44706         for ( i = 0; i < n; i ++ ) {
44707
44708             r = THREE.GeometryUtils.random() * totalArea;
44709
44710             index = binarySearchIndices( r );
44711
44712             result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry, true );
44713
44714             if ( ! stats[ index ] ) {
44715
44716                 stats[ index ] = 1;
44717
44718             } else {
44719
44720                 stats[ index ] += 1;
44721
44722             }
44723
44724         }
44725
44726         return result;
44727
44728     },
44729
44730     // Get triangle area (by Heron's formula)
44731     //     http://en.wikipedia.org/wiki/Heron%27s_formula
44732
44733     triangleArea: function ( vectorA, vectorB, vectorC ) {
44734
44735         var s, a, b, c,
44736             tmp = THREE.GeometryUtils.__v1;
44737
44738         tmp.sub( vectorA, vectorB );
44739         a = tmp.length();
44740
44741         tmp.sub( vectorA, vectorC );
44742         b = tmp.length();
44743
44744         tmp.sub( vectorB, vectorC );
44745         c = tmp.length();
44746
44747         s = 0.5 * ( a + b + c );
44748
44749         return Math.sqrt( s * ( s - a ) * ( s - b ) * ( s - c ) );
44750
44751     },
44752
44753     // Center geometry so that 0,0,0 is in center of bounding box
44754
44755     center: function ( geometry ) {
44756
44757         geometry.computeBoundingBox();
44758
44759         var bb = geometry.boundingBox;
44760
44761         var offset = new THREE.Vector3();
44762
44763         offset.add( bb.min, bb.max );
44764         offset.multiplyScalar( -0.5 );
44765
44766         geometry.applyMatrix( new THREE.Matrix4().makeTranslation( offset.x, offset.y, offset.z ) );
44767         geometry.computeBoundingBox();
44768
44769         return offset;
44770
44771     },
44772
44773     // Normalize UVs to be from <0,1>
44774     // (for now just the first set of UVs)
44775
44776     normalizeUVs: function ( geometry ) {
44777
44778         var uvSet = geometry.faceVertexUvs[ 0 ];
44779
44780         for ( var i = 0, il = uvSet.length; i < il; i ++ ) {
44781
44782             var uvs = uvSet[ i ];
44783
44784             for ( var j = 0, jl = uvs.length; j < jl; j ++ ) {
44785
44786                 // texture repeat
44787
44788                 if( uvs[ j ].u !== 1.0 ) uvs[ j ].u = uvs[ j ].u - Math.floor( uvs[ j ].u );
44789                 if( uvs[ j ].v !== 1.0 ) uvs[ j ].v = uvs[ j ].v - Math.floor( uvs[ j ].v );
44790
44791             }
44792
44793         }
44794
44795     },
44796
44797     triangulateQuads: function ( geometry ) {
44798
44799         var i, il, j, jl;
44800
44801         var faces = [];
44802         var faceUvs = [];
44803         var faceVertexUvs = [];
44804
44805         for ( i = 0, il = geometry.faceUvs.length; i < il; i ++ ) {
44806
44807             faceUvs[ i ] = [];
44808
44809         }
44810
44811         for ( i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
44812
44813             faceVertexUvs[ i ] = [];
44814
44815         }
44816
44817         for ( i = 0, il = geometry.faces.length; i < il; i ++ ) {
44818
44819             var face = geometry.faces[ i ];
44820
44821             if ( face instanceof THREE.Face4 ) {
44822
44823                 var a = face.a;
44824                 var b = face.b;
44825                 var c = face.c;
44826                 var d = face.d;
44827
44828                 var triA = new THREE.Face3();
44829                 var triB = new THREE.Face3();
44830
44831                 triA.color.copy( face.color );
44832                 triB.color.copy( face.color );
44833
44834                 triA.materialIndex = face.materialIndex;
44835                 triB.materialIndex = face.materialIndex;
44836
44837                 triA.a = a;
44838                 triA.b = b;
44839                 triA.c = d;
44840
44841                 triB.a = b;
44842                 triB.b = c;
44843                 triB.c = d;
44844
44845                 if ( face.vertexColors.length === 4 ) {
44846
44847                     triA.vertexColors[ 0 ] = face.vertexColors[ 0 ].clone();
44848                     triA.vertexColors[ 1 ] = face.vertexColors[ 1 ].clone();
44849                     triA.vertexColors[ 2 ] = face.vertexColors[ 3 ].clone();
44850
44851                     triB.vertexColors[ 0 ] = face.vertexColors[ 1 ].clone();
44852                     triB.vertexColors[ 1 ] = face.vertexColors[ 2 ].clone();
44853                     triB.vertexColors[ 2 ] = face.vertexColors[ 3 ].clone();
44854
44855                 }
44856
44857                 faces.push( triA, triB );
44858
44859                 for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
44860
44861                     if ( geometry.faceVertexUvs[ j ].length ) {
44862
44863                         var uvs = geometry.faceVertexUvs[ j ][ i ];
44864
44865                         var uvA = uvs[ 0 ];
44866                         var uvB = uvs[ 1 ];
44867                         var uvC = uvs[ 2 ];
44868                         var uvD = uvs[ 3 ];
44869
44870                         var uvsTriA = [ uvA.clone(), uvB.clone(), uvD.clone() ];
44871                         var uvsTriB = [ uvB.clone(), uvC.clone(), uvD.clone() ];
44872
44873                         faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
44874
44875                     }
44876
44877                 }
44878
44879                 for ( j = 0, jl = geometry.faceUvs.length; j < jl; j ++ ) {
44880
44881                     if ( geometry.faceUvs[ j ].length ) {
44882
44883                         var faceUv = geometry.faceUvs[ j ][ i ];
44884
44885                         faceUvs[ j ].push( faceUv, faceUv );
44886
44887                     }
44888
44889                 }
44890
44891             } else {
44892
44893                 faces.push( face );
44894
44895                 for ( j = 0, jl = geometry.faceUvs.length; j < jl; j ++ ) {
44896
44897                     faceUvs[ j ].push( geometry.faceUvs[ j ][ i ] );
44898
44899                 }
44900
44901                 for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
44902
44903                     faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
44904
44905                 }
44906
44907             }
44908
44909         }
44910
44911         geometry.faces = faces;
44912         geometry.faceUvs = faceUvs;
44913         geometry.faceVertexUvs = faceVertexUvs;
44914
44915         geometry.computeCentroids();
44916         geometry.computeFaceNormals();
44917         geometry.computeVertexNormals();
44918
44919         if ( geometry.hasTangents ) geometry.computeTangents();
44920
44921     },
44922
44923     // Make all faces use unique vertices
44924     // so that each face can be separated from others
44925
44926     explode: function( geometry ) {
44927
44928         var vertices = [];
44929
44930         for ( var i = 0, il = geometry.faces.length; i < il; i ++ ) {
44931
44932             var n = vertices.length;
44933
44934             var face = geometry.faces[ i ];
44935
44936             if ( face instanceof THREE.Face4 ) {
44937
44938                 var a = face.a;
44939                 var b = face.b;
44940                 var c = face.c;
44941                 var d = face.d;
44942
44943                 var va = geometry.vertices[ a ];
44944                 var vb = geometry.vertices[ b ];
44945                 var vc = geometry.vertices[ c ];
44946                 var vd = geometry.vertices[ d ];
44947
44948                 vertices.push( va.clone() );
44949                 vertices.push( vb.clone() );
44950                 vertices.push( vc.clone() );
44951                 vertices.push( vd.clone() );
44952
44953                 face.a = n;
44954                 face.b = n + 1;
44955                 face.c = n + 2;
44956                 face.d = n + 3;
44957
44958             } else {
44959
44960                 var a = face.a;
44961                 var b = face.b;
44962                 var c = face.c;
44963
44964                 var va = geometry.vertices[ a ];
44965                 var vb = geometry.vertices[ b ];
44966                 var vc = geometry.vertices[ c ];
44967
44968                 vertices.push( va.clone() );
44969                 vertices.push( vb.clone() );
44970                 vertices.push( vc.clone() );
44971
44972                 face.a = n;
44973                 face.b = n + 1;
44974                 face.c = n + 2;
44975
44976             }
44977
44978         }
44979
44980         geometry.vertices = vertices;
44981         delete geometry.__tmpVertices;
44982
44983     },
44984
44985     // Break faces with edges longer than maxEdgeLength
44986     // - not recursive
44987
44988     tessellate: function ( geometry, maxEdgeLength ) {
44989
44990         var i, il, face,
44991         a, b, c, d,
44992         va, vb, vc, vd,
44993         dab, dbc, dac, dcd, dad,
44994         m, m1, m2,
44995         vm, vm1, vm2,
44996         vnm, vnm1, vnm2,
44997         vcm, vcm1, vcm2,
44998         triA, triB,
44999         quadA, quadB,
45000         edge;
45001
45002         var faces = [];
45003         var faceVertexUvs = [];
45004
45005         for ( i = 0, il = geometry.faceVertexUvs.length; i < il; i ++ ) {
45006
45007             faceVertexUvs[ i ] = [];
45008
45009         }
45010
45011         for ( i = 0, il = geometry.faces.length; i < il; i ++ ) {
45012
45013             face = geometry.faces[ i ];
45014
45015             if ( face instanceof THREE.Face3 ) {
45016
45017                 a = face.a;
45018                 b = face.b;
45019                 c = face.c;
45020
45021                 va = geometry.vertices[ a ];
45022                 vb = geometry.vertices[ b ];
45023                 vc = geometry.vertices[ c ];
45024
45025                 dab = va.distanceTo( vb );
45026                 dbc = vb.distanceTo( vc );
45027                 dac = va.distanceTo( vc );
45028
45029                 if ( dab > maxEdgeLength || dbc > maxEdgeLength || dac > maxEdgeLength ) {
45030
45031                     m = geometry.vertices.length;
45032
45033                     triA = face.clone();
45034                     triB = face.clone();
45035
45036                     if ( dab >= dbc && dab >= dac ) {
45037
45038                         vm = va.clone();
45039                         vm.lerpSelf( vb, 0.5 );
45040
45041                         triA.a = a;
45042                         triA.b = m;
45043                         triA.c = c;
45044
45045                         triB.a = m;
45046                         triB.b = b;
45047                         triB.c = c;
45048
45049                         if ( face.vertexNormals.length === 3 ) {
45050
45051                             vnm = face.vertexNormals[ 0 ].clone();
45052                             vnm.lerpSelf( face.vertexNormals[ 1 ], 0.5 );
45053
45054                             triA.vertexNormals[ 1 ].copy( vnm );
45055                             triB.vertexNormals[ 0 ].copy( vnm );
45056
45057                         }
45058
45059                         if ( face.vertexColors.length === 3 ) {
45060
45061                             vcm = face.vertexColors[ 0 ].clone();
45062                             vcm.lerpSelf( face.vertexColors[ 1 ], 0.5 );
45063
45064                             triA.vertexColors[ 1 ].copy( vcm );
45065                             triB.vertexColors[ 0 ].copy( vcm );
45066
45067                         }
45068
45069                         edge = 0;
45070
45071                     } else if ( dbc >= dab && dbc >= dac ) {
45072
45073                         vm = vb.clone();
45074                         vm.lerpSelf( vc, 0.5 );
45075
45076                         triA.a = a;
45077                         triA.b = b;
45078                         triA.c = m;
45079
45080                         triB.a = m;
45081                         triB.b = c;
45082                         triB.c = a;
45083
45084                         if ( face.vertexNormals.length === 3 ) {
45085
45086                             vnm = face.vertexNormals[ 1 ].clone();
45087                             vnm.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
45088
45089                             triA.vertexNormals[ 2 ].copy( vnm );
45090
45091                             triB.vertexNormals[ 0 ].copy( vnm );
45092                             triB.vertexNormals[ 1 ].copy( face.vertexNormals[ 2 ] );
45093                             triB.vertexNormals[ 2 ].copy( face.vertexNormals[ 0 ] );
45094
45095                         }
45096
45097                         if ( face.vertexColors.length === 3 ) {
45098
45099                             vcm = face.vertexColors[ 1 ].clone();
45100                             vcm.lerpSelf( face.vertexColors[ 2 ], 0.5 );
45101
45102                             triA.vertexColors[ 2 ].copy( vcm );
45103
45104                             triB.vertexColors[ 0 ].copy( vcm );
45105                             triB.vertexColors[ 1 ].copy( face.vertexColors[ 2 ] );
45106                             triB.vertexColors[ 2 ].copy( face.vertexColors[ 0 ] );
45107
45108                         }
45109
45110                         edge = 1;
45111
45112                     } else {
45113
45114                         vm = va.clone();
45115                         vm.lerpSelf( vc, 0.5 );
45116
45117                         triA.a = a;
45118                         triA.b = b;
45119                         triA.c = m;
45120
45121                         triB.a = m;
45122                         triB.b = b;
45123                         triB.c = c;
45124
45125                         if ( face.vertexNormals.length === 3 ) {
45126
45127                             vnm = face.vertexNormals[ 0 ].clone();
45128                             vnm.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
45129
45130                             triA.vertexNormals[ 2 ].copy( vnm );
45131                             triB.vertexNormals[ 0 ].copy( vnm );
45132
45133                         }
45134
45135                         if ( face.vertexColors.length === 3 ) {
45136
45137                             vcm = face.vertexColors[ 0 ].clone();
45138                             vcm.lerpSelf( face.vertexColors[ 2 ], 0.5 );
45139
45140                             triA.vertexColors[ 2 ].copy( vcm );
45141                             triB.vertexColors[ 0 ].copy( vcm );
45142
45143                         }
45144
45145                         edge = 2;
45146
45147                     }
45148
45149                     faces.push( triA, triB );
45150                     geometry.vertices.push( vm );
45151
45152                     var j, jl, uvs, uvA, uvB, uvC, uvM, uvsTriA, uvsTriB;
45153
45154                     for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
45155
45156                         if ( geometry.faceVertexUvs[ j ].length ) {
45157
45158                             uvs = geometry.faceVertexUvs[ j ][ i ];
45159
45160                             uvA = uvs[ 0 ];
45161                             uvB = uvs[ 1 ];
45162                             uvC = uvs[ 2 ];
45163
45164                             // AB
45165
45166                             if ( edge === 0 ) {
45167
45168                                 uvM = uvA.clone();
45169                                 uvM.lerpSelf( uvB, 0.5 );
45170
45171                                 uvsTriA = [ uvA.clone(), uvM.clone(), uvC.clone() ];
45172                                 uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
45173
45174                             // BC
45175
45176                             } else if ( edge === 1 ) {
45177
45178                                 uvM = uvB.clone();
45179                                 uvM.lerpSelf( uvC, 0.5 );
45180
45181                                 uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
45182                                 uvsTriB = [ uvM.clone(), uvC.clone(), uvA.clone() ];
45183
45184                             // AC
45185
45186                             } else {
45187
45188                                 uvM = uvA.clone();
45189                                 uvM.lerpSelf( uvC, 0.5 );
45190
45191                                 uvsTriA = [ uvA.clone(), uvB.clone(), uvM.clone() ];
45192                                 uvsTriB = [ uvM.clone(), uvB.clone(), uvC.clone() ];
45193
45194                             }
45195
45196                             faceVertexUvs[ j ].push( uvsTriA, uvsTriB );
45197
45198                         }
45199
45200                     }
45201
45202                 } else {
45203
45204                     faces.push( face );
45205
45206                     for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
45207
45208                         faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
45209
45210                     }
45211
45212                 }
45213
45214             } else {
45215
45216                 a = face.a;
45217                 b = face.b;
45218                 c = face.c;
45219                 d = face.d;
45220
45221                 va = geometry.vertices[ a ];
45222                 vb = geometry.vertices[ b ];
45223                 vc = geometry.vertices[ c ];
45224                 vd = geometry.vertices[ d ];
45225
45226                 dab = va.distanceTo( vb );
45227                 dbc = vb.distanceTo( vc );
45228                 dcd = vc.distanceTo( vd );
45229                 dad = va.distanceTo( vd );
45230
45231                 if ( dab > maxEdgeLength || dbc > maxEdgeLength || dcd > maxEdgeLength || dad > maxEdgeLength ) {
45232
45233                     m1 = geometry.vertices.length;
45234                     m2 = geometry.vertices.length + 1;
45235
45236                     quadA = face.clone();
45237                     quadB = face.clone();
45238
45239                     if ( ( dab >= dbc && dab >= dcd && dab >= dad ) || ( dcd >= dbc && dcd >= dab && dcd >= dad ) ) {
45240
45241                         vm1 = va.clone();
45242                         vm1.lerpSelf( vb, 0.5 );
45243
45244                         vm2 = vc.clone();
45245                         vm2.lerpSelf( vd, 0.5 );
45246
45247                         quadA.a = a;
45248                         quadA.b = m1;
45249                         quadA.c = m2;
45250                         quadA.d = d;
45251
45252                         quadB.a = m1;
45253                         quadB.b = b;
45254                         quadB.c = c;
45255                         quadB.d = m2;
45256
45257                         if ( face.vertexNormals.length === 4 ) {
45258
45259                             vnm1 = face.vertexNormals[ 0 ].clone();
45260                             vnm1.lerpSelf( face.vertexNormals[ 1 ], 0.5 );
45261
45262                             vnm2 = face.vertexNormals[ 2 ].clone();
45263                             vnm2.lerpSelf( face.vertexNormals[ 3 ], 0.5 );
45264
45265                             quadA.vertexNormals[ 1 ].copy( vnm1 );
45266                             quadA.vertexNormals[ 2 ].copy( vnm2 );
45267
45268                             quadB.vertexNormals[ 0 ].copy( vnm1 );
45269                             quadB.vertexNormals[ 3 ].copy( vnm2 );
45270
45271                         }
45272
45273                         if ( face.vertexColors.length === 4 ) {
45274
45275                             vcm1 = face.vertexColors[ 0 ].clone();
45276                             vcm1.lerpSelf( face.vertexColors[ 1 ], 0.5 );
45277
45278                             vcm2 = face.vertexColors[ 2 ].clone();
45279                             vcm2.lerpSelf( face.vertexColors[ 3 ], 0.5 );
45280
45281                             quadA.vertexColors[ 1 ].copy( vcm1 );
45282                             quadA.vertexColors[ 2 ].copy( vcm2 );
45283
45284                             quadB.vertexColors[ 0 ].copy( vcm1 );
45285                             quadB.vertexColors[ 3 ].copy( vcm2 );
45286
45287                         }
45288
45289                         edge = 0;
45290
45291                     } else {
45292
45293                         vm1 = vb.clone();
45294                         vm1.lerpSelf( vc, 0.5 );
45295
45296                         vm2 = vd.clone();
45297                         vm2.lerpSelf( va, 0.5 );
45298
45299                         quadA.a = a;
45300                         quadA.b = b;
45301                         quadA.c = m1;
45302                         quadA.d = m2;
45303
45304                         quadB.a = m2;
45305                         quadB.b = m1;
45306                         quadB.c = c;
45307                         quadB.d = d;
45308
45309                         if ( face.vertexNormals.length === 4 ) {
45310
45311                             vnm1 = face.vertexNormals[ 1 ].clone();
45312                             vnm1.lerpSelf( face.vertexNormals[ 2 ], 0.5 );
45313
45314                             vnm2 = face.vertexNormals[ 3 ].clone();
45315                             vnm2.lerpSelf( face.vertexNormals[ 0 ], 0.5 );
45316
45317                             quadA.vertexNormals[ 2 ].copy( vnm1 );
45318                             quadA.vertexNormals[ 3 ].copy( vnm2 );
45319
45320                             quadB.vertexNormals[ 0 ].copy( vnm2 );
45321                             quadB.vertexNormals[ 1 ].copy( vnm1 );
45322
45323                         }
45324
45325                         if ( face.vertexColors.length === 4 ) {
45326
45327                             vcm1 = face.vertexColors[ 1 ].clone();
45328                             vcm1.lerpSelf( face.vertexColors[ 2 ], 0.5 );
45329
45330                             vcm2 = face.vertexColors[ 3 ].clone();
45331                             vcm2.lerpSelf( face.vertexColors[ 0 ], 0.5 );
45332
45333                             quadA.vertexColors[ 2 ].copy( vcm1 );
45334                             quadA.vertexColors[ 3 ].copy( vcm2 );
45335
45336                             quadB.vertexColors[ 0 ].copy( vcm2 );
45337                             quadB.vertexColors[ 1 ].copy( vcm1 );
45338
45339                         }
45340
45341                         edge = 1;
45342
45343                     }
45344
45345                     faces.push( quadA, quadB );
45346                     geometry.vertices.push( vm1, vm2 );
45347
45348                     var j, jl, uvs, uvA, uvB, uvC, uvD, uvM1, uvM2, uvsQuadA, uvsQuadB;
45349
45350                     for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
45351
45352                         if ( geometry.faceVertexUvs[ j ].length ) {
45353
45354                             uvs = geometry.faceVertexUvs[ j ][ i ];
45355
45356                             uvA = uvs[ 0 ];
45357                             uvB = uvs[ 1 ];
45358                             uvC = uvs[ 2 ];
45359                             uvD = uvs[ 3 ];
45360
45361                             // AB + CD
45362
45363                             if ( edge === 0 ) {
45364
45365                                 uvM1 = uvA.clone();
45366                                 uvM1.lerpSelf( uvB, 0.5 );
45367
45368                                 uvM2 = uvC.clone();
45369                                 uvM2.lerpSelf( uvD, 0.5 );
45370
45371                                 uvsQuadA = [ uvA.clone(), uvM1.clone(), uvM2.clone(), uvD.clone() ];
45372                                 uvsQuadB = [ uvM1.clone(), uvB.clone(), uvC.clone(), uvM2.clone() ];
45373
45374                             // BC + AD
45375
45376                             } else {
45377
45378                                 uvM1 = uvB.clone();
45379                                 uvM1.lerpSelf( uvC, 0.5 );
45380
45381                                 uvM2 = uvD.clone();
45382                                 uvM2.lerpSelf( uvA, 0.5 );
45383
45384                                 uvsQuadA = [ uvA.clone(), uvB.clone(), uvM1.clone(), uvM2.clone() ];
45385                                 uvsQuadB = [ uvM2.clone(), uvM1.clone(), uvC.clone(), uvD.clone() ];
45386
45387                             }
45388
45389                             faceVertexUvs[ j ].push( uvsQuadA, uvsQuadB );
45390
45391                         }
45392
45393                     }
45394
45395                 } else {
45396
45397                     faces.push( face );
45398
45399                     for ( j = 0, jl = geometry.faceVertexUvs.length; j < jl; j ++ ) {
45400
45401                         faceVertexUvs[ j ].push( geometry.faceVertexUvs[ j ][ i ] );
45402
45403                     }
45404
45405                 }
45406
45407             }
45408
45409         }
45410
45411         geometry.faces = faces;
45412         geometry.faceVertexUvs = faceVertexUvs;
45413
45414     }
45415
45416 };
45417
45418 THREE.GeometryUtils.random = THREE.Math.random16;
45419
45420 THREE.GeometryUtils.__v1 = new THREE.Vector3();
45421 /**
45422  * @author alteredq / http://alteredqualia.com/
45423  * @author mrdoob / http://mrdoob.com/
45424  */
45425
45426 THREE.ImageUtils = {
45427
45428     crossOrigin: 'anonymous',
45429
45430     loadTexture: function ( url, mapping, onLoad, onError ) {
45431
45432         var image = new Image();
45433         var texture = new THREE.Texture( image, mapping );
45434
45435         var loader = new THREE.ImageLoader();
45436
45437         loader.addEventListener( 'load', function ( event ) {
45438
45439             texture.image = event.content;
45440             texture.needsUpdate = true;
45441
45442             if ( onLoad ) onLoad( texture );
45443
45444         } );
45445
45446         loader.addEventListener( 'error', function ( event ) {
45447
45448             if ( onError ) onError( event.message );
45449
45450         } );
45451
45452         loader.crossOrigin = this.crossOrigin;
45453         loader.load( url, image );
45454
45455         return texture;
45456
45457     },
45458
45459     loadCompressedTexture: function ( url, mapping, onLoad, onError ) {
45460
45461         var texture = new THREE.CompressedTexture();
45462         texture.mapping = mapping;
45463
45464         var request = new XMLHttpRequest();
45465
45466         request.onload = function () {
45467
45468             var buffer = request.response;
45469             var dds = THREE.ImageUtils.parseDDS( buffer, true );
45470
45471             texture.format = dds.format;
45472
45473             texture.mipmaps = dds.mipmaps;
45474             texture.image.width = dds.width;
45475             texture.image.height = dds.height;
45476
45477             // gl.generateMipmap fails for compressed textures
45478             // mipmaps must be embedded in the DDS file
45479             // or texture filters must not use mipmapping
45480
45481             texture.generateMipmaps = false;
45482
45483             texture.needsUpdate = true;
45484
45485             if ( onLoad ) onLoad( texture );
45486
45487         }
45488
45489         request.onerror = onError;
45490
45491         request.open( 'GET', url, true );
45492         request.responseType = "arraybuffer";
45493         request.send( null );
45494
45495         return texture;
45496
45497     },
45498
45499     loadTextureCube: function ( array, mapping, onLoad, onError ) {
45500
45501         var images = [];
45502         images.loadCount = 0;
45503
45504         var texture = new THREE.Texture();
45505         texture.image = images;
45506         if ( mapping !== undefined ) texture.mapping = mapping;
45507
45508         // no flipping needed for cube textures
45509
45510         texture.flipY = false;
45511
45512         for ( var i = 0, il = array.length; i < il; ++ i ) {
45513
45514             var cubeImage = new Image();
45515             images[ i ] = cubeImage;
45516
45517             cubeImage.onload = function () {
45518
45519                 images.loadCount += 1;
45520
45521                 if ( images.loadCount === 6 ) {
45522
45523                     texture.needsUpdate = true;
45524                     if ( onLoad ) onLoad();
45525
45526                 }
45527
45528             };
45529
45530             cubeImage.onerror = onError;
45531
45532             cubeImage.crossOrigin = this.crossOrigin;
45533             cubeImage.src = array[ i ];
45534
45535         }
45536
45537         return texture;
45538
45539     },
45540
45541     loadCompressedTextureCube: function ( array, mapping, onLoad, onError ) {
45542
45543         var images = [];
45544         images.loadCount = 0;
45545
45546         var texture = new THREE.CompressedTexture();
45547         texture.image = images;
45548         if ( mapping !== undefined ) texture.mapping = mapping;
45549
45550         // no flipping for cube textures
45551         // (also flipping doesn't work for compressed textures )
45552
45553         texture.flipY = false;
45554
45555         // can't generate mipmaps for compressed textures
45556         // mips must be embedded in DDS files
45557
45558         texture.generateMipmaps = false;
45559
45560         var generateCubeFaceCallback = function ( rq, img ) {
45561
45562             return function () {
45563
45564                 var buffer = rq.response;
45565                 var dds = THREE.ImageUtils.parseDDS( buffer, true );
45566
45567                 img.format = dds.format;
45568
45569                 img.mipmaps = dds.mipmaps;
45570                 img.width = dds.width;
45571                 img.height = dds.height;
45572
45573                 images.loadCount += 1;
45574
45575                 if ( images.loadCount === 6 ) {
45576
45577                     texture.format = dds.format;
45578                     texture.needsUpdate = true;
45579                     if ( onLoad ) onLoad();
45580
45581                 }
45582
45583             }
45584
45585         }
45586
45587         for ( var i = 0, il = array.length; i < il; ++ i ) {
45588
45589             var cubeImage = {};
45590             images[ i ] = cubeImage;
45591
45592             var request = new XMLHttpRequest();
45593
45594             request.onload = generateCubeFaceCallback( request, cubeImage );
45595             request.onerror = onError;
45596
45597             var url = array[ i ];
45598
45599             request.open( 'GET', url, true );
45600             request.responseType = "arraybuffer";
45601             request.send( null );
45602
45603         }
45604
45605         return texture;
45606
45607     },
45608
45609     parseDDS: function ( buffer, loadMipmaps ) {
45610
45611         var dds = { mipmaps: [], width: 0, height: 0, format: null, mipmapCount: 1 };
45612
45613         // Adapted from @toji's DDS utils
45614         //    https://github.com/toji/webgl-texture-utils/blob/master/texture-util/dds.js
45615
45616         // All values and structures referenced from:
45617         // http://msdn.microsoft.com/en-us/library/bb943991.aspx/
45618
45619         var DDS_MAGIC = 0x20534444;
45620
45621         var DDSD_CAPS = 0x1,
45622             DDSD_HEIGHT = 0x2,
45623             DDSD_WIDTH = 0x4,
45624             DDSD_PITCH = 0x8,
45625             DDSD_PIXELFORMAT = 0x1000,
45626             DDSD_MIPMAPCOUNT = 0x20000,
45627             DDSD_LINEARSIZE = 0x80000,
45628             DDSD_DEPTH = 0x800000;
45629
45630         var DDSCAPS_COMPLEX = 0x8,
45631             DDSCAPS_MIPMAP = 0x400000,
45632             DDSCAPS_TEXTURE = 0x1000;
45633
45634         var DDSCAPS2_CUBEMAP = 0x200,
45635             DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
45636             DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
45637             DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
45638             DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
45639             DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
45640             DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
45641             DDSCAPS2_VOLUME = 0x200000;
45642
45643         var DDPF_ALPHAPIXELS = 0x1,
45644             DDPF_ALPHA = 0x2,
45645             DDPF_FOURCC = 0x4,
45646             DDPF_RGB = 0x40,
45647             DDPF_YUV = 0x200,
45648             DDPF_LUMINANCE = 0x20000;
45649
45650         function fourCCToInt32( value ) {
45651
45652             return value.charCodeAt(0) +
45653                 (value.charCodeAt(1) << 8) +
45654                 (value.charCodeAt(2) << 16) +
45655                 (value.charCodeAt(3) << 24);
45656
45657         }
45658
45659         function int32ToFourCC( value ) {
45660
45661             return String.fromCharCode(
45662                 value & 0xff,
45663                 (value >> 8) & 0xff,
45664                 (value >> 16) & 0xff,
45665                 (value >> 24) & 0xff
45666             );
45667         }
45668
45669         var FOURCC_DXT1 = fourCCToInt32("DXT1");
45670         var FOURCC_DXT3 = fourCCToInt32("DXT3");
45671         var FOURCC_DXT5 = fourCCToInt32("DXT5");
45672
45673         var headerLengthInt = 31; // The header length in 32 bit ints
45674
45675         // Offsets into the header array
45676
45677         var off_magic = 0;
45678
45679         var off_size = 1;
45680         var off_flags = 2;
45681         var off_height = 3;
45682         var off_width = 4;
45683
45684         var off_mipmapCount = 7;
45685
45686         var off_pfFlags = 20;
45687         var off_pfFourCC = 21;
45688
45689         // Parse header
45690
45691         var header = new Int32Array( buffer, 0, headerLengthInt );
45692
45693         if ( header[ off_magic ] !== DDS_MAGIC ) {
45694
45695             console.error( "ImageUtils.parseDDS(): Invalid magic number in DDS header" );
45696             return dds;
45697
45698         }
45699
45700         if ( ! header[ off_pfFlags ] & DDPF_FOURCC ) {
45701
45702             console.error( "ImageUtils.parseDDS(): Unsupported format, must contain a FourCC code" );
45703             return dds;
45704
45705         }
45706
45707         var blockBytes;
45708
45709         var fourCC = header[ off_pfFourCC ];
45710
45711         switch ( fourCC ) {
45712
45713             case FOURCC_DXT1:
45714
45715                 blockBytes = 8;
45716                 dds.format = THREE.RGB_S3TC_DXT1_Format;
45717                 break;
45718
45719             case FOURCC_DXT3:
45720
45721                 blockBytes = 16;
45722                 dds.format = THREE.RGBA_S3TC_DXT3_Format;
45723                 break;
45724
45725             case FOURCC_DXT5:
45726
45727                 blockBytes = 16;
45728                 dds.format = THREE.RGBA_S3TC_DXT5_Format;
45729                 break;
45730
45731             default:
45732
45733                 console.error( "ImageUtils.parseDDS(): Unsupported FourCC code: ", int32ToFourCC( fourCC ) );
45734                 return dds;
45735
45736         }
45737
45738         dds.mipmapCount = 1;
45739
45740         if ( header[ off_flags ] & DDSD_MIPMAPCOUNT && loadMipmaps !== false ) {
45741
45742             dds.mipmapCount = Math.max( 1, header[ off_mipmapCount ] );
45743
45744         }
45745
45746         dds.width = header[ off_width ];
45747         dds.height = header[ off_height ];
45748
45749         var dataOffset = header[ off_size ] + 4;
45750
45751         // Extract mipmaps buffers
45752
45753         var width = dds.width;
45754         var height = dds.height;
45755
45756         for ( var i = 0; i < dds.mipmapCount; i ++ ) {
45757
45758             var dataLength = Math.max( 4, width ) / 4 * Math.max( 4, height ) / 4 * blockBytes;
45759             var byteArray = new Uint8Array( buffer, dataOffset, dataLength );
45760
45761             var mipmap = { "data": byteArray, "width": width, "height": height };
45762             dds.mipmaps.push( mipmap );
45763
45764             dataOffset += dataLength;
45765
45766             width = Math.max( width * 0.5, 1 );
45767             height = Math.max( height * 0.5, 1 );
45768
45769         }
45770
45771         return dds;
45772
45773     },
45774
45775     getNormalMap: function ( image, depth ) {
45776
45777         // Adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
45778
45779         var cross = function ( a, b ) {
45780
45781             return [ a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ], a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ], a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ] ];
45782
45783         }
45784
45785         var subtract = function ( a, b ) {
45786
45787             return [ a[ 0 ] - b[ 0 ], a[ 1 ] - b[ 1 ], a[ 2 ] - b[ 2 ] ];
45788
45789         }
45790
45791         var normalize = function ( a ) {
45792
45793             var l = Math.sqrt( a[ 0 ] * a[ 0 ] + a[ 1 ] * a[ 1 ] + a[ 2 ] * a[ 2 ] );
45794             return [ a[ 0 ] / l, a[ 1 ] / l, a[ 2 ] / l ];
45795
45796         }
45797
45798         depth = depth | 1;
45799
45800         var width = image.width;
45801         var height = image.height;
45802
45803         var canvas = document.createElement( 'canvas' );
45804         canvas.width = width;
45805         canvas.height = height;
45806
45807         var context = canvas.getContext( '2d' );
45808         context.drawImage( image, 0, 0 );
45809
45810         var data = context.getImageData( 0, 0, width, height ).data;
45811         var imageData = context.createImageData( width, height );
45812         var output = imageData.data;
45813
45814         for ( var x = 0; x < width; x ++ ) {
45815
45816             for ( var y = 0; y < height; y ++ ) {
45817
45818                 var ly = y - 1 < 0 ? 0 : y - 1;
45819                 var uy = y + 1 > height - 1 ? height - 1 : y + 1;
45820                 var lx = x - 1 < 0 ? 0 : x - 1;
45821                 var ux = x + 1 > width - 1 ? width - 1 : x + 1;
45822
45823                 var points = [];
45824                 var origin = [ 0, 0, data[ ( y * width + x ) * 4 ] / 255 * depth ];
45825                 points.push( [ - 1, 0, data[ ( y * width + lx ) * 4 ] / 255 * depth ] );
45826                 points.push( [ - 1, - 1, data[ ( ly * width + lx ) * 4 ] / 255 * depth ] );
45827                 points.push( [ 0, - 1, data[ ( ly * width + x ) * 4 ] / 255 * depth ] );
45828                 points.push( [  1, - 1, data[ ( ly * width + ux ) * 4 ] / 255 * depth ] );
45829                 points.push( [ 1, 0, data[ ( y * width + ux ) * 4 ] / 255 * depth ] );
45830                 points.push( [ 1, 1, data[ ( uy * width + ux ) * 4 ] / 255 * depth ] );
45831                 points.push( [ 0, 1, data[ ( uy * width + x ) * 4 ] / 255 * depth ] );
45832                 points.push( [ - 1, 1, data[ ( uy * width + lx ) * 4 ] / 255 * depth ] );
45833
45834                 var normals = [];
45835                 var num_points = points.length;
45836
45837                 for ( var i = 0; i < num_points; i ++ ) {
45838
45839                     var v1 = points[ i ];
45840                     var v2 = points[ ( i + 1 ) % num_points ];
45841                     v1 = subtract( v1, origin );
45842                     v2 = subtract( v2, origin );
45843                     normals.push( normalize( cross( v1, v2 ) ) );
45844
45845                 }
45846
45847                 var normal = [ 0, 0, 0 ];
45848
45849                 for ( var i = 0; i < normals.length; i ++ ) {
45850
45851                     normal[ 0 ] += normals[ i ][ 0 ];
45852                     normal[ 1 ] += normals[ i ][ 1 ];
45853                     normal[ 2 ] += normals[ i ][ 2 ];
45854
45855                 }
45856
45857                 normal[ 0 ] /= normals.length;
45858                 normal[ 1 ] /= normals.length;
45859                 normal[ 2 ] /= normals.length;
45860
45861                 var idx = ( y * width + x ) * 4;
45862
45863                 output[ idx ] = ( ( normal[ 0 ] + 1.0 ) / 2.0 * 255 ) | 0;
45864                 output[ idx + 1 ] = ( ( normal[ 1 ] + 1.0 ) / 2.0 * 255 ) | 0;
45865                 output[ idx + 2 ] = ( normal[ 2 ] * 255 ) | 0;
45866                 output[ idx + 3 ] = 255;
45867
45868             }
45869
45870         }
45871
45872         context.putImageData( imageData, 0, 0 );
45873
45874         return canvas;
45875
45876     },
45877
45878     generateDataTexture: function ( width, height, color ) {
45879
45880         var size = width * height;
45881         var data = new Uint8Array( 3 * size );
45882
45883         var r = Math.floor( color.r * 255 );
45884         var g = Math.floor( color.g * 255 );
45885         var b = Math.floor( color.b * 255 );
45886
45887         for ( var i = 0; i < size; i ++ ) {
45888
45889             data[ i * 3 ]       = r;
45890             data[ i * 3 + 1 ] = g;
45891             data[ i * 3 + 2 ] = b;
45892
45893         }
45894
45895         var texture = new THREE.DataTexture( data, width, height, THREE.RGBFormat );
45896         texture.needsUpdate = true;
45897
45898         return texture;
45899
45900     }
45901
45902 };
45903 /**
45904  * @author alteredq / http://alteredqualia.com/
45905  */
45906
45907 THREE.SceneUtils = {
45908
45909     showHierarchy : function ( root, visible ) {
45910
45911         THREE.SceneUtils.traverseHierarchy( root, function( node ) { node.visible = visible; } );
45912
45913     },
45914
45915     traverseHierarchy : function ( root, callback ) {
45916
45917         var n, i, l = root.children.length;
45918
45919         for ( i = 0; i < l; i ++ ) {
45920
45921             n = root.children[ i ];
45922
45923             callback( n );
45924
45925             THREE.SceneUtils.traverseHierarchy( n, callback );
45926
45927         }
45928
45929     },
45930
45931     createMultiMaterialObject : function ( geometry, materials ) {
45932
45933         var i, il = materials.length,
45934             group = new THREE.Object3D();
45935
45936         for ( i = 0; i < il; i ++ ) {
45937
45938             var object = new THREE.Mesh( geometry, materials[ i ] );
45939             group.add( object );
45940
45941         }
45942
45943         return group;
45944
45945     },
45946
45947     cloneObject: function ( source ) {
45948
45949         var object;
45950
45951         // subclass specific properties
45952         // (must process in order from more specific subclasses to more abstract classes)
45953
45954         if ( source instanceof THREE.MorphAnimMesh ) {
45955
45956             object = new THREE.MorphAnimMesh( source.geometry, source.material );
45957
45958             object.duration = source.duration;
45959             object.mirroredLoop = source.mirroredLoop;
45960             object.time = source.time;
45961
45962             object.lastKeyframe = source.lastKeyframe;
45963             object.currentKeyframe = source.currentKeyframe;
45964
45965             object.direction = source.direction;
45966             object.directionBackwards = source.directionBackwards;
45967
45968         } else if ( source instanceof THREE.SkinnedMesh ) {
45969
45970             object = new THREE.SkinnedMesh( source.geometry, source.material, source.useVertexTexture );
45971
45972         } else if ( source instanceof THREE.Mesh ) {
45973
45974             object = new THREE.Mesh( source.geometry, source.material );
45975
45976         } else if ( source instanceof THREE.Line ) {
45977
45978             object = new THREE.Line( source.geometry, source.material, source.type );
45979
45980         } else if ( source instanceof THREE.Ribbon ) {
45981
45982             object = new THREE.Ribbon( source.geometry, source.material );
45983
45984         } else if ( source instanceof THREE.ParticleSystem ) {
45985
45986             object = new THREE.ParticleSystem( source.geometry, source.material );
45987             object.sortParticles = source.sortParticles;
45988
45989         } else if ( source instanceof THREE.Particle ) {
45990
45991             object = new THREE.Particle( source.material );
45992
45993         } else if ( source instanceof THREE.Sprite ) {
45994
45995             object = new THREE.Sprite( {} );
45996
45997             object.color.copy( source.color );
45998             object.map = source.map;
45999             object.blending = source.blending;
46000
46001             object.useScreenCoordinates = source.useScreenCoordinates;
46002             object.mergeWith3D = source.mergeWith3D;
46003             object.affectedByDistance = source.affectedByDistance;
46004             object.scaleByViewport = source.scaleByViewport;
46005             object.alignment = source.alignment;
46006
46007             object.rotation3d.copy( source.rotation3d );
46008             object.rotation = source.rotation;
46009             object.opacity = source.opacity;
46010
46011             object.uvOffset.copy( source.uvOffset );
46012             object.uvScale.copy( source.uvScale);
46013
46014         } else if ( source instanceof THREE.LOD ) {
46015
46016             object = new THREE.LOD();
46017
46018         /*
46019         } else if ( source instanceof THREE.MarchingCubes ) {
46020
46021             object = new THREE.MarchingCubes( source.resolution, source.material );
46022             object.field.set( source.field );
46023             object.isolation = source.isolation;
46024         */
46025
46026         } else if ( source instanceof THREE.Object3D ) {
46027
46028             object = new THREE.Object3D();
46029
46030         }
46031
46032         // base class properties
46033
46034         object.name = source.name;
46035
46036         object.parent = source.parent;
46037
46038         object.up.copy( source.up );
46039
46040         object.position.copy( source.position );
46041
46042         // because of Sprite madness
46043
46044         if ( object.rotation instanceof THREE.Vector3 )
46045             object.rotation.copy( source.rotation );
46046
46047         object.eulerOrder = source.eulerOrder;
46048
46049         object.scale.copy( source.scale );
46050
46051         object.dynamic = source.dynamic;
46052
46053         object.renderDepth = source.renderDepth;
46054
46055         object.rotationAutoUpdate = source.rotationAutoUpdate;
46056
46057         object.matrix.copy( source.matrix );
46058         object.matrixWorld.copy( source.matrixWorld );
46059         object.matrixRotationWorld.copy( source.matrixRotationWorld );
46060
46061         object.matrixAutoUpdate = source.matrixAutoUpdate;
46062         object.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
46063
46064         object.quaternion.copy( source.quaternion );
46065         object.useQuaternion = source.useQuaternion;
46066
46067         object.boundRadius = source.boundRadius;
46068         object.boundRadiusScale = source.boundRadiusScale;
46069
46070         object.visible = source.visible;
46071
46072         object.castShadow = source.castShadow;
46073         object.receiveShadow = source.receiveShadow;
46074
46075         object.frustumCulled = source.frustumCulled;
46076
46077         // children
46078
46079         for ( var i = 0; i < source.children.length; i ++ ) {
46080
46081             var child = THREE.SceneUtils.cloneObject( source.children[ i ] );
46082             object.children[ i ] = child;
46083
46084             child.parent = object;
46085
46086         }
46087
46088         // LODs need to be patched separately to use cloned children
46089
46090         if ( source instanceof THREE.LOD ) {
46091
46092             for ( var i = 0; i < source.LODs.length; i ++ ) {
46093
46094                 var lod = source.LODs[ i ];
46095                 object.LODs[ i ] = { visibleAtDistance: lod.visibleAtDistance, object3D: object.children[ i ] };
46096
46097             }
46098
46099         }
46100
46101         return object;
46102
46103     },
46104
46105     detach : function ( child, parent, scene ) {
46106
46107         child.applyMatrix( parent.matrixWorld );
46108         parent.remove( child );
46109         scene.add( child );
46110
46111     },
46112
46113     attach: function ( child, scene, parent ) {
46114
46115         var matrixWorldInverse = new THREE.Matrix4();
46116         matrixWorldInverse.getInverse( parent.matrixWorld );
46117         child.applyMatrix( matrixWorldInverse );
46118
46119         scene.remove( child );
46120         parent.add( child );
46121
46122     }
46123
46124 };
46125 /**
46126  * @author alteredq / http://alteredqualia.com/
46127  * @author mrdoob / http://mrdoob.com/
46128  *
46129  * ShaderUtils currently contains:
46130  *
46131  *    fresnel
46132  *    normal
46133  *     cube
46134  *
46135  */
46136
46137 if ( THREE.WebGLRenderer ) {
46138
46139 THREE.ShaderUtils = {
46140
46141     lib: {
46142
46143         /* -------------------------------------------------------------------------
46144         //    Fresnel shader
46145         //    - based on Nvidia Cg tutorial
46146          ------------------------------------------------------------------------- */
46147
46148         'fresnel': {
46149
46150             uniforms: {
46151
46152                 "mRefractionRatio": { type: "f", value: 1.02 },
46153                 "mFresnelBias": { type: "f", value: 0.1 },
46154                 "mFresnelPower": { type: "f", value: 2.0 },
46155                 "mFresnelScale": { type: "f", value: 1.0 },
46156                 "tCube": { type: "t", value: null }
46157
46158             },
46159
46160             fragmentShader: [
46161
46162                 "uniform samplerCube tCube;",
46163
46164                 "varying vec3 vReflect;",
46165                 "varying vec3 vRefract[3];",
46166                 "varying float vReflectionFactor;",
46167
46168                 "void main() {",
46169
46170                     "vec4 reflectedColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
46171                     "vec4 refractedColor = vec4( 1.0, 1.0, 1.0, 1.0 );",
46172
46173                     "refractedColor.r = textureCube( tCube, vec3( -vRefract[0].x, vRefract[0].yz ) ).r;",
46174                     "refractedColor.g = textureCube( tCube, vec3( -vRefract[1].x, vRefract[1].yz ) ).g;",
46175                     "refractedColor.b = textureCube( tCube, vec3( -vRefract[2].x, vRefract[2].yz ) ).b;",
46176                     "refractedColor.a = 1.0;",
46177
46178                     "gl_FragColor = mix( refractedColor, reflectedColor, clamp( vReflectionFactor, 0.0, 1.0 ) );",
46179
46180                 "}"
46181
46182             ].join("\n"),
46183
46184             vertexShader: [
46185
46186                 "uniform float mRefractionRatio;",
46187                 "uniform float mFresnelBias;",
46188                 "uniform float mFresnelScale;",
46189                 "uniform float mFresnelPower;",
46190
46191                 "varying vec3 vReflect;",
46192                 "varying vec3 vRefract[3];",
46193                 "varying float vReflectionFactor;",
46194
46195                 "void main() {",
46196
46197                     "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
46198                     "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
46199
46200                     "vec3 nWorld = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );",
46201
46202                     "vec3 I = mPosition.xyz - cameraPosition;",
46203
46204                     "vReflect = reflect( I, nWorld );",
46205                     "vRefract[0] = refract( normalize( I ), nWorld, mRefractionRatio );",
46206                     "vRefract[1] = refract( normalize( I ), nWorld, mRefractionRatio * 0.99 );",
46207                     "vRefract[2] = refract( normalize( I ), nWorld, mRefractionRatio * 0.98 );",
46208                     "vReflectionFactor = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( I ), nWorld ), mFresnelPower );",
46209
46210                     "gl_Position = projectionMatrix * mvPosition;",
46211
46212                 "}"
46213
46214             ].join("\n")
46215
46216         },
46217
46218         /* -------------------------------------------------------------------------
46219         //    Normal map shader
46220         //        - Blinn-Phong
46221         //        - normal + diffuse + specular + AO + displacement + reflection + shadow maps
46222         //        - point and directional lights (use with "lights: true" material option)
46223          ------------------------------------------------------------------------- */
46224
46225         'normal' : {
46226
46227             uniforms: THREE.UniformsUtils.merge( [
46228
46229                 THREE.UniformsLib[ "fog" ],
46230                 THREE.UniformsLib[ "lights" ],
46231                 THREE.UniformsLib[ "shadowmap" ],
46232
46233                 {
46234
46235                 "enableAO"          : { type: "i", value: 0 },
46236                 "enableDiffuse"      : { type: "i", value: 0 },
46237                 "enableSpecular"  : { type: "i", value: 0 },
46238                 "enableReflection": { type: "i", value: 0 },
46239                 "enableDisplacement": { type: "i", value: 0 },
46240
46241                 "tDisplacement": { type: "t", value: null }, // must go first as this is vertex texture
46242                 "tDiffuse"       : { type: "t", value: null },
46243                 "tCube"           : { type: "t", value: null },
46244                 "tNormal"       : { type: "t", value: null },
46245                 "tSpecular"       : { type: "t", value: null },
46246                 "tAO"           : { type: "t", value: null },
46247
46248                 "uNormalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) },
46249
46250                 "uDisplacementBias": { type: "f", value: 0.0 },
46251                 "uDisplacementScale": { type: "f", value: 1.0 },
46252
46253                 "uDiffuseColor": { type: "c", value: new THREE.Color( 0xffffff ) },
46254                 "uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
46255                 "uAmbientColor": { type: "c", value: new THREE.Color( 0xffffff ) },
46256                 "uShininess": { type: "f", value: 30 },
46257                 "uOpacity": { type: "f", value: 1 },
46258
46259                 "useRefract": { type: "i", value: 0 },
46260                 "uRefractionRatio": { type: "f", value: 0.98 },
46261                 "uReflectivity": { type: "f", value: 0.5 },
46262
46263                 "uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) },
46264                 "uRepeat" : { type: "v2", value: new THREE.Vector2( 1, 1 ) },
46265
46266                 "wrapRGB"  : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
46267
46268                 }
46269
46270             ] ),
46271
46272             fragmentShader: [
46273
46274                 "uniform vec3 uAmbientColor;",
46275                 "uniform vec3 uDiffuseColor;",
46276                 "uniform vec3 uSpecularColor;",
46277                 "uniform float uShininess;",
46278                 "uniform float uOpacity;",
46279
46280                 "uniform bool enableDiffuse;",
46281                 "uniform bool enableSpecular;",
46282                 "uniform bool enableAO;",
46283                 "uniform bool enableReflection;",
46284
46285                 "uniform sampler2D tDiffuse;",
46286                 "uniform sampler2D tNormal;",
46287                 "uniform sampler2D tSpecular;",
46288                 "uniform sampler2D tAO;",
46289
46290                 "uniform samplerCube tCube;",
46291
46292                 "uniform vec2 uNormalScale;",
46293
46294                 "uniform bool useRefract;",
46295                 "uniform float uRefractionRatio;",
46296                 "uniform float uReflectivity;",
46297
46298                 "varying vec3 vTangent;",
46299                 "varying vec3 vBinormal;",
46300                 "varying vec3 vNormal;",
46301                 "varying vec2 vUv;",
46302
46303                 "uniform vec3 ambientLightColor;",
46304
46305                 "#if MAX_DIR_LIGHTS > 0",
46306
46307                     "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
46308                     "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
46309
46310                 "#endif",
46311
46312                 "#if MAX_HEMI_LIGHTS > 0",
46313
46314                     "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
46315                     "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
46316                     "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
46317
46318                 "#endif",
46319
46320                 "#if MAX_POINT_LIGHTS > 0",
46321
46322                     "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
46323                     "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
46324                     "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
46325
46326                 "#endif",
46327
46328                 "#if MAX_SPOT_LIGHTS > 0",
46329
46330                     "uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ];",
46331                     "uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ];",
46332                     "uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ];",
46333                     "uniform float spotLightAngle[ MAX_SPOT_LIGHTS ];",
46334                     "uniform float spotLightExponent[ MAX_SPOT_LIGHTS ];",
46335                     "uniform float spotLightDistance[ MAX_SPOT_LIGHTS ];",
46336
46337                 "#endif",
46338
46339                 "#ifdef WRAP_AROUND",
46340
46341                     "uniform vec3 wrapRGB;",
46342
46343                 "#endif",
46344
46345                 "varying vec3 vWorldPosition;",
46346                 "varying vec3 vViewPosition;",
46347
46348                 THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
46349                 THREE.ShaderChunk[ "fog_pars_fragment" ],
46350
46351                 "void main() {",
46352
46353                     "gl_FragColor = vec4( vec3( 1.0 ), uOpacity );",
46354
46355                     "vec3 specularTex = vec3( 1.0 );",
46356
46357                     "vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
46358                     "normalTex.xy *= uNormalScale;",
46359                     "normalTex = normalize( normalTex );",
46360
46361                     "if( enableDiffuse ) {",
46362
46363                         "#ifdef GAMMA_INPUT",
46364
46365                             "vec4 texelColor = texture2D( tDiffuse, vUv );",
46366                             "texelColor.xyz *= texelColor.xyz;",
46367
46368                             "gl_FragColor = gl_FragColor * texelColor;",
46369
46370                         "#else",
46371
46372                             "gl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );",
46373
46374                         "#endif",
46375
46376                     "}",
46377
46378                     "if( enableAO ) {",
46379
46380                         "#ifdef GAMMA_INPUT",
46381
46382                             "vec4 aoColor = texture2D( tAO, vUv );",
46383                             "aoColor.xyz *= aoColor.xyz;",
46384
46385                             "gl_FragColor.xyz = gl_FragColor.xyz * aoColor.xyz;",
46386
46387                         "#else",
46388
46389                             "gl_FragColor.xyz = gl_FragColor.xyz * texture2D( tAO, vUv ).xyz;",
46390
46391                         "#endif",
46392
46393                     "}",
46394
46395                     "if( enableSpecular )",
46396                         "specularTex = texture2D( tSpecular, vUv ).xyz;",
46397
46398                     "mat3 tsb = mat3( normalize( vTangent ), normalize( vBinormal ), normalize( vNormal ) );",
46399                     "vec3 finalNormal = tsb * normalTex;",
46400
46401                     "#ifdef FLIP_SIDED",
46402
46403                         "finalNormal = -finalNormal;",
46404
46405                     "#endif",
46406
46407                     "vec3 normal = normalize( finalNormal );",
46408                     "vec3 viewPosition = normalize( vViewPosition );",
46409
46410                     // point lights
46411
46412                     "#if MAX_POINT_LIGHTS > 0",
46413
46414                         "vec3 pointDiffuse = vec3( 0.0 );",
46415                         "vec3 pointSpecular = vec3( 0.0 );",
46416
46417                         "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
46418
46419                             "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
46420                             "vec3 pointVector = lPosition.xyz + vViewPosition.xyz;",
46421
46422                             "float pointDistance = 1.0;",
46423                             "if ( pointLightDistance[ i ] > 0.0 )",
46424                                 "pointDistance = 1.0 - min( ( length( pointVector ) / pointLightDistance[ i ] ), 1.0 );",
46425
46426                             "pointVector = normalize( pointVector );",
46427
46428                             // diffuse
46429
46430                             "#ifdef WRAP_AROUND",
46431
46432                                 "float pointDiffuseWeightFull = max( dot( normal, pointVector ), 0.0 );",
46433                                 "float pointDiffuseWeightHalf = max( 0.5 * dot( normal, pointVector ) + 0.5, 0.0 );",
46434
46435                                 "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB );",
46436
46437                             "#else",
46438
46439                                 "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
46440
46441                             "#endif",
46442
46443                             "pointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;",
46444
46445                             // specular
46446
46447                             "vec3 pointHalfVector = normalize( pointVector + viewPosition );",
46448                             "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );",
46449                             "float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );",
46450
46451                             "#ifdef PHYSICALLY_BASED_SHADING",
46452
46453                                 // 2.0 => 2.0001 is hack to work around ANGLE bug
46454
46455                                 "float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
46456
46457                                 "vec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( pointVector, pointHalfVector ), 5.0 );",
46458                                 "pointSpecular += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * pointDistance * specularNormalization;",
46459
46460                             "#else",
46461
46462                                 "pointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;",
46463
46464                             "#endif",
46465
46466                         "}",
46467
46468                     "#endif",
46469
46470                     // spot lights
46471
46472                     "#if MAX_SPOT_LIGHTS > 0",
46473
46474                         "vec3 spotDiffuse = vec3( 0.0 );",
46475                         "vec3 spotSpecular = vec3( 0.0 );",
46476
46477                         "for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {",
46478
46479                             "vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 );",
46480                             "vec3 spotVector = lPosition.xyz + vViewPosition.xyz;",
46481
46482                             "float spotDistance = 1.0;",
46483                             "if ( spotLightDistance[ i ] > 0.0 )",
46484                                 "spotDistance = 1.0 - min( ( length( spotVector ) / spotLightDistance[ i ] ), 1.0 );",
46485
46486                             "spotVector = normalize( spotVector );",
46487
46488                             "float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) );",
46489
46490                             "if ( spotEffect > spotLightAngle[ i ] ) {",
46491
46492                                 "spotEffect = pow( spotEffect, spotLightExponent[ i ] );",
46493
46494                                 // diffuse
46495
46496                                 "#ifdef WRAP_AROUND",
46497
46498                                     "float spotDiffuseWeightFull = max( dot( normal, spotVector ), 0.0 );",
46499                                     "float spotDiffuseWeightHalf = max( 0.5 * dot( normal, spotVector ) + 0.5, 0.0 );",
46500
46501                                     "vec3 spotDiffuseWeight = mix( vec3 ( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB );",
46502
46503                                 "#else",
46504
46505                                     "float spotDiffuseWeight = max( dot( normal, spotVector ), 0.0 );",
46506
46507                                 "#endif",
46508
46509                                 "spotDiffuse += spotDistance * spotLightColor[ i ] * uDiffuseColor * spotDiffuseWeight * spotEffect;",
46510
46511                                 // specular
46512
46513                                 "vec3 spotHalfVector = normalize( spotVector + viewPosition );",
46514                                 "float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 );",
46515                                 "float spotSpecularWeight = specularTex.r * max( pow( spotDotNormalHalf, uShininess ), 0.0 );",
46516
46517                                 "#ifdef PHYSICALLY_BASED_SHADING",
46518
46519                                     // 2.0 => 2.0001 is hack to work around ANGLE bug
46520
46521                                     "float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
46522
46523                                     "vec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( spotVector, spotHalfVector ), 5.0 );",
46524                                     "spotSpecular += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * spotDistance * specularNormalization * spotEffect;",
46525
46526                                 "#else",
46527
46528                                     "spotSpecular += spotDistance * spotLightColor[ i ] * uSpecularColor * spotSpecularWeight * spotDiffuseWeight * spotEffect;",
46529
46530                                 "#endif",
46531
46532                             "}",
46533
46534                         "}",
46535
46536                     "#endif",
46537
46538                     // directional lights
46539
46540                     "#if MAX_DIR_LIGHTS > 0",
46541
46542                         "vec3 dirDiffuse = vec3( 0.0 );",
46543                         "vec3 dirSpecular = vec3( 0.0 );",
46544
46545                         "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
46546
46547                             "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
46548                             "vec3 dirVector = normalize( lDirection.xyz );",
46549
46550                             // diffuse
46551
46552                             "#ifdef WRAP_AROUND",
46553
46554                                 "float directionalLightWeightingFull = max( dot( normal, dirVector ), 0.0 );",
46555                                 "float directionalLightWeightingHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
46556
46557                                 "vec3 dirDiffuseWeight = mix( vec3( directionalLightWeightingFull ), vec3( directionalLightWeightingHalf ), wrapRGB );",
46558
46559                             "#else",
46560
46561                                 "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
46562
46563                             "#endif",
46564
46565                             "dirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;",
46566
46567                             // specular
46568
46569                             "vec3 dirHalfVector = normalize( dirVector + viewPosition );",
46570                             "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );",
46571                             "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, uShininess ), 0.0 );",
46572
46573                             "#ifdef PHYSICALLY_BASED_SHADING",
46574
46575                                 // 2.0 => 2.0001 is hack to work around ANGLE bug
46576
46577                                 "float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
46578
46579                                 "vec3 schlick = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( dirVector, dirHalfVector ), 5.0 );",
46580                                 "dirSpecular += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization;",
46581
46582                             "#else",
46583
46584                                 "dirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;",
46585
46586                             "#endif",
46587
46588                         "}",
46589
46590                     "#endif",
46591
46592                     // hemisphere lights
46593
46594                     "#if MAX_HEMI_LIGHTS > 0",
46595
46596                         "vec3 hemiDiffuse  = vec3( 0.0 );",
46597                         "vec3 hemiSpecular = vec3( 0.0 );" ,
46598
46599                         "for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
46600
46601                             "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
46602                             "vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
46603
46604                             // diffuse
46605
46606                             "float dotProduct = dot( normal, lVector );",
46607                             "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
46608
46609                             "vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
46610
46611                             "hemiDiffuse += uDiffuseColor * hemiColor;",
46612
46613                             // specular (sky light)
46614
46615
46616                             "vec3 hemiHalfVectorSky = normalize( lVector + viewPosition );",
46617                             "float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5;",
46618                             "float hemiSpecularWeightSky = specularTex.r * max( pow( hemiDotNormalHalfSky, uShininess ), 0.0 );",
46619
46620                             // specular (ground light)
46621
46622                             "vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
46623
46624                             "vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition );",
46625                             "float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5;",
46626                             "float hemiSpecularWeightGround = specularTex.r * max( pow( hemiDotNormalHalfGround, uShininess ), 0.0 );",
46627
46628                             "#ifdef PHYSICALLY_BASED_SHADING",
46629
46630                                 "float dotProductGround = dot( normal, lVectorGround );",
46631
46632                                 // 2.0 => 2.0001 is hack to work around ANGLE bug
46633
46634                                 "float specularNormalization = ( uShininess + 2.0001 ) / 8.0;",
46635
46636                                 "vec3 schlickSky = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVector, hemiHalfVectorSky ), 5.0 );",
46637                                 "vec3 schlickGround = uSpecularColor + vec3( 1.0 - uSpecularColor ) * pow( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 5.0 );",
46638                                 "hemiSpecular += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) );",
46639
46640                             "#else",
46641
46642                                 "hemiSpecular += uSpecularColor * hemiColor * ( hemiSpecularWeightSky + hemiSpecularWeightGround ) * hemiDiffuseWeight;",
46643
46644                             "#endif",
46645
46646                         "}",
46647
46648                     "#endif",
46649
46650                     // all lights contribution summation
46651
46652                     "vec3 totalDiffuse = vec3( 0.0 );",
46653                     "vec3 totalSpecular = vec3( 0.0 );",
46654
46655                     "#if MAX_DIR_LIGHTS > 0",
46656
46657                         "totalDiffuse += dirDiffuse;",
46658                         "totalSpecular += dirSpecular;",
46659
46660                     "#endif",
46661
46662                     "#if MAX_HEMI_LIGHTS > 0",
46663
46664                         "totalDiffuse += hemiDiffuse;",
46665                         "totalSpecular += hemiSpecular;",
46666
46667                     "#endif",
46668
46669                     "#if MAX_POINT_LIGHTS > 0",
46670
46671                         "totalDiffuse += pointDiffuse;",
46672                         "totalSpecular += pointSpecular;",
46673
46674                     "#endif",
46675
46676                     "#if MAX_SPOT_LIGHTS > 0",
46677
46678                         "totalDiffuse += spotDiffuse;",
46679                         "totalSpecular += spotSpecular;",
46680
46681                     "#endif",
46682
46683                     "#ifdef METAL",
46684
46685                         "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );",
46686
46687                     "#else",
46688
46689                         "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor ) + totalSpecular;",
46690
46691                     "#endif",
46692
46693                     "if ( enableReflection ) {",
46694
46695                         "vec3 vReflect;",
46696                         "vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );",
46697
46698                         "if ( useRefract ) {",
46699
46700                             "vReflect = refract( cameraToVertex, normal, uRefractionRatio );",
46701
46702                         "} else {",
46703
46704                             "vReflect = reflect( cameraToVertex, normal );",
46705
46706                         "}",
46707
46708                         "vec4 cubeColor = textureCube( tCube, vec3( -vReflect.x, vReflect.yz ) );",
46709
46710                         "#ifdef GAMMA_INPUT",
46711
46712                             "cubeColor.xyz *= cubeColor.xyz;",
46713
46714                         "#endif",
46715
46716                         "gl_FragColor.xyz = mix( gl_FragColor.xyz, cubeColor.xyz, specularTex.r * uReflectivity );",
46717
46718                     "}",
46719
46720                     THREE.ShaderChunk[ "shadowmap_fragment" ],
46721                     THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
46722                     THREE.ShaderChunk[ "fog_fragment" ],
46723
46724                 "}"
46725
46726             ].join("\n"),
46727
46728             vertexShader: [
46729
46730                 "attribute vec4 tangent;",
46731
46732                 "uniform vec2 uOffset;",
46733                 "uniform vec2 uRepeat;",
46734
46735                 "uniform bool enableDisplacement;",
46736
46737                 "#ifdef VERTEX_TEXTURES",
46738
46739                     "uniform sampler2D tDisplacement;",
46740                     "uniform float uDisplacementScale;",
46741                     "uniform float uDisplacementBias;",
46742
46743                 "#endif",
46744
46745                 "varying vec3 vTangent;",
46746                 "varying vec3 vBinormal;",
46747                 "varying vec3 vNormal;",
46748                 "varying vec2 vUv;",
46749
46750                 "varying vec3 vWorldPosition;",
46751                 "varying vec3 vViewPosition;",
46752
46753                 THREE.ShaderChunk[ "skinning_pars_vertex" ],
46754                 THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
46755
46756                 "void main() {",
46757
46758                     THREE.ShaderChunk[ "skinbase_vertex" ],
46759                     THREE.ShaderChunk[ "skinnormal_vertex" ],
46760
46761                     // normal, tangent and binormal vectors
46762
46763                     "#ifdef USE_SKINNING",
46764
46765                         "vNormal = normalMatrix * skinnedNormal.xyz;",
46766
46767                         "vec4 skinnedTangent = skinMatrix * vec4( tangent.xyz, 0.0 );",
46768                         "vTangent = normalMatrix * skinnedTangent.xyz;",
46769
46770                     "#else",
46771
46772                         "vNormal = normalMatrix * normal;",
46773                         "vTangent = normalMatrix * tangent.xyz;",
46774
46775                     "#endif",
46776
46777                     "vBinormal = cross( vNormal, vTangent ) * tangent.w;",
46778
46779                     "vUv = uv * uRepeat + uOffset;",
46780
46781                     // displacement mapping
46782
46783                     "vec3 displacedPosition;",
46784
46785                     "#ifdef VERTEX_TEXTURES",
46786
46787                         "if ( enableDisplacement ) {",
46788
46789                             "vec3 dv = texture2D( tDisplacement, uv ).xyz;",
46790                             "float df = uDisplacementScale * dv.x + uDisplacementBias;",
46791                             "displacedPosition = position + normalize( normal ) * df;",
46792
46793                         "} else {",
46794
46795                             "#ifdef USE_SKINNING",
46796
46797                                 "vec4 skinVertex = vec4( position, 1.0 );",
46798
46799                                 "vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
46800                                 "skinned       += boneMatY * skinVertex * skinWeight.y;",
46801
46802                                 "displacedPosition  = skinned.xyz;",
46803
46804                             "#else",
46805
46806                                 "displacedPosition = position;",
46807
46808                             "#endif",
46809
46810                         "}",
46811
46812                     "#else",
46813
46814                         "#ifdef USE_SKINNING",
46815
46816                             "vec4 skinVertex = vec4( position, 1.0 );",
46817
46818                             "vec4 skinned  = boneMatX * skinVertex * skinWeight.x;",
46819                             "skinned       += boneMatY * skinVertex * skinWeight.y;",
46820
46821                             "displacedPosition  = skinned.xyz;",
46822
46823                         "#else",
46824
46825                             "displacedPosition = position;",
46826
46827                         "#endif",
46828
46829                     "#endif",
46830
46831                     //
46832
46833                     "vec4 mvPosition = modelViewMatrix * vec4( displacedPosition, 1.0 );",
46834                     "vec4 mPosition = modelMatrix * vec4( displacedPosition, 1.0 );",
46835
46836                     "gl_Position = projectionMatrix * mvPosition;",
46837
46838                     //
46839
46840                     "vWorldPosition = mPosition.xyz;",
46841                     "vViewPosition = -mvPosition.xyz;",
46842
46843                     // shadows
46844
46845                     "#ifdef USE_SHADOWMAP",
46846
46847                         "for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
46848
46849                             "vShadowCoord[ i ] = shadowMatrix[ i ] * mPosition;",
46850
46851                         "}",
46852
46853                     "#endif",
46854
46855                 "}"
46856
46857             ].join("\n")
46858
46859         },
46860
46861         /* -------------------------------------------------------------------------
46862         //    Cube map shader
46863          ------------------------------------------------------------------------- */
46864
46865         'cube': {
46866
46867             uniforms: { "tCube": { type: "t", value: null },
46868                         "tFlip": { type: "f", value: -1 } },
46869
46870             vertexShader: [
46871
46872                 "varying vec3 vViewPosition;",
46873
46874                 "void main() {",
46875
46876                     "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
46877                     "vViewPosition = cameraPosition - mPosition.xyz;",
46878
46879                     "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
46880
46881                 "}"
46882
46883             ].join("\n"),
46884
46885             fragmentShader: [
46886
46887                 "uniform samplerCube tCube;",
46888                 "uniform float tFlip;",
46889
46890                 "varying vec3 vViewPosition;",
46891
46892                 "void main() {",
46893
46894                     "vec3 wPos = cameraPosition - vViewPosition;",
46895                     "gl_FragColor = textureCube( tCube, vec3( tFlip * wPos.x, wPos.yz ) );",
46896
46897                 "}"
46898
46899             ].join("\n")
46900
46901         }
46902
46903     }
46904
46905 };
46906
46907 };
46908 /**
46909  * @author zz85 / http://www.lab4games.net/zz85/blog
46910  * @author alteredq / http://alteredqualia.com/
46911  *
46912  * For Text operations in three.js (See TextGeometry)
46913  *
46914  * It uses techniques used in:
46915  *
46916  *     typeface.js and canvastext
46917  *         For converting fonts and rendering with javascript
46918  *        http://typeface.neocracy.org
46919  *
46920  *    Triangulation ported from AS3
46921  *        Simple Polygon Triangulation
46922  *        http://actionsnippet.com/?p=1462
46923  *
46924  *     A Method to triangulate shapes with holes
46925  *        http://www.sakri.net/blog/2009/06/12/an-approach-to-triangulating-polygons-with-holes/
46926  *
46927  */
46928
46929 THREE.FontUtils = {
46930
46931     faces : {},
46932
46933     // Just for now. face[weight][style]
46934
46935     face : "helvetiker",
46936     weight: "normal",
46937     style : "normal",
46938     size : 150,
46939     divisions : 10,
46940
46941     getFace : function() {
46942
46943         return this.faces[ this.face ][ this.weight ][ this.style ];
46944
46945     },
46946
46947     loadFace : function( data ) {
46948
46949         var family = data.familyName.toLowerCase();
46950
46951         var ThreeFont = this;
46952
46953         ThreeFont.faces[ family ] = ThreeFont.faces[ family ] || {};
46954
46955         ThreeFont.faces[ family ][ data.cssFontWeight ] = ThreeFont.faces[ family ][ data.cssFontWeight ] || {};
46956         ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data;
46957
46958         var face = ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data;
46959
46960         return data;
46961
46962     },
46963
46964     drawText : function( text ) {
46965
46966         var characterPts = [], allPts = [];
46967
46968         // RenderText
46969
46970         var i, p,
46971             face = this.getFace(),
46972             scale = this.size / face.resolution,
46973             offset = 0,
46974             chars = String( text ).split( '' ),
46975             length = chars.length;
46976
46977         var fontPaths = [];
46978
46979         for ( i = 0; i < length; i ++ ) {
46980
46981             var path = new THREE.Path();
46982
46983             var ret = this.extractGlyphPoints( chars[ i ], face, scale, offset, path );
46984             offset += ret.offset;
46985
46986             fontPaths.push( ret.path );
46987
46988         }
46989
46990         // get the width
46991
46992         var width = offset / 2;
46993         //
46994         // for ( p = 0; p < allPts.length; p++ ) {
46995         //
46996         //     allPts[ p ].x -= width;
46997         //
46998         // }
46999
47000         //var extract = this.extractPoints( allPts, characterPts );
47001         //extract.contour = allPts;
47002
47003         //extract.paths = fontPaths;
47004         //extract.offset = width;
47005
47006         return { paths : fontPaths, offset : width };
47007
47008     },
47009
47010
47011
47012
47013     extractGlyphPoints : function( c, face, scale, offset, path ) {
47014
47015         var pts = [];
47016
47017         var i, i2, divisions,
47018             outline, action, length,
47019             scaleX, scaleY,
47020             x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2,
47021             laste,
47022             glyph = face.glyphs[ c ] || face.glyphs[ '?' ];
47023
47024         if ( !glyph ) return;
47025
47026         if ( glyph.o ) {
47027
47028             outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
47029             length = outline.length;
47030
47031             scaleX = scale;
47032             scaleY = scale;
47033
47034             for ( i = 0; i < length; ) {
47035
47036                 action = outline[ i ++ ];
47037
47038                 //console.log( action );
47039
47040                 switch( action ) {
47041
47042                 case 'm':
47043
47044                     // Move To
47045
47046                     x = outline[ i++ ] * scaleX + offset;
47047                     y = outline[ i++ ] * scaleY;
47048
47049                     path.moveTo( x, y );
47050                     break;
47051
47052                 case 'l':
47053
47054                     // Line To
47055
47056                     x = outline[ i++ ] * scaleX + offset;
47057                     y = outline[ i++ ] * scaleY;
47058                     path.lineTo(x,y);
47059                     break;
47060
47061                 case 'q':
47062
47063                     // QuadraticCurveTo
47064
47065                     cpx  = outline[ i++ ] * scaleX + offset;
47066                     cpy  = outline[ i++ ] * scaleY;
47067                     cpx1 = outline[ i++ ] * scaleX + offset;
47068                     cpy1 = outline[ i++ ] * scaleY;
47069
47070                     path.quadraticCurveTo(cpx1, cpy1, cpx, cpy);
47071
47072                     laste = pts[ pts.length - 1 ];
47073
47074                     if ( laste ) {
47075
47076                         cpx0 = laste.x;
47077                         cpy0 = laste.y;
47078
47079                         for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
47080
47081                             var t = i2 / divisions;
47082                             var tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx );
47083                             var ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy );
47084                       }
47085
47086                   }
47087
47088                   break;
47089
47090                 case 'b':
47091
47092                     // Cubic Bezier Curve
47093
47094                     cpx  = outline[ i++ ] *  scaleX + offset;
47095                     cpy  = outline[ i++ ] *  scaleY;
47096                     cpx1 = outline[ i++ ] *  scaleX + offset;
47097                     cpy1 = outline[ i++ ] * -scaleY;
47098                     cpx2 = outline[ i++ ] *  scaleX + offset;
47099                     cpy2 = outline[ i++ ] * -scaleY;
47100
47101                     path.bezierCurveTo( cpx, cpy, cpx1, cpy1, cpx2, cpy2 );
47102
47103                     laste = pts[ pts.length - 1 ];
47104
47105                     if ( laste ) {
47106
47107                         cpx0 = laste.x;
47108                         cpy0 = laste.y;
47109
47110                         for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
47111
47112                             var t = i2 / divisions;
47113                             var tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx );
47114                             var ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy );
47115
47116                         }
47117
47118                     }
47119
47120                     break;
47121
47122                 }
47123
47124             }
47125         }
47126
47127
47128
47129         return { offset: glyph.ha*scale, path:path};
47130     }
47131
47132 };
47133
47134
47135 THREE.FontUtils.generateShapes = function( text, parameters ) {
47136
47137     // Parameters
47138
47139     parameters = parameters || {};
47140
47141     var size = parameters.size !== undefined ? parameters.size : 100;
47142     var curveSegments = parameters.curveSegments !== undefined ? parameters.curveSegments: 4;
47143
47144     var font = parameters.font !== undefined ? parameters.font : "helvetiker";
47145     var weight = parameters.weight !== undefined ? parameters.weight : "normal";
47146     var style = parameters.style !== undefined ? parameters.style : "normal";
47147
47148     THREE.FontUtils.size = size;
47149     THREE.FontUtils.divisions = curveSegments;
47150
47151     THREE.FontUtils.face = font;
47152     THREE.FontUtils.weight = weight;
47153     THREE.FontUtils.style = style;
47154
47155     // Get a Font data json object
47156
47157     var data = THREE.FontUtils.drawText( text );
47158
47159     var paths = data.paths;
47160     var shapes = [];
47161
47162     for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
47163
47164         Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
47165
47166     }
47167
47168     return shapes;
47169
47170 };
47171
47172
47173 /**
47174  * This code is a quick port of code written in C++ which was submitted to
47175  * flipcode.com by John W. Ratcliff  // July 22, 2000
47176  * See original code and more information here:
47177  * http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
47178  *
47179  * ported to actionscript by Zevan Rosser
47180  * www.actionsnippet.com
47181  *
47182  * ported to javascript by Joshua Koo
47183  * http://www.lab4games.net/zz85/blog
47184  *
47185  */
47186
47187
47188 ( function( namespace ) {
47189
47190     var EPSILON = 0.0000000001;
47191
47192     // takes in an contour array and returns
47193
47194     var process = function( contour, indices ) {
47195
47196         var n = contour.length;
47197
47198         if ( n < 3 ) return null;
47199
47200         var result = [],
47201             verts = [],
47202             vertIndices = [];
47203
47204         /* we want a counter-clockwise polygon in verts */
47205
47206         var u, v, w;
47207
47208         if ( area( contour ) > 0.0 ) {
47209
47210             for ( v = 0; v < n; v++ ) verts[ v ] = v;
47211
47212         } else {
47213
47214             for ( v = 0; v < n; v++ ) verts[ v ] = ( n - 1 ) - v;
47215
47216         }
47217
47218         var nv = n;
47219
47220         /*  remove nv - 2 vertices, creating 1 triangle every time */
47221
47222         var count = 2 * nv;   /* error detection */
47223
47224         for( v = nv - 1; nv > 2; ) {
47225
47226             /* if we loop, it is probably a non-simple polygon */
47227
47228             if ( ( count-- ) <= 0 ) {
47229
47230                 //** Triangulate: ERROR - probable bad polygon!
47231
47232                 //throw ( "Warning, unable to triangulate polygon!" );
47233                 //return null;
47234                 // Sometimes warning is fine, especially polygons are triangulated in reverse.
47235                 console.log( "Warning, unable to triangulate polygon!" );
47236
47237                 if ( indices ) return vertIndices;
47238                 return result;
47239
47240             }
47241
47242             /* three consecutive vertices in current polygon, <u,v,w> */
47243
47244             u = v;          if ( nv <= u ) u = 0;     /* previous */
47245             v = u + 1;  if ( nv <= v ) v = 0;     /* new v    */
47246             w = v + 1;  if ( nv <= w ) w = 0;     /* next     */
47247
47248             if ( snip( contour, u, v, w, nv, verts ) ) {
47249
47250                 var a, b, c, s, t;
47251
47252                 /* true names of the vertices */
47253
47254                 a = verts[ u ];
47255                 b = verts[ v ];
47256                 c = verts[ w ];
47257
47258                 /* output Triangle */
47259
47260                 /*
47261                 result.push( contour[ a ] );
47262                 result.push( contour[ b ] );
47263                 result.push( contour[ c ] );
47264                 */
47265                 result.push( [ contour[ a ],
47266                     contour[ b ],
47267                     contour[ c ] ] );
47268
47269
47270                 vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );
47271
47272                 /* remove v from the remaining polygon */
47273
47274                 for( s = v, t = v + 1; t < nv; s++, t++ ) {
47275
47276                     verts[ s ] = verts[ t ];
47277
47278                 }
47279
47280                 nv--;
47281
47282                 /* reset error detection counter */
47283
47284                 count = 2 * nv;
47285
47286             }
47287
47288         }
47289
47290         if ( indices ) return vertIndices;
47291         return result;
47292
47293     };
47294
47295     // calculate area of the contour polygon
47296
47297     var area = function ( contour ) {
47298
47299         var n = contour.length;
47300         var a = 0.0;
47301
47302         for( var p = n - 1, q = 0; q < n; p = q++ ) {
47303
47304             a += contour[ p ].x * contour[ q ].y - contour[ q ].x * contour[ p ].y;
47305
47306         }
47307
47308         return a * 0.5;
47309
47310     };
47311
47312     // see if p is inside triangle abc
47313
47314     var insideTriangle = function( ax, ay,
47315                                    bx, by,
47316                                    cx, cy,
47317                                    px, py ) {
47318
47319           var aX, aY, bX, bY;
47320           var cX, cY, apx, apy;
47321           var bpx, bpy, cpx, cpy;
47322           var cCROSSap, bCROSScp, aCROSSbp;
47323
47324           aX = cx - bx;  aY = cy - by;
47325           bX = ax - cx;  bY = ay - cy;
47326           cX = bx - ax;  cY = by - ay;
47327           apx= px  -ax;  apy= py - ay;
47328           bpx= px - bx;  bpy= py - by;
47329           cpx= px - cx;  cpy= py - cy;
47330
47331           aCROSSbp = aX*bpy - aY*bpx;
47332           cCROSSap = cX*apy - cY*apx;
47333           bCROSScp = bX*cpy - bY*cpx;
47334
47335           return ( (aCROSSbp >= 0.0) && (bCROSScp >= 0.0) && (cCROSSap >= 0.0) );
47336
47337     };
47338
47339
47340     var snip = function ( contour, u, v, w, n, verts ) {
47341
47342         var p;
47343         var ax, ay, bx, by;
47344         var cx, cy, px, py;
47345
47346         ax = contour[ verts[ u ] ].x;
47347         ay = contour[ verts[ u ] ].y;
47348
47349         bx = contour[ verts[ v ] ].x;
47350         by = contour[ verts[ v ] ].y;
47351
47352         cx = contour[ verts[ w ] ].x;
47353         cy = contour[ verts[ w ] ].y;
47354
47355         if ( EPSILON > (((bx-ax)*(cy-ay)) - ((by-ay)*(cx-ax))) ) return false;
47356
47357             for ( p = 0; p < n; p++ ) {
47358
47359                 if( (p == u) || (p == v) || (p == w) ) continue;
47360
47361                 px = contour[ verts[ p ] ].x
47362                 py = contour[ verts[ p ] ].y
47363
47364                 if ( insideTriangle( ax, ay, bx, by, cx, cy, px, py ) ) return false;
47365
47366           }
47367
47368           return true;
47369
47370     };
47371
47372
47373     namespace.Triangulate = process;
47374     namespace.Triangulate.area = area;
47375
47376     return namespace;
47377
47378 })(THREE.FontUtils);
47379
47380 // To use the typeface.js face files, hook up the API
47381 self._typeface_js = { faces: THREE.FontUtils.faces, loadFace: THREE.FontUtils.loadFace };/**
47382  * @author zz85 / http://www.lab4games.net/zz85/blog
47383  * Extensible curve object
47384  *
47385  * Some common of Curve methods
47386  * .getPoint(t), getTangent(t)
47387  * .getPointAt(u), getTagentAt(u)
47388  * .getPoints(), .getSpacedPoints()
47389  * .getLength()
47390  * .updateArcLengths()
47391  *
47392  * This file contains following classes:
47393  *
47394  * -- 2d classes --
47395  * THREE.Curve
47396  * THREE.LineCurve
47397  * THREE.QuadraticBezierCurve
47398  * THREE.CubicBezierCurve
47399  * THREE.SplineCurve
47400  * THREE.ArcCurve
47401  * THREE.EllipseCurve
47402  *
47403  * -- 3d classes --
47404  * THREE.LineCurve3
47405  * THREE.QuadraticBezierCurve3
47406  * THREE.CubicBezierCurve3
47407  * THREE.SplineCurve3
47408  * THREE.ClosedSplineCurve3
47409  *
47410  * A series of curves can be represented as a THREE.CurvePath
47411  *
47412  **/
47413
47414 /**************************************************************
47415  *    Abstract Curve base class
47416  **************************************************************/
47417
47418 THREE.Curve = function () {
47419
47420 };
47421
47422 // Virtual base class method to overwrite and implement in subclasses
47423 //    - t [0 .. 1]
47424
47425 THREE.Curve.prototype.getPoint = function ( t ) {
47426
47427     console.log( "Warning, getPoint() not implemented!" );
47428     return null;
47429
47430 };
47431
47432 // Get point at relative position in curve according to arc length
47433 // - u [0 .. 1]
47434
47435 THREE.Curve.prototype.getPointAt = function ( u ) {
47436
47437     var t = this.getUtoTmapping( u );
47438     return this.getPoint( t );
47439
47440 };
47441
47442 // Get sequence of points using getPoint( t )
47443
47444 THREE.Curve.prototype.getPoints = function ( divisions ) {
47445
47446     if ( !divisions ) divisions = 5;
47447
47448     var d, pts = [];
47449
47450     for ( d = 0; d <= divisions; d ++ ) {
47451
47452         pts.push( this.getPoint( d / divisions ) );
47453
47454     }
47455
47456     return pts;
47457
47458 };
47459
47460 // Get sequence of points using getPointAt( u )
47461
47462 THREE.Curve.prototype.getSpacedPoints = function ( divisions ) {
47463
47464     if ( !divisions ) divisions = 5;
47465
47466     var d, pts = [];
47467
47468     for ( d = 0; d <= divisions; d ++ ) {
47469
47470         pts.push( this.getPointAt( d / divisions ) );
47471
47472     }
47473
47474     return pts;
47475
47476 };
47477
47478 // Get total curve arc length
47479
47480 THREE.Curve.prototype.getLength = function () {
47481
47482     var lengths = this.getLengths();
47483     return lengths[ lengths.length - 1 ];
47484
47485 };
47486
47487 // Get list of cumulative segment lengths
47488
47489 THREE.Curve.prototype.getLengths = function ( divisions ) {
47490
47491     if ( !divisions ) divisions = (this.__arcLengthDivisions) ? (this.__arcLengthDivisions): 200;
47492
47493     if ( this.cacheArcLengths
47494         && ( this.cacheArcLengths.length == divisions + 1 )
47495         && !this.needsUpdate) {
47496
47497         //console.log( "cached", this.cacheArcLengths );
47498         return this.cacheArcLengths;
47499
47500     }
47501
47502     this.needsUpdate = false;
47503
47504     var cache = [];
47505     var current, last = this.getPoint( 0 );
47506     var p, sum = 0;
47507
47508     cache.push( 0 );
47509
47510     for ( p = 1; p <= divisions; p ++ ) {
47511
47512         current = this.getPoint ( p / divisions );
47513         sum += current.distanceTo( last );
47514         cache.push( sum );
47515         last = current;
47516
47517     }
47518
47519     this.cacheArcLengths = cache;
47520
47521     return cache; // { sums: cache, sum:sum }; Sum is in the last element.
47522
47523 };
47524
47525
47526 THREE.Curve.prototype.updateArcLengths = function() {
47527     this.needsUpdate = true;
47528     this.getLengths();
47529 };
47530
47531 // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equi distance
47532
47533 THREE.Curve.prototype.getUtoTmapping = function ( u, distance ) {
47534
47535     var arcLengths = this.getLengths();
47536
47537     var i = 0, il = arcLengths.length;
47538
47539     var targetArcLength; // The targeted u distance value to get
47540
47541     if ( distance ) {
47542
47543         targetArcLength = distance;
47544
47545     } else {
47546
47547         targetArcLength = u * arcLengths[ il - 1 ];
47548
47549     }
47550
47551     //var time = Date.now();
47552
47553     // binary search for the index with largest value smaller than target u distance
47554
47555     var low = 0, high = il - 1, comparison;
47556
47557     while ( low <= high ) {
47558
47559         i = Math.floor( low + ( high - low ) / 2 ); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
47560
47561         comparison = arcLengths[ i ] - targetArcLength;
47562
47563         if ( comparison < 0 ) {
47564
47565             low = i + 1;
47566             continue;
47567
47568         } else if ( comparison > 0 ) {
47569
47570             high = i - 1;
47571             continue;
47572
47573         } else {
47574
47575             high = i;
47576             break;
47577
47578             // DONE
47579
47580         }
47581
47582     }
47583
47584     i = high;
47585
47586     //console.log('b' , i, low, high, Date.now()- time);
47587
47588     if ( arcLengths[ i ] == targetArcLength ) {
47589
47590         var t = i / ( il - 1 );
47591         return t;
47592
47593     }
47594
47595     // we could get finer grain at lengths, or use simple interpolatation between two points
47596
47597     var lengthBefore = arcLengths[ i ];
47598     var lengthAfter = arcLengths[ i + 1 ];
47599
47600     var segmentLength = lengthAfter - lengthBefore;
47601
47602     // determine where we are between the 'before' and 'after' points
47603
47604     var segmentFraction = ( targetArcLength - lengthBefore ) / segmentLength;
47605
47606     // add that fractional amount to t
47607
47608     var t = ( i + segmentFraction ) / ( il -1 );
47609
47610     return t;
47611
47612 };
47613
47614
47615 // In 2D space, there are actually 2 normal vectors,
47616 // and in 3D space, infinte
47617 // TODO this should be depreciated.
47618 THREE.Curve.prototype.getNormalVector = function( t ) {
47619
47620     var vec = this.getTangent( t );
47621
47622     return new THREE.Vector2( -vec.y , vec.x );
47623
47624 };
47625
47626 // Returns a unit vector tangent at t
47627 // In case any sub curve does not implement its tangent / normal finding,
47628 // we get 2 points with a small delta and find a gradient of the 2 points
47629 // which seems to make a reasonable approximation
47630
47631 THREE.Curve.prototype.getTangent = function( t ) {
47632
47633     var delta = 0.0001;
47634     var t1 = t - delta;
47635     var t2 = t + delta;
47636
47637     // Capping in case of danger
47638
47639     if ( t1 < 0 ) t1 = 0;
47640     if ( t2 > 1 ) t2 = 1;
47641
47642     var pt1 = this.getPoint( t1 );
47643     var pt2 = this.getPoint( t2 );
47644
47645     var vec = pt2.clone().subSelf(pt1);
47646     return vec.normalize();
47647
47648 };
47649
47650
47651 THREE.Curve.prototype.getTangentAt = function ( u ) {
47652
47653     var t = this.getUtoTmapping( u );
47654     return this.getTangent( t );
47655
47656 };
47657
47658 /**************************************************************
47659  *    Line
47660  **************************************************************/
47661
47662 THREE.LineCurve = function ( v1, v2 ) {
47663
47664     this.v1 = v1;
47665     this.v2 = v2;
47666
47667 };
47668
47669 THREE.LineCurve.prototype = Object.create( THREE.Curve.prototype );
47670
47671 THREE.LineCurve.prototype.getPoint = function ( t ) {
47672
47673     var point = this.v2.clone().subSelf(this.v1);
47674     point.multiplyScalar( t ).addSelf( this.v1 );
47675
47676     return point;
47677
47678 };
47679
47680 // Line curve is linear, so we can overwrite default getPointAt
47681
47682 THREE.LineCurve.prototype.getPointAt = function ( u ) {
47683
47684     return this.getPoint( u );
47685
47686 };
47687
47688 THREE.LineCurve.prototype.getTangent = function( t ) {
47689
47690     var tangent = this.v2.clone().subSelf(this.v1);
47691
47692     return tangent.normalize();
47693
47694 };
47695
47696 /**************************************************************
47697  *    Quadratic Bezier curve
47698  **************************************************************/
47699
47700
47701 THREE.QuadraticBezierCurve = function ( v0, v1, v2 ) {
47702
47703     this.v0 = v0;
47704     this.v1 = v1;
47705     this.v2 = v2;
47706
47707 };
47708
47709 THREE.QuadraticBezierCurve.prototype = Object.create( THREE.Curve.prototype );
47710
47711
47712 THREE.QuadraticBezierCurve.prototype.getPoint = function ( t ) {
47713
47714     var tx, ty;
47715
47716     tx = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x );
47717     ty = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y );
47718
47719     return new THREE.Vector2( tx, ty );
47720
47721 };
47722
47723
47724 THREE.QuadraticBezierCurve.prototype.getTangent = function( t ) {
47725
47726     var tx, ty;
47727
47728     tx = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.x, this.v1.x, this.v2.x );
47729     ty = THREE.Curve.Utils.tangentQuadraticBezier( t, this.v0.y, this.v1.y, this.v2.y );
47730
47731     // returns unit vector
47732
47733     var tangent = new THREE.Vector2( tx, ty );
47734     tangent.normalize();
47735
47736     return tangent;
47737
47738 };
47739
47740
47741 /**************************************************************
47742  *    Cubic Bezier curve
47743  **************************************************************/
47744
47745 THREE.CubicBezierCurve = function ( v0, v1, v2, v3 ) {
47746
47747     this.v0 = v0;
47748     this.v1 = v1;
47749     this.v2 = v2;
47750     this.v3 = v3;
47751
47752 };
47753
47754 THREE.CubicBezierCurve.prototype = Object.create( THREE.Curve.prototype );
47755
47756 THREE.CubicBezierCurve.prototype.getPoint = function ( t ) {
47757
47758     var tx, ty;
47759
47760     tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
47761     ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
47762
47763     return new THREE.Vector2( tx, ty );
47764
47765 };
47766
47767 THREE.CubicBezierCurve.prototype.getTangent = function( t ) {
47768
47769     var tx, ty;
47770
47771     tx = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
47772     ty = THREE.Curve.Utils.tangentCubicBezier( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
47773
47774     var tangent = new THREE.Vector2( tx, ty );
47775     tangent.normalize();
47776
47777     return tangent;
47778
47779 };
47780
47781
47782 /**************************************************************
47783  *    Spline curve
47784  **************************************************************/
47785
47786 THREE.SplineCurve = function ( points /* array of Vector2 */ ) {
47787
47788     this.points = (points == undefined) ? [] : points;
47789
47790 };
47791
47792 THREE.SplineCurve.prototype = Object.create( THREE.Curve.prototype );
47793
47794 THREE.SplineCurve.prototype.getPoint = function ( t ) {
47795
47796     var v = new THREE.Vector2();
47797     var c = [];
47798     var points = this.points, point, intPoint, weight;
47799     point = ( points.length - 1 ) * t;
47800
47801     intPoint = Math.floor( point );
47802     weight = point - intPoint;
47803
47804     c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
47805     c[ 1 ] = intPoint;
47806     c[ 2 ] = intPoint  > points.length - 2 ? points.length -1 : intPoint + 1;
47807     c[ 3 ] = intPoint  > points.length - 3 ? points.length -1 : intPoint + 2;
47808
47809     v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
47810     v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
47811
47812     return v;
47813
47814 };
47815
47816 /**************************************************************
47817  *    Ellipse curve
47818  **************************************************************/
47819
47820 THREE.EllipseCurve = function ( aX, aY, xRadius, yRadius,
47821                             aStartAngle, aEndAngle,
47822                             aClockwise ) {
47823
47824     this.aX = aX;
47825     this.aY = aY;
47826
47827     this.xRadius = xRadius;
47828     this.yRadius = yRadius;
47829
47830     this.aStartAngle = aStartAngle;
47831     this.aEndAngle = aEndAngle;
47832
47833     this.aClockwise = aClockwise;
47834
47835 };
47836
47837 THREE.EllipseCurve.prototype = Object.create( THREE.Curve.prototype );
47838
47839 THREE.EllipseCurve.prototype.getPoint = function ( t ) {
47840
47841     var deltaAngle = this.aEndAngle - this.aStartAngle;
47842
47843     if ( !this.aClockwise ) {
47844
47845         t = 1 - t;
47846
47847     }
47848
47849     var angle = this.aStartAngle + t * deltaAngle;
47850
47851     var tx = this.aX + this.xRadius * Math.cos( angle );
47852     var ty = this.aY + this.yRadius * Math.sin( angle );
47853
47854     return new THREE.Vector2( tx, ty );
47855
47856 };
47857
47858 /**************************************************************
47859  *    Arc curve
47860  **************************************************************/
47861
47862 THREE.ArcCurve = function ( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) {
47863
47864     THREE.EllipseCurve.call( this, aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise );
47865 };
47866
47867 THREE.ArcCurve.prototype = Object.create( THREE.EllipseCurve.prototype );
47868
47869
47870 /**************************************************************
47871  *    Utils
47872  **************************************************************/
47873
47874 THREE.Curve.Utils = {
47875
47876     tangentQuadraticBezier: function ( t, p0, p1, p2 ) {
47877
47878         return 2 * ( 1 - t ) * ( p1 - p0 ) + 2 * t * ( p2 - p1 );
47879
47880     },
47881
47882     // Puay Bing, thanks for helping with this derivative!
47883
47884     tangentCubicBezier: function (t, p0, p1, p2, p3 ) {
47885
47886         return -3 * p0 * (1 - t) * (1 - t)  +
47887             3 * p1 * (1 - t) * (1-t) - 6 *t *p1 * (1-t) +
47888             6 * t *  p2 * (1-t) - 3 * t * t * p2 +
47889             3 * t * t * p3;
47890     },
47891
47892
47893     tangentSpline: function ( t, p0, p1, p2, p3 ) {
47894
47895         // To check if my formulas are correct
47896
47897         var h00 = 6 * t * t - 6 * t;     // derived from 2t^3 − 3t^2 + 1
47898         var h10 = 3 * t * t - 4 * t + 1; // t^3 − 2t^2 + t
47899         var h01 = -6 * t * t + 6 * t;     // − 2t3 + 3t2
47900         var h11 = 3 * t * t - 2 * t;    // t3 − t2
47901
47902         return h00 + h10 + h01 + h11;
47903
47904     },
47905
47906     // Catmull-Rom
47907
47908     interpolate: function( p0, p1, p2, p3, t ) {
47909
47910         var v0 = ( p2 - p0 ) * 0.5;
47911         var v1 = ( p3 - p1 ) * 0.5;
47912         var t2 = t * t;
47913         var t3 = t * t2;
47914         return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
47915
47916     }
47917
47918 };
47919
47920
47921 // TODO: Transformation for Curves?
47922
47923 /**************************************************************
47924  *    3D Curves
47925  **************************************************************/
47926
47927 // A Factory method for creating new curve subclasses
47928
47929 THREE.Curve.create = function ( constructor, getPointFunc ) {
47930
47931     constructor.prototype = Object.create( THREE.Curve.prototype );
47932     constructor.prototype.getPoint = getPointFunc;
47933
47934     return constructor;
47935
47936 };
47937
47938
47939 /**************************************************************
47940  *    Line3D
47941  **************************************************************/
47942
47943 THREE.LineCurve3 = THREE.Curve.create(
47944
47945     function ( v1, v2 ) {
47946
47947         this.v1 = v1;
47948         this.v2 = v2;
47949
47950     },
47951
47952     function ( t ) {
47953
47954         var r = new THREE.Vector3();
47955
47956
47957         r.sub( this.v2, this.v1 ); // diff
47958         r.multiplyScalar( t );
47959         r.addSelf( this.v1 );
47960
47961         return r;
47962
47963     }
47964
47965 );
47966
47967
47968 /**************************************************************
47969  *    Quadratic Bezier 3D curve
47970  **************************************************************/
47971
47972 THREE.QuadraticBezierCurve3 = THREE.Curve.create(
47973
47974     function ( v0, v1, v2 ) {
47975
47976         this.v0 = v0;
47977         this.v1 = v1;
47978         this.v2 = v2;
47979
47980     },
47981
47982     function ( t ) {
47983
47984         var tx, ty, tz;
47985
47986         tx = THREE.Shape.Utils.b2( t, this.v0.x, this.v1.x, this.v2.x );
47987         ty = THREE.Shape.Utils.b2( t, this.v0.y, this.v1.y, this.v2.y );
47988         tz = THREE.Shape.Utils.b2( t, this.v0.z, this.v1.z, this.v2.z );
47989
47990         return new THREE.Vector3( tx, ty, tz );
47991
47992     }
47993
47994 );
47995
47996
47997
47998 /**************************************************************
47999  *    Cubic Bezier 3D curve
48000  **************************************************************/
48001
48002 THREE.CubicBezierCurve3 = THREE.Curve.create(
48003
48004     function ( v0, v1, v2, v3 ) {
48005
48006         this.v0 = v0;
48007         this.v1 = v1;
48008         this.v2 = v2;
48009         this.v3 = v3;
48010
48011     },
48012
48013     function ( t ) {
48014
48015         var tx, ty, tz;
48016
48017         tx = THREE.Shape.Utils.b3( t, this.v0.x, this.v1.x, this.v2.x, this.v3.x );
48018         ty = THREE.Shape.Utils.b3( t, this.v0.y, this.v1.y, this.v2.y, this.v3.y );
48019         tz = THREE.Shape.Utils.b3( t, this.v0.z, this.v1.z, this.v2.z, this.v3.z );
48020
48021         return new THREE.Vector3( tx, ty, tz );
48022
48023     }
48024
48025 );
48026
48027
48028
48029 /**************************************************************
48030  *    Spline 3D curve
48031  **************************************************************/
48032
48033
48034 THREE.SplineCurve3 = THREE.Curve.create(
48035
48036     function ( points /* array of Vector3 */) {
48037
48038         this.points = (points == undefined) ? [] : points;
48039
48040     },
48041
48042     function ( t ) {
48043
48044         var v = new THREE.Vector3();
48045         var c = [];
48046         var points = this.points, point, intPoint, weight;
48047         point = ( points.length - 1 ) * t;
48048
48049         intPoint = Math.floor( point );
48050         weight = point - intPoint;
48051
48052         c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
48053         c[ 1 ] = intPoint;
48054         c[ 2 ] = intPoint  > points.length - 2 ? points.length - 1 : intPoint + 1;
48055         c[ 3 ] = intPoint  > points.length - 3 ? points.length - 1 : intPoint + 2;
48056
48057         var pt0 = points[ c[0] ],
48058             pt1 = points[ c[1] ],
48059             pt2 = points[ c[2] ],
48060             pt3 = points[ c[3] ];
48061
48062         v.x = THREE.Curve.Utils.interpolate(pt0.x, pt1.x, pt2.x, pt3.x, weight);
48063         v.y = THREE.Curve.Utils.interpolate(pt0.y, pt1.y, pt2.y, pt3.y, weight);
48064         v.z = THREE.Curve.Utils.interpolate(pt0.z, pt1.z, pt2.z, pt3.z, weight);
48065
48066         return v;
48067
48068     }
48069
48070 );
48071
48072
48073 // THREE.SplineCurve3.prototype.getTangent = function(t) {
48074 //         var v = new THREE.Vector3();
48075 //         var c = [];
48076 //         var points = this.points, point, intPoint, weight;
48077 //         point = ( points.length - 1 ) * t;
48078
48079 //         intPoint = Math.floor( point );
48080 //         weight = point - intPoint;
48081
48082 //         c[ 0 ] = intPoint == 0 ? intPoint : intPoint - 1;
48083 //         c[ 1 ] = intPoint;
48084 //         c[ 2 ] = intPoint  > points.length - 2 ? points.length - 1 : intPoint + 1;
48085 //         c[ 3 ] = intPoint  > points.length - 3 ? points.length - 1 : intPoint + 2;
48086
48087 //         var pt0 = points[ c[0] ],
48088 //             pt1 = points[ c[1] ],
48089 //             pt2 = points[ c[2] ],
48090 //             pt3 = points[ c[3] ];
48091
48092 //     // t = weight;
48093 //     v.x = THREE.Curve.Utils.tangentSpline( t, pt0.x, pt1.x, pt2.x, pt3.x );
48094 //     v.y = THREE.Curve.Utils.tangentSpline( t, pt0.y, pt1.y, pt2.y, pt3.y );
48095 //     v.z = THREE.Curve.Utils.tangentSpline( t, pt0.z, pt1.z, pt2.z, pt3.z );
48096
48097 //     return v;
48098
48099 // }
48100
48101 /**************************************************************
48102  *    Closed Spline 3D curve
48103  **************************************************************/
48104
48105
48106 THREE.ClosedSplineCurve3 = THREE.Curve.create(
48107
48108     function ( points /* array of Vector3 */) {
48109
48110         this.points = (points == undefined) ? [] : points;
48111
48112     },
48113
48114     function ( t ) {
48115
48116         var v = new THREE.Vector3();
48117         var c = [];
48118         var points = this.points, point, intPoint, weight;
48119         point = ( points.length - 0 ) * t;
48120             // This needs to be from 0-length +1
48121
48122         intPoint = Math.floor( point );
48123         weight = point - intPoint;
48124
48125         intPoint += intPoint > 0 ? 0 : ( Math.floor( Math.abs( intPoint ) / points.length ) + 1 ) * points.length;
48126         c[ 0 ] = ( intPoint - 1 ) % points.length;
48127         c[ 1 ] = ( intPoint ) % points.length;
48128         c[ 2 ] = ( intPoint + 1 ) % points.length;
48129         c[ 3 ] = ( intPoint + 2 ) % points.length;
48130
48131         v.x = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].x, points[ c[ 1 ] ].x, points[ c[ 2 ] ].x, points[ c[ 3 ] ].x, weight );
48132         v.y = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].y, points[ c[ 1 ] ].y, points[ c[ 2 ] ].y, points[ c[ 3 ] ].y, weight );
48133         v.z = THREE.Curve.Utils.interpolate( points[ c[ 0 ] ].z, points[ c[ 1 ] ].z, points[ c[ 2 ] ].z, points[ c[ 3 ] ].z, weight );
48134
48135         return v;
48136
48137     }
48138
48139 );
48140 /**
48141  * @author zz85 / http://www.lab4games.net/zz85/blog
48142  *
48143  **/
48144
48145 /**************************************************************
48146  *    Curved Path - a curve path is simply a array of connected
48147  *  curves, but retains the api of a curve
48148  **************************************************************/
48149
48150 THREE.CurvePath = function () {
48151
48152     this.curves = [];
48153     this.bends = [];
48154
48155     this.autoClose = false; // Automatically closes the path
48156 };
48157
48158 THREE.CurvePath.prototype = Object.create( THREE.Curve.prototype );
48159
48160 THREE.CurvePath.prototype.add = function ( curve ) {
48161
48162     this.curves.push( curve );
48163
48164 };
48165
48166 THREE.CurvePath.prototype.checkConnection = function() {
48167     // TODO
48168     // If the ending of curve is not connected to the starting
48169     // or the next curve, then, this is not a real path
48170 };
48171
48172 THREE.CurvePath.prototype.closePath = function() {
48173     // TODO Test
48174     // and verify for vector3 (needs to implement equals)
48175     // Add a line curve if start and end of lines are not connected
48176     var startPoint = this.curves[0].getPoint(0);
48177     var endPoint = this.curves[this.curves.length-1].getPoint(1);
48178
48179     if (!startPoint.equals(endPoint)) {
48180         this.curves.push( new THREE.LineCurve(endPoint, startPoint) );
48181     }
48182
48183 };
48184
48185 // To get accurate point with reference to
48186 // entire path distance at time t,
48187 // following has to be done:
48188
48189 // 1. Length of each sub path have to be known
48190 // 2. Locate and identify type of curve
48191 // 3. Get t for the curve
48192 // 4. Return curve.getPointAt(t')
48193
48194 THREE.CurvePath.prototype.getPoint = function( t ) {
48195
48196     var d = t * this.getLength();
48197     var curveLengths = this.getCurveLengths();
48198     var i = 0, diff, curve;
48199
48200     // To think about boundaries points.
48201
48202     while ( i < curveLengths.length ) {
48203
48204         if ( curveLengths[ i ] >= d ) {
48205
48206             diff = curveLengths[ i ] - d;
48207             curve = this.curves[ i ];
48208
48209             var u = 1 - diff / curve.getLength();
48210
48211             return curve.getPointAt( u );
48212
48213             break;
48214         }
48215
48216         i ++;
48217
48218     }
48219
48220     return null;
48221
48222     // loop where sum != 0, sum > d , sum+1 <d
48223
48224 };
48225
48226 /*
48227 THREE.CurvePath.prototype.getTangent = function( t ) {
48228 };*/
48229
48230
48231 // We cannot use the default THREE.Curve getPoint() with getLength() because in
48232 // THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
48233 // getPoint() depends on getLength
48234
48235 THREE.CurvePath.prototype.getLength = function() {
48236
48237     var lens = this.getCurveLengths();
48238     return lens[ lens.length - 1 ];
48239
48240 };
48241
48242 // Compute lengths and cache them
48243 // We cannot overwrite getLengths() because UtoT mapping uses it.
48244
48245 THREE.CurvePath.prototype.getCurveLengths = function() {
48246
48247     // We use cache values if curves and cache array are same length
48248
48249     if ( this.cacheLengths && this.cacheLengths.length == this.curves.length ) {
48250
48251         return this.cacheLengths;
48252
48253     };
48254
48255     // Get length of subsurve
48256     // Push sums into cached array
48257
48258     var lengths = [], sums = 0;
48259     var i, il = this.curves.length;
48260
48261     for ( i = 0; i < il; i ++ ) {
48262
48263         sums += this.curves[ i ].getLength();
48264         lengths.push( sums );
48265
48266     }
48267
48268     this.cacheLengths = lengths;
48269
48270     return lengths;
48271
48272 };
48273
48274
48275
48276 // Returns min and max coordinates, as well as centroid
48277
48278 THREE.CurvePath.prototype.getBoundingBox = function () {
48279
48280     var points = this.getPoints();
48281
48282     var maxX, maxY, maxZ;
48283     var minX, minY, minZ;
48284
48285     maxX = maxY = Number.NEGATIVE_INFINITY;
48286     minX = minY = Number.POSITIVE_INFINITY;
48287
48288     var p, i, il, sum;
48289
48290     var v3 = points[0] instanceof THREE.Vector3;
48291
48292     sum = v3 ? new THREE.Vector3() : new THREE.Vector2();
48293
48294     for ( i = 0, il = points.length; i < il; i ++ ) {
48295
48296         p = points[ i ];
48297
48298         if ( p.x > maxX ) maxX = p.x;
48299         else if ( p.x < minX ) minX = p.x;
48300
48301         if ( p.y > maxY ) maxY = p.y;
48302         else if ( p.y < minY ) minY = p.y;
48303
48304         if (v3) {
48305
48306             if ( p.z > maxZ ) maxZ = p.z;
48307             else if ( p.z < minZ ) minZ = p.z;
48308
48309         }
48310
48311         sum.addSelf( p );
48312
48313     }
48314
48315     var ret = {
48316
48317         minX: minX,
48318         minY: minY,
48319         maxX: maxX,
48320         maxY: maxY,
48321         centroid: sum.divideScalar( il )
48322
48323     };
48324
48325     if (v3) {
48326
48327         ret.maxZ = maxZ;
48328         ret.minZ = minZ;
48329
48330     }
48331
48332     return ret;
48333
48334 };
48335
48336 /**************************************************************
48337  *    Create Geometries Helpers
48338  **************************************************************/
48339
48340 /// Generate geometry from path points (for Line or ParticleSystem objects)
48341
48342 THREE.CurvePath.prototype.createPointsGeometry = function( divisions ) {
48343
48344     var pts = this.getPoints( divisions, true );
48345     return this.createGeometry( pts );
48346
48347 };
48348
48349 // Generate geometry from equidistance sampling along the path
48350
48351 THREE.CurvePath.prototype.createSpacedPointsGeometry = function( divisions ) {
48352
48353     var pts = this.getSpacedPoints( divisions, true );
48354     return this.createGeometry( pts );
48355
48356 };
48357
48358 THREE.CurvePath.prototype.createGeometry = function( points ) {
48359
48360     var geometry = new THREE.Geometry();
48361
48362     for ( var i = 0; i < points.length; i ++ ) {
48363
48364         geometry.vertices.push( new THREE.Vector3( points[ i ].x, points[ i ].y, points[ i ].z || 0) );
48365
48366     }
48367
48368     return geometry;
48369
48370 };
48371
48372
48373 /**************************************************************
48374  *    Bend / Wrap Helper Methods
48375  **************************************************************/
48376
48377 // Wrap path / Bend modifiers?
48378
48379 THREE.CurvePath.prototype.addWrapPath = function ( bendpath ) {
48380
48381     this.bends.push( bendpath );
48382
48383 };
48384
48385 THREE.CurvePath.prototype.getTransformedPoints = function( segments, bends ) {
48386
48387     var oldPts = this.getPoints( segments ); // getPoints getSpacedPoints
48388     var i, il;
48389
48390     if ( !bends ) {
48391
48392         bends = this.bends;
48393
48394     }
48395
48396     for ( i = 0, il = bends.length; i < il; i ++ ) {
48397
48398         oldPts = this.getWrapPoints( oldPts, bends[ i ] );
48399
48400     }
48401
48402     return oldPts;
48403
48404 };
48405
48406 THREE.CurvePath.prototype.getTransformedSpacedPoints = function( segments, bends ) {
48407
48408     var oldPts = this.getSpacedPoints( segments );
48409
48410     var i, il;
48411
48412     if ( !bends ) {
48413
48414         bends = this.bends;
48415
48416     }
48417
48418     for ( i = 0, il = bends.length; i < il; i ++ ) {
48419
48420         oldPts = this.getWrapPoints( oldPts, bends[ i ] );
48421
48422     }
48423
48424     return oldPts;
48425
48426 };
48427
48428 // This returns getPoints() bend/wrapped around the contour of a path.
48429 // Read http://www.planetclegg.com/projects/WarpingTextToSplines.html
48430
48431 THREE.CurvePath.prototype.getWrapPoints = function ( oldPts, path ) {
48432
48433     var bounds = this.getBoundingBox();
48434
48435     var i, il, p, oldX, oldY, xNorm;
48436
48437     for ( i = 0, il = oldPts.length; i < il; i ++ ) {
48438
48439         p = oldPts[ i ];
48440
48441         oldX = p.x;
48442         oldY = p.y;
48443
48444         xNorm = oldX / bounds.maxX;
48445
48446         // If using actual distance, for length > path, requires line extrusions
48447         //xNorm = path.getUtoTmapping(xNorm, oldX); // 3 styles. 1) wrap stretched. 2) wrap stretch by arc length 3) warp by actual distance
48448
48449         xNorm = path.getUtoTmapping( xNorm, oldX );
48450
48451         // check for out of bounds?
48452
48453         var pathPt = path.getPoint( xNorm );
48454         var normal = path.getNormalVector( xNorm ).multiplyScalar( oldY );
48455
48456         p.x = pathPt.x + normal.x;
48457         p.y = pathPt.y + normal.y;
48458
48459     }
48460
48461     return oldPts;
48462
48463 };
48464
48465 /**
48466  * @author alteredq / http://alteredqualia.com/
48467  */
48468
48469 THREE.Gyroscope = function () {
48470
48471     THREE.Object3D.call( this );
48472
48473 };
48474
48475 THREE.Gyroscope.prototype = Object.create( THREE.Object3D.prototype );
48476
48477 THREE.Gyroscope.prototype.updateMatrixWorld = function ( force ) {
48478
48479     this.matrixAutoUpdate && this.updateMatrix();
48480
48481     // update matrixWorld
48482
48483     if ( this.matrixWorldNeedsUpdate || force ) {
48484
48485         if ( this.parent ) {
48486
48487             this.matrixWorld.multiply( this.parent.matrixWorld, this.matrix );
48488
48489             this.matrixWorld.decompose( this.translationWorld, this.rotationWorld, this.scaleWorld );
48490             this.matrix.decompose( this.translationObject, this.rotationObject, this.scaleObject );
48491
48492             this.matrixWorld.compose( this.translationWorld, this.rotationObject, this.scaleWorld );
48493
48494
48495         } else {
48496
48497             this.matrixWorld.copy( this.matrix );
48498
48499         }
48500
48501
48502         this.matrixWorldNeedsUpdate = false;
48503
48504         force = true;
48505
48506     }
48507
48508     // update children
48509
48510     for ( var i = 0, l = this.children.length; i < l; i ++ ) {
48511
48512         this.children[ i ].updateMatrixWorld( force );
48513
48514     }
48515
48516 };
48517
48518 THREE.Gyroscope.prototype.translationWorld = new THREE.Vector3();
48519 THREE.Gyroscope.prototype.translationObject = new THREE.Vector3();
48520 THREE.Gyroscope.prototype.rotationWorld = new THREE.Quaternion();
48521 THREE.Gyroscope.prototype.rotationObject = new THREE.Quaternion();
48522 THREE.Gyroscope.prototype.scaleWorld = new THREE.Vector3();
48523 THREE.Gyroscope.prototype.scaleObject = new THREE.Vector3();
48524
48525 /**
48526  * @author zz85 / http://www.lab4games.net/zz85/blog
48527  * Creates free form 2d path using series of points, lines or curves.
48528  *
48529  **/
48530
48531 THREE.Path = function ( points ) {
48532
48533     THREE.CurvePath.call(this);
48534
48535     this.actions = [];
48536
48537     if ( points ) {
48538
48539         this.fromPoints( points );
48540
48541     }
48542
48543 };
48544
48545 THREE.Path.prototype = Object.create( THREE.CurvePath.prototype );
48546
48547 THREE.PathActions = {
48548
48549     MOVE_TO: 'moveTo',
48550     LINE_TO: 'lineTo',
48551     QUADRATIC_CURVE_TO: 'quadraticCurveTo', // Bezier quadratic curve
48552     BEZIER_CURVE_TO: 'bezierCurveTo',         // Bezier cubic curve
48553     CSPLINE_THRU: 'splineThru',                // Catmull-rom spline
48554     ARC: 'arc',                                // Circle
48555     ELLIPSE: 'ellipse'
48556 };
48557
48558 // TODO Clean up PATH API
48559
48560 // Create path using straight lines to connect all points
48561 // - vectors: array of Vector2
48562
48563 THREE.Path.prototype.fromPoints = function ( vectors ) {
48564
48565     this.moveTo( vectors[ 0 ].x, vectors[ 0 ].y );
48566
48567     for ( var v = 1, vlen = vectors.length; v < vlen; v ++ ) {
48568
48569         this.lineTo( vectors[ v ].x, vectors[ v ].y );
48570
48571     };
48572
48573 };
48574
48575 // startPath() endPath()?
48576
48577 THREE.Path.prototype.moveTo = function ( x, y ) {
48578
48579     var args = Array.prototype.slice.call( arguments );
48580     this.actions.push( { action: THREE.PathActions.MOVE_TO, args: args } );
48581
48582 };
48583
48584 THREE.Path.prototype.lineTo = function ( x, y ) {
48585
48586     var args = Array.prototype.slice.call( arguments );
48587
48588     var lastargs = this.actions[ this.actions.length - 1 ].args;
48589
48590     var x0 = lastargs[ lastargs.length - 2 ];
48591     var y0 = lastargs[ lastargs.length - 1 ];
48592
48593     var curve = new THREE.LineCurve( new THREE.Vector2( x0, y0 ), new THREE.Vector2( x, y ) );
48594     this.curves.push( curve );
48595
48596     this.actions.push( { action: THREE.PathActions.LINE_TO, args: args } );
48597
48598 };
48599
48600 THREE.Path.prototype.quadraticCurveTo = function( aCPx, aCPy, aX, aY ) {
48601
48602     var args = Array.prototype.slice.call( arguments );
48603
48604     var lastargs = this.actions[ this.actions.length - 1 ].args;
48605
48606     var x0 = lastargs[ lastargs.length - 2 ];
48607     var y0 = lastargs[ lastargs.length - 1 ];
48608
48609     var curve = new THREE.QuadraticBezierCurve( new THREE.Vector2( x0, y0 ),
48610                                                 new THREE.Vector2( aCPx, aCPy ),
48611                                                 new THREE.Vector2( aX, aY ) );
48612     this.curves.push( curve );
48613
48614     this.actions.push( { action: THREE.PathActions.QUADRATIC_CURVE_TO, args: args } );
48615
48616 };
48617
48618 THREE.Path.prototype.bezierCurveTo = function( aCP1x, aCP1y,
48619                                                aCP2x, aCP2y,
48620                                                aX, aY ) {
48621
48622     var args = Array.prototype.slice.call( arguments );
48623
48624     var lastargs = this.actions[ this.actions.length - 1 ].args;
48625
48626     var x0 = lastargs[ lastargs.length - 2 ];
48627     var y0 = lastargs[ lastargs.length - 1 ];
48628
48629     var curve = new THREE.CubicBezierCurve( new THREE.Vector2( x0, y0 ),
48630                                             new THREE.Vector2( aCP1x, aCP1y ),
48631                                             new THREE.Vector2( aCP2x, aCP2y ),
48632                                             new THREE.Vector2( aX, aY ) );
48633     this.curves.push( curve );
48634
48635     this.actions.push( { action: THREE.PathActions.BEZIER_CURVE_TO, args: args } );
48636
48637 };
48638
48639 THREE.Path.prototype.splineThru = function( pts /*Array of Vector*/ ) {
48640
48641     var args = Array.prototype.slice.call( arguments );
48642     var lastargs = this.actions[ this.actions.length - 1 ].args;
48643
48644     var x0 = lastargs[ lastargs.length - 2 ];
48645     var y0 = lastargs[ lastargs.length - 1 ];
48646 //---
48647     var npts = [ new THREE.Vector2( x0, y0 ) ];
48648     Array.prototype.push.apply( npts, pts );
48649
48650     var curve = new THREE.SplineCurve( npts );
48651     this.curves.push( curve );
48652
48653     this.actions.push( { action: THREE.PathActions.CSPLINE_THRU, args: args } );
48654
48655 };
48656
48657 // FUTURE: Change the API or follow canvas API?
48658
48659 THREE.Path.prototype.arc = function ( aX, aY, aRadius,
48660                                       aStartAngle, aEndAngle, aClockwise ) {
48661
48662     var lastargs = this.actions[ this.actions.length - 1].args;
48663     var x0 = lastargs[ lastargs.length - 2 ];
48664     var y0 = lastargs[ lastargs.length - 1 ];
48665
48666     this.absarc(aX + x0, aY + y0, aRadius,
48667         aStartAngle, aEndAngle, aClockwise );
48668
48669  };
48670
48671  THREE.Path.prototype.absarc = function ( aX, aY, aRadius,
48672                                       aStartAngle, aEndAngle, aClockwise ) {
48673     this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise);
48674  };
48675
48676 THREE.Path.prototype.ellipse = function ( aX, aY, xRadius, yRadius,
48677                                       aStartAngle, aEndAngle, aClockwise ) {
48678
48679     var lastargs = this.actions[ this.actions.length - 1].args;
48680     var x0 = lastargs[ lastargs.length - 2 ];
48681     var y0 = lastargs[ lastargs.length - 1 ];
48682
48683     this.absellipse(aX + x0, aY + y0, xRadius, yRadius,
48684         aStartAngle, aEndAngle, aClockwise );
48685
48686  };
48687
48688
48689 THREE.Path.prototype.absellipse = function ( aX, aY, xRadius, yRadius,
48690                                       aStartAngle, aEndAngle, aClockwise ) {
48691
48692     var args = Array.prototype.slice.call( arguments );
48693     var curve = new THREE.EllipseCurve( aX, aY, xRadius, yRadius,
48694                                     aStartAngle, aEndAngle, aClockwise );
48695     this.curves.push( curve );
48696
48697     var lastPoint = curve.getPoint(aClockwise ? 1 : 0);
48698     args.push(lastPoint.x);
48699     args.push(lastPoint.y);
48700
48701     this.actions.push( { action: THREE.PathActions.ELLIPSE, args: args } );
48702
48703  };
48704
48705 THREE.Path.prototype.getSpacedPoints = function ( divisions, closedPath ) {
48706
48707     if ( ! divisions ) divisions = 40;
48708
48709     var points = [];
48710
48711     for ( var i = 0; i < divisions; i ++ ) {
48712
48713         points.push( this.getPoint( i / divisions ) );
48714
48715         //if( !this.getPoint( i / divisions ) ) throw "DIE";
48716
48717     }
48718
48719     // if ( closedPath ) {
48720     //
48721     //     points.push( points[ 0 ] );
48722     //
48723     // }
48724
48725     return points;
48726
48727 };
48728
48729 /* Return an array of vectors based on contour of the path */
48730
48731 THREE.Path.prototype.getPoints = function( divisions, closedPath ) {
48732
48733     if (this.useSpacedPoints) {
48734         console.log('tata');
48735         return this.getSpacedPoints( divisions, closedPath );
48736     }
48737
48738     divisions = divisions || 12;
48739
48740     var points = [];
48741
48742     var i, il, item, action, args;
48743     var cpx, cpy, cpx2, cpy2, cpx1, cpy1, cpx0, cpy0,
48744         laste, j,
48745         t, tx, ty;
48746
48747     for ( i = 0, il = this.actions.length; i < il; i ++ ) {
48748
48749         item = this.actions[ i ];
48750
48751         action = item.action;
48752         args = item.args;
48753
48754         switch( action ) {
48755
48756         case THREE.PathActions.MOVE_TO:
48757
48758             points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
48759
48760             break;
48761
48762         case THREE.PathActions.LINE_TO:
48763
48764             points.push( new THREE.Vector2( args[ 0 ], args[ 1 ] ) );
48765
48766             break;
48767
48768         case THREE.PathActions.QUADRATIC_CURVE_TO:
48769
48770             cpx  = args[ 2 ];
48771             cpy  = args[ 3 ];
48772
48773             cpx1 = args[ 0 ];
48774             cpy1 = args[ 1 ];
48775
48776             if ( points.length > 0 ) {
48777
48778                 laste = points[ points.length - 1 ];
48779
48780                 cpx0 = laste.x;
48781                 cpy0 = laste.y;
48782
48783             } else {
48784
48785                 laste = this.actions[ i - 1 ].args;
48786
48787                 cpx0 = laste[ laste.length - 2 ];
48788                 cpy0 = laste[ laste.length - 1 ];
48789
48790             }
48791
48792             for ( j = 1; j <= divisions; j ++ ) {
48793
48794                 t = j / divisions;
48795
48796                 tx = THREE.Shape.Utils.b2( t, cpx0, cpx1, cpx );
48797                 ty = THREE.Shape.Utils.b2( t, cpy0, cpy1, cpy );
48798
48799                 points.push( new THREE.Vector2( tx, ty ) );
48800
48801               }
48802
48803             break;
48804
48805         case THREE.PathActions.BEZIER_CURVE_TO:
48806
48807             cpx  = args[ 4 ];
48808             cpy  = args[ 5 ];
48809
48810             cpx1 = args[ 0 ];
48811             cpy1 = args[ 1 ];
48812
48813             cpx2 = args[ 2 ];
48814             cpy2 = args[ 3 ];
48815
48816             if ( points.length > 0 ) {
48817
48818                 laste = points[ points.length - 1 ];
48819
48820                 cpx0 = laste.x;
48821                 cpy0 = laste.y;
48822
48823             } else {
48824
48825                 laste = this.actions[ i - 1 ].args;
48826
48827                 cpx0 = laste[ laste.length - 2 ];
48828                 cpy0 = laste[ laste.length - 1 ];
48829
48830             }
48831
48832
48833             for ( j = 1; j <= divisions; j ++ ) {
48834
48835                 t = j / divisions;
48836
48837                 tx = THREE.Shape.Utils.b3( t, cpx0, cpx1, cpx2, cpx );
48838                 ty = THREE.Shape.Utils.b3( t, cpy0, cpy1, cpy2, cpy );
48839
48840                 points.push( new THREE.Vector2( tx, ty ) );
48841
48842             }
48843
48844             break;
48845
48846         case THREE.PathActions.CSPLINE_THRU:
48847
48848             laste = this.actions[ i - 1 ].args;
48849
48850             var last = new THREE.Vector2( laste[ laste.length - 2 ], laste[ laste.length - 1 ] );
48851             var spts = [ last ];
48852
48853             var n = divisions * args[ 0 ].length;
48854
48855             spts = spts.concat( args[ 0 ] );
48856
48857             var spline = new THREE.SplineCurve( spts );
48858
48859             for ( j = 1; j <= n; j ++ ) {
48860
48861                 points.push( spline.getPointAt( j / n ) ) ;
48862
48863             }
48864
48865             break;
48866
48867         case THREE.PathActions.ARC:
48868
48869             var aX = args[ 0 ], aY = args[ 1 ],
48870                 aRadius = args[ 2 ],
48871                 aStartAngle = args[ 3 ], aEndAngle = args[ 4 ],
48872                 aClockwise = !!args[ 5 ];
48873
48874             var deltaAngle = aEndAngle - aStartAngle;
48875             var angle;
48876             var tdivisions = divisions * 2;
48877
48878             for ( j = 1; j <= tdivisions; j ++ ) {
48879
48880                 t = j / tdivisions;
48881
48882                 if ( ! aClockwise ) {
48883
48884                     t = 1 - t;
48885
48886                 }
48887
48888                 angle = aStartAngle + t * deltaAngle;
48889
48890                 tx = aX + aRadius * Math.cos( angle );
48891                 ty = aY + aRadius * Math.sin( angle );
48892
48893                 //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty);
48894
48895                 points.push( new THREE.Vector2( tx, ty ) );
48896
48897             }
48898
48899             //console.log(points);
48900
48901           break;
48902
48903         case THREE.PathActions.ELLIPSE:
48904
48905             var aX = args[ 0 ], aY = args[ 1 ],
48906                 xRadius = args[ 2 ],
48907                 yRadius = args[ 3 ],
48908                 aStartAngle = args[ 4 ], aEndAngle = args[ 5 ],
48909                 aClockwise = !!args[ 6 ];
48910
48911
48912             var deltaAngle = aEndAngle - aStartAngle;
48913             var angle;
48914             var tdivisions = divisions * 2;
48915
48916             for ( j = 1; j <= tdivisions; j ++ ) {
48917
48918                 t = j / tdivisions;
48919
48920                 if ( ! aClockwise ) {
48921
48922                     t = 1 - t;
48923
48924                 }
48925
48926                 angle = aStartAngle + t * deltaAngle;
48927
48928                 tx = aX + xRadius * Math.cos( angle );
48929                 ty = aY + yRadius * Math.sin( angle );
48930
48931                 //console.log('t', t, 'angle', angle, 'tx', tx, 'ty', ty);
48932
48933                 points.push( new THREE.Vector2( tx, ty ) );
48934
48935             }
48936
48937             //console.log(points);
48938
48939           break;
48940
48941         } // end switch
48942
48943     }
48944
48945
48946
48947     // Normalize to remove the closing point by default.
48948     var lastPoint = points[ points.length - 1];
48949     var EPSILON = 0.0000000001;
48950     if ( Math.abs(lastPoint.x - points[ 0 ].x) < EPSILON &&
48951              Math.abs(lastPoint.y - points[ 0 ].y) < EPSILON)
48952         points.splice( points.length - 1, 1);
48953     if ( closedPath ) {
48954
48955         points.push( points[ 0 ] );
48956
48957     }
48958
48959     return points;
48960
48961 };
48962
48963 // Breaks path into shapes
48964
48965 THREE.Path.prototype.toShapes = function() {
48966
48967     var i, il, item, action, args;
48968
48969     var subPaths = [], lastPath = new THREE.Path();
48970
48971     for ( i = 0, il = this.actions.length; i < il; i ++ ) {
48972
48973         item = this.actions[ i ];
48974
48975         args = item.args;
48976         action = item.action;
48977
48978         if ( action == THREE.PathActions.MOVE_TO ) {
48979
48980             if ( lastPath.actions.length != 0 ) {
48981
48982                 subPaths.push( lastPath );
48983                 lastPath = new THREE.Path();
48984
48985             }
48986
48987         }
48988
48989         lastPath[ action ].apply( lastPath, args );
48990
48991     }
48992
48993     if ( lastPath.actions.length != 0 ) {
48994
48995         subPaths.push( lastPath );
48996
48997     }
48998
48999     // console.log(subPaths);
49000
49001     if ( subPaths.length == 0 ) return [];
49002
49003     var tmpPath, tmpShape, shapes = [];
49004
49005     var holesFirst = !THREE.Shape.Utils.isClockWise( subPaths[ 0 ].getPoints() );
49006     // console.log("Holes first", holesFirst);
49007
49008     if ( subPaths.length == 1) {
49009         tmpPath = subPaths[0];
49010         tmpShape = new THREE.Shape();
49011         tmpShape.actions = tmpPath.actions;
49012         tmpShape.curves = tmpPath.curves;
49013         shapes.push( tmpShape );
49014         return shapes;
49015     };
49016
49017     if ( holesFirst ) {
49018
49019         tmpShape = new THREE.Shape();
49020
49021         for ( i = 0, il = subPaths.length; i < il; i ++ ) {
49022
49023             tmpPath = subPaths[ i ];
49024
49025             if ( THREE.Shape.Utils.isClockWise( tmpPath.getPoints() ) ) {
49026
49027                 tmpShape.actions = tmpPath.actions;
49028                 tmpShape.curves = tmpPath.curves;
49029
49030                 shapes.push( tmpShape );
49031                 tmpShape = new THREE.Shape();
49032
49033                 //console.log('cw', i);
49034
49035             } else {
49036
49037                 tmpShape.holes.push( tmpPath );
49038
49039                 //console.log('ccw', i);
49040
49041             }
49042
49043         }
49044
49045     } else {
49046
49047         // Shapes first
49048
49049         for ( i = 0, il = subPaths.length; i < il; i ++ ) {
49050
49051             tmpPath = subPaths[ i ];
49052
49053             if ( THREE.Shape.Utils.isClockWise( tmpPath.getPoints() ) ) {
49054
49055
49056                 if ( tmpShape ) shapes.push( tmpShape );
49057
49058                 tmpShape = new THREE.Shape();
49059                 tmpShape.actions = tmpPath.actions;
49060                 tmpShape.curves = tmpPath.curves;
49061
49062             } else {
49063
49064                 tmpShape.holes.push( tmpPath );
49065
49066             }
49067
49068         }
49069
49070         shapes.push( tmpShape );
49071
49072     }
49073
49074     //console.log("shape", shapes);
49075
49076     return shapes;
49077
49078 };
49079 /**
49080  * @author zz85 / http://www.lab4games.net/zz85/blog
49081  * Defines a 2d shape plane using paths.
49082  **/
49083
49084 // STEP 1 Create a path.
49085 // STEP 2 Turn path into shape.
49086 // STEP 3 ExtrudeGeometry takes in Shape/Shapes
49087 // STEP 3a - Extract points from each shape, turn to vertices
49088 // STEP 3b - Triangulate each shape, add faces.
49089
49090 THREE.Shape = function ( ) {
49091
49092     THREE.Path.apply( this, arguments );
49093     this.holes = [];
49094
49095 };
49096
49097 THREE.Shape.prototype = Object.create( THREE.Path.prototype );
49098
49099 // Convenience method to return ExtrudeGeometry
49100
49101 THREE.Shape.prototype.extrude = function ( options ) {
49102
49103     var extruded = new THREE.ExtrudeGeometry( this, options );
49104     return extruded;
49105
49106 };
49107
49108 // Convenience method to return ShapeGeometry
49109
49110 THREE.Shape.prototype.makeGeometry = function ( options ) {
49111
49112     var geometry = new THREE.ShapeGeometry( this, options );
49113     return geometry;
49114
49115 };
49116
49117 // Get points of holes
49118
49119 THREE.Shape.prototype.getPointsHoles = function ( divisions ) {
49120
49121     var i, il = this.holes.length, holesPts = [];
49122
49123     for ( i = 0; i < il; i ++ ) {
49124
49125         holesPts[ i ] = this.holes[ i ].getTransformedPoints( divisions, this.bends );
49126
49127     }
49128
49129     return holesPts;
49130
49131 };
49132
49133 // Get points of holes (spaced by regular distance)
49134
49135 THREE.Shape.prototype.getSpacedPointsHoles = function ( divisions ) {
49136
49137     var i, il = this.holes.length, holesPts = [];
49138
49139     for ( i = 0; i < il; i ++ ) {
49140
49141         holesPts[ i ] = this.holes[ i ].getTransformedSpacedPoints( divisions, this.bends );
49142
49143     }
49144
49145     return holesPts;
49146
49147 };
49148
49149
49150 // Get points of shape and holes (keypoints based on segments parameter)
49151
49152 THREE.Shape.prototype.extractAllPoints = function ( divisions ) {
49153
49154     return {
49155
49156         shape: this.getTransformedPoints( divisions ),
49157         holes: this.getPointsHoles( divisions )
49158
49159     };
49160
49161 };
49162
49163 THREE.Shape.prototype.extractPoints = function ( divisions ) {
49164
49165     if (this.useSpacedPoints) {
49166         return this.extractAllSpacedPoints(divisions);
49167     }
49168
49169     return this.extractAllPoints(divisions);
49170
49171 };
49172
49173 //
49174 // THREE.Shape.prototype.extractAllPointsWithBend = function ( divisions, bend ) {
49175 //
49176 //     return {
49177 //
49178 //         shape: this.transform( bend, divisions ),
49179 //         holes: this.getPointsHoles( divisions, bend )
49180 //
49181 //     };
49182 //
49183 // };
49184
49185 // Get points of shape and holes (spaced by regular distance)
49186
49187 THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) {
49188
49189     return {
49190
49191         shape: this.getTransformedSpacedPoints( divisions ),
49192         holes: this.getSpacedPointsHoles( divisions )
49193
49194     };
49195
49196 };
49197
49198 /**************************************************************
49199  *    Utils
49200  **************************************************************/
49201
49202 THREE.Shape.Utils = {
49203
49204     /*
49205         contour - array of vector2 for contour
49206         holes   - array of array of vector2
49207     */
49208
49209     removeHoles: function ( contour, holes ) {
49210
49211         var shape = contour.concat(); // work on this shape
49212         var allpoints = shape.concat();
49213
49214         /* For each isolated shape, find the closest points and break to the hole to allow triangulation */
49215
49216
49217         var prevShapeVert, nextShapeVert,
49218             prevHoleVert, nextHoleVert,
49219             holeIndex, shapeIndex,
49220             shapeId, shapeGroup,
49221             h, h2,
49222             hole, shortest, d,
49223             p, pts1, pts2,
49224             tmpShape1, tmpShape2,
49225             tmpHole1, tmpHole2,
49226             verts = [];
49227
49228         for ( h = 0; h < holes.length; h ++ ) {
49229
49230             hole = holes[ h ];
49231
49232             /*
49233             shapeholes[ h ].concat(); // preserves original
49234             holes.push( hole );
49235             */
49236
49237             Array.prototype.push.apply( allpoints, hole );
49238
49239             shortest = Number.POSITIVE_INFINITY;
49240
49241
49242             // Find the shortest pair of pts between shape and hole
49243
49244             // Note: Actually, I'm not sure now if we could optimize this to be faster than O(m*n)
49245             // Using distanceToSquared() intead of distanceTo() should speed a little
49246             // since running square roots operations are reduced.
49247
49248             for ( h2 = 0; h2 < hole.length; h2 ++ ) {
49249
49250                 pts1 = hole[ h2 ];
49251                 var dist = [];
49252
49253                 for ( p = 0; p < shape.length; p++ ) {
49254
49255                     pts2 = shape[ p ];
49256                     d = pts1.distanceToSquared( pts2 );
49257                     dist.push( d );
49258
49259                     if ( d < shortest ) {
49260
49261                         shortest = d;
49262                         holeIndex = h2;
49263                         shapeIndex = p;
49264
49265                     }
49266
49267                 }
49268
49269             }
49270
49271             //console.log("shortest", shortest, dist);
49272
49273             prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
49274             prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
49275
49276             var areaapts = [
49277
49278                 hole[ holeIndex ],
49279                 shape[ shapeIndex ],
49280                 shape[ prevShapeVert ]
49281
49282             ];
49283
49284             var areaa = THREE.FontUtils.Triangulate.area( areaapts );
49285
49286             var areabpts = [
49287
49288                 hole[ holeIndex ],
49289                 hole[ prevHoleVert ],
49290                 shape[ shapeIndex ]
49291
49292             ];
49293
49294             var areab = THREE.FontUtils.Triangulate.area( areabpts );
49295
49296             var shapeOffset = 1;
49297             var holeOffset = -1;
49298
49299             var oldShapeIndex = shapeIndex, oldHoleIndex = holeIndex;
49300             shapeIndex += shapeOffset;
49301             holeIndex += holeOffset;
49302
49303             if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
49304             shapeIndex %= shape.length;
49305
49306             if ( holeIndex < 0 ) { holeIndex += hole.length;  }
49307             holeIndex %= hole.length;
49308
49309             prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
49310             prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
49311
49312             areaapts = [
49313
49314                 hole[ holeIndex ],
49315                 shape[ shapeIndex ],
49316                 shape[ prevShapeVert ]
49317
49318             ];
49319
49320             var areaa2 = THREE.FontUtils.Triangulate.area( areaapts );
49321
49322             areabpts = [
49323
49324                 hole[ holeIndex ],
49325                 hole[ prevHoleVert ],
49326                 shape[ shapeIndex ]
49327
49328             ];
49329
49330             var areab2 = THREE.FontUtils.Triangulate.area( areabpts );
49331             //console.log(areaa,areab ,areaa2,areab2, ( areaa + areab ),  ( areaa2 + areab2 ));
49332
49333             if ( ( areaa + areab ) > ( areaa2 + areab2 ) ) {
49334
49335                 // In case areas are not correct.
49336                 //console.log("USE THIS");
49337
49338                 shapeIndex = oldShapeIndex;
49339                 holeIndex = oldHoleIndex ;
49340
49341                 if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
49342                 shapeIndex %= shape.length;
49343
49344                 if ( holeIndex < 0 ) { holeIndex += hole.length;  }
49345                 holeIndex %= hole.length;
49346
49347                 prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
49348                 prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
49349
49350             } else {
49351
49352                 //console.log("USE THAT ")
49353
49354             }
49355
49356             tmpShape1 = shape.slice( 0, shapeIndex );
49357             tmpShape2 = shape.slice( shapeIndex );
49358             tmpHole1 = hole.slice( holeIndex );
49359             tmpHole2 = hole.slice( 0, holeIndex );
49360
49361             // Should check orders here again?
49362
49363             var trianglea = [
49364
49365                 hole[ holeIndex ],
49366                 shape[ shapeIndex ],
49367                 shape[ prevShapeVert ]
49368
49369             ];
49370
49371             var triangleb = [
49372
49373                 hole[ holeIndex ] ,
49374                 hole[ prevHoleVert ],
49375                 shape[ shapeIndex ]
49376
49377             ];
49378
49379             verts.push( trianglea );
49380             verts.push( triangleb );
49381
49382             shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
49383
49384         }
49385
49386         return {
49387
49388             shape:shape,         /* shape with no holes */
49389             isolatedPts: verts, /* isolated faces */
49390             allpoints: allpoints
49391
49392         }
49393
49394
49395     },
49396
49397     triangulateShape: function ( contour, holes ) {
49398
49399         var shapeWithoutHoles = THREE.Shape.Utils.removeHoles( contour, holes );
49400
49401         var shape = shapeWithoutHoles.shape,
49402             allpoints = shapeWithoutHoles.allpoints,
49403             isolatedPts = shapeWithoutHoles.isolatedPts;
49404
49405         var triangles = THREE.FontUtils.Triangulate( shape, false ); // True returns indices for points of spooled shape
49406
49407         // To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
49408
49409         //console.log( "triangles",triangles, triangles.length );
49410         //console.log( "allpoints",allpoints, allpoints.length );
49411
49412         var i, il, f, face,
49413             key, index,
49414             allPointsMap = {},
49415             isolatedPointsMap = {};
49416
49417         // prepare all points map
49418
49419         for ( i = 0, il = allpoints.length; i < il; i ++ ) {
49420
49421             key = allpoints[ i ].x + ":" + allpoints[ i ].y;
49422
49423             if ( allPointsMap[ key ] !== undefined ) {
49424
49425                 console.log( "Duplicate point", key );
49426
49427             }
49428
49429             allPointsMap[ key ] = i;
49430
49431         }
49432
49433         // check all face vertices against all points map
49434
49435         for ( i = 0, il = triangles.length; i < il; i ++ ) {
49436
49437             face = triangles[ i ];
49438
49439             for ( f = 0; f < 3; f ++ ) {
49440
49441                 key = face[ f ].x + ":" + face[ f ].y;
49442
49443                 index = allPointsMap[ key ];
49444
49445                 if ( index !== undefined ) {
49446
49447                     face[ f ] = index;
49448
49449                 }
49450
49451             }
49452
49453         }
49454
49455         // check isolated points vertices against all points map
49456
49457         for ( i = 0, il = isolatedPts.length; i < il; i ++ ) {
49458
49459             face = isolatedPts[ i ];
49460
49461             for ( f = 0; f < 3; f ++ ) {
49462
49463                 key = face[ f ].x + ":" + face[ f ].y;
49464
49465                 index = allPointsMap[ key ];
49466
49467                 if ( index !== undefined ) {
49468
49469                     face[ f ] = index;
49470
49471                 }
49472
49473             }
49474
49475         }
49476
49477         return triangles.concat( isolatedPts );
49478
49479     }, // end triangulate shapes
49480
49481     /*
49482     triangulate2 : function( pts, holes ) {
49483
49484         // For use with Poly2Tri.js
49485
49486         var allpts = pts.concat();
49487         var shape = [];
49488         for (var p in pts) {
49489             shape.push(new js.poly2tri.Point(pts[p].x, pts[p].y));
49490         }
49491
49492         var swctx = new js.poly2tri.SweepContext(shape);
49493
49494         for (var h in holes) {
49495             var aHole = holes[h];
49496             var newHole = []
49497             for (i in aHole) {
49498                 newHole.push(new js.poly2tri.Point(aHole[i].x, aHole[i].y));
49499                 allpts.push(aHole[i]);
49500             }
49501             swctx.AddHole(newHole);
49502         }
49503
49504         var find;
49505         var findIndexForPt = function (pt) {
49506             find = new THREE.Vector2(pt.x, pt.y);
49507             var p;
49508             for (p=0, pl = allpts.length; p<pl; p++) {
49509                 if (allpts[p].equals(find)) return p;
49510             }
49511             return -1;
49512         };
49513
49514         // triangulate
49515         js.poly2tri.sweep.Triangulate(swctx);
49516
49517         var triangles =  swctx.GetTriangles();
49518         var tr ;
49519         var facesPts = [];
49520         for (var t in triangles) {
49521             tr =  triangles[t];
49522             facesPts.push([
49523                 findIndexForPt(tr.GetPoint(0)),
49524                 findIndexForPt(tr.GetPoint(1)),
49525                 findIndexForPt(tr.GetPoint(2))
49526                     ]);
49527         }
49528
49529
49530     //    console.log(facesPts);
49531     //    console.log("triangles", triangles.length, triangles);
49532
49533         // Returns array of faces with 3 element each
49534     return facesPts;
49535     },
49536 */
49537
49538     isClockWise: function ( pts ) {
49539
49540         return THREE.FontUtils.Triangulate.area( pts ) < 0;
49541
49542     },
49543
49544     // Bezier Curves formulas obtained from
49545     // http://en.wikipedia.org/wiki/B%C3%A9zier_curve
49546
49547     // Quad Bezier Functions
49548
49549     b2p0: function ( t, p ) {
49550
49551         var k = 1 - t;
49552         return k * k * p;
49553
49554     },
49555
49556     b2p1: function ( t, p ) {
49557
49558         return 2 * ( 1 - t ) * t * p;
49559
49560     },
49561
49562     b2p2: function ( t, p ) {
49563
49564         return t * t * p;
49565
49566     },
49567
49568     b2: function ( t, p0, p1, p2 ) {
49569
49570         return this.b2p0( t, p0 ) + this.b2p1( t, p1 ) + this.b2p2( t, p2 );
49571
49572     },
49573
49574     // Cubic Bezier Functions
49575
49576     b3p0: function ( t, p ) {
49577
49578         var k = 1 - t;
49579         return k * k * k * p;
49580
49581     },
49582
49583     b3p1: function ( t, p ) {
49584
49585         var k = 1 - t;
49586         return 3 * k * k * t * p;
49587
49588     },
49589
49590     b3p2: function ( t, p ) {
49591
49592         var k = 1 - t;
49593         return 3 * k * t * t * p;
49594
49595     },
49596
49597     b3p3: function ( t, p ) {
49598
49599         return t * t * t * p;
49600
49601     },
49602
49603     b3: function ( t, p0, p1, p2, p3 ) {
49604
49605         return this.b3p0( t, p0 ) + this.b3p1( t, p1 ) + this.b3p2( t, p2 ) +  this.b3p3( t, p3 );
49606
49607     }
49608
49609 };
49610
49611 /**
49612  * @author mikael emtinger / http://gomo.se/
49613  */
49614
49615 THREE.AnimationHandler = (function() {
49616
49617     var playing = [];
49618     var library = {};
49619     var that    = {};
49620
49621
49622     //--- update ---
49623
49624     that.update = function( deltaTimeMS ) {
49625
49626         for( var i = 0; i < playing.length; i ++ )
49627             playing[ i ].update( deltaTimeMS );
49628
49629     };
49630
49631
49632     //--- add ---
49633
49634     that.addToUpdate = function( animation ) {
49635
49636         if ( playing.indexOf( animation ) === -1 )
49637             playing.push( animation );
49638
49639     };
49640
49641
49642     //--- remove ---
49643
49644     that.removeFromUpdate = function( animation ) {
49645
49646         var index = playing.indexOf( animation );
49647
49648         if( index !== -1 )
49649             playing.splice( index, 1 );
49650
49651     };
49652
49653
49654     //--- add ---
49655
49656     that.add = function( data ) {
49657
49658         if ( library[ data.name ] !== undefined )
49659             console.log( "THREE.AnimationHandler.add: Warning! " + data.name + " already exists in library. Overwriting." );
49660
49661         library[ data.name ] = data;
49662         initData( data );
49663
49664     };
49665
49666
49667     //--- get ---
49668
49669     that.get = function( name ) {
49670
49671         if ( typeof name === "string" ) {
49672
49673             if ( library[ name ] ) {
49674
49675                 return library[ name ];
49676
49677             } else {
49678
49679                 console.log( "THREE.AnimationHandler.get: Couldn't find animation " + name );
49680                 return null;
49681
49682             }
49683
49684         } else {
49685
49686             // todo: add simple tween library
49687
49688         }
49689
49690     };
49691
49692     //--- parse ---
49693
49694     that.parse = function( root ) {
49695
49696         // setup hierarchy
49697
49698         var hierarchy = [];
49699
49700         if ( root instanceof THREE.SkinnedMesh ) {
49701
49702             for( var b = 0; b < root.bones.length; b++ ) {
49703
49704                 hierarchy.push( root.bones[ b ] );
49705
49706             }
49707
49708         } else {
49709
49710             parseRecurseHierarchy( root, hierarchy );
49711
49712         }
49713
49714         return hierarchy;
49715
49716     };
49717
49718     var parseRecurseHierarchy = function( root, hierarchy ) {
49719
49720         hierarchy.push( root );
49721
49722         for( var c = 0; c < root.children.length; c++ )
49723             parseRecurseHierarchy( root.children[ c ], hierarchy );
49724
49725     }
49726
49727
49728     //--- init data ---
49729
49730     var initData = function( data ) {
49731
49732         if( data.initialized === true )
49733             return;
49734
49735
49736         // loop through all keys
49737
49738         for( var h = 0; h < data.hierarchy.length; h ++ ) {
49739
49740             for( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
49741
49742                 // remove minus times
49743
49744                 if( data.hierarchy[ h ].keys[ k ].time < 0 )
49745                     data.hierarchy[ h ].keys[ k ].time = 0;
49746
49747
49748                 // create quaternions
49749
49750                 if( data.hierarchy[ h ].keys[ k ].rot !== undefined &&
49751                  !( data.hierarchy[ h ].keys[ k ].rot instanceof THREE.Quaternion ) ) {
49752
49753                     var quat = data.hierarchy[ h ].keys[ k ].rot;
49754                     data.hierarchy[ h ].keys[ k ].rot = new THREE.Quaternion( quat[0], quat[1], quat[2], quat[3] );
49755
49756                 }
49757
49758             }
49759
49760
49761             // prepare morph target keys
49762
49763             if( data.hierarchy[ h ].keys.length && data.hierarchy[ h ].keys[ 0 ].morphTargets !== undefined ) {
49764
49765                 // get all used
49766
49767                 var usedMorphTargets = {};
49768
49769                 for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
49770
49771                     for ( var m = 0; m < data.hierarchy[ h ].keys[ k ].morphTargets.length; m ++ ) {
49772
49773                         var morphTargetName = data.hierarchy[ h ].keys[ k ].morphTargets[ m ];
49774                         usedMorphTargets[ morphTargetName ] = -1;
49775
49776                     }
49777
49778                 }
49779
49780                 data.hierarchy[ h ].usedMorphTargets = usedMorphTargets;
49781
49782
49783                 // set all used on all frames
49784
49785                 for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
49786
49787                     var influences = {};
49788
49789                     for ( var morphTargetName in usedMorphTargets ) {
49790
49791                         for ( var m = 0; m < data.hierarchy[ h ].keys[ k ].morphTargets.length; m ++ ) {
49792
49793                             if ( data.hierarchy[ h ].keys[ k ].morphTargets[ m ] === morphTargetName ) {
49794
49795                                 influences[ morphTargetName ] = data.hierarchy[ h ].keys[ k ].morphTargetsInfluences[ m ];
49796                                 break;
49797
49798                             }
49799
49800                         }
49801
49802                         if ( m === data.hierarchy[ h ].keys[ k ].morphTargets.length ) {
49803
49804                             influences[ morphTargetName ] = 0;
49805
49806                         }
49807
49808                     }
49809
49810                     data.hierarchy[ h ].keys[ k ].morphTargetsInfluences = influences;
49811
49812                 }
49813
49814             }
49815
49816
49817             // remove all keys that are on the same time
49818
49819             for ( var k = 1; k < data.hierarchy[ h ].keys.length; k ++ ) {
49820
49821                 if ( data.hierarchy[ h ].keys[ k ].time === data.hierarchy[ h ].keys[ k - 1 ].time ) {
49822
49823                     data.hierarchy[ h ].keys.splice( k, 1 );
49824                     k --;
49825
49826                 }
49827
49828             }
49829
49830
49831             // set index
49832
49833             for ( var k = 0; k < data.hierarchy[ h ].keys.length; k ++ ) {
49834
49835                 data.hierarchy[ h ].keys[ k ].index = k;
49836
49837             }
49838
49839         }
49840
49841
49842         // JIT
49843
49844         var lengthInFrames = parseInt( data.length * data.fps, 10 );
49845
49846         data.JIT = {};
49847         data.JIT.hierarchy = [];
49848
49849         for( var h = 0; h < data.hierarchy.length; h ++ )
49850             data.JIT.hierarchy.push( new Array( lengthInFrames ) );
49851
49852
49853         // done
49854
49855         data.initialized = true;
49856
49857     };
49858
49859
49860     // interpolation types
49861
49862     that.LINEAR = 0;
49863     that.CATMULLROM = 1;
49864     that.CATMULLROM_FORWARD = 2;
49865
49866     return that;
49867
49868 }());
49869 /**
49870  * @author mikael emtinger / http://gomo.se/
49871  * @author mrdoob / http://mrdoob.com/
49872  * @author alteredq / http://alteredqualia.com/
49873  */
49874
49875 THREE.Animation = function ( root, name, interpolationType ) {
49876
49877     this.root = root;
49878     this.data = THREE.AnimationHandler.get( name );
49879     this.hierarchy = THREE.AnimationHandler.parse( root );
49880
49881     this.currentTime = 0;
49882     this.timeScale = 1;
49883
49884     this.isPlaying = false;
49885     this.isPaused = true;
49886     this.loop = true;
49887
49888     this.interpolationType = interpolationType !== undefined ? interpolationType : THREE.AnimationHandler.LINEAR;
49889
49890     this.points = [];
49891     this.target = new THREE.Vector3();
49892
49893 };
49894
49895 THREE.Animation.prototype.play = function ( loop, startTimeMS ) {
49896
49897     if ( this.isPlaying === false ) {
49898
49899         this.isPlaying = true;
49900         this.loop = loop !== undefined ? loop : true;
49901         this.currentTime = startTimeMS !== undefined ? startTimeMS : 0;
49902
49903         // reset key cache
49904
49905         var h, hl = this.hierarchy.length,
49906             object;
49907
49908         for ( h = 0; h < hl; h ++ ) {
49909
49910             object = this.hierarchy[ h ];
49911
49912             if ( this.interpolationType !== THREE.AnimationHandler.CATMULLROM_FORWARD ) {
49913
49914                 object.useQuaternion = true;
49915
49916             }
49917
49918             object.matrixAutoUpdate = true;
49919
49920             if ( object.animationCache === undefined ) {
49921
49922                 object.animationCache = {};
49923                 object.animationCache.prevKey = { pos: 0, rot: 0, scl: 0 };
49924                 object.animationCache.nextKey = { pos: 0, rot: 0, scl: 0 };
49925                 object.animationCache.originalMatrix = object instanceof THREE.Bone ? object.skinMatrix : object.matrix;
49926
49927             }
49928
49929             var prevKey = object.animationCache.prevKey;
49930             var nextKey = object.animationCache.nextKey;
49931
49932             prevKey.pos = this.data.hierarchy[ h ].keys[ 0 ];
49933             prevKey.rot = this.data.hierarchy[ h ].keys[ 0 ];
49934             prevKey.scl = this.data.hierarchy[ h ].keys[ 0 ];
49935
49936             nextKey.pos = this.getNextKeyWith( "pos", h, 1 );
49937             nextKey.rot = this.getNextKeyWith( "rot", h, 1 );
49938             nextKey.scl = this.getNextKeyWith( "scl", h, 1 );
49939
49940         }
49941
49942         this.update( 0 );
49943
49944     }
49945
49946     this.isPaused = false;
49947
49948     THREE.AnimationHandler.addToUpdate( this );
49949
49950 };
49951
49952
49953 THREE.Animation.prototype.pause = function() {
49954
49955     if ( this.isPaused === true ) {
49956
49957         THREE.AnimationHandler.addToUpdate( this );
49958
49959     } else {
49960
49961         THREE.AnimationHandler.removeFromUpdate( this );
49962
49963     }
49964
49965     this.isPaused = !this.isPaused;
49966
49967 };
49968
49969
49970 THREE.Animation.prototype.stop = function() {
49971
49972     this.isPlaying = false;
49973     this.isPaused  = false;
49974     THREE.AnimationHandler.removeFromUpdate( this );
49975
49976 };
49977
49978
49979 THREE.Animation.prototype.update = function ( deltaTimeMS ) {
49980
49981     // early out
49982
49983     if ( this.isPlaying === false ) return;
49984
49985
49986     // vars
49987
49988     var types = [ "pos", "rot", "scl" ];
49989     var type;
49990     var scale;
49991     var vector;
49992     var prevXYZ, nextXYZ;
49993     var prevKey, nextKey;
49994     var object;
49995     var animationCache;
49996     var frame;
49997     var JIThierarchy = this.data.JIT.hierarchy;
49998     var currentTime, unloopedCurrentTime;
49999     var currentPoint, forwardPoint, angle;
50000
50001
50002     this.currentTime += deltaTimeMS * this.timeScale;
50003
50004     unloopedCurrentTime = this.currentTime;
50005     currentTime = this.currentTime = this.currentTime % this.data.length;
50006     frame = parseInt( Math.min( currentTime * this.data.fps, this.data.length * this.data.fps ), 10 );
50007
50008
50009     for ( var h = 0, hl = this.hierarchy.length; h < hl; h ++ ) {
50010
50011         object = this.hierarchy[ h ];
50012         animationCache = object.animationCache;
50013
50014         // loop through pos/rot/scl
50015
50016         for ( var t = 0; t < 3; t ++ ) {
50017
50018             // get keys
50019
50020             type    = types[ t ];
50021             prevKey = animationCache.prevKey[ type ];
50022             nextKey = animationCache.nextKey[ type ];
50023
50024             // switch keys?
50025
50026             if ( nextKey.time <= unloopedCurrentTime ) {
50027
50028                 // did we loop?
50029
50030                 if ( currentTime < unloopedCurrentTime ) {
50031
50032                     if ( this.loop ) {
50033
50034                         prevKey = this.data.hierarchy[ h ].keys[ 0 ];
50035                         nextKey = this.getNextKeyWith( type, h, 1 );
50036
50037                         while( nextKey.time < currentTime ) {
50038
50039                             prevKey = nextKey;
50040                             nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );
50041
50042                         }
50043
50044                     } else {
50045
50046                         this.stop();
50047                         return;
50048
50049                     }
50050
50051                 } else {
50052
50053                     do {
50054
50055                         prevKey = nextKey;
50056                         nextKey = this.getNextKeyWith( type, h, nextKey.index + 1 );
50057
50058                     } while( nextKey.time < currentTime )
50059
50060                 }
50061
50062                 animationCache.prevKey[ type ] = prevKey;
50063                 animationCache.nextKey[ type ] = nextKey;
50064
50065             }
50066
50067
50068             object.matrixAutoUpdate = true;
50069             object.matrixWorldNeedsUpdate = true;
50070
50071             scale = ( currentTime - prevKey.time ) / ( nextKey.time - prevKey.time );
50072             prevXYZ = prevKey[ type ];
50073             nextXYZ = nextKey[ type ];
50074
50075
50076             // check scale error
50077
50078             if ( scale < 0 || scale > 1 ) {
50079
50080                 console.log( "THREE.Animation.update: Warning! Scale out of bounds:" + scale + " on bone " + h );
50081                 scale = scale < 0 ? 0 : 1;
50082
50083             }
50084
50085             // interpolate
50086
50087             if ( type === "pos" ) {
50088
50089                 vector = object.position;
50090
50091                 if ( this.interpolationType === THREE.AnimationHandler.LINEAR ) {
50092
50093                     vector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale;
50094                     vector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale;
50095                     vector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale;
50096
50097                 } else if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
50098                             this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
50099
50100                     this.points[ 0 ] = this.getPrevKeyWith( "pos", h, prevKey.index - 1 )[ "pos" ];
50101                     this.points[ 1 ] = prevXYZ;
50102                     this.points[ 2 ] = nextXYZ;
50103                     this.points[ 3 ] = this.getNextKeyWith( "pos", h, nextKey.index + 1 )[ "pos" ];
50104
50105                     scale = scale * 0.33 + 0.33;
50106
50107                     currentPoint = this.interpolateCatmullRom( this.points, scale );
50108
50109                     vector.x = currentPoint[ 0 ];
50110                     vector.y = currentPoint[ 1 ];
50111                     vector.z = currentPoint[ 2 ];
50112
50113                     if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
50114
50115                         forwardPoint = this.interpolateCatmullRom( this.points, scale * 1.01 );
50116
50117                         this.target.set( forwardPoint[ 0 ], forwardPoint[ 1 ], forwardPoint[ 2 ] );
50118                         this.target.subSelf( vector );
50119                         this.target.y = 0;
50120                         this.target.normalize();
50121
50122                         angle = Math.atan2( this.target.x, this.target.z );
50123                         object.rotation.set( 0, angle, 0 );
50124
50125                     }
50126
50127                 }
50128
50129             } else if ( type === "rot" ) {
50130
50131                 THREE.Quaternion.slerp( prevXYZ, nextXYZ, object.quaternion, scale );
50132
50133             } else if ( type === "scl" ) {
50134
50135                 vector = object.scale;
50136
50137                 vector.x = prevXYZ[ 0 ] + ( nextXYZ[ 0 ] - prevXYZ[ 0 ] ) * scale;
50138                 vector.y = prevXYZ[ 1 ] + ( nextXYZ[ 1 ] - prevXYZ[ 1 ] ) * scale;
50139                 vector.z = prevXYZ[ 2 ] + ( nextXYZ[ 2 ] - prevXYZ[ 2 ] ) * scale;
50140
50141             }
50142
50143         }
50144
50145     }
50146
50147 };
50148
50149 // Catmull-Rom spline
50150
50151 THREE.Animation.prototype.interpolateCatmullRom = function ( points, scale ) {
50152
50153     var c = [], v3 = [],
50154     point, intPoint, weight, w2, w3,
50155     pa, pb, pc, pd;
50156
50157     point = ( points.length - 1 ) * scale;
50158     intPoint = Math.floor( point );
50159     weight = point - intPoint;
50160
50161     c[ 0 ] = intPoint === 0 ? intPoint : intPoint - 1;
50162     c[ 1 ] = intPoint;
50163     c[ 2 ] = intPoint > points.length - 2 ? intPoint : intPoint + 1;
50164     c[ 3 ] = intPoint > points.length - 3 ? intPoint : intPoint + 2;
50165
50166     pa = points[ c[ 0 ] ];
50167     pb = points[ c[ 1 ] ];
50168     pc = points[ c[ 2 ] ];
50169     pd = points[ c[ 3 ] ];
50170
50171     w2 = weight * weight;
50172     w3 = weight * w2;
50173
50174     v3[ 0 ] = this.interpolate( pa[ 0 ], pb[ 0 ], pc[ 0 ], pd[ 0 ], weight, w2, w3 );
50175     v3[ 1 ] = this.interpolate( pa[ 1 ], pb[ 1 ], pc[ 1 ], pd[ 1 ], weight, w2, w3 );
50176     v3[ 2 ] = this.interpolate( pa[ 2 ], pb[ 2 ], pc[ 2 ], pd[ 2 ], weight, w2, w3 );
50177
50178     return v3;
50179
50180 };
50181
50182 THREE.Animation.prototype.interpolate = function ( p0, p1, p2, p3, t, t2, t3 ) {
50183
50184     var v0 = ( p2 - p0 ) * 0.5,
50185         v1 = ( p3 - p1 ) * 0.5;
50186
50187     return ( 2 * ( p1 - p2 ) + v0 + v1 ) * t3 + ( - 3 * ( p1 - p2 ) - 2 * v0 - v1 ) * t2 + v0 * t + p1;
50188
50189 };
50190
50191
50192
50193 // Get next key with
50194
50195 THREE.Animation.prototype.getNextKeyWith = function ( type, h, key ) {
50196
50197     var keys = this.data.hierarchy[ h ].keys;
50198
50199     if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
50200          this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
50201
50202         key = key < keys.length - 1 ? key : keys.length - 1;
50203
50204     } else {
50205
50206         key = key % keys.length;
50207
50208     }
50209
50210     for ( ; key < keys.length; key++ ) {
50211
50212         if ( keys[ key ][ type ] !== undefined ) {
50213
50214             return keys[ key ];
50215
50216         }
50217
50218     }
50219
50220     return this.data.hierarchy[ h ].keys[ 0 ];
50221
50222 };
50223
50224 // Get previous key with
50225
50226 THREE.Animation.prototype.getPrevKeyWith = function ( type, h, key ) {
50227
50228     var keys = this.data.hierarchy[ h ].keys;
50229
50230     if ( this.interpolationType === THREE.AnimationHandler.CATMULLROM ||
50231          this.interpolationType === THREE.AnimationHandler.CATMULLROM_FORWARD ) {
50232
50233         key = key > 0 ? key : 0;
50234
50235     } else {
50236
50237         key = key >= 0 ? key : key + keys.length;
50238
50239     }
50240
50241
50242     for ( ; key >= 0; key -- ) {
50243
50244         if ( keys[ key ][ type ] !== undefined ) {
50245
50246             return keys[ key ];
50247
50248         }
50249
50250     }
50251
50252     return this.data.hierarchy[ h ].keys[ keys.length - 1 ];
50253
50254 };
50255 /**
50256  * @author mikael emtinger / http://gomo.se/
50257  * @author mrdoob / http://mrdoob.com/
50258  * @author alteredq / http://alteredqualia.com/
50259  * @author khang duong
50260  * @author erik kitson
50261  */
50262
50263 THREE.KeyFrameAnimation = function( root, data, JITCompile ) {
50264
50265     this.root = root;
50266     this.data = THREE.AnimationHandler.get( data );
50267     this.hierarchy = THREE.AnimationHandler.parse( root );
50268     this.currentTime = 0;
50269     this.timeScale = 0.001;
50270     this.isPlaying = false;
50271     this.isPaused = true;
50272     this.loop = true;
50273     this.JITCompile = JITCompile !== undefined ? JITCompile : true;
50274
50275     // initialize to first keyframes
50276
50277     for ( var h = 0, hl = this.hierarchy.length; h < hl; h++ ) {
50278
50279         var keys = this.data.hierarchy[h].keys,
50280             sids = this.data.hierarchy[h].sids,
50281             obj = this.hierarchy[h];
50282
50283         if ( keys.length && sids ) {
50284
50285             for ( var s = 0; s < sids.length; s++ ) {
50286
50287                 var sid = sids[ s ],
50288                     next = this.getNextKeyWith( sid, h, 0 );
50289
50290                 if ( next ) {
50291
50292                     next.apply( sid );
50293
50294                 }
50295
50296             }
50297
50298             obj.matrixAutoUpdate = false;
50299             this.data.hierarchy[h].node.updateMatrix();
50300             obj.matrixWorldNeedsUpdate = true;
50301
50302         }
50303
50304     }
50305
50306 };
50307
50308 // Play
50309
50310 THREE.KeyFrameAnimation.prototype.play = function( loop, startTimeMS ) {
50311
50312     if( !this.isPlaying ) {
50313
50314         this.isPlaying = true;
50315         this.loop = loop !== undefined ? loop : true;
50316         this.currentTime = startTimeMS !== undefined ? startTimeMS : 0;
50317         this.startTimeMs = startTimeMS;
50318         this.startTime = 10000000;
50319         this.endTime = -this.startTime;
50320
50321
50322         // reset key cache
50323
50324         var h, hl = this.hierarchy.length,
50325             object,
50326             node;
50327
50328         for ( h = 0; h < hl; h++ ) {
50329
50330             object = this.hierarchy[ h ];
50331             node = this.data.hierarchy[ h ];
50332             object.useQuaternion = true;
50333
50334             if ( node.animationCache === undefined ) {
50335
50336                 node.animationCache = {};
50337                 node.animationCache.prevKey = null;
50338                 node.animationCache.nextKey = null;
50339                 node.animationCache.originalMatrix = object instanceof THREE.Bone ? object.skinMatrix : object.matrix;
50340
50341             }
50342
50343             var keys = this.data.hierarchy[h].keys;
50344
50345             if (keys.length) {
50346
50347                 node.animationCache.prevKey = keys[ 0 ];
50348                 node.animationCache.nextKey = keys[ 1 ];
50349
50350                 this.startTime = Math.min( keys[0].time, this.startTime );
50351                 this.endTime = Math.max( keys[keys.length - 1].time, this.endTime );
50352
50353             }
50354
50355         }
50356
50357         this.update( 0 );
50358
50359     }
50360
50361     this.isPaused = false;
50362
50363     THREE.AnimationHandler.addToUpdate( this );
50364
50365 };
50366
50367
50368
50369 // Pause
50370
50371 THREE.KeyFrameAnimation.prototype.pause = function() {
50372
50373     if( this.isPaused ) {
50374
50375         THREE.AnimationHandler.addToUpdate( this );
50376
50377     } else {
50378
50379         THREE.AnimationHandler.removeFromUpdate( this );
50380
50381     }
50382
50383     this.isPaused = !this.isPaused;
50384
50385 };
50386
50387
50388 // Stop
50389
50390 THREE.KeyFrameAnimation.prototype.stop = function() {
50391
50392     this.isPlaying = false;
50393     this.isPaused  = false;
50394     THREE.AnimationHandler.removeFromUpdate( this );
50395
50396
50397     // reset JIT matrix and remove cache
50398
50399     for ( var h = 0; h < this.data.hierarchy.length; h++ ) {
50400
50401         var obj = this.hierarchy[ h ];
50402         var node = this.data.hierarchy[ h ];
50403
50404         if ( node.animationCache !== undefined ) {
50405
50406             var original = node.animationCache.originalMatrix;
50407
50408             if( obj instanceof THREE.Bone ) {
50409
50410                 original.copy( obj.skinMatrix );
50411                 obj.skinMatrix = original;
50412
50413             } else {
50414
50415                 original.copy( obj.matrix );
50416                 obj.matrix = original;
50417
50418             }
50419
50420             delete node.animationCache;
50421
50422         }
50423
50424     }
50425
50426 };
50427
50428
50429 // Update
50430
50431 THREE.KeyFrameAnimation.prototype.update = function( deltaTimeMS ) {
50432
50433     // early out
50434
50435     if( !this.isPlaying ) return;
50436
50437
50438     // vars
50439
50440     var prevKey, nextKey;
50441     var object;
50442     var node;
50443     var frame;
50444     var JIThierarchy = this.data.JIT.hierarchy;
50445     var currentTime, unloopedCurrentTime;
50446     var looped;
50447
50448
50449     // update
50450
50451     this.currentTime += deltaTimeMS * this.timeScale;
50452
50453     unloopedCurrentTime = this.currentTime;
50454     currentTime         = this.currentTime = this.currentTime % this.data.length;
50455
50456     // if looped around, the current time should be based on the startTime
50457     if ( currentTime < this.startTimeMs ) {
50458
50459         currentTime = this.currentTime = this.startTimeMs + currentTime;
50460
50461     }
50462
50463     frame               = parseInt( Math.min( currentTime * this.data.fps, this.data.length * this.data.fps ), 10 );
50464     looped                 = currentTime < unloopedCurrentTime;
50465
50466     if ( looped && !this.loop ) {
50467
50468         // Set the animation to the last keyframes and stop
50469         for ( var h = 0, hl = this.hierarchy.length; h < hl; h++ ) {
50470
50471             var keys = this.data.hierarchy[h].keys,
50472                 sids = this.data.hierarchy[h].sids,
50473                 end = keys.length-1,
50474                 obj = this.hierarchy[h];
50475
50476             if ( keys.length ) {
50477
50478                 for ( var s = 0; s < sids.length; s++ ) {
50479
50480                     var sid = sids[ s ],
50481                         prev = this.getPrevKeyWith( sid, h, end );
50482
50483                     if ( prev ) {
50484                         prev.apply( sid );
50485
50486                     }
50487
50488                 }
50489
50490                 this.data.hierarchy[h].node.updateMatrix();
50491                 obj.matrixWorldNeedsUpdate = true;
50492
50493             }
50494
50495         }
50496
50497         this.stop();
50498         return;
50499
50500     }
50501
50502     // check pre-infinity
50503     if ( currentTime < this.startTime ) {
50504
50505         return;
50506
50507     }
50508
50509     // update
50510
50511     for ( var h = 0, hl = this.hierarchy.length; h < hl; h++ ) {
50512
50513         object = this.hierarchy[ h ];
50514         node = this.data.hierarchy[ h ];
50515
50516         var keys = node.keys,
50517             animationCache = node.animationCache;
50518
50519         // use JIT?
50520
50521         if ( this.JITCompile && JIThierarchy[ h ][ frame ] !== undefined ) {
50522
50523             if( object instanceof THREE.Bone ) {
50524
50525                 object.skinMatrix = JIThierarchy[ h ][ frame ];
50526                 object.matrixWorldNeedsUpdate = false;
50527
50528             } else {
50529
50530                 object.matrix = JIThierarchy[ h ][ frame ];
50531                 object.matrixWorldNeedsUpdate = true;
50532
50533             }
50534
50535         // use interpolation
50536
50537         } else if ( keys.length ) {
50538
50539             // make sure so original matrix and not JIT matrix is set
50540
50541             if ( this.JITCompile && animationCache ) {
50542
50543                 if( object instanceof THREE.Bone ) {
50544
50545                     object.skinMatrix = animationCache.originalMatrix;
50546
50547                 } else {
50548
50549                     object.matrix = animationCache.originalMatrix;
50550
50551                 }
50552
50553             }
50554
50555             prevKey = animationCache.prevKey;
50556             nextKey = animationCache.nextKey;
50557
50558             if ( prevKey && nextKey ) {
50559
50560                 // switch keys?
50561
50562                 if ( nextKey.time <= unloopedCurrentTime ) {
50563
50564                     // did we loop?
50565
50566                     if ( looped && this.loop ) {
50567
50568                         prevKey = keys[ 0 ];
50569                         nextKey = keys[ 1 ];
50570
50571                         while ( nextKey.time < currentTime ) {
50572
50573                             prevKey = nextKey;
50574                             nextKey = keys[ prevKey.index + 1 ];
50575
50576                         }
50577
50578                     } else if ( !looped ) {
50579
50580                         var lastIndex = keys.length - 1;
50581
50582                         while ( nextKey.time < currentTime && nextKey.index !== lastIndex ) {
50583
50584                             prevKey = nextKey;
50585                             nextKey = keys[ prevKey.index + 1 ];
50586
50587                         }
50588
50589                     }
50590
50591                     animationCache.prevKey = prevKey;
50592                     animationCache.nextKey = nextKey;
50593
50594                 }
50595                 if(nextKey.time >= currentTime)
50596                     prevKey.interpolate( nextKey, currentTime );
50597                 else
50598                     prevKey.interpolate( nextKey, nextKey.time);
50599
50600             }
50601
50602             this.data.hierarchy[h].node.updateMatrix();
50603             object.matrixWorldNeedsUpdate = true;
50604
50605         }
50606
50607     }
50608
50609     // update JIT?
50610
50611     if ( this.JITCompile ) {
50612
50613         if ( JIThierarchy[ 0 ][ frame ] === undefined ) {
50614
50615             this.hierarchy[ 0 ].updateMatrixWorld( true );
50616
50617             for ( var h = 0; h < this.hierarchy.length; h++ ) {
50618
50619                 if( this.hierarchy[ h ] instanceof THREE.Bone ) {
50620
50621                     JIThierarchy[ h ][ frame ] = this.hierarchy[ h ].skinMatrix.clone();
50622
50623                 } else {
50624
50625                     JIThierarchy[ h ][ frame ] = this.hierarchy[ h ].matrix.clone();
50626
50627                 }
50628
50629             }
50630
50631         }
50632
50633     }
50634
50635 };
50636
50637 // Get next key with
50638
50639 THREE.KeyFrameAnimation.prototype.getNextKeyWith = function( sid, h, key ) {
50640
50641     var keys = this.data.hierarchy[ h ].keys;
50642     key = key % keys.length;
50643
50644     for ( ; key < keys.length; key++ ) {
50645
50646         if ( keys[ key ].hasTarget( sid ) ) {
50647
50648             return keys[ key ];
50649
50650         }
50651
50652     }
50653
50654     return keys[ 0 ];
50655
50656 };
50657
50658 // Get previous key with
50659
50660 THREE.KeyFrameAnimation.prototype.getPrevKeyWith = function( sid, h, key ) {
50661
50662     var keys = this.data.hierarchy[ h ].keys;
50663     key = key >= 0 ? key : key + keys.length;
50664
50665     for ( ; key >= 0; key-- ) {
50666
50667         if ( keys[ key ].hasTarget( sid ) ) {
50668
50669             return keys[ key ];
50670
50671         }
50672
50673     }
50674
50675     return keys[ keys.length - 1 ];
50676
50677 };
50678 /**
50679  * Camera for rendering cube maps
50680  *    - renders scene into axis-aligned cube
50681  *
50682  * @author alteredq / http://alteredqualia.com/
50683  */
50684
50685 THREE.CubeCamera = function ( near, far, cubeResolution ) {
50686
50687     THREE.Object3D.call( this );
50688
50689     var fov = 90, aspect = 1;
50690
50691     var cameraPX = new THREE.PerspectiveCamera( fov, aspect, near, far );
50692     cameraPX.up.set( 0, -1, 0 );
50693     cameraPX.lookAt( new THREE.Vector3( 1, 0, 0 ) );
50694     this.add( cameraPX );
50695
50696     var cameraNX = new THREE.PerspectiveCamera( fov, aspect, near, far );
50697     cameraNX.up.set( 0, -1, 0 );
50698     cameraNX.lookAt( new THREE.Vector3( -1, 0, 0 ) );
50699     this.add( cameraNX );
50700
50701     var cameraPY = new THREE.PerspectiveCamera( fov, aspect, near, far );
50702     cameraPY.up.set( 0, 0, 1 );
50703     cameraPY.lookAt( new THREE.Vector3( 0, 1, 0 ) );
50704     this.add( cameraPY );
50705
50706     var cameraNY = new THREE.PerspectiveCamera( fov, aspect, near, far );
50707     cameraNY.up.set( 0, 0, -1 );
50708     cameraNY.lookAt( new THREE.Vector3( 0, -1, 0 ) );
50709     this.add( cameraNY );
50710
50711     var cameraPZ = new THREE.PerspectiveCamera( fov, aspect, near, far );
50712     cameraPZ.up.set( 0, -1, 0 );
50713     cameraPZ.lookAt( new THREE.Vector3( 0, 0, 1 ) );
50714     this.add( cameraPZ );
50715
50716     var cameraNZ = new THREE.PerspectiveCamera( fov, aspect, near, far );
50717     cameraNZ.up.set( 0, -1, 0 );
50718     cameraNZ.lookAt( new THREE.Vector3( 0, 0, -1 ) );
50719     this.add( cameraNZ );
50720
50721     this.renderTarget = new THREE.WebGLRenderTargetCube( cubeResolution, cubeResolution, { format: THREE.RGBFormat, magFilter: THREE.LinearFilter, minFilter: THREE.LinearFilter } );
50722
50723     this.updateCubeMap = function ( renderer, scene ) {
50724
50725         var renderTarget = this.renderTarget;
50726         var generateMipmaps = renderTarget.generateMipmaps;
50727
50728         renderTarget.generateMipmaps = false;
50729
50730         renderTarget.activeCubeFace = 0;
50731         renderer.render( scene, cameraPX, renderTarget );
50732
50733         renderTarget.activeCubeFace = 1;
50734         renderer.render( scene, cameraNX, renderTarget );
50735
50736         renderTarget.activeCubeFace = 2;
50737         renderer.render( scene, cameraPY, renderTarget );
50738
50739         renderTarget.activeCubeFace = 3;
50740         renderer.render( scene, cameraNY, renderTarget );
50741
50742         renderTarget.activeCubeFace = 4;
50743         renderer.render( scene, cameraPZ, renderTarget );
50744
50745         renderTarget.generateMipmaps = generateMipmaps;
50746
50747         renderTarget.activeCubeFace = 5;
50748         renderer.render( scene, cameraNZ, renderTarget );
50749
50750     };
50751
50752 };
50753
50754 THREE.CubeCamera.prototype = Object.create( THREE.Object3D.prototype );
50755 /*
50756  *    @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
50757  *
50758  *    A general perpose camera, for setting FOV, Lens Focal Length,
50759  *        and switching between perspective and orthographic views easily.
50760  *        Use this only if you do not wish to manage
50761  *        both a Orthographic and Perspective Camera
50762  *
50763  */
50764
50765
50766 THREE.CombinedCamera = function ( width, height, fov, near, far, orthoNear, orthoFar ) {
50767
50768     THREE.Camera.call( this );
50769
50770     this.fov = fov;
50771
50772     this.left = -width / 2;
50773     this.right = width / 2
50774     this.top = height / 2;
50775     this.bottom = -height / 2;
50776
50777     // We could also handle the projectionMatrix internally, but just wanted to test nested camera objects
50778
50779     this.cameraO = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2,     orthoNear, orthoFar );
50780     this.cameraP = new THREE.PerspectiveCamera( fov, width / height, near, far );
50781
50782     this.zoom = 1;
50783
50784     this.toPerspective();
50785
50786     var aspect = width/height;
50787
50788 };
50789
50790 THREE.CombinedCamera.prototype = Object.create( THREE.Camera.prototype );
50791
50792 THREE.CombinedCamera.prototype.toPerspective = function () {
50793
50794     // Switches to the Perspective Camera
50795
50796     this.near = this.cameraP.near;
50797     this.far = this.cameraP.far;
50798
50799     this.cameraP.fov =  this.fov / this.zoom ;
50800
50801     this.cameraP.updateProjectionMatrix();
50802
50803     this.projectionMatrix = this.cameraP.projectionMatrix;
50804
50805     this.inPerspectiveMode = true;
50806     this.inOrthographicMode = false;
50807
50808 };
50809
50810 THREE.CombinedCamera.prototype.toOrthographic = function () {
50811
50812     // Switches to the Orthographic camera estimating viewport from Perspective
50813
50814     var fov = this.fov;
50815     var aspect = this.cameraP.aspect;
50816     var near = this.cameraP.near;
50817     var far = this.cameraP.far;
50818
50819     // The size that we set is the mid plane of the viewing frustum
50820
50821     var hyperfocus = ( near + far ) / 2;
50822
50823     var halfHeight = Math.tan( fov / 2 ) * hyperfocus;
50824     var planeHeight = 2 * halfHeight;
50825     var planeWidth = planeHeight * aspect;
50826     var halfWidth = planeWidth / 2;
50827
50828     halfHeight /= this.zoom;
50829     halfWidth /= this.zoom;
50830
50831     this.cameraO.left = -halfWidth;
50832     this.cameraO.right = halfWidth;
50833     this.cameraO.top = halfHeight;
50834     this.cameraO.bottom = -halfHeight;
50835
50836     // this.cameraO.left = -farHalfWidth;
50837     // this.cameraO.right = farHalfWidth;
50838     // this.cameraO.top = farHalfHeight;
50839     // this.cameraO.bottom = -farHalfHeight;
50840
50841     // this.cameraO.left = this.left / this.zoom;
50842     // this.cameraO.right = this.right / this.zoom;
50843     // this.cameraO.top = this.top / this.zoom;
50844     // this.cameraO.bottom = this.bottom / this.zoom;
50845
50846     this.cameraO.updateProjectionMatrix();
50847
50848     this.near = this.cameraO.near;
50849     this.far = this.cameraO.far;
50850     this.projectionMatrix = this.cameraO.projectionMatrix;
50851
50852     this.inPerspectiveMode = false;
50853     this.inOrthographicMode = true;
50854
50855 };
50856
50857
50858 THREE.CombinedCamera.prototype.setSize = function( width, height ) {
50859
50860     this.cameraP.aspect = width / height;
50861     this.left = -width / 2;
50862     this.right = width / 2
50863     this.top = height / 2;
50864     this.bottom = -height / 2;
50865
50866 };
50867
50868
50869 THREE.CombinedCamera.prototype.setFov = function( fov ) {
50870
50871     this.fov = fov;
50872
50873     if ( this.inPerspectiveMode ) {
50874
50875         this.toPerspective();
50876
50877     } else {
50878
50879         this.toOrthographic();
50880
50881     }
50882
50883 };
50884
50885 // For mantaining similar API with PerspectiveCamera
50886
50887 THREE.CombinedCamera.prototype.updateProjectionMatrix = function() {
50888
50889     if ( this.inPerspectiveMode ) {
50890
50891         this.toPerspective();
50892
50893     } else {
50894
50895         this.toPerspective();
50896         this.toOrthographic();
50897
50898     }
50899
50900 };
50901
50902 /*
50903 * Uses Focal Length (in mm) to estimate and set FOV
50904 * 35mm (fullframe) camera is used if frame size is not specified;
50905 * Formula based on http://www.bobatkins.com/photography/technical/field_of_view.html
50906 */
50907 THREE.CombinedCamera.prototype.setLens = function ( focalLength, frameHeight ) {
50908
50909     if ( frameHeight === undefined ) frameHeight = 24;
50910
50911     var fov = 2 * Math.atan( frameHeight / ( focalLength * 2 ) ) * ( 180 / Math.PI );
50912
50913     this.setFov( fov );
50914
50915     return fov;
50916 };
50917
50918
50919 THREE.CombinedCamera.prototype.setZoom = function( zoom ) {
50920
50921     this.zoom = zoom;
50922
50923     if ( this.inPerspectiveMode ) {
50924
50925         this.toPerspective();
50926
50927     } else {
50928
50929         this.toOrthographic();
50930
50931     }
50932
50933 };
50934
50935 THREE.CombinedCamera.prototype.toFrontView = function() {
50936
50937     this.rotation.x = 0;
50938     this.rotation.y = 0;
50939     this.rotation.z = 0;
50940
50941     // should we be modifing the matrix instead?
50942
50943     this.rotationAutoUpdate = false;
50944
50945 };
50946
50947 THREE.CombinedCamera.prototype.toBackView = function() {
50948
50949     this.rotation.x = 0;
50950     this.rotation.y = Math.PI;
50951     this.rotation.z = 0;
50952     this.rotationAutoUpdate = false;
50953
50954 };
50955
50956 THREE.CombinedCamera.prototype.toLeftView = function() {
50957
50958     this.rotation.x = 0;
50959     this.rotation.y = - Math.PI / 2;
50960     this.rotation.z = 0;
50961     this.rotationAutoUpdate = false;
50962
50963 };
50964
50965 THREE.CombinedCamera.prototype.toRightView = function() {
50966
50967     this.rotation.x = 0;
50968     this.rotation.y = Math.PI / 2;
50969     this.rotation.z = 0;
50970     this.rotationAutoUpdate = false;
50971
50972 };
50973
50974 THREE.CombinedCamera.prototype.toTopView = function() {
50975
50976     this.rotation.x = - Math.PI / 2;
50977     this.rotation.y = 0;
50978     this.rotation.z = 0;
50979     this.rotationAutoUpdate = false;
50980
50981 };
50982
50983 THREE.CombinedCamera.prototype.toBottomView = function() {
50984
50985     this.rotation.x = Math.PI / 2;
50986     this.rotation.y = 0;
50987     this.rotation.z = 0;
50988     this.rotationAutoUpdate = false;
50989
50990 };
50991
50992 /**
50993  * @author mrdoob / http://mrdoob.com/
50994  * @author alteredq / http://alteredqualia.com/
50995  * @author paulirish / http://paulirish.com/
50996  */
50997
50998 THREE.FirstPersonControls = function ( object, domElement ) {
50999
51000     this.object = object;
51001     this.target = new THREE.Vector3( 0, 0, 0 );
51002
51003     this.domElement = ( domElement !== undefined ) ? domElement : document;
51004
51005     this.movementSpeed = 1.0;
51006     this.lookSpeed = 0.005;
51007
51008     this.lookVertical = true;
51009     this.autoForward = false;
51010     // this.invertVertical = false;
51011
51012     this.activeLook = true;
51013
51014     this.heightSpeed = false;
51015     this.heightCoef = 1.0;
51016     this.heightMin = 0.0;
51017     this.heightMax = 1.0;
51018
51019     this.constrainVertical = false;
51020     this.verticalMin = 0;
51021     this.verticalMax = Math.PI;
51022
51023     this.autoSpeedFactor = 0.0;
51024
51025     this.mouseX = 0;
51026     this.mouseY = 0;
51027
51028     this.lat = 0;
51029     this.lon = 0;
51030     this.phi = 0;
51031     this.theta = 0;
51032
51033     this.moveForward = false;
51034     this.moveBackward = false;
51035     this.moveLeft = false;
51036     this.moveRight = false;
51037     this.freeze = false;
51038
51039     this.mouseDragOn = false;
51040
51041     this.viewHalfX = 0;
51042     this.viewHalfY = 0;
51043
51044     if ( this.domElement !== document ) {
51045
51046         this.domElement.setAttribute( 'tabindex', -1 );
51047
51048     }
51049
51050     //
51051
51052     this.handleResize = function () {
51053
51054         if ( this.domElement === document ) {
51055
51056             this.viewHalfX = window.innerWidth / 2;
51057             this.viewHalfY = window.innerHeight / 2;
51058
51059         } else {
51060
51061             this.viewHalfX = this.domElement.offsetWidth / 2;
51062             this.viewHalfY = this.domElement.offsetHeight / 2;
51063
51064         }
51065
51066     };
51067
51068     this.onMouseDown = function ( event ) {
51069
51070         if ( this.domElement !== document ) {
51071
51072             this.domElement.focus();
51073
51074         }
51075
51076         event.preventDefault();
51077         event.stopPropagation();
51078
51079         if ( this.activeLook ) {
51080
51081             switch ( event.button ) {
51082
51083                 case 0: this.moveForward = true; break;
51084                 case 2: this.moveBackward = true; break;
51085
51086             }
51087
51088         }
51089
51090         this.mouseDragOn = true;
51091
51092     };
51093
51094     this.onMouseUp = function ( event ) {
51095
51096         event.preventDefault();
51097         event.stopPropagation();
51098
51099         if ( this.activeLook ) {
51100
51101             switch ( event.button ) {
51102
51103                 case 0: this.moveForward = false; break;
51104                 case 2: this.moveBackward = false; break;
51105
51106             }
51107
51108         }
51109
51110         this.mouseDragOn = false;
51111
51112     };
51113
51114     this.onMouseMove = function ( event ) {
51115
51116         if ( this.domElement === document ) {
51117
51118             this.mouseX = event.pageX - this.viewHalfX;
51119             this.mouseY = event.pageY - this.viewHalfY;
51120
51121         } else {
51122
51123             this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
51124             this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
51125
51126         }
51127
51128     };
51129
51130     this.onKeyDown = function ( event ) {
51131
51132         //event.preventDefault();
51133
51134         switch ( event.keyCode ) {
51135
51136             case 38: /*up*/
51137             case 87: /*W*/ this.moveForward = true; break;
51138
51139             case 37: /*left*/
51140             case 65: /*A*/ this.moveLeft = true; break;
51141
51142             case 40: /*down*/
51143             case 83: /*S*/ this.moveBackward = true; break;
51144
51145             case 39: /*right*/
51146             case 68: /*D*/ this.moveRight = true; break;
51147
51148             case 82: /*R*/ this.moveUp = true; break;
51149             case 70: /*F*/ this.moveDown = true; break;
51150
51151             case 81: /*Q*/ this.freeze = !this.freeze; break;
51152
51153         }
51154
51155     };
51156
51157     this.onKeyUp = function ( event ) {
51158
51159         switch( event.keyCode ) {
51160
51161             case 38: /*up*/
51162             case 87: /*W*/ this.moveForward = false; break;
51163
51164             case 37: /*left*/
51165             case 65: /*A*/ this.moveLeft = false; break;
51166
51167             case 40: /*down*/
51168             case 83: /*S*/ this.moveBackward = false; break;
51169
51170             case 39: /*right*/
51171             case 68: /*D*/ this.moveRight = false; break;
51172
51173             case 82: /*R*/ this.moveUp = false; break;
51174             case 70: /*F*/ this.moveDown = false; break;
51175
51176         }
51177
51178     };
51179
51180     this.update = function( delta ) {
51181         var actualMoveSpeed = 0;
51182
51183         if ( this.freeze ) {
51184
51185             return;
51186
51187         } else {
51188
51189             if ( this.heightSpeed ) {
51190
51191                 var y = THREE.Math.clamp( this.object.position.y, this.heightMin, this.heightMax );
51192                 var heightDelta = y - this.heightMin;
51193
51194                 this.autoSpeedFactor = delta * ( heightDelta * this.heightCoef );
51195
51196             } else {
51197
51198                 this.autoSpeedFactor = 0.0;
51199
51200             }
51201
51202             actualMoveSpeed = delta * this.movementSpeed;
51203
51204             if ( this.moveForward || ( this.autoForward && !this.moveBackward ) ) this.object.translateZ( - ( actualMoveSpeed + this.autoSpeedFactor ) );
51205             if ( this.moveBackward ) this.object.translateZ( actualMoveSpeed );
51206
51207             if ( this.moveLeft ) this.object.translateX( - actualMoveSpeed );
51208             if ( this.moveRight ) this.object.translateX( actualMoveSpeed );
51209
51210             if ( this.moveUp ) this.object.translateY( actualMoveSpeed );
51211             if ( this.moveDown ) this.object.translateY( - actualMoveSpeed );
51212
51213             var actualLookSpeed = delta * this.lookSpeed;
51214
51215             if ( !this.activeLook ) {
51216
51217                 actualLookSpeed = 0;
51218
51219             }
51220
51221             this.lon += this.mouseX * actualLookSpeed;
51222             if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed; // * this.invertVertical?-1:1;
51223
51224             this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
51225             this.phi = ( 90 - this.lat ) * Math.PI / 180;
51226             this.theta = this.lon * Math.PI / 180;
51227
51228             var targetPosition = this.target,
51229                 position = this.object.position;
51230
51231             targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
51232             targetPosition.y = position.y + 100 * Math.cos( this.phi );
51233             targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
51234
51235         }
51236
51237         var verticalLookRatio = 1;
51238
51239         if ( this.constrainVertical ) {
51240
51241             verticalLookRatio = Math.PI / ( this.verticalMax - this.verticalMin );
51242
51243         }
51244
51245         this.lon += this.mouseX * actualLookSpeed;
51246         if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
51247
51248         this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
51249         this.phi = ( 90 - this.lat ) * Math.PI / 180;
51250
51251         this.theta = this.lon * Math.PI / 180;
51252
51253         if ( this.constrainVertical ) {
51254
51255             this.phi = THREE.Math.mapLinear( this.phi, 0, Math.PI, this.verticalMin, this.verticalMax );
51256
51257         }
51258
51259         var targetPosition = this.target,
51260             position = this.object.position;
51261
51262         targetPosition.x = position.x + 100 * Math.sin( this.phi ) * Math.cos( this.theta );
51263         targetPosition.y = position.y + 100 * Math.cos( this.phi );
51264         targetPosition.z = position.z + 100 * Math.sin( this.phi ) * Math.sin( this.theta );
51265
51266         this.object.lookAt( targetPosition );
51267
51268     };
51269
51270
51271     this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
51272
51273     this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
51274     this.domElement.addEventListener( 'mousedown', bind( this, this.onMouseDown ), false );
51275     this.domElement.addEventListener( 'mouseup', bind( this, this.onMouseUp ), false );
51276     this.domElement.addEventListener( 'keydown', bind( this, this.onKeyDown ), false );
51277     this.domElement.addEventListener( 'keyup', bind( this, this.onKeyUp ), false );
51278
51279     function bind( scope, fn ) {
51280
51281         return function () {
51282
51283             fn.apply( scope, arguments );
51284
51285         };
51286
51287     };
51288
51289     this.handleResize();
51290
51291 };
51292 /**
51293  * @author alteredq / http://alteredqualia.com/
51294  */
51295
51296 THREE.PathControls = function ( object, domElement ) {
51297
51298     this.object = object;
51299     this.domElement = ( domElement !== undefined ) ? domElement : document;
51300
51301     this.id = "PathControls" + THREE.PathControlsIdCounter ++;
51302
51303     // API
51304
51305     this.duration = 10 * 1000; // milliseconds
51306     this.waypoints = [];
51307
51308     this.useConstantSpeed = true;
51309     this.resamplingCoef = 50;
51310
51311     this.debugPath = new THREE.Object3D();
51312     this.debugDummy = new THREE.Object3D();
51313
51314     this.animationParent = new THREE.Object3D();
51315
51316     this.lookSpeed = 0.005;
51317     this.lookVertical = true;
51318     this.lookHorizontal = true;
51319     this.verticalAngleMap   = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
51320     this.horizontalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
51321
51322     // internals
51323
51324     this.target = new THREE.Object3D();
51325
51326     this.mouseX = 0;
51327     this.mouseY = 0;
51328
51329     this.lat = 0;
51330     this.lon = 0;
51331
51332     this.phi = 0;
51333     this.theta = 0;
51334
51335     var PI2 = Math.PI * 2,
51336         PI180 = Math.PI / 180;
51337
51338     this.viewHalfX = 0;
51339     this.viewHalfY = 0;
51340
51341     if ( this.domElement !== document ) {
51342
51343         this.domElement.setAttribute( 'tabindex', -1 );
51344
51345     }
51346
51347     // methods
51348
51349     this.handleResize = function () {
51350
51351         if ( this.domElement === document ) {
51352
51353             this.viewHalfX = window.innerWidth / 2;
51354             this.viewHalfY = window.innerHeight / 2;
51355
51356         } else {
51357
51358             this.viewHalfX = this.domElement.offsetWidth / 2;
51359             this.viewHalfY = this.domElement.offsetHeight / 2;
51360
51361         }
51362
51363     };
51364
51365     this.update = function ( delta ) {
51366
51367         var srcRange, dstRange;
51368
51369         if( this.lookHorizontal ) this.lon += this.mouseX * this.lookSpeed * delta;
51370         if( this.lookVertical )   this.lat -= this.mouseY * this.lookSpeed * delta;
51371
51372         this.lon = Math.max( 0, Math.min( 360, this.lon ) );
51373         this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
51374
51375         this.phi = ( 90 - this.lat ) * PI180;
51376         this.theta = this.lon * PI180;
51377
51378         this.phi = normalize_angle_rad( this.phi );
51379
51380         // constrain vertical look angle
51381
51382         srcRange = this.verticalAngleMap.srcRange;
51383         dstRange = this.verticalAngleMap.dstRange;
51384
51385         var tmpPhi = THREE.Math.mapLinear( this.phi, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
51386         var tmpPhiFullRange = dstRange[ 1 ] - dstRange[ 0 ];
51387         var tmpPhiNormalized = ( tmpPhi - dstRange[ 0 ] ) / tmpPhiFullRange;
51388
51389         this.phi = QuadraticEaseInOut( tmpPhiNormalized ) * tmpPhiFullRange + dstRange[ 0 ];
51390
51391         // constrain horizontal look angle
51392
51393         srcRange = this.horizontalAngleMap.srcRange;
51394         dstRange = this.horizontalAngleMap.dstRange;
51395
51396         var tmpTheta = THREE.Math.mapLinear( this.theta, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
51397         var tmpThetaFullRange = dstRange[ 1 ] - dstRange[ 0 ];
51398         var tmpThetaNormalized = ( tmpTheta - dstRange[ 0 ] ) / tmpThetaFullRange;
51399
51400         this.theta = QuadraticEaseInOut( tmpThetaNormalized ) * tmpThetaFullRange + dstRange[ 0 ];
51401
51402         var targetPosition = this.target.position,
51403             position = this.object.position;
51404
51405         targetPosition.x = 100 * Math.sin( this.phi ) * Math.cos( this.theta );
51406         targetPosition.y = 100 * Math.cos( this.phi );
51407         targetPosition.z = 100 * Math.sin( this.phi ) * Math.sin( this.theta );
51408
51409         this.object.lookAt( this.target.position );
51410
51411     };
51412
51413     this.onMouseMove = function ( event ) {
51414
51415         if ( this.domElement === document ) {
51416
51417             this.mouseX = event.pageX - this.viewHalfX;
51418             this.mouseY = event.pageY - this.viewHalfY;
51419
51420         } else {
51421
51422             this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
51423             this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
51424
51425         }
51426
51427     };
51428
51429     // utils
51430
51431     function normalize_angle_rad( a ) {
51432
51433         var b = a % PI2;
51434         return b >= 0 ? b : b + PI2;
51435
51436     };
51437
51438     function distance( a, b ) {
51439
51440         var dx = a[ 0 ] - b[ 0 ],
51441             dy = a[ 1 ] - b[ 1 ],
51442             dz = a[ 2 ] - b[ 2 ];
51443
51444         return Math.sqrt( dx * dx + dy * dy + dz * dz );
51445
51446     };
51447
51448     function QuadraticEaseInOut ( k ) {
51449
51450         if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
51451         return - 0.5 * ( --k * ( k - 2 ) - 1 );
51452
51453     };
51454
51455     function bind( scope, fn ) {
51456
51457         return function () {
51458
51459             fn.apply( scope, arguments );
51460
51461         };
51462
51463     };
51464
51465     function initAnimationPath( parent, spline, name, duration ) {
51466
51467         var animationData = {
51468
51469            name: name,
51470            fps: 0.6,
51471            length: duration,
51472
51473            hierarchy: []
51474
51475         };
51476
51477         var i,
51478             parentAnimation, childAnimation,
51479             path = spline.getControlPointsArray(),
51480             sl = spline.getLength(),
51481             pl = path.length,
51482             t = 0,
51483             first = 0,
51484             last  = pl - 1;
51485
51486         parentAnimation = { parent: -1, keys: [] };
51487         parentAnimation.keys[ first ] = { time: 0,        pos: path[ first ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
51488         parentAnimation.keys[ last  ] = { time: duration, pos: path[ last ],  rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
51489
51490         for ( i = 1; i < pl - 1; i++ ) {
51491
51492             // real distance (approximation via linear segments)
51493
51494             t = duration * sl.chunks[ i ] / sl.total;
51495
51496             // equal distance
51497
51498             //t = duration * ( i / pl );
51499
51500             // linear distance
51501
51502             //t += duration * distance( path[ i ], path[ i - 1 ] ) / sl.total;
51503
51504             parentAnimation.keys[ i ] = { time: t, pos: path[ i ] };
51505
51506         }
51507
51508         animationData.hierarchy[ 0 ] = parentAnimation;
51509
51510         THREE.AnimationHandler.add( animationData );
51511
51512         return new THREE.Animation( parent, name, THREE.AnimationHandler.CATMULLROM_FORWARD, false );
51513
51514     };
51515
51516
51517     function createSplineGeometry( spline, n_sub ) {
51518
51519         var i, index, position,
51520             geometry = new THREE.Geometry();
51521
51522         for ( i = 0; i < spline.points.length * n_sub; i ++ ) {
51523
51524             index = i / ( spline.points.length * n_sub );
51525             position = spline.getPoint( index );
51526
51527             geometry.vertices[ i ] = new THREE.Vector3( position.x, position.y, position.z );
51528
51529         }
51530
51531         return geometry;
51532
51533     };
51534
51535     function createPath( parent, spline ) {
51536
51537         var lineGeo = createSplineGeometry( spline, 10 ),
51538             particleGeo = createSplineGeometry( spline, 10 ),
51539             lineMat = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 3 } ),
51540             lineObj = new THREE.Line( lineGeo, lineMat ),
51541             particleObj = new THREE.ParticleSystem( particleGeo, new THREE.ParticleBasicMaterial( { color: 0xffaa00, size: 3 } ) );
51542
51543         lineObj.scale.set( 1, 1, 1 );
51544         parent.add( lineObj );
51545
51546         particleObj.scale.set( 1, 1, 1 );
51547         parent.add( particleObj );
51548
51549         var waypoint,
51550             geo = new THREE.SphereGeometry( 1, 16, 8 ),
51551             mat = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
51552
51553         for ( var i = 0; i < spline.points.length; i ++ ) {
51554
51555             waypoint = new THREE.Mesh( geo, mat );
51556             waypoint.position.copy( spline.points[ i ] );
51557             parent.add( waypoint );
51558
51559         }
51560
51561     };
51562
51563     this.init = function ( ) {
51564
51565         // constructor
51566
51567         this.spline = new THREE.Spline();
51568         this.spline.initFromArray( this.waypoints );
51569
51570         if ( this.useConstantSpeed ) {
51571
51572             this.spline.reparametrizeByArcLength( this.resamplingCoef );
51573
51574         }
51575
51576         if ( this.createDebugDummy ) {
51577
51578             var dummyParentMaterial = new THREE.MeshLambertMaterial( { color: 0x0077ff } ),
51579             dummyChildMaterial  = new THREE.MeshLambertMaterial( { color: 0x00ff00 } ),
51580             dummyParentGeo = new THREE.CubeGeometry( 10, 10, 20 ),
51581             dummyChildGeo  = new THREE.CubeGeometry( 2, 2, 10 );
51582
51583             this.animationParent = new THREE.Mesh( dummyParentGeo, dummyParentMaterial );
51584
51585             var dummyChild = new THREE.Mesh( dummyChildGeo, dummyChildMaterial );
51586             dummyChild.position.set( 0, 10, 0 );
51587
51588             this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
51589
51590             this.animationParent.add( this.object );
51591             this.animationParent.add( this.target );
51592             this.animationParent.add( dummyChild );
51593
51594         } else {
51595
51596             this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
51597             this.animationParent.add( this.target );
51598             this.animationParent.add( this.object );
51599
51600         }
51601
51602         if ( this.createDebugPath ) {
51603
51604             createPath( this.debugPath, this.spline );
51605
51606         }
51607
51608         this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
51609
51610     };
51611
51612     this.handleResize();
51613
51614 };
51615
51616 THREE.PathControlsIdCounter = 0;
51617 /**
51618  * @author James Baicoianu / http://www.baicoianu.com/
51619  */
51620
51621 THREE.FlyControls = function ( object, domElement ) {
51622
51623     this.object = object;
51624
51625     this.domElement = ( domElement !== undefined ) ? domElement : document;
51626     if ( domElement ) this.domElement.setAttribute( 'tabindex', -1 );
51627
51628     // API
51629
51630     this.movementSpeed = 1.0;
51631     this.rollSpeed = 0.005;
51632
51633     this.dragToLook = false;
51634     this.autoForward = false;
51635
51636     // disable default target object behavior
51637
51638     this.object.useQuaternion = true;
51639
51640     // internals
51641
51642     this.tmpQuaternion = new THREE.Quaternion();
51643
51644     this.mouseStatus = 0;
51645
51646     this.moveState = { up: 0, down: 0, left: 0, right: 0, forward: 0, back: 0, pitchUp: 0, pitchDown: 0, yawLeft: 0, yawRight: 0, rollLeft: 0, rollRight: 0 };
51647     this.moveVector = new THREE.Vector3( 0, 0, 0 );
51648     this.rotationVector = new THREE.Vector3( 0, 0, 0 );
51649
51650     this.handleEvent = function ( event ) {
51651
51652         if ( typeof this[ event.type ] == 'function' ) {
51653
51654             this[ event.type ]( event );
51655
51656         }
51657
51658     };
51659
51660     this.keydown = function( event ) {
51661
51662         if ( event.altKey ) {
51663
51664             return;
51665
51666         }
51667
51668         //event.preventDefault();
51669
51670         switch ( event.keyCode ) {
51671
51672             case 16: /* shift */ this.movementSpeedMultiplier = .1; break;
51673
51674             case 87: /*W*/ this.moveState.forward = 1; break;
51675             case 83: /*S*/ this.moveState.back = 1; break;
51676
51677             case 65: /*A*/ this.moveState.left = 1; break;
51678             case 68: /*D*/ this.moveState.right = 1; break;
51679
51680             case 82: /*R*/ this.moveState.up = 1; break;
51681             case 70: /*F*/ this.moveState.down = 1; break;
51682
51683             case 38: /*up*/ this.moveState.pitchUp = 1; break;
51684             case 40: /*down*/ this.moveState.pitchDown = 1; break;
51685
51686             case 37: /*left*/ this.moveState.yawLeft = 1; break;
51687             case 39: /*right*/ this.moveState.yawRight = 1; break;
51688
51689             case 81: /*Q*/ this.moveState.rollLeft = 1; break;
51690             case 69: /*E*/ this.moveState.rollRight = 1; break;
51691
51692         }
51693
51694         this.updateMovementVector();
51695         this.updateRotationVector();
51696
51697     };
51698
51699     this.keyup = function( event ) {
51700
51701         switch( event.keyCode ) {
51702
51703             case 16: /* shift */ this.movementSpeedMultiplier = 1; break;
51704
51705             case 87: /*W*/ this.moveState.forward = 0; break;
51706             case 83: /*S*/ this.moveState.back = 0; break;
51707
51708             case 65: /*A*/ this.moveState.left = 0; break;
51709             case 68: /*D*/ this.moveState.right = 0; break;
51710
51711             case 82: /*R*/ this.moveState.up = 0; break;
51712             case 70: /*F*/ this.moveState.down = 0; break;
51713
51714             case 38: /*up*/ this.moveState.pitchUp = 0; break;
51715             case 40: /*down*/ this.moveState.pitchDown = 0; break;
51716
51717             case 37: /*left*/ this.moveState.yawLeft = 0; break;
51718             case 39: /*right*/ this.moveState.yawRight = 0; break;
51719
51720             case 81: /*Q*/ this.moveState.rollLeft = 0; break;
51721             case 69: /*E*/ this.moveState.rollRight = 0; break;
51722
51723         }
51724
51725         this.updateMovementVector();
51726         this.updateRotationVector();
51727
51728     };
51729
51730     this.mousedown = function( event ) {
51731
51732         if ( this.domElement !== document ) {
51733
51734             this.domElement.focus();
51735
51736         }
51737
51738         event.preventDefault();
51739         event.stopPropagation();
51740
51741         if ( this.dragToLook ) {
51742
51743             this.mouseStatus ++;
51744
51745         } else {
51746
51747             switch ( event.button ) {
51748
51749                 case 0: this.object.moveForward = true; break;
51750                 case 2: this.object.moveBackward = true; break;
51751
51752             }
51753
51754         }
51755
51756     };
51757
51758     this.mousemove = function( event ) {
51759
51760         if ( !this.dragToLook || this.mouseStatus > 0 ) {
51761
51762             var container = this.getContainerDimensions();
51763             var halfWidth  = container.size[ 0 ] / 2;
51764             var halfHeight = container.size[ 1 ] / 2;
51765
51766             this.moveState.yawLeft   = - ( ( event.pageX - container.offset[ 0 ] ) - halfWidth  ) / halfWidth;
51767             this.moveState.pitchDown =   ( ( event.pageY - container.offset[ 1 ] ) - halfHeight ) / halfHeight;
51768
51769             this.updateRotationVector();
51770
51771         }
51772
51773     };
51774
51775     this.mouseup = function( event ) {
51776
51777         event.preventDefault();
51778         event.stopPropagation();
51779
51780         if ( this.dragToLook ) {
51781
51782             this.mouseStatus --;
51783
51784             this.moveState.yawLeft = this.moveState.pitchDown = 0;
51785
51786         } else {
51787
51788             switch ( event.button ) {
51789
51790                 case 0: this.moveForward = false; break;
51791                 case 2: this.moveBackward = false; break;
51792
51793             }
51794
51795         }
51796
51797         this.updateRotationVector();
51798
51799     };
51800
51801     this.update = function( delta ) {
51802
51803         var moveMult = delta * this.movementSpeed;
51804         var rotMult = delta * this.rollSpeed;
51805
51806         this.object.translateX( this.moveVector.x * moveMult );
51807         this.object.translateY( this.moveVector.y * moveMult );
51808         this.object.translateZ( this.moveVector.z * moveMult );
51809
51810         this.tmpQuaternion.set( this.rotationVector.x * rotMult, this.rotationVector.y * rotMult, this.rotationVector.z * rotMult, 1 ).normalize();
51811         this.object.quaternion.multiplySelf( this.tmpQuaternion );
51812
51813         this.object.matrix.setPosition( this.object.position );
51814         this.object.matrix.setRotationFromQuaternion( this.object.quaternion );
51815         this.object.matrixWorldNeedsUpdate = true;
51816
51817
51818     };
51819
51820     this.updateMovementVector = function() {
51821
51822         var forward = ( this.moveState.forward || ( this.autoForward && !this.moveState.back ) ) ? 1 : 0;
51823
51824         this.moveVector.x = ( -this.moveState.left    + this.moveState.right );
51825         this.moveVector.y = ( -this.moveState.down    + this.moveState.up );
51826         this.moveVector.z = ( -forward + this.moveState.back );
51827
51828         //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] );
51829
51830     };
51831
51832     this.updateRotationVector = function() {
51833
51834         this.rotationVector.x = ( -this.moveState.pitchDown + this.moveState.pitchUp );
51835         this.rotationVector.y = ( -this.moveState.yawRight  + this.moveState.yawLeft );
51836         this.rotationVector.z = ( -this.moveState.rollRight + this.moveState.rollLeft );
51837
51838         //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] );
51839
51840     };
51841
51842     this.getContainerDimensions = function() {
51843
51844         if ( this.domElement != document ) {
51845
51846             return {
51847                 size    : [ this.domElement.offsetWidth, this.domElement.offsetHeight ],
51848                 offset    : [ this.domElement.offsetLeft,  this.domElement.offsetTop ]
51849             };
51850
51851         } else {
51852
51853             return {
51854                 size    : [ window.innerWidth, window.innerHeight ],
51855                 offset    : [ 0, 0 ]
51856             };
51857
51858         }
51859
51860     };
51861
51862     function bind( scope, fn ) {
51863
51864         return function () {
51865
51866             fn.apply( scope, arguments );
51867
51868         };
51869
51870     };
51871
51872     this.domElement.addEventListener( 'mousemove', bind( this, this.mousemove ), false );
51873     this.domElement.addEventListener( 'mousedown', bind( this, this.mousedown ), false );
51874     this.domElement.addEventListener( 'mouseup',   bind( this, this.mouseup ), false );
51875
51876     this.domElement.addEventListener( 'keydown', bind( this, this.keydown ), false );
51877     this.domElement.addEventListener( 'keyup',   bind( this, this.keyup ), false );
51878
51879     this.updateMovementVector();
51880     this.updateRotationVector();
51881
51882 };
51883 /**
51884  * @author mikael emtinger / http://gomo.se/
51885  * @author alteredq / http://alteredqualia.com/
51886  */
51887
51888 THREE.RollControls = function ( object, domElement ) {
51889
51890     this.object = object;
51891     this.domElement = ( domElement !== undefined ) ? domElement : document;
51892
51893     // API
51894
51895     this.mouseLook = true;
51896     this.autoForward = false;
51897
51898     this.lookSpeed = 1;
51899     this.movementSpeed = 1;
51900     this.rollSpeed = 1;
51901
51902     this.constrainVertical = [ -0.9, 0.9 ];
51903
51904     // disable default target object behavior
51905
51906     this.object.matrixAutoUpdate = false;
51907
51908     // internals
51909
51910     this.forward = new THREE.Vector3( 0, 0, 1 );
51911     this.roll = 0;
51912
51913     var xTemp = new THREE.Vector3();
51914     var yTemp = new THREE.Vector3();
51915     var zTemp = new THREE.Vector3();
51916     var rollMatrix = new THREE.Matrix4();
51917
51918     var doRoll = false, rollDirection = 1, forwardSpeed = 0, sideSpeed = 0, upSpeed = 0;
51919
51920     var mouseX = 0, mouseY = 0;
51921
51922     var windowHalfX = 0;
51923     var windowHalfY = 0;
51924
51925     //
51926
51927     this.handleResize = function () {
51928
51929         windowHalfX = window.innerWidth / 2;
51930         windowHalfY = window.innerHeight / 2;
51931
51932     };
51933
51934     // custom update
51935
51936     this.update = function ( delta ) {
51937
51938         if ( this.mouseLook ) {
51939
51940             var actualLookSpeed = delta * this.lookSpeed;
51941
51942             this.rotateHorizontally( actualLookSpeed * mouseX );
51943             this.rotateVertically( actualLookSpeed * mouseY );
51944
51945         }
51946
51947         var actualSpeed = delta * this.movementSpeed;
51948         var forwardOrAuto = ( forwardSpeed > 0 || ( this.autoForward && ! ( forwardSpeed < 0 ) ) ) ? 1 : forwardSpeed;
51949
51950         this.object.translateZ( -actualSpeed * forwardOrAuto );
51951         this.object.translateX( actualSpeed * sideSpeed );
51952         this.object.translateY( actualSpeed * upSpeed );
51953
51954         if( doRoll ) {
51955
51956             this.roll += this.rollSpeed * delta * rollDirection;
51957
51958         }
51959
51960         // cap forward up / down
51961
51962         if( this.forward.y > this.constrainVertical[ 1 ] ) {
51963
51964             this.forward.y = this.constrainVertical[ 1 ];
51965             this.forward.normalize();
51966
51967         } else if( this.forward.y < this.constrainVertical[ 0 ] ) {
51968
51969             this.forward.y = this.constrainVertical[ 0 ];
51970             this.forward.normalize();
51971
51972         }
51973
51974
51975         // construct unrolled camera matrix
51976
51977         zTemp.copy( this.forward );
51978         yTemp.set( 0, 1, 0 );
51979
51980         xTemp.cross( yTemp, zTemp ).normalize();
51981         yTemp.cross( zTemp, xTemp ).normalize();
51982
51983         this.object.matrix.elements[0] = xTemp.x; this.object.matrix.elements[4] = yTemp.x; this.object.matrix.elements[8] = zTemp.x;
51984         this.object.matrix.elements[1] = xTemp.y; this.object.matrix.elements[5] = yTemp.y; this.object.matrix.elements[9] = zTemp.y;
51985         this.object.matrix.elements[2] = xTemp.z; this.object.matrix.elements[6] = yTemp.z; this.object.matrix.elements[10] = zTemp.z;
51986
51987         // calculate roll matrix
51988
51989         rollMatrix.identity();
51990         rollMatrix.elements[0] = Math.cos( this.roll ); rollMatrix.elements[4] = -Math.sin( this.roll );
51991         rollMatrix.elements[1] = Math.sin( this.roll ); rollMatrix.elements[5] =  Math.cos( this.roll );
51992
51993         // multiply camera with roll
51994
51995         this.object.matrix.multiplySelf( rollMatrix );
51996         this.object.matrixWorldNeedsUpdate = true;
51997
51998         // set position
51999
52000         this.object.matrix.elements[12] = this.object.position.x;
52001         this.object.matrix.elements[13] = this.object.position.y;
52002         this.object.matrix.elements[14] = this.object.position.z;
52003
52004
52005     };
52006
52007     this.translateX = function ( distance ) {
52008
52009         this.object.position.x += this.object.matrix.elements[0] * distance;
52010         this.object.position.y += this.object.matrix.elements[1] * distance;
52011         this.object.position.z += this.object.matrix.elements[2] * distance;
52012
52013     };
52014
52015     this.translateY = function ( distance ) {
52016
52017         this.object.position.x += this.object.matrix.elements[4] * distance;
52018         this.object.position.y += this.object.matrix.elements[5] * distance;
52019         this.object.position.z += this.object.matrix.elements[6] * distance;
52020
52021     };
52022
52023     this.translateZ = function ( distance ) {
52024
52025         this.object.position.x -= this.object.matrix.elements[8] * distance;
52026         this.object.position.y -= this.object.matrix.elements[9] * distance;
52027         this.object.position.z -= this.object.matrix.elements[10] * distance;
52028
52029     };
52030
52031
52032     this.rotateHorizontally = function ( amount ) {
52033
52034         // please note that the amount is NOT degrees, but a scale value
52035
52036         xTemp.set( this.object.matrix.elements[0], this.object.matrix.elements[1], this.object.matrix.elements[2] );
52037         xTemp.multiplyScalar( amount );
52038
52039         this.forward.subSelf( xTemp );
52040         this.forward.normalize();
52041
52042     };
52043
52044     this.rotateVertically = function ( amount ) {
52045
52046         // please note that the amount is NOT degrees, but a scale value
52047
52048         yTemp.set( this.object.matrix.elements[4], this.object.matrix.elements[5], this.object.matrix.elements[6] );
52049         yTemp.multiplyScalar( amount );
52050
52051         this.forward.addSelf( yTemp );
52052         this.forward.normalize();
52053
52054     };
52055
52056     function onKeyDown( event ) {
52057
52058         //event.preventDefault();
52059
52060         switch ( event.keyCode ) {
52061
52062             case 38: /*up*/
52063             case 87: /*W*/ forwardSpeed = 1; break;
52064
52065             case 37: /*left*/
52066             case 65: /*A*/ sideSpeed = -1; break;
52067
52068             case 40: /*down*/
52069             case 83: /*S*/ forwardSpeed = -1; break;
52070
52071             case 39: /*right*/
52072             case 68: /*D*/ sideSpeed = 1; break;
52073
52074             case 81: /*Q*/ doRoll = true; rollDirection = 1; break;
52075             case 69: /*E*/ doRoll = true; rollDirection = -1; break;
52076
52077             case 82: /*R*/ upSpeed = 1; break;
52078             case 70: /*F*/ upSpeed = -1; break;
52079
52080         }
52081
52082     };
52083
52084     function onKeyUp( event ) {
52085
52086         switch( event.keyCode ) {
52087
52088             case 38: /*up*/
52089             case 87: /*W*/ forwardSpeed = 0; break;
52090
52091             case 37: /*left*/
52092             case 65: /*A*/ sideSpeed = 0; break;
52093
52094             case 40: /*down*/
52095             case 83: /*S*/ forwardSpeed = 0; break;
52096
52097             case 39: /*right*/
52098             case 68: /*D*/ sideSpeed = 0; break;
52099
52100             case 81: /*Q*/ doRoll = false; break;
52101             case 69: /*E*/ doRoll = false; break;
52102
52103             case 82: /*R*/ upSpeed = 0; break;
52104             case 70: /*F*/ upSpeed = 0; break;
52105
52106         }
52107
52108     };
52109
52110     function onMouseMove( event ) {
52111
52112         mouseX = ( event.clientX - windowHalfX ) / window.innerWidth;
52113         mouseY = ( event.clientY - windowHalfY ) / window.innerHeight;
52114
52115     };
52116
52117     function onMouseDown ( event ) {
52118
52119         event.preventDefault();
52120         event.stopPropagation();
52121
52122         switch ( event.button ) {
52123
52124             case 0: forwardSpeed = 1; break;
52125             case 2: forwardSpeed = -1; break;
52126
52127         }
52128
52129     };
52130
52131     function onMouseUp ( event ) {
52132
52133         event.preventDefault();
52134         event.stopPropagation();
52135
52136         switch ( event.button ) {
52137
52138             case 0: forwardSpeed = 0; break;
52139             case 2: forwardSpeed = 0; break;
52140
52141         }
52142
52143     };
52144
52145     this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
52146
52147     this.domElement.addEventListener( 'mousemove', onMouseMove, false );
52148     this.domElement.addEventListener( 'mousedown', onMouseDown, false );
52149     this.domElement.addEventListener( 'mouseup', onMouseUp, false );
52150     this.domElement.addEventListener( 'keydown', onKeyDown, false );
52151     this.domElement.addEventListener( 'keyup', onKeyUp, false );
52152
52153     this.handleResize();
52154
52155 };
52156 /**
52157  * @author Eberhard Graether / http://egraether.com/
52158  */
52159
52160 THREE.TrackballControls = function ( object, domElement ) {
52161
52162     THREE.EventTarget.call( this );
52163
52164     var _this = this,
52165     STATE = { NONE : -1, ROTATE : 0, ZOOM : 1, PAN : 2 };
52166
52167     this.object = object;
52168     this.domElement = ( domElement !== undefined ) ? domElement : document;
52169
52170     // API
52171
52172     this.enabled = true;
52173
52174     this.screen = { width: 0, height: 0, offsetLeft: 0, offsetTop: 0 };
52175     this.radius = ( this.screen.width + this.screen.height ) / 4;
52176
52177     this.rotateSpeed = 1.0;
52178     this.zoomSpeed = 1.2;
52179     this.panSpeed = 0.3;
52180
52181     this.noRotate = false;
52182     this.noZoom = false;
52183     this.noPan = false;
52184
52185     this.staticMoving = false;
52186     this.dynamicDampingFactor = 0.2;
52187
52188     this.minDistance = 0;
52189     this.maxDistance = Infinity;
52190
52191     this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
52192
52193     // internals
52194
52195     this.target = new THREE.Vector3();
52196
52197     var lastPosition = new THREE.Vector3();
52198
52199     var _keyPressed = false,
52200     _state = STATE.NONE,
52201
52202     _eye = new THREE.Vector3(),
52203
52204     _rotateStart = new THREE.Vector3(),
52205     _rotateEnd = new THREE.Vector3(),
52206
52207     _zoomStart = new THREE.Vector2(),
52208     _zoomEnd = new THREE.Vector2(),
52209
52210     _panStart = new THREE.Vector2(),
52211     _panEnd = new THREE.Vector2();
52212
52213     // events
52214
52215     var changeEvent = { type: 'change' };
52216
52217
52218     // methods
52219
52220     this.handleResize = function () {
52221
52222         this.screen.width = window.innerWidth;
52223         this.screen.height = window.innerHeight;
52224
52225         this.screen.offsetLeft = 0;
52226         this.screen.offsetTop = 0;
52227
52228         this.radius = ( this.screen.width + this.screen.height ) / 4;
52229     };
52230
52231     this.handleEvent = function ( event ) {
52232
52233         if ( typeof this[ event.type ] == 'function' ) {
52234
52235             this[ event.type ]( event );
52236
52237         }
52238
52239     };
52240
52241     this.getMouseOnScreen = function ( clientX, clientY ) {
52242
52243         return new THREE.Vector2(
52244             ( clientX - _this.screen.offsetLeft ) / _this.radius * 0.5,
52245             ( clientY - _this.screen.offsetTop ) / _this.radius * 0.5
52246         );
52247
52248     };
52249
52250     this.getMouseProjectionOnBall = function ( clientX, clientY ) {
52251
52252         var mouseOnBall = new THREE.Vector3(
52253             ( clientX - _this.screen.width * 0.5 - _this.screen.offsetLeft ) / _this.radius,
52254             ( _this.screen.height * 0.5 + _this.screen.offsetTop - clientY ) / _this.radius,
52255             0.0
52256         );
52257
52258         var length = mouseOnBall.length();
52259
52260         if ( length > 1.0 ) {
52261
52262             mouseOnBall.normalize();
52263
52264         } else {
52265
52266             mouseOnBall.z = Math.sqrt( 1.0 - length * length );
52267
52268         }
52269
52270         _eye.copy( _this.object.position ).subSelf( _this.target );
52271
52272         var projection = _this.object.up.clone().setLength( mouseOnBall.y );
52273         projection.addSelf( _this.object.up.clone().crossSelf( _eye ).setLength( mouseOnBall.x ) );
52274         projection.addSelf( _eye.setLength( mouseOnBall.z ) );
52275
52276         return projection;
52277
52278     };
52279
52280     this.rotateCamera = function () {
52281
52282         var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
52283
52284         if ( angle ) {
52285
52286             var axis = ( new THREE.Vector3() ).cross( _rotateStart, _rotateEnd ).normalize(),
52287                 quaternion = new THREE.Quaternion();
52288
52289             angle *= _this.rotateSpeed;
52290
52291             quaternion.setFromAxisAngle( axis, -angle );
52292
52293             quaternion.multiplyVector3( _eye );
52294             quaternion.multiplyVector3( _this.object.up );
52295
52296             quaternion.multiplyVector3( _rotateEnd );
52297
52298             if ( _this.staticMoving ) {
52299
52300                 _rotateStart.copy( _rotateEnd );
52301
52302             } else {
52303
52304                 quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
52305                 quaternion.multiplyVector3( _rotateStart );
52306
52307             }
52308
52309         }
52310
52311     };
52312
52313     this.zoomCamera = function () {
52314
52315         var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
52316
52317         if ( factor !== 1.0 && factor > 0.0 ) {
52318
52319             _eye.multiplyScalar( factor );
52320
52321             if ( _this.staticMoving ) {
52322
52323                 _zoomStart.copy( _zoomEnd );
52324
52325             } else {
52326
52327                 _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
52328
52329             }
52330
52331         }
52332
52333     };
52334
52335     this.panCamera = function () {
52336
52337         var mouseChange = _panEnd.clone().subSelf( _panStart );
52338
52339         if ( mouseChange.lengthSq() ) {
52340
52341             mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
52342
52343             var pan = _eye.clone().crossSelf( _this.object.up ).setLength( mouseChange.x );
52344             pan.addSelf( _this.object.up.clone().setLength( mouseChange.y ) );
52345
52346             _this.object.position.addSelf( pan );
52347             _this.target.addSelf( pan );
52348
52349             if ( _this.staticMoving ) {
52350
52351                 _panStart = _panEnd;
52352
52353             } else {
52354
52355                 _panStart.addSelf( mouseChange.sub( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
52356
52357             }
52358
52359         }
52360
52361     };
52362
52363     this.checkDistances = function () {
52364
52365         if ( !_this.noZoom || !_this.noPan ) {
52366
52367             if ( _this.object.position.lengthSq() > _this.maxDistance * _this.maxDistance ) {
52368
52369                 _this.object.position.setLength( _this.maxDistance );
52370
52371             }
52372
52373             if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
52374
52375                 _this.object.position.add( _this.target, _eye.setLength( _this.minDistance ) );
52376
52377             }
52378
52379         }
52380
52381     };
52382
52383     this.update = function () {
52384
52385         _eye.copy( _this.object.position ).subSelf( _this.target );
52386
52387         if ( !_this.noRotate ) {
52388
52389             _this.rotateCamera();
52390
52391         }
52392
52393         if ( !_this.noZoom ) {
52394
52395             _this.zoomCamera();
52396
52397         }
52398
52399         if ( !_this.noPan ) {
52400
52401             _this.panCamera();
52402
52403         }
52404
52405         _this.object.position.add( _this.target, _eye );
52406
52407         _this.checkDistances();
52408
52409         _this.object.lookAt( _this.target );
52410
52411         if ( lastPosition.distanceToSquared( _this.object.position ) > 0 ) {
52412
52413             _this.dispatchEvent( changeEvent );
52414
52415             lastPosition.copy( _this.object.position );
52416
52417         }
52418
52419     };
52420
52421     // listeners
52422
52423     function keydown( event ) {
52424
52425         if ( ! _this.enabled ) return;
52426
52427         //event.preventDefault();
52428
52429         if ( _state !== STATE.NONE ) {
52430
52431             return;
52432
52433         } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) {
52434
52435             _state = STATE.ROTATE;
52436
52437         } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) {
52438
52439             _state = STATE.ZOOM;
52440
52441         } else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) {
52442
52443             _state = STATE.PAN;
52444
52445         }
52446
52447         if ( _state !== STATE.NONE ) {
52448
52449             _keyPressed = true;
52450
52451         }
52452
52453     }
52454
52455     function keyup( event ) {
52456
52457         if ( ! _this.enabled ) return;
52458
52459         if ( _state !== STATE.NONE ) {
52460
52461             _state = STATE.NONE;
52462
52463         }
52464
52465     }
52466
52467     function mousedown( event ) {
52468
52469         if ( ! _this.enabled ) return;
52470
52471         event.preventDefault();
52472         event.stopPropagation();
52473
52474         if ( _state === STATE.NONE ) {
52475
52476             _state = event.button;
52477
52478             if ( _state === STATE.ROTATE && !_this.noRotate ) {
52479
52480                 _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
52481
52482             } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
52483
52484                 _zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52485
52486             } else if ( !this.noPan ) {
52487
52488                 _panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52489
52490             }
52491
52492         }
52493
52494     }
52495
52496     function mousemove( event ) {
52497
52498         if ( ! _this.enabled ) return;
52499
52500         if ( _keyPressed ) {
52501
52502             _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
52503             _zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52504             _panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52505
52506             _keyPressed = false;
52507
52508         }
52509
52510         if ( _state === STATE.NONE ) {
52511
52512             return;
52513
52514         } else if ( _state === STATE.ROTATE && !_this.noRotate ) {
52515
52516             _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
52517
52518         } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
52519
52520             _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52521
52522         } else if ( _state === STATE.PAN && !_this.noPan ) {
52523
52524             _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
52525
52526         }
52527
52528     }
52529
52530     function mouseup( event ) {
52531
52532         if ( ! _this.enabled ) return;
52533
52534         event.preventDefault();
52535         event.stopPropagation();
52536
52537         _state = STATE.NONE;
52538
52539     }
52540
52541     function mousewheel( event ) {
52542
52543         if ( ! _this.enabled ) return;
52544
52545         event.preventDefault();
52546         event.stopPropagation();
52547
52548         var delta = 0;
52549
52550         if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
52551
52552             delta = event.wheelDelta / 40;
52553
52554         } else if ( event.detail ) { // Firefox
52555
52556             delta = - event.detail / 3;
52557
52558         }
52559
52560         _zoomStart.y += ( 1 / delta ) * 0.05;
52561
52562     }
52563
52564     this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
52565
52566     this.domElement.addEventListener( 'mousemove', mousemove, false );
52567     this.domElement.addEventListener( 'mousedown', mousedown, false );
52568     this.domElement.addEventListener( 'mouseup', mouseup, false );
52569     this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false );
52570     this.domElement.addEventListener( 'mousewheel', mousewheel, false );
52571
52572     window.addEventListener( 'keydown', keydown, false );
52573     window.addEventListener( 'keyup', keyup, false );
52574
52575     this.handleResize();
52576
52577 };
52578 /**
52579  * @author qiao / https://github.com/qiao
52580  * @author mrdoob / http://mrdoob.com
52581  * @author alteredq / http://alteredqualia.com/
52582  */
52583
52584 THREE.OrbitControls = function ( object, domElement ) {
52585
52586     THREE.EventTarget.call( this );
52587
52588     this.object = object;
52589     this.domElement = ( domElement !== undefined ) ? domElement : document;
52590
52591     // API
52592
52593     this.center = new THREE.Vector3();
52594
52595     this.userZoom = true;
52596     this.userZoomSpeed = 1.0;
52597
52598     this.userRotate = true;
52599     this.userRotateSpeed = 1.0;
52600
52601     this.autoRotate = false;
52602     this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
52603
52604     // internals
52605
52606     var scope = this;
52607
52608     var EPS = 0.000001;
52609     var PIXELS_PER_ROUND = 1800;
52610
52611     var rotateStart = new THREE.Vector2();
52612     var rotateEnd = new THREE.Vector2();
52613     var rotateDelta = new THREE.Vector2();
52614
52615     var zoomStart = new THREE.Vector2();
52616     var zoomEnd = new THREE.Vector2();
52617     var zoomDelta = new THREE.Vector2();
52618
52619     var phiDelta = 0;
52620     var thetaDelta = 0;
52621     var scale = 1;
52622
52623     var lastPosition = new THREE.Vector3();
52624
52625     var STATE = { NONE : -1, ROTATE : 0, ZOOM : 1 };
52626     var state = STATE.NONE;
52627
52628     // events
52629
52630     var changeEvent = { type: 'change' };
52631
52632
52633     this.rotateLeft = function ( angle ) {
52634
52635         if ( angle === undefined ) {
52636
52637             angle = getAutoRotationAngle();
52638
52639         }
52640
52641         thetaDelta -= angle;
52642
52643     };
52644
52645     this.rotateRight = function ( angle ) {
52646
52647         if ( angle === undefined ) {
52648
52649             angle = getAutoRotationAngle();
52650
52651         }
52652
52653         thetaDelta += angle;
52654
52655     };
52656
52657     this.rotateUp = function ( angle ) {
52658
52659         if ( angle === undefined ) {
52660
52661             angle = getAutoRotationAngle();
52662
52663         }
52664
52665         phiDelta -= angle;
52666
52667     };
52668
52669     this.rotateDown = function ( angle ) {
52670
52671         if ( angle === undefined ) {
52672
52673             angle = getAutoRotationAngle();
52674
52675         }
52676
52677         phiDelta += angle;
52678
52679     };
52680
52681     this.zoomIn = function ( zoomScale ) {
52682
52683         if ( zoomScale === undefined ) {
52684
52685             zoomScale = getZoomScale();
52686
52687         }
52688
52689         scale /= zoomScale;
52690
52691     };
52692
52693     this.zoomOut = function ( zoomScale ) {
52694
52695         if ( zoomScale === undefined ) {
52696
52697             zoomScale = getZoomScale();
52698
52699         }
52700
52701         scale *= zoomScale;
52702
52703     };
52704
52705     this.update = function () {
52706
52707         var position = this.object.position;
52708         var offset = position.clone().subSelf( this.center )
52709
52710         // angle from z-axis around y-axis
52711
52712         var theta = Math.atan2( offset.x, offset.z );
52713
52714         // angle from y-axis
52715
52716         var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
52717
52718         if ( this.autoRotate ) {
52719
52720             this.rotateLeft( getAutoRotationAngle() );
52721
52722         }
52723
52724         theta += thetaDelta;
52725         phi += phiDelta;
52726
52727         // restrict phi to be betwee EPS and PI-EPS
52728
52729         phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
52730
52731         var radius = offset.length();
52732         offset.x = radius * Math.sin( phi ) * Math.sin( theta );
52733         offset.y = radius * Math.cos( phi );
52734         offset.z = radius * Math.sin( phi ) * Math.cos( theta );
52735         offset.multiplyScalar( scale );
52736
52737         position.copy( this.center ).addSelf( offset );
52738
52739         this.object.lookAt( this.center );
52740
52741         thetaDelta = 0;
52742         phiDelta = 0;
52743         scale = 1;
52744
52745         if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
52746
52747             this.dispatchEvent( changeEvent );
52748
52749             lastPosition.copy( this.object.position );
52750
52751         }
52752
52753     };
52754
52755
52756     function getAutoRotationAngle() {
52757
52758         return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
52759
52760     }
52761
52762     function getZoomScale() {
52763
52764         return Math.pow( 0.95, scope.userZoomSpeed );
52765
52766     }
52767
52768     function onMouseDown( event ) {
52769
52770         if ( !scope.userRotate ) return;
52771
52772         event.preventDefault();
52773
52774         if ( event.button === 0 || event.button === 2 ) {
52775
52776             state = STATE.ROTATE;
52777
52778             rotateStart.set( event.clientX, event.clientY );
52779
52780         } else if ( event.button === 1 ) {
52781
52782             state = STATE.ZOOM;
52783
52784             zoomStart.set( event.clientX, event.clientY );
52785
52786         }
52787
52788         document.addEventListener( 'mousemove', onMouseMove, false );
52789         document.addEventListener( 'mouseup', onMouseUp, false );
52790
52791     }
52792
52793     function onMouseMove( event ) {
52794
52795         event.preventDefault();
52796
52797         if ( state === STATE.ROTATE ) {
52798
52799             rotateEnd.set( event.clientX, event.clientY );
52800             rotateDelta.sub( rotateEnd, rotateStart );
52801
52802             scope.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed );
52803             scope.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed );
52804
52805             rotateStart.copy( rotateEnd );
52806
52807         } else if ( state === STATE.ZOOM ) {
52808
52809             zoomEnd.set( event.clientX, event.clientY );
52810             zoomDelta.sub( zoomEnd, zoomStart );
52811
52812             if ( zoomDelta.y > 0 ) {
52813
52814                 scope.zoomIn();
52815
52816             } else {
52817
52818                 scope.zoomOut();
52819
52820             }
52821
52822             zoomStart.copy( zoomEnd );
52823
52824         }
52825
52826     }
52827
52828     function onMouseUp( event ) {
52829
52830         if ( ! scope.userRotate ) return;
52831
52832         document.removeEventListener( 'mousemove', onMouseMove, false );
52833         document.removeEventListener( 'mouseup', onMouseUp, false );
52834
52835         state = STATE.NONE;
52836
52837     }
52838
52839     function onMouseWheel( event ) {
52840
52841         if ( ! scope.userZoom ) return;
52842
52843         if ( event.wheelDelta > 0 ) {
52844
52845             scope.zoomOut();
52846
52847         } else {
52848
52849             scope.zoomIn();
52850
52851         }
52852
52853     }
52854
52855     this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
52856     this.domElement.addEventListener( 'mousedown', onMouseDown, false );
52857     this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
52858
52859 };
52860 /**
52861  * @author hughes
52862  */
52863
52864 THREE.CircleGeometry = function ( radius, segments, thetaStart, thetaLength ) {
52865
52866     THREE.Geometry.call( this );
52867
52868     radius = radius || 50;
52869
52870     thetaStart = thetaStart !== undefined ? thetaStart : 0;
52871     thetaLength = thetaLength !== undefined ? thetaLength : Math.PI * 2;
52872     segments = segments !== undefined ? Math.max( 3, segments ) : 8;
52873
52874     var i, uvs = [],
52875     center = new THREE.Vector3(), centerUV = new THREE.UV( 0.5, 0.5 );
52876
52877     this.vertices.push(center);
52878     uvs.push( centerUV );
52879
52880     for ( i = 0; i <= segments; i ++ ) {
52881
52882         var vertex = new THREE.Vector3();
52883
52884         vertex.x = radius * Math.cos( thetaStart + i / segments * thetaLength );
52885         vertex.y = radius * Math.sin( thetaStart + i / segments * thetaLength );
52886
52887         this.vertices.push( vertex );
52888         uvs.push( new THREE.UV( ( vertex.x / radius + 1 ) / 2, - ( vertex.y / radius + 1 ) / 2 + 1 ) );
52889
52890     }
52891
52892     var n = new THREE.Vector3( 0, 0, -1 );
52893
52894     for ( i = 1; i <= segments; i ++ ) {
52895
52896         var v1 = i;
52897         var v2 = i + 1 ;
52898         var v3 = 0;
52899
52900         this.faces.push( new THREE.Face3( v1, v2, v3, [ n, n, n ] ) );
52901         this.faceVertexUvs[ 0 ].push( [ uvs[ i ], uvs[ i + 1 ], centerUV ] );
52902
52903     }
52904
52905     this.computeCentroids();
52906     this.computeFaceNormals();
52907
52908     this.boundingSphere = { radius: radius };
52909
52910 };
52911
52912 THREE.CircleGeometry.prototype = Object.create( THREE.Geometry.prototype );
52913 /**
52914  * @author mrdoob / http://mrdoob.com/
52915  * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Cube.as
52916  */
52917
52918 THREE.CubeGeometry = function ( width, height, depth, segmentsWidth, segmentsHeight, segmentsDepth, materials, sides ) {
52919
52920     THREE.Geometry.call( this );
52921
52922     var scope = this,
52923     width_half = width / 2,
52924     height_half = height / 2,
52925     depth_half = depth / 2;
52926
52927     var mpx, mpy, mpz, mnx, mny, mnz;
52928
52929     if ( materials !== undefined ) {
52930
52931         if ( materials instanceof Array ) {
52932
52933             this.materials = materials;
52934
52935         } else {
52936
52937             this.materials = [];
52938
52939             for ( var i = 0; i < 6; i ++ ) {
52940
52941                 this.materials.push( materials );
52942
52943             }
52944
52945         }
52946
52947         mpx = 0; mnx = 1; mpy = 2; mny = 3; mpz = 4; mnz = 5;
52948
52949     } else {
52950
52951         this.materials = [];
52952
52953     }
52954
52955     this.sides = { px: true, nx: true, py: true, ny: true, pz: true, nz: true };
52956
52957     if ( sides != undefined ) {
52958
52959         for ( var s in sides ) {
52960
52961             if ( this.sides[ s ] !== undefined ) {
52962
52963                 this.sides[ s ] = sides[ s ];
52964
52965             }
52966
52967         }
52968
52969     }
52970
52971     this.sides.px && buildPlane( 'z', 'y', - 1, - 1, depth, height, width_half, mpx ); // px
52972     this.sides.nx && buildPlane( 'z', 'y',   1, - 1, depth, height, - width_half, mnx ); // nx
52973     this.sides.py && buildPlane( 'x', 'z',   1,   1, width, depth, height_half, mpy ); // py
52974     this.sides.ny && buildPlane( 'x', 'z',   1, - 1, width, depth, - height_half, mny ); // ny
52975     this.sides.pz && buildPlane( 'x', 'y',   1, - 1, width, height, depth_half, mpz ); // pz
52976     this.sides.nz && buildPlane( 'x', 'y', - 1, - 1, width, height, - depth_half, mnz ); // nz
52977
52978     function buildPlane( u, v, udir, vdir, width, height, depth, material ) {
52979
52980         var w, ix, iy,
52981         gridX = segmentsWidth || 1,
52982         gridY = segmentsHeight || 1,
52983         width_half = width / 2,
52984         height_half = height / 2,
52985         offset = scope.vertices.length;
52986
52987         if ( ( u === 'x' && v === 'y' ) || ( u === 'y' && v === 'x' ) ) {
52988
52989             w = 'z';
52990
52991         } else if ( ( u === 'x' && v === 'z' ) || ( u === 'z' && v === 'x' ) ) {
52992
52993             w = 'y';
52994             gridY = segmentsDepth || 1;
52995
52996         } else if ( ( u === 'z' && v === 'y' ) || ( u === 'y' && v === 'z' ) ) {
52997
52998             w = 'x';
52999             gridX = segmentsDepth || 1;
53000
53001         }
53002
53003         var gridX1 = gridX + 1,
53004         gridY1 = gridY + 1,
53005         segment_width = width / gridX,
53006         segment_height = height / gridY,
53007         normal = new THREE.Vector3();
53008
53009         normal[ w ] = depth > 0 ? 1 : - 1;
53010
53011         for ( iy = 0; iy < gridY1; iy ++ ) {
53012
53013             for ( ix = 0; ix < gridX1; ix ++ ) {
53014
53015                 var vector = new THREE.Vector3();
53016                 vector[ u ] = ( ix * segment_width - width_half ) * udir;
53017                 vector[ v ] = ( iy * segment_height - height_half ) * vdir;
53018                 vector[ w ] = depth;
53019
53020                 scope.vertices.push( vector );
53021
53022             }
53023
53024         }
53025
53026         for ( iy = 0; iy < gridY; iy++ ) {
53027
53028             for ( ix = 0; ix < gridX; ix++ ) {
53029
53030                 var a = ix + gridX1 * iy;
53031                 var b = ix + gridX1 * ( iy + 1 );
53032                 var c = ( ix + 1 ) + gridX1 * ( iy + 1 );
53033                 var d = ( ix + 1 ) + gridX1 * iy;
53034
53035                 var face = new THREE.Face4( a + offset, b + offset, c + offset, d + offset );
53036                 face.normal.copy( normal );
53037                 face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone(), normal.clone() );
53038                 face.materialIndex = material;
53039
53040                 scope.faces.push( face );
53041                 scope.faceVertexUvs[ 0 ].push( [
53042                             new THREE.UV( ix / gridX, 1 - iy / gridY ),
53043                             new THREE.UV( ix / gridX, 1 - ( iy + 1 ) / gridY ),
53044                             new THREE.UV( ( ix + 1 ) / gridX, 1- ( iy + 1 ) / gridY ),
53045                             new THREE.UV( ( ix + 1 ) / gridX, 1 - iy / gridY )
53046                         ] );
53047
53048             }
53049
53050         }
53051
53052     }
53053
53054     this.computeCentroids();
53055     this.mergeVertices();
53056
53057 };
53058
53059 THREE.CubeGeometry.prototype = Object.create( THREE.Geometry.prototype );
53060 /**
53061  * @author mrdoob / http://mrdoob.com/
53062  */
53063
53064 THREE.CylinderGeometry = function ( radiusTop, radiusBottom, height, segmentsRadius, segmentsHeight, openEnded ) {
53065
53066     THREE.Geometry.call( this );
53067
53068     radiusTop = radiusTop !== undefined ? radiusTop : 20;
53069     radiusBottom = radiusBottom !== undefined ? radiusBottom : 20;
53070     height = height !== undefined ? height : 100;
53071
53072     var heightHalf = height / 2;
53073     var segmentsX = segmentsRadius || 8;
53074     var segmentsY = segmentsHeight || 1;
53075
53076     var x, y, vertices = [], uvs = [];
53077
53078     for ( y = 0; y <= segmentsY; y ++ ) {
53079
53080         var verticesRow = [];
53081         var uvsRow = [];
53082
53083         var v = y / segmentsY;
53084         var radius = v * ( radiusBottom - radiusTop ) + radiusTop;
53085
53086         for ( x = 0; x <= segmentsX; x ++ ) {
53087
53088             var u = x / segmentsX;
53089
53090             var vertex = new THREE.Vector3();
53091             vertex.x = radius * Math.sin( u * Math.PI * 2 );
53092             vertex.y = - v * height + heightHalf;
53093             vertex.z = radius * Math.cos( u * Math.PI * 2 );
53094
53095             this.vertices.push( vertex );
53096
53097             verticesRow.push( this.vertices.length - 1 );
53098             uvsRow.push( new THREE.UV( u, 1 - v ) );
53099
53100         }
53101
53102         vertices.push( verticesRow );
53103         uvs.push( uvsRow );
53104
53105     }
53106
53107     var tanTheta = ( radiusBottom - radiusTop ) / height;
53108     var na, nb;
53109
53110     for ( x = 0; x < segmentsX; x ++ ) {
53111
53112         if ( radiusTop !== 0 ) {
53113
53114             na = this.vertices[ vertices[ 0 ][ x ] ].clone();
53115             nb = this.vertices[ vertices[ 0 ][ x + 1 ] ].clone();
53116
53117         } else {
53118
53119             na = this.vertices[ vertices[ 1 ][ x ] ].clone();
53120             nb = this.vertices[ vertices[ 1 ][ x + 1 ] ].clone();
53121
53122         }
53123
53124         na.setY( Math.sqrt( na.x * na.x + na.z * na.z ) * tanTheta ).normalize();
53125         nb.setY( Math.sqrt( nb.x * nb.x + nb.z * nb.z ) * tanTheta ).normalize();
53126
53127         for ( y = 0; y < segmentsY; y ++ ) {
53128
53129             var v1 = vertices[ y ][ x ];
53130             var v2 = vertices[ y + 1 ][ x ];
53131             var v3 = vertices[ y + 1 ][ x + 1 ];
53132             var v4 = vertices[ y ][ x + 1 ];
53133
53134             var n1 = na.clone();
53135             var n2 = na.clone();
53136             var n3 = nb.clone();
53137             var n4 = nb.clone();
53138
53139             var uv1 = uvs[ y ][ x ].clone();
53140             var uv2 = uvs[ y + 1 ][ x ].clone();
53141             var uv3 = uvs[ y + 1 ][ x + 1 ].clone();
53142             var uv4 = uvs[ y ][ x + 1 ].clone();
53143
53144             this.faces.push( new THREE.Face4( v1, v2, v3, v4, [ n1, n2, n3, n4 ] ) );
53145             this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3, uv4 ] );
53146
53147         }
53148
53149     }
53150
53151     // top cap
53152
53153     if ( !openEnded && radiusTop > 0 ) {
53154
53155         this.vertices.push( new THREE.Vector3( 0, heightHalf, 0 ) );
53156
53157         for ( x = 0; x < segmentsX; x ++ ) {
53158
53159             var v1 = vertices[ 0 ][ x ];
53160             var v2 = vertices[ 0 ][ x + 1 ];
53161             var v3 = this.vertices.length - 1;
53162
53163             var n1 = new THREE.Vector3( 0, 1, 0 );
53164             var n2 = new THREE.Vector3( 0, 1, 0 );
53165             var n3 = new THREE.Vector3( 0, 1, 0 );
53166
53167             var uv1 = uvs[ 0 ][ x ].clone();
53168             var uv2 = uvs[ 0 ][ x + 1 ].clone();
53169             var uv3 = new THREE.UV( uv2.u, 0 );
53170
53171             this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) );
53172             this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
53173
53174         }
53175
53176     }
53177
53178     // bottom cap
53179
53180     if ( !openEnded && radiusBottom > 0 ) {
53181
53182         this.vertices.push( new THREE.Vector3( 0, - heightHalf, 0 ) );
53183
53184         for ( x = 0; x < segmentsX; x ++ ) {
53185
53186             var v1 = vertices[ y ][ x + 1 ];
53187             var v2 = vertices[ y ][ x ];
53188             var v3 = this.vertices.length - 1;
53189
53190             var n1 = new THREE.Vector3( 0, - 1, 0 );
53191             var n2 = new THREE.Vector3( 0, - 1, 0 );
53192             var n3 = new THREE.Vector3( 0, - 1, 0 );
53193
53194             var uv1 = uvs[ y ][ x + 1 ].clone();
53195             var uv2 = uvs[ y ][ x ].clone();
53196             var uv3 = new THREE.UV( uv2.u, 1 );
53197
53198             this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) );
53199             this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
53200
53201         }
53202
53203     }
53204
53205     this.computeCentroids();
53206     this.computeFaceNormals();
53207
53208 }
53209
53210 THREE.CylinderGeometry.prototype = Object.create( THREE.Geometry.prototype );
53211 /**
53212  * @author zz85 / http://www.lab4games.net/zz85/blog
53213  *
53214  * Creates extruded geometry from a path shape.
53215  *
53216  * parameters = {
53217  *
53218  *  size: <float>, // size of the text
53219  *  height: <float>, // thickness to extrude text
53220  *  curveSegments: <int>, // number of points on the curves
53221  *  steps: <int>, // number of points for z-side extrusions / used for subdividing segements of extrude spline too
53222  *  amount: <int>, // Amount
53223  *
53224  *  bevelEnabled: <bool>, // turn on bevel
53225  *  bevelThickness: <float>, // how deep into text bevel goes
53226  *  bevelSize: <float>, // how far from text outline is bevel
53227  *  bevelSegments: <int>, // number of bevel layers
53228  *
53229  *  extrudePath: <THREE.CurvePath> // 3d spline path to extrude shape along. (creates Frames if .frames aren't defined)
53230  *  frames: <THREE.TubeGeometry.FrenetFrames> // containing arrays of tangents, normals, binormals
53231  *
53232  *  material: <int> // material index for front and back faces
53233  *  extrudeMaterial: <int> // material index for extrusion and beveled faces
53234  *  uvGenerator: <Object> // object that provides UV generator functions
53235  *
53236  * }
53237  **/
53238
53239 THREE.ExtrudeGeometry = function ( shapes, options ) {
53240
53241     if ( typeof( shapes ) === "undefined" ) {
53242         shapes = [];
53243         return;
53244     }
53245
53246     THREE.Geometry.call( this );
53247
53248     shapes = shapes instanceof Array ? shapes : [ shapes ];
53249
53250     this.shapebb = shapes[ shapes.length - 1 ].getBoundingBox();
53251
53252     this.addShapeList( shapes, options );
53253
53254     this.computeCentroids();
53255     this.computeFaceNormals();
53256
53257     // can't really use automatic vertex normals
53258     // as then front and back sides get smoothed too
53259     // should do separate smoothing just for sides
53260
53261     //this.computeVertexNormals();
53262
53263     //console.log( "took", ( Date.now() - startTime ) );
53264
53265 };
53266
53267 THREE.ExtrudeGeometry.prototype = Object.create( THREE.Geometry.prototype );
53268
53269 THREE.ExtrudeGeometry.prototype.addShapeList = function ( shapes, options ) {
53270     var sl = shapes.length;
53271
53272     for ( var s = 0; s < sl; s ++ ) {
53273         var shape = shapes[ s ];
53274         this.addShape( shape, options );
53275     }
53276 };
53277
53278 THREE.ExtrudeGeometry.prototype.addShape = function ( shape, options ) {
53279
53280     var amount = options.amount !== undefined ? options.amount : 100;
53281
53282     var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10
53283     var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8
53284     var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
53285
53286     var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false
53287
53288     var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
53289
53290     var steps = options.steps !== undefined ? options.steps : 1;
53291
53292     var extrudePath = options.extrudePath;
53293     var extrudePts, extrudeByPath = false;
53294
53295     var material = options.material;
53296     var extrudeMaterial = options.extrudeMaterial;
53297
53298     // Use default WorldUVGenerator if no UV generators are specified.
53299     var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : THREE.ExtrudeGeometry.WorldUVGenerator;
53300
53301     var shapebb = this.shapebb;
53302     //shapebb = shape.getBoundingBox();
53303
53304
53305
53306     var splineTube, binormal, normal, position2;
53307     if ( extrudePath ) {
53308
53309         extrudePts = extrudePath.getSpacedPoints( steps );
53310
53311         extrudeByPath = true;
53312         bevelEnabled = false; // bevels not supported for path extrusion
53313
53314         // SETUP TNB variables
53315
53316         // Reuse TNB from TubeGeomtry for now.
53317         // TODO1 - have a .isClosed in spline?
53318
53319         splineTube = options.frames !== undefined ? options.frames : new THREE.TubeGeometry.FrenetFrames(extrudePath, steps, false);
53320
53321         // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
53322
53323         binormal = new THREE.Vector3();
53324         normal = new THREE.Vector3();
53325         position2 = new THREE.Vector3();
53326
53327     }
53328
53329     // Safeguards if bevels are not enabled
53330
53331     if ( ! bevelEnabled ) {
53332
53333         bevelSegments = 0;
53334         bevelThickness = 0;
53335         bevelSize = 0;
53336
53337     }
53338
53339     // Variables initalization
53340
53341     var ahole, h, hl; // looping of holes
53342     var scope = this;
53343     var bevelPoints = [];
53344
53345     var shapesOffset = this.vertices.length;
53346
53347     var shapePoints = shape.extractPoints();
53348
53349     var vertices = shapePoints.shape;
53350     var holes = shapePoints.holes;
53351
53352     var reverse = !THREE.Shape.Utils.isClockWise( vertices ) ;
53353
53354     if ( reverse ) {
53355
53356         vertices = vertices.reverse();
53357
53358         // Maybe we should also check if holes are in the opposite direction, just to be safe ...
53359
53360         for ( h = 0, hl = holes.length; h < hl; h ++ ) {
53361
53362             ahole = holes[ h ];
53363
53364             if ( THREE.Shape.Utils.isClockWise( ahole ) ) {
53365
53366                 holes[ h ] = ahole.reverse();
53367
53368             }
53369
53370         }
53371
53372         reverse = false; // If vertices are in order now, we shouldn't need to worry about them again (hopefully)!
53373
53374     }
53375
53376
53377     var faces = THREE.Shape.Utils.triangulateShape ( vertices, holes );
53378
53379     /* Vertices */
53380
53381     var contour = vertices; // vertices has all points but contour has only points of circumference
53382
53383     for ( h = 0, hl = holes.length;  h < hl; h ++ ) {
53384
53385         ahole = holes[ h ];
53386
53387         vertices = vertices.concat( ahole );
53388
53389     }
53390
53391
53392     function scalePt2 ( pt, vec, size ) {
53393
53394         if ( !vec ) console.log( "die" );
53395
53396         return vec.clone().multiplyScalar( size ).addSelf( pt );
53397
53398     }
53399
53400     var b, bs, t, z,
53401         vert, vlen = vertices.length,
53402         face, flen = faces.length,
53403         cont, clen = contour.length;
53404
53405
53406     // Find directions for point movement
53407
53408     var RAD_TO_DEGREES = 180 / Math.PI;
53409
53410
53411     function getBevelVec( pt_i, pt_j, pt_k ) {
53412
53413         // Algorithm 2
53414
53415         return getBevelVec2( pt_i, pt_j, pt_k );
53416
53417     }
53418
53419     function getBevelVec1( pt_i, pt_j, pt_k ) {
53420
53421         var anglea = Math.atan2( pt_j.y - pt_i.y, pt_j.x - pt_i.x );
53422         var angleb = Math.atan2( pt_k.y - pt_i.y, pt_k.x - pt_i.x );
53423
53424         if ( anglea > angleb ) {
53425
53426             angleb += Math.PI * 2;
53427
53428         }
53429
53430         var anglec = ( anglea + angleb ) / 2;
53431
53432
53433         //console.log('angle1', anglea * RAD_TO_DEGREES,'angle2', angleb * RAD_TO_DEGREES, 'anglec', anglec *RAD_TO_DEGREES);
53434
53435         var x = - Math.cos( anglec );
53436         var y = - Math.sin( anglec );
53437
53438         var vec = new THREE.Vector2( x, y ); //.normalize();
53439
53440         return vec;
53441
53442     }
53443
53444     function getBevelVec2( pt_i, pt_j, pt_k ) {
53445
53446         var a = THREE.ExtrudeGeometry.__v1,
53447             b = THREE.ExtrudeGeometry.__v2,
53448             v_hat = THREE.ExtrudeGeometry.__v3,
53449             w_hat = THREE.ExtrudeGeometry.__v4,
53450             p = THREE.ExtrudeGeometry.__v5,
53451             q = THREE.ExtrudeGeometry.__v6,
53452             v, w,
53453             v_dot_w_hat, q_sub_p_dot_w_hat,
53454             s, intersection;
53455
53456         // good reading for line-line intersection
53457         // http://sputsoft.com/blog/2010/03/line-line-intersection.html
53458
53459         // define a as vector j->i
53460         // define b as vectot k->i
53461
53462         a.set( pt_i.x - pt_j.x, pt_i.y - pt_j.y );
53463         b.set( pt_i.x - pt_k.x, pt_i.y - pt_k.y );
53464
53465         // get unit vectors
53466
53467         v = a.normalize();
53468         w = b.normalize();
53469
53470         // normals from pt i
53471
53472         v_hat.set( -v.y, v.x );
53473         w_hat.set( w.y, -w.x );
53474
53475         // pts from i
53476
53477         p.copy( pt_i ).addSelf( v_hat );
53478         q.copy( pt_i ).addSelf( w_hat );
53479
53480         if ( p.equals( q ) ) {
53481
53482             //console.log("Warning: lines are straight");
53483             return w_hat.clone();
53484
53485         }
53486
53487         // Points from j, k. helps prevents points cross overover most of the time
53488
53489         p.copy( pt_j ).addSelf( v_hat );
53490         q.copy( pt_k ).addSelf( w_hat );
53491
53492         v_dot_w_hat = v.dot( w_hat );
53493         q_sub_p_dot_w_hat = q.subSelf( p ).dot( w_hat );
53494
53495         // We should not reach these conditions
53496
53497         if ( v_dot_w_hat === 0 ) {
53498
53499             console.log( "Either infinite or no solutions!" );
53500
53501             if ( q_sub_p_dot_w_hat === 0 ) {
53502
53503                 console.log( "Its finite solutions." );
53504
53505             } else {
53506
53507                 console.log( "Too bad, no solutions." );
53508
53509             }
53510
53511         }
53512
53513         s = q_sub_p_dot_w_hat / v_dot_w_hat;
53514
53515         if ( s < 0 ) {
53516
53517             // in case of emergecy, revert to algorithm 1.
53518
53519             return getBevelVec1( pt_i, pt_j, pt_k );
53520
53521         }
53522
53523         intersection = v.multiplyScalar( s ).addSelf( p );
53524
53525         return intersection.subSelf( pt_i ).clone(); // Don't normalize!, otherwise sharp corners become ugly
53526
53527     }
53528
53529     var contourMovements = [];
53530
53531     for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
53532
53533         if ( j === il ) j = 0;
53534         if ( k === il ) k = 0;
53535
53536         //  (j)---(i)---(k)
53537         // console.log('i,j,k', i, j , k)
53538
53539         var pt_i = contour[ i ];
53540         var pt_j = contour[ j ];
53541         var pt_k = contour[ k ];
53542
53543         contourMovements[ i ]= getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
53544
53545     }
53546
53547     var holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();
53548
53549     for ( h = 0, hl = holes.length; h < hl; h ++ ) {
53550
53551         ahole = holes[ h ];
53552
53553         oneHoleMovements = [];
53554
53555         for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
53556
53557             if ( j === il ) j = 0;
53558             if ( k === il ) k = 0;
53559
53560             //  (j)---(i)---(k)
53561             oneHoleMovements[ i ]= getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
53562
53563         }
53564
53565         holesMovements.push( oneHoleMovements );
53566         verticesMovements = verticesMovements.concat( oneHoleMovements );
53567
53568     }
53569
53570
53571     // Loop bevelSegments, 1 for the front, 1 for the back
53572
53573     for ( b = 0; b < bevelSegments; b ++ ) {
53574     //for ( b = bevelSegments; b > 0; b -- ) {
53575
53576         t = b / bevelSegments;
53577         z = bevelThickness * ( 1 - t );
53578
53579         //z = bevelThickness * t;
53580         bs = bevelSize * ( Math.sin ( t * Math.PI/2 ) ) ; // curved
53581         //bs = bevelSize * t ; // linear
53582
53583         // contract shape
53584
53585         for ( i = 0, il = contour.length; i < il; i ++ ) {
53586
53587             vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
53588             //vert = scalePt( contour[ i ], contourCentroid, bs, false );
53589             v( vert.x, vert.y,  - z );
53590
53591         }
53592
53593         // expand holes
53594
53595         for ( h = 0, hl = holes.length; h < hl; h++ ) {
53596
53597             ahole = holes[ h ];
53598             oneHoleMovements = holesMovements[ h ];
53599
53600             for ( i = 0, il = ahole.length; i < il; i++ ) {
53601
53602                 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
53603                 //vert = scalePt( ahole[ i ], holesCentroids[ h ], bs, true );
53604
53605                 v( vert.x, vert.y,  -z );
53606
53607             }
53608
53609         }
53610
53611     }
53612
53613     bs = bevelSize;
53614
53615     // Back facing vertices
53616
53617     for ( i = 0; i < vlen; i ++ ) {
53618
53619         vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
53620
53621         if ( !extrudeByPath ) {
53622
53623             v( vert.x, vert.y, 0 );
53624
53625         } else {
53626
53627             // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
53628
53629             normal.copy( splineTube.normals[0] ).multiplyScalar(vert.x);
53630             binormal.copy( splineTube.binormals[0] ).multiplyScalar(vert.y);
53631
53632             position2.copy( extrudePts[0] ).addSelf(normal).addSelf(binormal);
53633
53634             v( position2.x, position2.y, position2.z );
53635
53636         }
53637
53638     }
53639
53640     // Add stepped vertices...
53641     // Including front facing vertices
53642
53643     var s;
53644
53645     for ( s = 1; s <= steps; s ++ ) {
53646
53647         for ( i = 0; i < vlen; i ++ ) {
53648
53649             vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
53650
53651             if ( !extrudeByPath ) {
53652
53653                 v( vert.x, vert.y, amount / steps * s );
53654
53655             } else {
53656
53657                 // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
53658
53659                 normal.copy( splineTube.normals[s] ).multiplyScalar( vert.x );
53660                 binormal.copy( splineTube.binormals[s] ).multiplyScalar( vert.y );
53661
53662                 position2.copy( extrudePts[s] ).addSelf( normal ).addSelf( binormal );
53663
53664                 v( position2.x, position2.y, position2.z );
53665
53666             }
53667
53668         }
53669
53670     }
53671
53672
53673     // Add bevel segments planes
53674
53675     //for ( b = 1; b <= bevelSegments; b ++ ) {
53676     for ( b = bevelSegments - 1; b >= 0; b -- ) {
53677
53678         t = b / bevelSegments;
53679         z = bevelThickness * ( 1 - t );
53680         //bs = bevelSize * ( 1-Math.sin ( ( 1 - t ) * Math.PI/2 ) );
53681         bs = bevelSize * Math.sin ( t * Math.PI/2 ) ;
53682
53683         // contract shape
53684
53685         for ( i = 0, il = contour.length; i < il; i ++ ) {
53686
53687             vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
53688             v( vert.x, vert.y,  amount + z );
53689
53690         }
53691
53692         // expand holes
53693
53694         for ( h = 0, hl = holes.length; h < hl; h ++ ) {
53695
53696             ahole = holes[ h ];
53697             oneHoleMovements = holesMovements[ h ];
53698
53699             for ( i = 0, il = ahole.length; i < il; i ++ ) {
53700
53701                 vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
53702
53703                 if ( !extrudeByPath ) {
53704
53705                     v( vert.x, vert.y,  amount + z );
53706
53707                 } else {
53708
53709                     v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
53710
53711                 }
53712
53713             }
53714
53715         }
53716
53717     }
53718
53719     /* Faces */
53720
53721     // Top and bottom faces
53722
53723     buildLidFaces();
53724
53725     // Sides faces
53726
53727     buildSideFaces();
53728
53729
53730     /////  Internal functions
53731
53732     function buildLidFaces() {
53733
53734         if ( bevelEnabled ) {
53735
53736             var layer = 0 ; // steps + 1
53737             var offset = vlen * layer;
53738
53739             // Bottom faces
53740
53741             for ( i = 0; i < flen; i ++ ) {
53742
53743                 face = faces[ i ];
53744                 f3( face[ 2 ]+ offset, face[ 1 ]+ offset, face[ 0 ] + offset, true );
53745
53746             }
53747
53748             layer = steps + bevelSegments * 2;
53749             offset = vlen * layer;
53750
53751             // Top faces
53752
53753             for ( i = 0; i < flen; i ++ ) {
53754
53755                 face = faces[ i ];
53756                 f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset, false );
53757
53758             }
53759
53760         } else {
53761
53762             // Bottom faces
53763
53764             for ( i = 0; i < flen; i++ ) {
53765
53766                 face = faces[ i ];
53767                 f3( face[ 2 ], face[ 1 ], face[ 0 ], true );
53768
53769             }
53770
53771             // Top faces
53772
53773             for ( i = 0; i < flen; i ++ ) {
53774
53775                 face = faces[ i ];
53776                 f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps, false );
53777
53778             }
53779         }
53780
53781     }
53782
53783     // Create faces for the z-sides of the shape
53784
53785     function buildSideFaces() {
53786
53787         var layeroffset = 0;
53788         sidewalls( contour, layeroffset );
53789         layeroffset += contour.length;
53790
53791         for ( h = 0, hl = holes.length;  h < hl; h ++ ) {
53792
53793             ahole = holes[ h ];
53794             sidewalls( ahole, layeroffset );
53795
53796             //, true
53797             layeroffset += ahole.length;
53798
53799         }
53800
53801     }
53802
53803     function sidewalls( contour, layeroffset ) {
53804
53805         var j, k;
53806         i = contour.length;
53807
53808         while ( --i >= 0 ) {
53809
53810             j = i;
53811             k = i - 1;
53812             if ( k < 0 ) k = contour.length - 1;
53813
53814             //console.log('b', i,j, i-1, k,vertices.length);
53815
53816             var s = 0, sl = steps  + bevelSegments * 2;
53817
53818             for ( s = 0; s < sl; s ++ ) {
53819
53820                 var slen1 = vlen * s;
53821                 var slen2 = vlen * ( s + 1 );
53822
53823                 var a = layeroffset + j + slen1,
53824                     b = layeroffset + k + slen1,
53825                     c = layeroffset + k + slen2,
53826                     d = layeroffset + j + slen2;
53827
53828                 f4( a, b, c, d, contour, s, sl, j, k );
53829
53830             }
53831         }
53832
53833     }
53834
53835
53836     function v( x, y, z ) {
53837
53838         scope.vertices.push( new THREE.Vector3( x, y, z ) );
53839
53840     }
53841
53842     function f3( a, b, c, isBottom ) {
53843
53844         a += shapesOffset;
53845         b += shapesOffset;
53846         c += shapesOffset;
53847
53848         // normal, color, material
53849         scope.faces.push( new THREE.Face3( a, b, c, null, null, material ) );
53850
53851         var uvs = isBottom ? uvgen.generateBottomUV( scope, shape, options, a, b, c ) : uvgen.generateTopUV( scope, shape, options, a, b, c );
53852
53853          scope.faceVertexUvs[ 0 ].push( uvs );
53854
53855     }
53856
53857     function f4( a, b, c, d, wallContour, stepIndex, stepsLength, contourIndex1, contourIndex2 ) {
53858
53859         a += shapesOffset;
53860         b += shapesOffset;
53861         c += shapesOffset;
53862         d += shapesOffset;
53863
53864          scope.faces.push( new THREE.Face4( a, b, c, d, null, null, extrudeMaterial ) );
53865
53866          var uvs = uvgen.generateSideWallUV( scope, shape, wallContour, options, a, b, c, d,
53867                                              stepIndex, stepsLength, contourIndex1, contourIndex2 );
53868          scope.faceVertexUvs[ 0 ].push( uvs );
53869
53870     }
53871
53872 };
53873
53874 THREE.ExtrudeGeometry.WorldUVGenerator = {
53875
53876     generateTopUV: function( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC ) {
53877         var ax = geometry.vertices[ indexA ].x,
53878             ay = geometry.vertices[ indexA ].y,
53879
53880             bx = geometry.vertices[ indexB ].x,
53881             by = geometry.vertices[ indexB ].y,
53882
53883             cx = geometry.vertices[ indexC ].x,
53884             cy = geometry.vertices[ indexC ].y;
53885
53886         return [
53887             new THREE.UV( ax, ay ),
53888             new THREE.UV( bx, by ),
53889             new THREE.UV( cx, cy )
53890         ];
53891
53892     },
53893
53894     generateBottomUV: function( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC ) {
53895
53896         return this.generateTopUV( geometry, extrudedShape, extrudeOptions, indexA, indexB, indexC );
53897
53898     },
53899
53900     generateSideWallUV: function( geometry, extrudedShape, wallContour, extrudeOptions,
53901                                   indexA, indexB, indexC, indexD, stepIndex, stepsLength,
53902                                   contourIndex1, contourIndex2 ) {
53903
53904         var ax = geometry.vertices[ indexA ].x,
53905             ay = geometry.vertices[ indexA ].y,
53906             az = geometry.vertices[ indexA ].z,
53907
53908             bx = geometry.vertices[ indexB ].x,
53909             by = geometry.vertices[ indexB ].y,
53910             bz = geometry.vertices[ indexB ].z,
53911
53912             cx = geometry.vertices[ indexC ].x,
53913             cy = geometry.vertices[ indexC ].y,
53914             cz = geometry.vertices[ indexC ].z,
53915
53916             dx = geometry.vertices[ indexD ].x,
53917             dy = geometry.vertices[ indexD ].y,
53918             dz = geometry.vertices[ indexD ].z;
53919
53920         if ( Math.abs( ay - by ) < 0.01 ) {
53921             return [
53922                 new THREE.UV( ax, 1 - az ),
53923                 new THREE.UV( bx, 1 - bz ),
53924                 new THREE.UV( cx, 1 - cz ),
53925                 new THREE.UV( dx, 1 - dz )
53926             ];
53927         } else {
53928             return [
53929                 new THREE.UV( ay, 1 - az ),
53930                 new THREE.UV( by, 1 - bz ),
53931                 new THREE.UV( cy, 1 - cz ),
53932                 new THREE.UV( dy, 1 - dz )
53933             ];
53934         }
53935     }
53936 };
53937
53938 THREE.ExtrudeGeometry.__v1 = new THREE.Vector2();
53939 THREE.ExtrudeGeometry.__v2 = new THREE.Vector2();
53940 THREE.ExtrudeGeometry.__v3 = new THREE.Vector2();
53941 THREE.ExtrudeGeometry.__v4 = new THREE.Vector2();
53942 THREE.ExtrudeGeometry.__v5 = new THREE.Vector2();
53943 THREE.ExtrudeGeometry.__v6 = new THREE.Vector2();
53944 /**
53945  * @author jonobr1 / http://jonobr1.com
53946  *
53947  * Creates a one-sided polygonal geometry from a path shape. Similar to
53948  * ExtrudeGeometry.
53949  *
53950  * parameters = {
53951  *
53952  *    curveSegments: <int>, // number of points on the curves. NOT USED AT THE MOMENT.
53953  *
53954  *    material: <int> // material index for front and back faces
53955  *    uvGenerator: <Object> // object that provides UV generator functions
53956  *
53957  * }
53958  **/
53959
53960 THREE.ShapeGeometry = function ( shapes, options ) {
53961
53962     THREE.Geometry.call( this );
53963
53964     if ( shapes instanceof Array === false ) shapes = [ shapes ];
53965
53966     this.shapebb = shapes[ shapes.length - 1 ].getBoundingBox();
53967
53968     this.addShapeList( shapes, options );
53969
53970     this.computeCentroids();
53971     this.computeFaceNormals();
53972
53973 };
53974
53975 THREE.ShapeGeometry.prototype = Object.create( THREE.Geometry.prototype );
53976
53977 /**
53978  * Add an array of shapes to THREE.ShapeGeometry.
53979  */
53980 THREE.ShapeGeometry.prototype.addShapeList = function ( shapes, options ) {
53981
53982     for ( var i = 0, l = shapes.length; i < l; i++ ) {
53983
53984         this.addShape( shapes[ i ], options );
53985
53986     }
53987
53988     return this;
53989
53990 };
53991
53992 /**
53993  * Adds a shape to THREE.ShapeGeometry, based on THREE.ExtrudeGeometry.
53994  */
53995 THREE.ShapeGeometry.prototype.addShape = function ( shape, options ) {
53996
53997     if ( options === undefined ) options = {};
53998
53999     var material = options.material;
54000     var uvgen = options.UVGenerator === undefined ? THREE.ExtrudeGeometry.WorldUVGenerator : options.UVGenerator;
54001
54002     var shapebb = this.shapebb;
54003
54004     //
54005
54006     var i, l, hole, s;
54007
54008     var shapesOffset = this.vertices.length;
54009     var shapePoints = shape.extractPoints();
54010
54011     var vertices = shapePoints.shape;
54012     var holes = shapePoints.holes;
54013
54014     var reverse = !THREE.Shape.Utils.isClockWise( vertices );
54015
54016     if ( reverse ) {
54017
54018         vertices = vertices.reverse();
54019
54020         // Maybe we should also check if holes are in the opposite direction, just to be safe...
54021
54022         for ( i = 0, l = holes.length; i < l; i++ ) {
54023
54024             hole = holes[ i ];
54025
54026             if ( THREE.Shape.Utils.isClockWise( hole ) ) {
54027
54028                 holes[ i ] = hole.reverse();
54029
54030             }
54031
54032         }
54033
54034         reverse = false;
54035
54036     }
54037
54038     var faces = THREE.Shape.Utils.triangulateShape( vertices, holes );
54039
54040     // Vertices
54041
54042     var contour = vertices;
54043
54044     for ( i = 0, l = holes.length; i < l; i++ ) {
54045
54046         hole = holes[ i ];
54047         vertices = vertices.concat( hole );
54048
54049     }
54050
54051     //
54052
54053     var vert, vlen = vertices.length;
54054     var face, flen = faces.length;
54055     var cont, clen = contour.length;
54056
54057     for ( i = 0; i < vlen; i++ ) {
54058
54059         vert = vertices[ i ];
54060
54061         this.vertices.push( new THREE.Vector3( vert.x, vert.y, 0 ) );
54062
54063     }
54064
54065     for ( i = 0; i < flen; i++ ) {
54066
54067         face = faces[ i ];
54068
54069         var a = face[ 2 ] + shapesOffset;
54070         var b = face[ 1 ] + shapesOffset;
54071         var c = face[ 0 ] + shapesOffset;
54072
54073         this.faces.push( new THREE.Face3( a, b, c, null, null, material ) );
54074         this.faceVertexUvs[ 0 ].push( uvgen.generateBottomUV( this, shape, options, a, b, c ) );
54075
54076     }
54077
54078 };
54079 /**
54080  * @author astrodud / http://astrodud.isgreat.org/
54081  * @author zz85 / https://github.com/zz85
54082  */
54083
54084 THREE.LatheGeometry = function ( points, steps, angle ) {
54085
54086     THREE.Geometry.call( this );
54087
54088     var _steps = steps || 12;
54089     var _angle = angle || 2 * Math.PI;
54090
54091     var _newV = [];
54092     var _matrix = new THREE.Matrix4().makeRotationZ( _angle / _steps );
54093
54094     for ( var j = 0; j < points.length; j ++ ) {
54095
54096         _newV[ j ] = points[ j ].clone();
54097         this.vertices.push( _newV[ j ] );
54098
54099     }
54100
54101     var i, il = _steps + 1;
54102
54103     for ( i = 0; i < il; i ++ ) {
54104
54105         for ( var j = 0; j < _newV.length; j ++ ) {
54106
54107             _newV[ j ] = _matrix.multiplyVector3( _newV[ j ].clone() );
54108             this.vertices.push( _newV[ j ] );
54109
54110         }
54111
54112     }
54113
54114     for ( i = 0; i < _steps; i ++ ) {
54115
54116         for ( var k = 0, kl = points.length; k < kl - 1; k ++ ) {
54117
54118             var a = i * kl + k;
54119             var b = ( ( i + 1 ) % il ) * kl + k;
54120             var c = ( ( i + 1 ) % il ) * kl + ( k + 1 ) % kl;
54121             var d = i * kl + ( k + 1 ) % kl;
54122
54123             this.faces.push( new THREE.Face4( a, b, c, d ) );
54124
54125             this.faceVertexUvs[ 0 ].push( [
54126
54127                 new THREE.UV( 1 - i / _steps, k / kl ),
54128                 new THREE.UV( 1 - ( i + 1 ) / _steps, k / kl ),
54129                 new THREE.UV( 1 - ( i + 1 ) / _steps, ( k + 1 ) / kl ),
54130                 new THREE.UV( 1 - i / _steps, ( k + 1 ) / kl )
54131
54132             ] );
54133
54134         }
54135
54136     }
54137
54138     this.computeCentroids();
54139     this.computeFaceNormals();
54140     this.computeVertexNormals();
54141
54142 };
54143
54144 THREE.LatheGeometry.prototype = Object.create( THREE.Geometry.prototype );
54145 /**
54146  * @author mrdoob / http://mrdoob.com/
54147  * based on http://papervision3d.googlecode.com/svn/trunk/as3/trunk/src/org/papervision3d/objects/primitives/Plane.as
54148  */
54149
54150 THREE.PlaneGeometry = function ( width, height, segmentsWidth, segmentsheight ) {
54151
54152     THREE.Geometry.call( this );
54153
54154     var ix, iz,
54155     width_half = width / 2,
54156     height_half = height / 2,
54157     gridX = segmentsWidth || 1,
54158     gridZ = segmentsheight || 1,
54159     gridX1 = gridX + 1,
54160     gridZ1 = gridZ + 1,
54161     segment_width = width / gridX,
54162     segment_height = height / gridZ,
54163     normal = new THREE.Vector3( 0, 0, 1 );
54164
54165     for ( iz = 0; iz < gridZ1; iz ++ ) {
54166
54167         for ( ix = 0; ix < gridX1; ix ++ ) {
54168
54169             var x = ix * segment_width - width_half;
54170             var y = iz * segment_height - height_half;
54171
54172             this.vertices.push( new THREE.Vector3( x, - y, 0 ) );
54173
54174         }
54175
54176     }
54177
54178     for ( iz = 0; iz < gridZ; iz ++ ) {
54179
54180         for ( ix = 0; ix < gridX; ix ++ ) {
54181
54182             var a = ix + gridX1 * iz;
54183             var b = ix + gridX1 * ( iz + 1 );
54184             var c = ( ix + 1 ) + gridX1 * ( iz + 1 );
54185             var d = ( ix + 1 ) + gridX1 * iz;
54186
54187             var face = new THREE.Face4( a, b, c, d );
54188             face.normal.copy( normal );
54189             face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone(), normal.clone() );
54190
54191             this.faces.push( face );
54192             this.faceVertexUvs[ 0 ].push( [
54193                 new THREE.UV( ix / gridX, 1 - iz / gridZ ),
54194                 new THREE.UV( ix / gridX, 1 - ( iz + 1 ) / gridZ ),
54195                 new THREE.UV( ( ix + 1 ) / gridX, 1 - ( iz + 1 ) / gridZ ),
54196                 new THREE.UV( ( ix + 1 ) / gridX, 1 - iz / gridZ )
54197             ] );
54198
54199         }
54200
54201     }
54202
54203     this.computeCentroids();
54204
54205 };
54206
54207 THREE.PlaneGeometry.prototype = Object.create( THREE.Geometry.prototype );
54208 /**
54209  * @author mrdoob / http://mrdoob.com/
54210  */
54211
54212 THREE.SphereGeometry = function ( radius, segmentsWidth, segmentsHeight, phiStart, phiLength, thetaStart, thetaLength ) {
54213
54214     THREE.Geometry.call( this );
54215
54216     radius = radius || 50;
54217
54218     phiStart = phiStart !== undefined ? phiStart : 0;
54219     phiLength = phiLength !== undefined ? phiLength : Math.PI * 2;
54220
54221     thetaStart = thetaStart !== undefined ? thetaStart : 0;
54222     thetaLength = thetaLength !== undefined ? thetaLength : Math.PI;
54223
54224     var segmentsX = Math.max( 3, Math.floor( segmentsWidth ) || 8 );
54225     var segmentsY = Math.max( 2, Math.floor( segmentsHeight ) || 6 );
54226
54227     var x, y, vertices = [], uvs = [];
54228
54229     for ( y = 0; y <= segmentsY; y ++ ) {
54230
54231         var verticesRow = [];
54232         var uvsRow = [];
54233
54234         for ( x = 0; x <= segmentsX; x ++ ) {
54235
54236             var u = x / segmentsX;
54237             var v = y / segmentsY;
54238
54239             var vertex = new THREE.Vector3();
54240             vertex.x = - radius * Math.cos( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
54241             vertex.y = radius * Math.cos( thetaStart + v * thetaLength );
54242             vertex.z = radius * Math.sin( phiStart + u * phiLength ) * Math.sin( thetaStart + v * thetaLength );
54243
54244             this.vertices.push( vertex );
54245
54246             verticesRow.push( this.vertices.length - 1 );
54247             uvsRow.push( new THREE.UV( u, 1 - v ) );
54248
54249         }
54250
54251         vertices.push( verticesRow );
54252         uvs.push( uvsRow );
54253
54254     }
54255
54256     for ( y = 0; y < segmentsY; y ++ ) {
54257
54258         for ( x = 0; x < segmentsX; x ++ ) {
54259
54260             var v1 = vertices[ y ][ x + 1 ];
54261             var v2 = vertices[ y ][ x ];
54262             var v3 = vertices[ y + 1 ][ x ];
54263             var v4 = vertices[ y + 1 ][ x + 1 ];
54264
54265             var n1 = this.vertices[ v1 ].clone().normalize();
54266             var n2 = this.vertices[ v2 ].clone().normalize();
54267             var n3 = this.vertices[ v3 ].clone().normalize();
54268             var n4 = this.vertices[ v4 ].clone().normalize();
54269
54270             var uv1 = uvs[ y ][ x + 1 ].clone();
54271             var uv2 = uvs[ y ][ x ].clone();
54272             var uv3 = uvs[ y + 1 ][ x ].clone();
54273             var uv4 = uvs[ y + 1 ][ x + 1 ].clone();
54274
54275             if ( Math.abs( this.vertices[ v1 ].y ) == radius ) {
54276
54277                 this.faces.push( new THREE.Face3( v1, v3, v4, [ n1, n3, n4 ] ) );
54278                 this.faceVertexUvs[ 0 ].push( [ uv1, uv3, uv4 ] );
54279
54280             } else if ( Math.abs( this.vertices[ v3 ].y ) ==  radius ) {
54281
54282                 this.faces.push( new THREE.Face3( v1, v2, v3, [ n1, n2, n3 ] ) );
54283                 this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3 ] );
54284
54285             } else {
54286
54287                 this.faces.push( new THREE.Face4( v1, v2, v3, v4, [ n1, n2, n3, n4 ] ) );
54288                 this.faceVertexUvs[ 0 ].push( [ uv1, uv2, uv3, uv4 ] );
54289
54290             }
54291
54292         }
54293
54294     }
54295
54296     this.computeCentroids();
54297     this.computeFaceNormals();
54298
54299     this.boundingSphere = { radius: radius };
54300
54301 };
54302
54303 THREE.SphereGeometry.prototype = Object.create( THREE.Geometry.prototype );
54304 /**
54305  * @author zz85 / http://www.lab4games.net/zz85/blog
54306  * @author alteredq / http://alteredqualia.com/
54307  *
54308  * For creating 3D text geometry in three.js
54309  *
54310  * Text = 3D Text
54311  *
54312  * parameters = {
54313  *  size:             <float>,     // size of the text
54314  *  height:         <float>,     // thickness to extrude text
54315  *  curveSegments:     <int>,        // number of points on the curves
54316  *
54317  *  font:             <string>,        // font name
54318  *  weight:         <string>,        // font weight (normal, bold)
54319  *  style:             <string>,        // font style  (normal, italics)
54320  *
54321  *  bevelEnabled:    <bool>,            // turn on bevel
54322  *  bevelThickness: <float>,         // how deep into text bevel goes
54323  *  bevelSize:        <float>,         // how far from text outline is bevel
54324  *  }
54325  *
54326  */
54327
54328 /*    Usage Examples
54329
54330     // TextGeometry wrapper
54331
54332     var text3d = new TextGeometry( text, options );
54333
54334     // Complete manner
54335
54336     var textShapes = THREE.FontUtils.generateShapes( text, options );
54337     var text3d = new ExtrudeGeometry( textShapes, options );
54338
54339 */
54340
54341
54342 THREE.TextGeometry = function ( text, parameters ) {
54343
54344     var textShapes = THREE.FontUtils.generateShapes( text, parameters );
54345
54346     // translate parameters to ExtrudeGeometry API
54347
54348     parameters.amount = parameters.height !== undefined ? parameters.height : 50;
54349
54350     // defaults
54351
54352     if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
54353     if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
54354     if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
54355
54356     THREE.ExtrudeGeometry.call( this, textShapes, parameters );
54357
54358 };
54359
54360 THREE.TextGeometry.prototype = Object.create( THREE.ExtrudeGeometry.prototype );
54361 /**
54362  * @author oosmoxiecode
54363  * @author mrdoob / http://mrdoob.com/
54364  * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3DLite/src/away3dlite/primitives/Torus.as?r=2888
54365  */
54366
54367 THREE.TorusGeometry = function ( radius, tube, segmentsR, segmentsT, arc ) {
54368
54369     THREE.Geometry.call( this );
54370
54371     var scope = this;
54372
54373     this.radius = radius || 100;
54374     this.tube = tube || 40;
54375     this.segmentsR = segmentsR || 8;
54376     this.segmentsT = segmentsT || 6;
54377     this.arc = arc || Math.PI * 2;
54378
54379     var center = new THREE.Vector3(), uvs = [], normals = [];
54380
54381     for ( var j = 0; j <= this.segmentsR; j ++ ) {
54382
54383         for ( var i = 0; i <= this.segmentsT; i ++ ) {
54384
54385             var u = i / this.segmentsT * this.arc;
54386             var v = j / this.segmentsR * Math.PI * 2;
54387
54388             center.x = this.radius * Math.cos( u );
54389             center.y = this.radius * Math.sin( u );
54390
54391             var vertex = new THREE.Vector3();
54392             vertex.x = ( this.radius + this.tube * Math.cos( v ) ) * Math.cos( u );
54393             vertex.y = ( this.radius + this.tube * Math.cos( v ) ) * Math.sin( u );
54394             vertex.z = this.tube * Math.sin( v );
54395
54396             this.vertices.push( vertex );
54397
54398             uvs.push( new THREE.UV( i / this.segmentsT, j / this.segmentsR ) );
54399             normals.push( vertex.clone().subSelf( center ).normalize() );
54400
54401         }
54402     }
54403
54404
54405     for ( var j = 1; j <= this.segmentsR; j ++ ) {
54406
54407         for ( var i = 1; i <= this.segmentsT; i ++ ) {
54408
54409             var a = ( this.segmentsT + 1 ) * j + i - 1;
54410             var b = ( this.segmentsT + 1 ) * ( j - 1 ) + i - 1;
54411             var c = ( this.segmentsT + 1 ) * ( j - 1 ) + i;
54412             var d = ( this.segmentsT + 1 ) * j + i;
54413
54414             var face = new THREE.Face4( a, b, c, d, [ normals[ a ], normals[ b ], normals[ c ], normals[ d ] ] );
54415             face.normal.addSelf( normals[ a ] );
54416             face.normal.addSelf( normals[ b ] );
54417             face.normal.addSelf( normals[ c ] );
54418             face.normal.addSelf( normals[ d ] );
54419             face.normal.normalize();
54420
54421             this.faces.push( face );
54422
54423             this.faceVertexUvs[ 0 ].push( [ uvs[ a ].clone(), uvs[ b ].clone(), uvs[ c ].clone(), uvs[ d ].clone() ] );
54424         }
54425
54426     }
54427
54428     this.computeCentroids();
54429
54430 };
54431
54432 THREE.TorusGeometry.prototype = Object.create( THREE.Geometry.prototype );
54433 /**
54434  * @author oosmoxiecode
54435  * based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
54436  */
54437
54438 THREE.TorusKnotGeometry = function ( radius, tube, segmentsR, segmentsT, p, q, heightScale ) {
54439
54440     THREE.Geometry.call( this );
54441
54442     var scope = this;
54443
54444     this.radius = radius || 200;
54445     this.tube = tube || 40;
54446     this.segmentsR = segmentsR || 64;
54447     this.segmentsT = segmentsT || 8;
54448     this.p = p || 2;
54449     this.q = q || 3;
54450     this.heightScale = heightScale || 1;
54451     this.grid = new Array(this.segmentsR);
54452
54453     var tang = new THREE.Vector3();
54454     var n = new THREE.Vector3();
54455     var bitan = new THREE.Vector3();
54456
54457     for ( var i = 0; i < this.segmentsR; ++ i ) {
54458
54459         this.grid[ i ] = new Array( this.segmentsT );
54460
54461         for ( var j = 0; j < this.segmentsT; ++ j ) {
54462
54463             var u = i / this.segmentsR * 2 * this.p * Math.PI;
54464             var v = j / this.segmentsT * 2 * Math.PI;
54465             var p1 = getPos( u, v, this.q, this.p, this.radius, this.heightScale );
54466             var p2 = getPos( u + 0.01, v, this.q, this.p, this.radius, this.heightScale );
54467             var cx, cy;
54468
54469             tang.sub( p2, p1 );
54470             n.add( p2, p1 );
54471
54472             bitan.cross( tang, n );
54473             n.cross( bitan, tang );
54474             bitan.normalize();
54475             n.normalize();
54476
54477             cx = - this.tube * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
54478             cy = this.tube * Math.sin( v );
54479
54480             p1.x += cx * n.x + cy * bitan.x;
54481             p1.y += cx * n.y + cy * bitan.y;
54482             p1.z += cx * n.z + cy * bitan.z;
54483
54484             this.grid[ i ][ j ] = vert( p1.x, p1.y, p1.z );
54485
54486         }
54487
54488     }
54489
54490     for ( var i = 0; i < this.segmentsR; ++ i ) {
54491
54492         for ( var j = 0; j < this.segmentsT; ++ j ) {
54493
54494             var ip = ( i + 1 ) % this.segmentsR;
54495             var jp = ( j + 1 ) % this.segmentsT;
54496
54497             var a = this.grid[ i ][ j ];
54498             var b = this.grid[ ip ][ j ];
54499             var c = this.grid[ ip ][ jp ];
54500             var d = this.grid[ i ][ jp ];
54501
54502             var uva = new THREE.UV( i / this.segmentsR, j / this.segmentsT );
54503             var uvb = new THREE.UV( ( i + 1 ) / this.segmentsR, j / this.segmentsT );
54504             var uvc = new THREE.UV( ( i + 1 ) / this.segmentsR, ( j + 1 ) / this.segmentsT );
54505             var uvd = new THREE.UV( i / this.segmentsR, ( j + 1 ) / this.segmentsT );
54506
54507             this.faces.push( new THREE.Face4( a, b, c, d ) );
54508             this.faceVertexUvs[ 0 ].push( [ uva,uvb,uvc, uvd ] );
54509
54510         }
54511     }
54512
54513     this.computeCentroids();
54514     this.computeFaceNormals();
54515     this.computeVertexNormals();
54516
54517     function vert( x, y, z ) {
54518
54519         return scope.vertices.push( new THREE.Vector3( x, y, z ) ) - 1;
54520
54521     }
54522
54523     function getPos( u, v, in_q, in_p, radius, heightScale ) {
54524
54525         var cu = Math.cos( u );
54526         var cv = Math.cos( v );
54527         var su = Math.sin( u );
54528         var quOverP = in_q / in_p * u;
54529         var cs = Math.cos( quOverP );
54530
54531         var tx = radius * ( 2 + cs ) * 0.5 * cu;
54532         var ty = radius * ( 2 + cs ) * su * 0.5;
54533         var tz = heightScale * radius * Math.sin( quOverP ) * 0.5;
54534
54535         return new THREE.Vector3( tx, ty, tz );
54536
54537     }
54538
54539 };
54540
54541 THREE.TorusKnotGeometry.prototype = Object.create( THREE.Geometry.prototype );
54542 /**
54543  * @author WestLangley / https://github.com/WestLangley
54544  * @author zz85 / https://github.com/zz85
54545  * @author miningold / https://github.com/miningold
54546  *
54547  * Modified from the TorusKnotGeometry by @oosmoxiecode
54548  *
54549  * Creates a tube which extrudes along a 3d spline
54550  *
54551  * Uses parallel transport frames as described in
54552  * http://www.cs.indiana.edu/pub/techreports/TR425.pdf
54553  */
54554
54555 THREE.TubeGeometry = function( path, segments, radius, segmentsRadius, closed, debug ) {
54556
54557     THREE.Geometry.call( this );
54558
54559     this.path = path;
54560     this.segments = segments || 64;
54561     this.radius = radius || 1;
54562     this.segmentsRadius = segmentsRadius || 8;
54563     this.closed = closed || false;
54564     if ( debug ) this.debug = new THREE.Object3D();
54565
54566     this.grid = [];
54567
54568     var scope = this,
54569
54570         tangent,
54571         normal,
54572         binormal,
54573
54574         numpoints = this.segments + 1,
54575
54576         x, y, z,
54577         tx, ty, tz,
54578         u, v,
54579
54580         cx, cy,
54581         pos, pos2 = new THREE.Vector3(),
54582         i, j,
54583         ip, jp,
54584         a, b, c, d,
54585         uva, uvb, uvc, uvd;
54586
54587     var frames = new THREE.TubeGeometry.FrenetFrames(path, segments, closed),
54588         tangents = frames.tangents,
54589         normals = frames.normals,
54590         binormals = frames.binormals;
54591
54592     // proxy internals
54593     this.tangents = tangents;
54594     this.normals = normals;
54595     this.binormals = binormals;
54596
54597
54598     function vert( x, y, z ) {
54599
54600         return scope.vertices.push( new THREE.Vector3( x, y, z ) ) - 1;
54601
54602     }
54603
54604
54605
54606
54607     // consruct the grid
54608
54609     for ( i = 0; i < numpoints; i++ ) {
54610
54611         this.grid[ i ] = [];
54612
54613         u = i / ( numpoints - 1 );
54614
54615         pos = path.getPointAt( u );
54616
54617         tangent = tangents[ i ];
54618         normal = normals[ i ];
54619         binormal = binormals[ i ];
54620
54621         if ( this.debug ) {
54622
54623             this.debug.add(new THREE.ArrowHelper(tangent, pos, radius, 0x0000ff));
54624             this.debug.add(new THREE.ArrowHelper(normal, pos, radius, 0xff0000));
54625             this.debug.add(new THREE.ArrowHelper(binormal, pos, radius, 0x00ff00));
54626
54627         }
54628
54629         for ( j = 0; j < this.segmentsRadius; j++ ) {
54630
54631             v = j / this.segmentsRadius * 2 * Math.PI;
54632
54633             cx = -this.radius * Math.cos( v ); // TODO: Hack: Negating it so it faces outside.
54634             cy = this.radius * Math.sin( v );
54635
54636             pos2.copy( pos );
54637             pos2.x += cx * normal.x + cy * binormal.x;
54638             pos2.y += cx * normal.y + cy * binormal.y;
54639             pos2.z += cx * normal.z + cy * binormal.z;
54640
54641             this.grid[ i ][ j ] = vert( pos2.x, pos2.y, pos2.z );
54642
54643         }
54644     }
54645
54646
54647     // construct the mesh
54648
54649     for ( i = 0; i < this.segments; i++ ) {
54650
54651         for ( j = 0; j < this.segmentsRadius; j++ ) {
54652
54653             ip = ( closed ) ? (i + 1) % this.segments : i + 1;
54654             jp = (j + 1) % this.segmentsRadius;
54655
54656             a = this.grid[ i ][ j ];        // *** NOT NECESSARILY PLANAR ! ***
54657             b = this.grid[ ip ][ j ];
54658             c = this.grid[ ip ][ jp ];
54659             d = this.grid[ i ][ jp ];
54660
54661             uva = new THREE.UV( i / this.segments, j / this.segmentsRadius );
54662             uvb = new THREE.UV( ( i + 1 ) / this.segments, j / this.segmentsRadius );
54663             uvc = new THREE.UV( ( i + 1 ) / this.segments, ( j + 1 ) / this.segmentsRadius );
54664             uvd = new THREE.UV( i / this.segments, ( j + 1 ) / this.segmentsRadius );
54665
54666             this.faces.push( new THREE.Face4( a, b, c, d ) );
54667             this.faceVertexUvs[ 0 ].push( [ uva, uvb, uvc, uvd ] );
54668
54669         }
54670     }
54671
54672     this.computeCentroids();
54673     this.computeFaceNormals();
54674     this.computeVertexNormals();
54675
54676 };
54677
54678 THREE.TubeGeometry.prototype = Object.create( THREE.Geometry.prototype );
54679
54680
54681 // For computing of Frenet frames, exposing the tangents, normals and binormals the spline
54682 THREE.TubeGeometry.FrenetFrames = function(path, segments, closed) {
54683
54684     var
54685         tangent = new THREE.Vector3(),
54686         normal = new THREE.Vector3(),
54687         binormal = new THREE.Vector3(),
54688
54689         tangents = [],
54690         normals = [],
54691         binormals = [],
54692
54693         vec = new THREE.Vector3(),
54694         mat = new THREE.Matrix4(),
54695
54696         numpoints = segments + 1,
54697         theta,
54698         epsilon = 0.0001,
54699         smallest,
54700
54701         tx, ty, tz,
54702         i, u, v;
54703
54704
54705     // expose internals
54706     this.tangents = tangents;
54707     this.normals = normals;
54708     this.binormals = binormals;
54709
54710     // compute the tangent vectors for each segment on the path
54711
54712     for ( i = 0; i < numpoints; i++ ) {
54713
54714         u = i / ( numpoints - 1 );
54715
54716         tangents[ i ] = path.getTangentAt( u );
54717         tangents[ i ].normalize();
54718
54719     }
54720
54721     initialNormal3();
54722
54723     function initialNormal1(lastBinormal) {
54724         // fixed start binormal. Has dangers of 0 vectors
54725         normals[ 0 ] = new THREE.Vector3();
54726         binormals[ 0 ] = new THREE.Vector3();
54727         if (lastBinormal===undefined) lastBinormal = new THREE.Vector3( 0, 0, 1 );
54728         normals[ 0 ].cross( lastBinormal, tangents[ 0 ] ).normalize();
54729         binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] ).normalize();
54730     }
54731
54732     function initialNormal2() {
54733
54734         // This uses the Frenet-Serret formula for deriving binormal
54735         var t2 = path.getTangentAt( epsilon );
54736
54737         normals[ 0 ] = new THREE.Vector3().sub( t2, tangents[ 0 ] ).normalize();
54738         binormals[ 0 ] = new THREE.Vector3().cross( tangents[ 0 ], normals[ 0 ] );
54739
54740         normals[ 0 ].cross( binormals[ 0 ], tangents[ 0 ] ).normalize(); // last binormal x tangent
54741         binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] ).normalize();
54742
54743     }
54744
54745     function initialNormal3() {
54746         // select an initial normal vector perpenicular to the first tangent vector,
54747         // and in the direction of the smallest tangent xyz component
54748
54749         normals[ 0 ] = new THREE.Vector3();
54750         binormals[ 0 ] = new THREE.Vector3();
54751         smallest = Number.MAX_VALUE;
54752         tx = Math.abs( tangents[ 0 ].x );
54753         ty = Math.abs( tangents[ 0 ].y );
54754         tz = Math.abs( tangents[ 0 ].z );
54755
54756         if ( tx <= smallest ) {
54757             smallest = tx;
54758             normal.set( 1, 0, 0 );
54759         }
54760
54761         if ( ty <= smallest ) {
54762             smallest = ty;
54763             normal.set( 0, 1, 0 );
54764         }
54765
54766         if ( tz <= smallest ) {
54767             normal.set( 0, 0, 1 );
54768         }
54769
54770         vec.cross( tangents[ 0 ], normal ).normalize();
54771
54772         normals[ 0 ].cross( tangents[ 0 ], vec );
54773         binormals[ 0 ].cross( tangents[ 0 ], normals[ 0 ] );
54774     }
54775
54776
54777     // compute the slowly-varying normal and binormal vectors for each segment on the path
54778
54779     for ( i = 1; i < numpoints; i++ ) {
54780
54781         normals[ i ] = normals[ i-1 ].clone();
54782
54783         binormals[ i ] = binormals[ i-1 ].clone();
54784
54785         vec.cross( tangents[ i-1 ], tangents[ i ] );
54786
54787         if ( vec.length() > epsilon ) {
54788
54789             vec.normalize();
54790
54791             theta = Math.acos( tangents[ i-1 ].dot( tangents[ i ] ) );
54792
54793             mat.makeRotationAxis( vec, theta ).multiplyVector3( normals[ i ] );
54794
54795         }
54796
54797         binormals[ i ].cross( tangents[ i ], normals[ i ] );
54798
54799     }
54800
54801
54802     // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
54803
54804     if ( closed ) {
54805
54806         theta = Math.acos( normals[ 0 ].dot( normals[ numpoints-1 ] ) );
54807         theta /= ( numpoints - 1 );
54808
54809         if ( tangents[ 0 ].dot( vec.cross( normals[ 0 ], normals[ numpoints-1 ] ) ) > 0 ) {
54810
54811             theta = -theta;
54812
54813         }
54814
54815         for ( i = 1; i < numpoints; i++ ) {
54816
54817             // twist a little...
54818             mat.makeRotationAxis( tangents[ i ], theta * i ).multiplyVector3( normals[ i ] );
54819             binormals[ i ].cross( tangents[ i ], normals[ i ] );
54820
54821         }
54822
54823     }
54824 };
54825 /**
54826  * @author clockworkgeek / https://github.com/clockworkgeek
54827  * @author timothypratley / https://github.com/timothypratley
54828  */
54829
54830 THREE.PolyhedronGeometry = function ( vertices, faces, radius, detail ) {
54831
54832     THREE.Geometry.call( this );
54833
54834     radius = radius || 1;
54835     detail = detail || 0;
54836
54837     var that = this;
54838
54839     for ( var i = 0, l = vertices.length; i < l; i ++ ) {
54840
54841         prepare( new THREE.Vector3( vertices[ i ][ 0 ], vertices[ i ][ 1 ], vertices[ i ][ 2 ] ) );
54842
54843     }
54844
54845     var midpoints = [], p = this.vertices;
54846
54847     for ( var i = 0, l = faces.length; i < l; i ++ ) {
54848
54849         make( p[ faces[ i ][ 0 ] ], p[ faces[ i ][ 1 ] ], p[ faces[ i ][ 2 ] ], detail );
54850
54851     }
54852
54853     this.mergeVertices();
54854
54855     // Apply radius
54856
54857     for ( var i = 0, l = this.vertices.length; i < l; i ++ ) {
54858
54859         this.vertices[ i ].multiplyScalar( radius );
54860
54861     }
54862
54863
54864     // Project vector onto sphere's surface
54865
54866     function prepare( vector ) {
54867
54868         var vertex = vector.normalize().clone();
54869         vertex.index = that.vertices.push( vertex ) - 1;
54870
54871         // Texture coords are equivalent to map coords, calculate angle and convert to fraction of a circle.
54872
54873         var u = azimuth( vector ) / 2 / Math.PI + 0.5;
54874         var v = inclination( vector ) / Math.PI + 0.5;
54875         vertex.uv = new THREE.UV( u, 1 - v );
54876
54877         return vertex;
54878
54879     }
54880
54881
54882     // Approximate a curved face with recursively sub-divided triangles.
54883
54884     function make( v1, v2, v3, detail ) {
54885
54886         if ( detail < 1 ) {
54887
54888             var face = new THREE.Face3( v1.index, v2.index, v3.index, [ v1.clone(), v2.clone(), v3.clone() ] );
54889             face.centroid.addSelf( v1 ).addSelf( v2 ).addSelf( v3 ).divideScalar( 3 );
54890             face.normal = face.centroid.clone().normalize();
54891             that.faces.push( face );
54892
54893             var azi = azimuth( face.centroid );
54894             that.faceVertexUvs[ 0 ].push( [
54895                 correctUV( v1.uv, v1, azi ),
54896                 correctUV( v2.uv, v2, azi ),
54897                 correctUV( v3.uv, v3, azi )
54898             ] );
54899
54900         } else {
54901
54902             detail -= 1;
54903
54904             // split triangle into 4 smaller triangles
54905
54906             make( v1, midpoint( v1, v2 ), midpoint( v1, v3 ), detail ); // top quadrant
54907             make( midpoint( v1, v2 ), v2, midpoint( v2, v3 ), detail ); // left quadrant
54908             make( midpoint( v1, v3 ), midpoint( v2, v3 ), v3, detail ); // right quadrant
54909             make( midpoint( v1, v2 ), midpoint( v2, v3 ), midpoint( v1, v3 ), detail ); // center quadrant
54910
54911         }
54912
54913     }
54914
54915     function midpoint( v1, v2 ) {
54916
54917         if ( !midpoints[ v1.index ] ) midpoints[ v1.index ] = [];
54918         if ( !midpoints[ v2.index ] ) midpoints[ v2.index ] = [];
54919
54920         var mid = midpoints[ v1.index ][ v2.index ];
54921
54922         if ( mid === undefined ) {
54923
54924             // generate mean point and project to surface with prepare()
54925
54926             midpoints[ v1.index ][ v2.index ] = midpoints[ v2.index ][ v1.index ] = mid = prepare(
54927                 new THREE.Vector3().add( v1, v2 ).divideScalar( 2 )
54928             );
54929         }
54930
54931         return mid;
54932
54933     }
54934
54935
54936     // Angle around the Y axis, counter-clockwise when looking from above.
54937
54938     function azimuth( vector ) {
54939
54940         return Math.atan2( vector.z, -vector.x );
54941
54942     }
54943
54944
54945     // Angle above the XZ plane.
54946
54947     function inclination( vector ) {
54948
54949         return Math.atan2( -vector.y, Math.sqrt( ( vector.x * vector.x ) + ( vector.z * vector.z ) ) );
54950
54951     }
54952
54953
54954     // Texture fixing helper. Spheres have some odd behaviours.
54955
54956     function correctUV( uv, vector, azimuth ) {
54957
54958         if ( ( azimuth < 0 ) && ( uv.u === 1 ) ) uv = new THREE.UV( uv.u - 1, uv.v );
54959         if ( ( vector.x === 0 ) && ( vector.z === 0 ) ) uv = new THREE.UV( azimuth / 2 / Math.PI + 0.5, uv.v );
54960         return uv;
54961
54962     }
54963
54964     this.computeCentroids();
54965
54966     this.boundingSphere = { radius: radius };
54967
54968 };
54969
54970 THREE.PolyhedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
54971 /**
54972  * @author timothypratley / https://github.com/timothypratley
54973  */
54974
54975 THREE.IcosahedronGeometry = function ( radius, detail ) {
54976
54977     var t = ( 1 + Math.sqrt( 5 ) ) / 2;
54978
54979     var vertices = [
54980         [ -1,  t,  0 ], [  1, t, 0 ], [ -1, -t,  0 ], [  1, -t,  0 ],
54981         [  0, -1,  t ], [  0, 1, t ], [  0, -1, -t ], [  0,  1, -t ],
54982         [  t,  0, -1 ], [  t, 0, 1 ], [ -t,  0, -1 ], [ -t,  0,  1 ]
54983     ];
54984
54985     var faces = [
54986         [ 0, 11,  5 ], [ 0,  5,  1 ], [  0,  1,  7 ], [  0,  7, 10 ], [  0, 10, 11 ],
54987         [ 1,  5,  9 ], [ 5, 11,  4 ], [ 11, 10,  2 ], [ 10,  7,  6 ], [  7,  1,  8 ],
54988         [ 3,  9,  4 ], [ 3,  4,  2 ], [  3,  2,  6 ], [  3,  6,  8 ], [  3,  8,  9 ],
54989         [ 4,  9,  5 ], [ 2,  4, 11 ], [  6,  2, 10 ], [  8,  6,  7 ], [  9,  8,  1 ]
54990     ];
54991
54992     THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
54993
54994 };
54995
54996 THREE.IcosahedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
54997 /**
54998  * @author timothypratley / https://github.com/timothypratley
54999  */
55000
55001 THREE.OctahedronGeometry = function ( radius, detail ) {
55002
55003     var vertices = [
55004         [ 1, 0, 0 ], [ -1, 0, 0 ], [ 0, 1, 0 ], [ 0, -1, 0 ], [ 0, 0, 1 ], [ 0, 0, -1 ]
55005     ];
55006
55007     var faces = [
55008         [ 0, 2, 4 ], [ 0, 4, 3 ], [ 0, 3, 5 ], [ 0, 5, 2 ], [ 1, 2, 5 ], [ 1, 5, 3 ], [ 1, 3, 4 ], [ 1, 4, 2 ]
55009     ];
55010
55011     THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
55012 };
55013
55014 THREE.OctahedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
55015 /**
55016  * @author timothypratley / https://github.com/timothypratley
55017  */
55018
55019 THREE.TetrahedronGeometry = function ( radius, detail ) {
55020
55021     var vertices = [
55022         [ 1,  1,  1 ], [ -1, -1, 1 ], [ -1, 1, -1 ], [ 1, -1, -1 ]
55023     ];
55024
55025     var faces = [
55026         [ 2, 1, 0 ], [ 0, 3, 2 ], [ 1, 3, 0 ], [ 2, 3, 1 ]
55027     ];
55028
55029     THREE.PolyhedronGeometry.call( this, vertices, faces, radius, detail );
55030
55031 };
55032
55033 THREE.TetrahedronGeometry.prototype = Object.create( THREE.Geometry.prototype );
55034 /**
55035  * @author zz85 / https://github.com/zz85
55036  * Parametric Surfaces Geometry
55037  * based on the brilliant article by @prideout http://prideout.net/blog/?p=44
55038  *
55039  * new THREE.ParametricGeometry( parametricFunction, uSegments, ySegements, useTris );
55040  *
55041  */
55042
55043 THREE.ParametricGeometry = function ( func, slices, stacks, useTris ) {
55044
55045     THREE.Geometry.call( this );
55046
55047     var verts = this.vertices;
55048     var faces = this.faces;
55049     var uvs = this.faceVertexUvs[ 0 ];
55050
55051     useTris = (useTris === undefined) ? false : useTris;
55052
55053     var i, il, j, p;
55054     var u, v;
55055
55056     var stackCount = stacks + 1;
55057     var sliceCount = slices + 1;
55058
55059     for ( i = 0; i <= stacks; i ++ ) {
55060
55061         v = i / stacks;
55062
55063         for ( j = 0; j <= slices; j ++ ) {
55064
55065             u = j / slices;
55066
55067             p = func( u, v );
55068             verts.push( p );
55069
55070         }
55071     }
55072
55073     var a, b, c, d;
55074     var uva, uvb, uvc, uvd;
55075
55076     for ( i = 0; i < stacks; i ++ ) {
55077
55078         for ( j = 0; j < slices; j ++ ) {
55079
55080             a = i * sliceCount + j;
55081             b = i * sliceCount + j + 1;
55082             c = (i + 1) * sliceCount + j;
55083             d = (i + 1) * sliceCount + j + 1;
55084
55085             uva = new THREE.UV( j / slices, i / stacks );
55086             uvb = new THREE.UV( ( j + 1 ) / slices, i / stacks );
55087             uvc = new THREE.UV( j / slices, ( i + 1 ) / stacks );
55088             uvd = new THREE.UV( ( j + 1 ) / slices, ( i + 1 ) / stacks );
55089
55090             if ( useTris ) {
55091
55092                 faces.push( new THREE.Face3( a, b, c ) );
55093                 faces.push( new THREE.Face3( b, d, c ) );
55094
55095                 uvs.push( [ uva, uvb, uvc ] );
55096                 uvs.push( [ uvb, uvd, uvc ] );
55097
55098             } else {
55099
55100                 faces.push( new THREE.Face4( a, b, d, c ) );
55101                 uvs.push( [ uva, uvb, uvd, uvc ] );
55102
55103             }
55104
55105         }
55106
55107     }
55108
55109     // console.log(this);
55110
55111     // magic bullet
55112     // var diff = this.mergeVertices();
55113     // console.log('removed ', diff, ' vertices by merging');
55114
55115     this.computeCentroids();
55116     this.computeFaceNormals();
55117     this.computeVertexNormals();
55118
55119 };
55120
55121 THREE.ParametricGeometry.prototype = Object.create( THREE.Geometry.prototype );
55122 /**
55123  * @author qiao / https://github.com/qiao
55124  * @fileoverview This is a convex hull generator using the incremental method.
55125  * The complexity is O(n^2) where n is the number of vertices.
55126  * O(nlogn) algorithms do exist, but they are much more complicated.
55127  *
55128  * Benchmark:
55129  *
55130  *  Platform: CPU: P7350 @2.00GHz Engine: V8
55131  *
55132  *  Num Vertices    Time(ms)
55133  *
55134  *     10           1
55135  *     20           3
55136  *     30           19
55137  *     40           48
55138  *     50           107
55139  */
55140
55141 THREE.ConvexGeometry = function( vertices ) {
55142
55143     THREE.Geometry.call( this );
55144
55145     var faces = [ [ 0, 1, 2 ], [ 0, 2, 1 ] ];
55146
55147     for ( var i = 3; i < vertices.length; i++ ) {
55148
55149         addPoint( i );
55150
55151     }
55152
55153
55154     function addPoint( vertexId ) {
55155
55156         var vertex = vertices[ vertexId ].clone();
55157
55158         var mag = vertex.length();
55159         vertex.x += mag * randomOffset();
55160         vertex.y += mag * randomOffset();
55161         vertex.z += mag * randomOffset();
55162
55163         var hole = [];
55164
55165         for ( var f = 0; f < faces.length; ) {
55166
55167             var face = faces[ f ];
55168
55169             // for each face, if the vertex can see it,
55170             // then we try to add the face's edges into the hole.
55171             if ( visible( face, vertex ) ) {
55172
55173                 for ( var e = 0; e < 3; e++ ) {
55174
55175                     var edge = [ face[ e ], face[ ( e + 1 ) % 3 ] ];
55176                     var boundary = true;
55177
55178                     // remove duplicated edges.
55179                     for ( var h = 0; h < hole.length; h++ ) {
55180
55181                         if ( equalEdge( hole[ h ], edge ) ) {
55182
55183                             hole[ h ] = hole[ hole.length - 1 ];
55184                             hole.pop();
55185                             boundary = false;
55186                             break;
55187
55188                         }
55189
55190                     }
55191
55192                     if ( boundary ) {
55193
55194                         hole.push( edge );
55195
55196                     }
55197
55198                 }
55199
55200                 // remove faces[ f ]
55201                 faces[ f ] = faces[ faces.length - 1 ];
55202                 faces.pop();
55203
55204             } else { // not visible
55205
55206                 f++;
55207
55208             }
55209         }
55210
55211         // construct the new faces formed by the edges of the hole and the vertex
55212         for ( var h = 0; h < hole.length; h++ ) {
55213
55214             faces.push( [
55215                 hole[ h ][ 0 ],
55216                 hole[ h ][ 1 ],
55217                 vertexId
55218             ] );
55219
55220         }
55221     }
55222
55223     /**
55224      * Whether the face is visible from the vertex
55225      */
55226     function visible( face, vertex ) {
55227
55228         var va = vertices[ face[ 0 ] ];
55229         var vb = vertices[ face[ 1 ] ];
55230         var vc = vertices[ face[ 2 ] ];
55231
55232         var n = normal( va, vb, vc );
55233
55234         // distance from face to origin
55235         var dist = n.dot( va );
55236
55237         return n.dot( vertex ) >= dist;
55238
55239     }
55240
55241     /**
55242      * Face normal
55243      */
55244     function normal( va, vb, vc ) {
55245
55246         var cb = new THREE.Vector3();
55247         var ab = new THREE.Vector3();
55248
55249         cb.sub( vc, vb );
55250         ab.sub( va, vb );
55251         cb.crossSelf( ab );
55252
55253         if ( !cb.isZero() ) {
55254
55255             cb.normalize();
55256
55257         }
55258
55259         return cb;
55260
55261     }
55262
55263     /**
55264      * Detect whether two edges are equal.
55265      * Note that when constructing the convex hull, two same edges can only
55266      * be of the negative direction.
55267      */
55268     function equalEdge( ea, eb ) {
55269
55270         return ea[ 0 ] === eb[ 1 ] && ea[ 1 ] === eb[ 0 ];
55271
55272     }
55273
55274     /**
55275      * Create a random offset between -1e-6 and 1e-6.
55276      */
55277     function randomOffset() {
55278
55279         return ( Math.random() - 0.5 ) * 2 * 1e-6;
55280
55281     }
55282
55283
55284     /**
55285      * XXX: Not sure if this is the correct approach. Need someone to review.
55286      */
55287     function vertexUv( vertex ) {
55288
55289         var mag = vertex.length();
55290         return new THREE.UV( vertex.x / mag, vertex.y / mag );
55291
55292     }
55293
55294     // Push vertices into `this.vertices`, skipping those inside the hull
55295     var id = 0;
55296     var newId = new Array( vertices.length ); // map from old vertex id to new id
55297
55298     for ( var i = 0; i < faces.length; i++ ) {
55299
55300          var face = faces[ i ];
55301
55302          for ( var j = 0; j < 3; j++ ) {
55303
55304                 if ( newId[ face[ j ] ] === undefined ) {
55305
55306                         newId[ face[ j ] ] = id++;
55307                         this.vertices.push( vertices[ face[ j ] ] );
55308
55309                 }
55310
55311                 face[ j ] = newId[ face[ j ] ];
55312
55313          }
55314
55315     }
55316
55317     // Convert faces into instances of THREE.Face3
55318     for ( var i = 0; i < faces.length; i++ ) {
55319
55320         this.faces.push( new THREE.Face3(
55321                 faces[ i ][ 0 ],
55322                 faces[ i ][ 1 ],
55323                 faces[ i ][ 2 ]
55324         ) );
55325
55326     }
55327
55328     // Compute UVs
55329     for ( var i = 0; i < this.faces.length; i++ ) {
55330
55331         var face = this.faces[ i ];
55332
55333         this.faceVertexUvs[ 0 ].push( [
55334             vertexUv( this.vertices[ face.a ] ),
55335             vertexUv( this.vertices[ face.b ] ),
55336             vertexUv( this.vertices[ face.c ])
55337         ] );
55338
55339     }
55340
55341
55342     this.computeCentroids();
55343     this.computeFaceNormals();
55344     this.computeVertexNormals();
55345
55346 };
55347
55348 THREE.ConvexGeometry.prototype = Object.create( THREE.Geometry.prototype );
55349 /**
55350  * @author sroucheray / http://sroucheray.org/
55351  * @author mrdoob / http://mrdoob.com/
55352  */
55353
55354 THREE.AxisHelper = function () {
55355
55356     THREE.Object3D.call( this );
55357
55358     var lineGeometry = new THREE.Geometry();
55359     lineGeometry.vertices.push( new THREE.Vector3() );
55360     lineGeometry.vertices.push( new THREE.Vector3( 0, 100, 0 ) );
55361
55362     var coneGeometry = new THREE.CylinderGeometry( 0, 5, 25, 5, 1 );
55363
55364     var line, cone;
55365
55366     // x
55367
55368     line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color : 0xff0000 } ) );
55369     line.rotation.z = - Math.PI / 2;
55370     this.add( line );
55371
55372     cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color : 0xff0000 } ) );
55373     cone.position.x = 100;
55374     cone.rotation.z = - Math.PI / 2;
55375     this.add( cone );
55376
55377     // y
55378
55379     line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color : 0x00ff00 } ) );
55380     this.add( line );
55381
55382     cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color : 0x00ff00 } ) );
55383     cone.position.y = 100;
55384     this.add( cone );
55385
55386     // z
55387
55388     line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color : 0x0000ff } ) );
55389     line.rotation.x = Math.PI / 2;
55390     this.add( line );
55391
55392     cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color : 0x0000ff } ) );
55393     cone.position.z = 100;
55394     cone.rotation.x = Math.PI / 2;
55395     this.add( cone );
55396
55397 };
55398
55399 THREE.AxisHelper.prototype = Object.create( THREE.Object3D.prototype );
55400 /**
55401  * @author WestLangley / http://github.com/WestLangley
55402  * @author zz85 / https://github.com/zz85
55403  *
55404  * Creates an arrow for visualizing directions
55405  *
55406  * Parameters:
55407  *  dir - Vector3
55408  *  origin - Vector3
55409  *  length - Number
55410  *  hex - color in hex value
55411  */
55412
55413 THREE.ArrowHelper = function ( dir, origin, length, hex ) {
55414
55415     THREE.Object3D.call( this );
55416
55417     if ( hex === undefined ) hex = 0xffff00;
55418     if ( length === undefined ) length = 20;
55419
55420     var lineGeometry = new THREE.Geometry();
55421     lineGeometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
55422     lineGeometry.vertices.push( new THREE.Vector3( 0, 1, 0 ) );
55423
55424     this.line = new THREE.Line( lineGeometry, new THREE.LineBasicMaterial( { color: hex } ) );
55425     this.add( this.line );
55426
55427     var coneGeometry = new THREE.CylinderGeometry( 0, 0.05, 0.25, 5, 1 );
55428
55429     this.cone = new THREE.Mesh( coneGeometry, new THREE.MeshBasicMaterial( { color: hex } ) );
55430     this.cone.position.set( 0, 1, 0 );
55431     this.add( this.cone );
55432
55433     if ( origin instanceof THREE.Vector3 ) this.position = origin;
55434
55435     this.setDirection( dir );
55436     this.setLength( length );
55437
55438 };
55439
55440 THREE.ArrowHelper.prototype = Object.create( THREE.Object3D.prototype );
55441
55442 THREE.ArrowHelper.prototype.setDirection = function ( dir ) {
55443
55444     var axis = new THREE.Vector3( 0, 1, 0 ).crossSelf( dir );
55445
55446     var radians = Math.acos( new THREE.Vector3( 0, 1, 0 ).dot( dir.clone().normalize() ) );
55447
55448     this.matrix = new THREE.Matrix4().makeRotationAxis( axis.normalize(), radians );
55449
55450     this.rotation.setEulerFromRotationMatrix( this.matrix, this.eulerOrder );
55451
55452 };
55453
55454 THREE.ArrowHelper.prototype.setLength = function ( length ) {
55455
55456     this.scale.set( length, length, length );
55457
55458 };
55459
55460 THREE.ArrowHelper.prototype.setColor = function ( hex ) {
55461
55462     this.line.material.color.setHex( hex );
55463     this.cone.material.color.setHex( hex );
55464
55465 };
55466 /**
55467  * @author alteredq / http://alteredqualia.com/
55468  *
55469  *    - shows frustum, line of sight and up of the camera
55470  *    - suitable for fast updates
55471  *     - based on frustum visualization in lightgl.js shadowmap example
55472  *        http://evanw.github.com/lightgl.js/tests/shadowmap.html
55473  */
55474
55475 THREE.CameraHelper = function ( camera ) {
55476
55477     THREE.Line.call( this );
55478
55479     var scope = this;
55480
55481     this.geometry = new THREE.Geometry();
55482     this.material = new THREE.LineBasicMaterial( { color: 0xffffff, vertexColors: THREE.FaceColors } );
55483     this.type = THREE.LinePieces;
55484
55485     this.matrixWorld = camera.matrixWorld;
55486     this.matrixAutoUpdate = false;
55487
55488     this.pointMap = {};
55489
55490     // colors
55491
55492     var hexFrustum = 0xffaa00;
55493     var hexCone = 0xff0000;
55494     var hexUp = 0x00aaff;
55495     var hexTarget = 0xffffff;
55496     var hexCross = 0x333333;
55497
55498     // near
55499
55500     addLine( "n1", "n2", hexFrustum );
55501     addLine( "n2", "n4", hexFrustum );
55502     addLine( "n4", "n3", hexFrustum );
55503     addLine( "n3", "n1", hexFrustum );
55504
55505     // far
55506
55507     addLine( "f1", "f2", hexFrustum );
55508     addLine( "f2", "f4", hexFrustum );
55509     addLine( "f4", "f3", hexFrustum );
55510     addLine( "f3", "f1", hexFrustum );
55511
55512     // sides
55513
55514     addLine( "n1", "f1", hexFrustum );
55515     addLine( "n2", "f2", hexFrustum );
55516     addLine( "n3", "f3", hexFrustum );
55517     addLine( "n4", "f4", hexFrustum );
55518
55519     // cone
55520
55521     addLine( "p", "n1", hexCone );
55522     addLine( "p", "n2", hexCone );
55523     addLine( "p", "n3", hexCone );
55524     addLine( "p", "n4", hexCone );
55525
55526     // up
55527
55528     addLine( "u1", "u2", hexUp );
55529     addLine( "u2", "u3", hexUp );
55530     addLine( "u3", "u1", hexUp );
55531
55532     // target
55533
55534     addLine( "c", "t", hexTarget );
55535     addLine( "p", "c", hexCross );
55536
55537     // cross
55538
55539     addLine( "cn1", "cn2", hexCross );
55540     addLine( "cn3", "cn4", hexCross );
55541
55542     addLine( "cf1", "cf2", hexCross );
55543     addLine( "cf3", "cf4", hexCross );
55544
55545     this.camera = camera;
55546
55547     function addLine( a, b, hex ) {
55548
55549         addPoint( a, hex );
55550         addPoint( b, hex );
55551
55552     }
55553
55554     function addPoint( id, hex ) {
55555
55556         scope.geometry.vertices.push( new THREE.Vector3() );
55557         scope.geometry.colors.push( new THREE.Color( hex ) );
55558
55559         if ( scope.pointMap[ id ] === undefined ) scope.pointMap[ id ] = [];
55560
55561         scope.pointMap[ id ].push( scope.geometry.vertices.length - 1 );
55562
55563     }
55564
55565     this.update( camera );
55566
55567 };
55568
55569 THREE.CameraHelper.prototype = Object.create( THREE.Line.prototype );
55570
55571 THREE.CameraHelper.prototype.update = function () {
55572
55573     var scope = this;
55574
55575     var w = 1, h = 1;
55576
55577     // we need just camera projection matrix
55578     // world matrix must be identity
55579
55580     THREE.CameraHelper.__c.projectionMatrix.copy( this.camera.projectionMatrix );
55581
55582     // center / target
55583
55584     setPoint( "c", 0, 0, -1 );
55585     setPoint( "t", 0, 0,  1 );
55586
55587     // near
55588
55589     setPoint( "n1", -w, -h, -1 );
55590     setPoint( "n2",  w, -h, -1 );
55591     setPoint( "n3", -w,  h, -1 );
55592     setPoint( "n4",  w,  h, -1 );
55593
55594     // far
55595
55596     setPoint( "f1", -w, -h, 1 );
55597     setPoint( "f2",  w, -h, 1 );
55598     setPoint( "f3", -w,  h, 1 );
55599     setPoint( "f4",  w,  h, 1 );
55600
55601     // up
55602
55603     setPoint( "u1",  w * 0.7, h * 1.1, -1 );
55604     setPoint( "u2", -w * 0.7, h * 1.1, -1 );
55605     setPoint( "u3",        0, h * 2,   -1 );
55606
55607     // cross
55608
55609     setPoint( "cf1", -w,  0, 1 );
55610     setPoint( "cf2",  w,  0, 1 );
55611     setPoint( "cf3",  0, -h, 1 );
55612     setPoint( "cf4",  0,  h, 1 );
55613
55614     setPoint( "cn1", -w,  0, -1 );
55615     setPoint( "cn2",  w,  0, -1 );
55616     setPoint( "cn3",  0, -h, -1 );
55617     setPoint( "cn4",  0,  h, -1 );
55618
55619     function setPoint( point, x, y, z ) {
55620
55621         THREE.CameraHelper.__v.set( x, y, z );
55622         THREE.CameraHelper.__projector.unprojectVector( THREE.CameraHelper.__v, THREE.CameraHelper.__c );
55623
55624         var points = scope.pointMap[ point ];
55625
55626         if ( points !== undefined ) {
55627
55628             for ( var i = 0, il = points.length; i < il; i ++ ) {
55629
55630                 scope.geometry.vertices[ points[ i ] ].copy( THREE.CameraHelper.__v );
55631
55632             }
55633
55634         }
55635
55636     }
55637
55638     this.geometry.verticesNeedUpdate = true;
55639
55640 };
55641
55642 THREE.CameraHelper.__projector = new THREE.Projector();
55643 THREE.CameraHelper.__v = new THREE.Vector3();
55644 THREE.CameraHelper.__c = new THREE.Camera();
55645
55646 /*
55647  *    @author zz85 / http://twitter.com/blurspline / http://www.lab4games.net/zz85/blog
55648  *
55649  *    Subdivision Geometry Modifier
55650  *        using Catmull-Clark Subdivision Surfaces
55651  *        for creating smooth geometry meshes
55652  *
55653  *    Note: a modifier modifies vertices and faces of geometry,
55654  *        so use THREE.GeometryUtils.clone() if orignal geoemtry needs to be retained
55655  *
55656  *    Readings:
55657  *        http://en.wikipedia.org/wiki/Catmull%E2%80%93Clark_subdivision_surface
55658  *        http://www.rorydriscoll.com/2008/08/01/catmull-clark-subdivision-the-basics/
55659  *        http://xrt.wikidot.com/blog:31
55660  *        "Subdivision Surfaces in Character Animation"
55661  *
55662  *    Supports:
55663  *        Closed and Open geometries.
55664  *
55665  *    TODO:
55666  *        crease vertex and "semi-sharp" features
55667  *        selective subdivision
55668  */
55669
55670 THREE.SubdivisionModifier = function( subdivisions ) {
55671
55672     this.subdivisions = (subdivisions === undefined ) ? 1 : subdivisions;
55673
55674     // Settings
55675     this.useOldVertexColors = false;
55676     this.supportUVs = true;
55677     this.debug = false;
55678
55679 };
55680
55681 // Applies the "modify" pattern
55682 THREE.SubdivisionModifier.prototype.modify = function ( geometry ) {
55683
55684     var repeats = this.subdivisions;
55685
55686     while ( repeats-- > 0 ) {
55687         this.smooth( geometry );
55688     }
55689
55690 };
55691
55692 // Performs an iteration of Catmull-Clark Subdivision
55693 THREE.SubdivisionModifier.prototype.smooth = function ( oldGeometry ) {
55694
55695     //debug( 'running smooth' );
55696
55697     // New set of vertices, faces and uvs
55698     var newVertices = [], newFaces = [], newUVs = [];
55699
55700     function v( x, y, z ) {
55701         newVertices.push( new THREE.Vector3( x, y, z ) );
55702     }
55703
55704     var scope = this;
55705
55706     function debug() {
55707         if (scope.debug) console.log.apply(console, arguments);
55708     }
55709
55710     function warn() {
55711         if (console)
55712         console.log.apply(console, arguments);
55713     }
55714
55715     function f4( a, b, c, d, oldFace, orders, facei ) {
55716
55717         // TODO move vertex selection over here!
55718
55719         var newFace = new THREE.Face4( a, b, c, d, null, oldFace.color, oldFace.materialIndex );
55720
55721         if (scope.useOldVertexColors) {
55722
55723             newFace.vertexColors = [];
55724
55725             var color, tmpColor, order;
55726             for (var i=0;i<4;i++) {
55727                 order = orders[i];
55728
55729                 color = new THREE.Color(),
55730                 color.setRGB(0,0,0);
55731
55732                 for (var j=0, jl=0; j<order.length;j++) {
55733                     tmpColor = oldFace.vertexColors[order[j]-1];
55734                     color.r += tmpColor.r;
55735                     color.g += tmpColor.g;
55736                     color.b += tmpColor.b;
55737                 }
55738
55739                 color.r /= order.length;
55740                 color.g /= order.length;
55741                 color.b /= order.length;
55742
55743                 newFace.vertexColors[i] = color;
55744
55745             }
55746
55747         }
55748
55749         newFaces.push( newFace );
55750
55751         if (scope.supportUVs) {
55752
55753             var aUv = [
55754                 getUV(a, ''),
55755                 getUV(b, facei),
55756                 getUV(c, facei),
55757                 getUV(d, facei)
55758             ];
55759
55760             if (!aUv[0]) debug('a :( ', a+':'+facei);
55761             else if (!aUv[1]) debug('b :( ', b+':'+facei);
55762             else if (!aUv[2]) debug('c :( ', c+':'+facei);
55763             else if (!aUv[3]) debug('d :( ', d+':'+facei);
55764             else
55765                 newUVs.push( aUv );
55766
55767         }
55768     }
55769
55770     function edge_hash( a, b ) {
55771
55772         return Math.min( a, b ) + "_" + Math.max( a, b );
55773
55774     }
55775
55776     function computeEdgeFaces( geometry ) {
55777
55778         var i, il, v1, v2, j, k,
55779             face, faceIndices, faceIndex,
55780             edge,
55781             hash,
55782             edgeFaceMap = {};
55783
55784         function mapEdgeHash( hash, i ) {
55785
55786             if ( edgeFaceMap[ hash ] === undefined ) {
55787
55788                 edgeFaceMap[ hash ] = [];
55789
55790             }
55791
55792             edgeFaceMap[ hash ].push( i );
55793         }
55794
55795
55796         // construct vertex -> face map
55797
55798         for( i = 0, il = geometry.faces.length; i < il; i ++ ) {
55799
55800             face = geometry.faces[ i ];
55801
55802             if ( face instanceof THREE.Face3 ) {
55803
55804                 hash = edge_hash( face.a, face.b );
55805                 mapEdgeHash( hash, i );
55806
55807                 hash = edge_hash( face.b, face.c );
55808                 mapEdgeHash( hash, i );
55809
55810                 hash = edge_hash( face.c, face.a );
55811                 mapEdgeHash( hash, i );
55812
55813             } else if ( face instanceof THREE.Face4 ) {
55814
55815                 hash = edge_hash( face.a, face.b );
55816                 mapEdgeHash( hash, i );
55817
55818                 hash = edge_hash( face.b, face.c );
55819                 mapEdgeHash( hash, i );
55820
55821                 hash = edge_hash( face.c, face.d );
55822                 mapEdgeHash( hash, i );
55823
55824                 hash = edge_hash( face.d, face.a );
55825                 mapEdgeHash( hash, i );
55826
55827             }
55828
55829         }
55830
55831         // extract faces
55832
55833         // var edges = [];
55834         //
55835         // var numOfEdges = 0;
55836         // for (i in edgeFaceMap) {
55837         //     numOfEdges++;
55838         //
55839         //     edge = edgeFaceMap[i];
55840         //     edges.push(edge);
55841         //
55842         // }
55843
55844         //debug('edgeFaceMap', edgeFaceMap, 'geometry.edges',geometry.edges, 'numOfEdges', numOfEdges);
55845
55846         return edgeFaceMap;
55847
55848     }
55849
55850     var originalPoints = oldGeometry.vertices;
55851     var originalFaces = oldGeometry.faces;
55852
55853     var newPoints = originalPoints.concat(); // Vertices
55854
55855     var facePoints = [], edgePoints = {};
55856
55857     var sharpEdges = {}, sharpVertices = [], sharpFaces = [];
55858
55859     var uvForVertices = {}; // Stored in {vertex}:{old face} format
55860
55861     var originalVerticesLength = originalPoints.length;
55862
55863     function getUV(vertexNo, oldFaceNo) {
55864         var j,jl;
55865
55866         var key = vertexNo+':'+oldFaceNo;
55867         var theUV = uvForVertices[key];
55868
55869         if (!theUV) {
55870             if (vertexNo>=originalVerticesLength && vertexNo < (originalVerticesLength + originalFaces.length)) {
55871                 debug('face pt');
55872             } else {
55873                 debug('edge pt');
55874             }
55875
55876             warn('warning, UV not found for', key);
55877
55878             return null;
55879         }
55880
55881         return theUV;
55882
55883         // Original faces -> Vertex Nos.
55884         // new Facepoint -> Vertex Nos.
55885         // edge Points
55886
55887     }
55888
55889     function addUV(vertexNo, oldFaceNo, value) {
55890
55891         var key = vertexNo+':'+oldFaceNo;
55892         if (!(key in uvForVertices)) {
55893             uvForVertices[key] = value;
55894         } else {
55895             warn('dup vertexNo', vertexNo, 'oldFaceNo', oldFaceNo, 'value', value, 'key', key, uvForVertices[key]);
55896         }
55897     }
55898
55899     // Step 1
55900     //    For each face, add a face point
55901     //    Set each face point to be the centroid of all original points for the respective face.
55902     // debug(oldGeometry);
55903     var i, il, j, jl, face;
55904
55905     // For Uvs
55906     var uvs = oldGeometry.faceVertexUvs[0];
55907     var abcd = 'abcd', vertice;
55908
55909     debug('originalFaces, uvs, originalVerticesLength', originalFaces.length, uvs.length, originalVerticesLength);
55910     if (scope.supportUVs)
55911     for (i=0, il = uvs.length; i<il; i++ ) {
55912         for (j=0,jl=uvs[i].length;j<jl;j++) {
55913             vertice = originalFaces[i][abcd.charAt(j)];
55914
55915             addUV(vertice, i, uvs[i][j]);
55916
55917         }
55918     }
55919
55920     if (uvs.length == 0) scope.supportUVs = false;
55921
55922     // Additional UVs check, if we index original
55923     var uvCount = 0;
55924     for (var u in uvForVertices) {
55925         uvCount++;
55926     }
55927     if (!uvCount) {
55928         scope.supportUVs = false;
55929         debug('no uvs');
55930     }
55931
55932     debug('-- Original Faces + Vertices UVs completed', uvForVertices, 'vs', uvs.length);
55933
55934     var avgUv ;
55935     for (i=0, il = originalFaces.length; i<il ;i++) {
55936         face = originalFaces[ i ];
55937         facePoints.push( face.centroid );
55938         newPoints.push( face.centroid );
55939
55940
55941         if (!scope.supportUVs) continue;
55942
55943         // Prepare subdivided uv
55944
55945         avgUv = new THREE.UV();
55946
55947         if ( face instanceof THREE.Face3 ) {
55948             avgUv.u = getUV( face.a, i ).u + getUV( face.b, i ).u + getUV( face.c, i ).u;
55949             avgUv.v = getUV( face.a, i ).v + getUV( face.b, i ).v + getUV( face.c, i ).v;
55950             avgUv.u /= 3;
55951             avgUv.v /= 3;
55952
55953         } else if ( face instanceof THREE.Face4 ) {
55954             avgUv.u = getUV( face.a, i ).u + getUV( face.b, i ).u + getUV( face.c, i ).u + getUV( face.d, i ).u;
55955             avgUv.v = getUV( face.a, i ).v + getUV( face.b, i ).v + getUV( face.c, i ).v + getUV( face.d, i ).v;
55956             avgUv.u /= 4;
55957             avgUv.v /= 4;
55958         }
55959
55960         addUV(originalVerticesLength + i, '', avgUv);
55961
55962     }
55963
55964     debug('-- added UVs for new Faces', uvForVertices);
55965
55966     // Step 2
55967     //    For each edge, add an edge point.
55968     //    Set each edge point to be the average of the two neighbouring face points and its two original endpoints.
55969
55970     var edgeFaceMap = computeEdgeFaces ( oldGeometry ); // Edge Hash -> Faces Index
55971     var edge, faceIndexA, faceIndexB, avg;
55972
55973     // debug('edgeFaceMap', edgeFaceMap);
55974
55975     var edgeCount = 0;
55976
55977     var edgeVertex, edgeVertexA, edgeVertexB;
55978
55979     ////
55980
55981     var vertexEdgeMap = {}; // Gives edges connecting from each vertex
55982     var vertexFaceMap = {}; // Gives faces connecting from each vertex
55983
55984     function addVertexEdgeMap(vertex, edge) {
55985         if (vertexEdgeMap[vertex]===undefined) {
55986             vertexEdgeMap[vertex] = [];
55987         }
55988
55989         vertexEdgeMap[vertex].push(edge);
55990     }
55991
55992     function addVertexFaceMap(vertex, face, edge) {
55993         if (vertexFaceMap[vertex]===undefined) {
55994             vertexFaceMap[vertex] = {};
55995         }
55996
55997         vertexFaceMap[vertex][face] = edge;
55998         // vertexFaceMap[vertex][face] = null;
55999     }
56000
56001     // Prepares vertexEdgeMap and vertexFaceMap
56002     for (i in edgeFaceMap) { // This is for every edge
56003         edge = edgeFaceMap[i];
56004
56005         edgeVertex = i.split('_');
56006         edgeVertexA = edgeVertex[0];
56007         edgeVertexB = edgeVertex[1];
56008
56009         // Maps an edgeVertex to connecting edges
56010         addVertexEdgeMap(edgeVertexA, [edgeVertexA, edgeVertexB] );
56011         addVertexEdgeMap(edgeVertexB, [edgeVertexA, edgeVertexB] );
56012
56013
56014         for (j=0,jl=edge.length;j<jl;j++) {
56015             face = edge[j];
56016
56017             addVertexFaceMap(edgeVertexA, face, i);
56018             addVertexFaceMap(edgeVertexB, face, i);
56019         }
56020
56021         if (edge.length < 2) {
56022             // edge is "sharp";
56023             sharpEdges[i] = true;
56024             sharpVertices[edgeVertexA] = true;
56025             sharpVertices[edgeVertexB] = true;
56026
56027         }
56028
56029     }
56030
56031     debug('vertexEdgeMap',vertexEdgeMap, 'vertexFaceMap', vertexFaceMap);
56032
56033
56034     for (i in edgeFaceMap) {
56035         edge = edgeFaceMap[i];
56036
56037         faceIndexA = edge[0]; // face index a
56038         faceIndexB = edge[1]; // face index b
56039
56040         edgeVertex = i.split('_');
56041         edgeVertexA = edgeVertex[0];
56042         edgeVertexB = edgeVertex[1];
56043
56044
56045         avg = new THREE.Vector3();
56046
56047         //debug(i, faceIndexB,facePoints[faceIndexB]);
56048
56049         if (sharpEdges[i]) {
56050             //debug('warning, ', i, 'edge has only 1 connecting face', edge);
56051
56052             // For a sharp edge, average the edge end points.
56053             avg.addSelf(originalPoints[edgeVertexA]);
56054             avg.addSelf(originalPoints[edgeVertexB]);
56055
56056             avg.multiplyScalar(0.5);
56057
56058             sharpVertices[newPoints.length] = true;
56059
56060         } else {
56061
56062             avg.addSelf(facePoints[faceIndexA]);
56063             avg.addSelf(facePoints[faceIndexB]);
56064
56065             avg.addSelf(originalPoints[edgeVertexA]);
56066             avg.addSelf(originalPoints[edgeVertexB]);
56067
56068             avg.multiplyScalar(0.25);
56069
56070         }
56071
56072         edgePoints[i] = originalVerticesLength + originalFaces.length + edgeCount;
56073
56074         newPoints.push( avg );
56075
56076         edgeCount ++;
56077
56078         if (!scope.supportUVs) {
56079             continue;
56080         }
56081
56082         // debug('faceIndexAB', faceIndexA, faceIndexB, sharpEdges[i]);
56083
56084         // Prepare subdivided uv
56085
56086         avgUv = new THREE.UV();
56087
56088         avgUv.u = getUV(edgeVertexA, faceIndexA).u + getUV(edgeVertexB, faceIndexA).u;
56089         avgUv.v = getUV(edgeVertexA, faceIndexA).v + getUV(edgeVertexB, faceIndexA).v;
56090         avgUv.u /= 2;
56091         avgUv.v /= 2;
56092
56093         addUV(edgePoints[i], faceIndexA, avgUv);
56094
56095         if (!sharpEdges[i]) {
56096         avgUv = new THREE.UV();
56097
56098         avgUv.u = getUV(edgeVertexA, faceIndexB).u + getUV(edgeVertexB, faceIndexB).u;
56099         avgUv.v = getUV(edgeVertexA, faceIndexB).v + getUV(edgeVertexB, faceIndexB).v;
56100         avgUv.u /= 2;
56101         avgUv.v /= 2;
56102
56103         addUV(edgePoints[i], faceIndexB, avgUv);
56104         }
56105
56106     }
56107
56108     debug('-- Step 2 done');
56109
56110     // Step 3
56111     //    For each face point, add an edge for every edge of the face,
56112     //    connecting the face point to each edge point for the face.
56113
56114
56115     var facePt, currentVerticeIndex;
56116
56117     var hashAB, hashBC, hashCD, hashDA, hashCA;
56118
56119     var abc123 = ['123', '12', '2', '23'];
56120     var bca123 = ['123', '23', '3', '31'];
56121     var cab123 = ['123', '31', '1', '12'];
56122     var abc1234 = ['1234', '12', '2', '23'];
56123     var bcd1234 = ['1234', '23', '3', '34'];
56124     var cda1234 = ['1234', '34', '4', '41'];
56125     var dab1234 = ['1234', '41', '1', '12'];
56126
56127
56128     for (i=0, il = facePoints.length; i<il ;i++) { // for every face
56129         facePt = facePoints[i];
56130         face = originalFaces[i];
56131         currentVerticeIndex = originalVerticesLength+ i;
56132
56133         if ( face instanceof THREE.Face3 ) {
56134
56135             // create 3 face4s
56136
56137             hashAB = edge_hash( face.a, face.b );
56138             hashBC = edge_hash( face.b, face.c );
56139             hashCA = edge_hash( face.c, face.a );
56140
56141             f4( currentVerticeIndex, edgePoints[hashAB], face.b, edgePoints[hashBC], face, abc123, i );
56142             f4( currentVerticeIndex, edgePoints[hashBC], face.c, edgePoints[hashCA], face, bca123, i );
56143             f4( currentVerticeIndex, edgePoints[hashCA], face.a, edgePoints[hashAB], face, cab123, i );
56144
56145         } else if ( face instanceof THREE.Face4 ) {
56146             // create 4 face4s
56147
56148             hashAB = edge_hash( face.a, face.b );
56149             hashBC = edge_hash( face.b, face.c );
56150             hashCD = edge_hash( face.c, face.d );
56151             hashDA = edge_hash( face.d, face.a );
56152
56153             f4( currentVerticeIndex, edgePoints[hashAB], face.b, edgePoints[hashBC], face, abc1234, i );
56154             f4( currentVerticeIndex, edgePoints[hashBC], face.c, edgePoints[hashCD], face, bcd1234, i );
56155             f4( currentVerticeIndex, edgePoints[hashCD], face.d, edgePoints[hashDA], face, cda1234, i );
56156             f4( currentVerticeIndex, edgePoints[hashDA], face.a, edgePoints[hashAB], face, dab1234, i );
56157
56158
56159         } else {
56160             debug('face should be a face!', face);
56161         }
56162     }
56163
56164     newVertices = newPoints;
56165
56166     // debug('original ', oldGeometry.vertices.length, oldGeometry.faces.length );
56167     // debug('new points', newPoints.length, 'faces', newFaces.length );
56168
56169     // Step 4
56170
56171     //    For each original point P,
56172     //        take the average F of all n face points for faces touching P,
56173     //        and take the average R of all n edge midpoints for edges touching P,
56174     //        where each edge midpoint is the average of its two endpoint vertices.
56175     //    Move each original point to the point
56176
56177
56178     var F = new THREE.Vector3();
56179     var R = new THREE.Vector3();
56180
56181     var n;
56182     for (i=0, il = originalPoints.length; i<il; i++) {
56183         // (F + 2R + (n-3)P) / n
56184
56185         if (vertexEdgeMap[i]===undefined) continue;
56186
56187         F.set(0,0,0);
56188         R.set(0,0,0);
56189         var newPos =  new THREE.Vector3(0,0,0);
56190
56191         var f =0;
56192         for (j in vertexFaceMap[i]) {
56193             F.addSelf(facePoints[j]);
56194             f++;
56195         }
56196
56197         var sharpEdgeCount = 0;
56198
56199         n = vertexEdgeMap[i].length;
56200
56201         for (j=0;j<n;j++) {
56202             if (
56203                 sharpEdges[
56204                     edge_hash(vertexEdgeMap[i][j][0],vertexEdgeMap[i][j][1])
56205                 ]) {
56206                     sharpEdgeCount++;
56207                 }
56208         }
56209
56210         if ( sharpEdgeCount==2 ) {
56211             continue;
56212             // Do not move vertex if there's 2 connecting sharp edges.
56213         }
56214
56215         /*
56216         if (sharpEdgeCount>2) {
56217             // TODO
56218         }
56219         */
56220
56221         F.divideScalar(f);
56222
56223
56224
56225         for (j=0; j<n;j++) {
56226             edge = vertexEdgeMap[i][j];
56227             var midPt = originalPoints[edge[0]].clone().addSelf(originalPoints[edge[1]]).divideScalar(2);
56228             R.addSelf(midPt);
56229             // R.addSelf(originalPoints[edge[0]]);
56230             // R.addSelf(originalPoints[edge[1]]);
56231         }
56232
56233         R.divideScalar(n);
56234
56235         newPos.addSelf(originalPoints[i]);
56236         newPos.multiplyScalar(n - 3);
56237
56238         newPos.addSelf(F);
56239         newPos.addSelf(R.multiplyScalar(2));
56240         newPos.divideScalar(n);
56241
56242         newVertices[i] = newPos;
56243
56244
56245     }
56246
56247     var newGeometry = oldGeometry; // Let's pretend the old geometry is now new :P
56248
56249     newGeometry.vertices = newVertices;
56250     newGeometry.faces = newFaces;
56251     newGeometry.faceVertexUvs[ 0 ] = newUVs;
56252
56253     delete newGeometry.__tmpVertices; // makes __tmpVertices undefined :P
56254
56255     newGeometry.computeCentroids();
56256     newGeometry.computeFaceNormals();
56257     newGeometry.computeVertexNormals();
56258
56259 };
56260 /**
56261  * @author alteredq / http://alteredqualia.com/
56262  */
56263
56264 THREE.ImmediateRenderObject = function ( ) {
56265
56266     THREE.Object3D.call( this );
56267
56268     this.render = function ( renderCallback ) { };
56269
56270 };
56271
56272 THREE.ImmediateRenderObject.prototype = Object.create( THREE.Object3D.prototype );
56273 /**
56274  * @author mikael emtinger / http://gomo.se/
56275  * @author alteredq / http://alteredqualia.com/
56276  */
56277
56278 THREE.LensFlare = function ( texture, size, distance, blending, color ) {
56279
56280     THREE.Object3D.call( this );
56281
56282     this.lensFlares = [];
56283
56284     this.positionScreen = new THREE.Vector3();
56285     this.customUpdateCallback = undefined;
56286
56287     if( texture !== undefined ) {
56288
56289         this.add( texture, size, distance, blending, color );
56290
56291     }
56292
56293 };
56294
56295 THREE.LensFlare.prototype = Object.create( THREE.Object3D.prototype );
56296
56297
56298 /*
56299  * Add: adds another flare
56300  */
56301
56302 THREE.LensFlare.prototype.add = function ( texture, size, distance, blending, color, opacity ) {
56303
56304     if( size === undefined ) size = -1;
56305     if( distance === undefined ) distance = 0;
56306     if( opacity === undefined ) opacity = 1;
56307     if( color === undefined ) color = new THREE.Color( 0xffffff );
56308     if( blending === undefined ) blending = THREE.NormalBlending;
56309
56310     distance = Math.min( distance, Math.max( 0, distance ) );
56311
56312     this.lensFlares.push( { texture: texture,             // THREE.Texture
56313                             size: size,                 // size in pixels (-1 = use texture.width)
56314                             distance: distance,         // distance (0-1) from light source (0=at light source)
56315                             x: 0, y: 0, z: 0,            // screen position (-1 => 1) z = 0 is ontop z = 1 is back
56316                             scale: 1,                     // scale
56317                             rotation: 1,                 // rotation
56318                             opacity: opacity,            // opacity
56319                             color: color,                // color
56320                             blending: blending } );        // blending
56321
56322 };
56323
56324
56325 /*
56326  * Update lens flares update positions on all flares based on the screen position
56327  * Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
56328  */
56329
56330 THREE.LensFlare.prototype.updateLensFlares = function () {
56331
56332     var f, fl = this.lensFlares.length;
56333     var flare;
56334     var vecX = -this.positionScreen.x * 2;
56335     var vecY = -this.positionScreen.y * 2;
56336
56337     for( f = 0; f < fl; f ++ ) {
56338
56339         flare = this.lensFlares[ f ];
56340
56341         flare.x = this.positionScreen.x + vecX * flare.distance;
56342         flare.y = this.positionScreen.y + vecY * flare.distance;
56343
56344         flare.wantedRotation = flare.x * Math.PI * 0.25;
56345         flare.rotation += ( flare.wantedRotation - flare.rotation ) * 0.25;
56346
56347     }
56348
56349 };
56350
56351
56352
56353
56354
56355
56356
56357
56358
56359
56360
56361
56362 /**
56363  * @author alteredq / http://alteredqualia.com/
56364  */
56365
56366 THREE.MorphBlendMesh = function( geometry, material ) {
56367
56368     THREE.Mesh.call( this, geometry, material );
56369
56370     this.animationsMap = {};
56371     this.animationsList = [];
56372
56373     // prepare default animation
56374     // (all frames played together in 1 second)
56375
56376     var numFrames = this.geometry.morphTargets.length;
56377
56378     var name = "__default";
56379
56380     var startFrame = 0;
56381     var endFrame = numFrames - 1;
56382
56383     var fps = numFrames / 1;
56384
56385     this.createAnimation( name, startFrame, endFrame, fps );
56386     this.setAnimationWeight( name, 1 );
56387
56388 };
56389
56390 THREE.MorphBlendMesh.prototype = Object.create( THREE.Mesh.prototype );
56391
56392 THREE.MorphBlendMesh.prototype.createAnimation = function ( name, start, end, fps ) {
56393
56394     var animation = {
56395
56396         startFrame: start,
56397         endFrame: end,
56398
56399         length: end - start + 1,
56400
56401         fps: fps,
56402         duration: ( end - start ) / fps,
56403
56404         lastFrame: 0,
56405         currentFrame: 0,
56406
56407         active: false,
56408
56409         time: 0,
56410         direction: 1,
56411         weight: 1,
56412
56413         directionBackwards: false,
56414         mirroredLoop: false
56415
56416     };
56417
56418     this.animationsMap[ name ] = animation;
56419     this.animationsList.push( animation );
56420
56421 };
56422
56423 THREE.MorphBlendMesh.prototype.autoCreateAnimations = function ( fps ) {
56424
56425     var pattern = /([a-z]+)(\d+)/;
56426
56427     var firstAnimation, frameRanges = {};
56428
56429     var geometry = this.geometry;
56430
56431     for ( var i = 0, il = geometry.morphTargets.length; i < il; i ++ ) {
56432
56433         var morph = geometry.morphTargets[ i ];
56434         var chunks = morph.name.match( pattern );
56435
56436         if ( chunks && chunks.length > 1 ) {
56437
56438             var name = chunks[ 1 ];
56439             var num = chunks[ 2 ];
56440
56441             if ( ! frameRanges[ name ] ) frameRanges[ name ] = { start: Infinity, end: -Infinity };
56442
56443             var range = frameRanges[ name ];
56444
56445             if ( i < range.start ) range.start = i;
56446             if ( i > range.end ) range.end = i;
56447
56448             if ( ! firstAnimation ) firstAnimation = name;
56449
56450         }
56451
56452     }
56453
56454     for ( var name in frameRanges ) {
56455
56456         var range = frameRanges[ name ];
56457         this.createAnimation( name, range.start, range.end, fps );
56458
56459     }
56460
56461     this.firstAnimation = firstAnimation;
56462
56463 };
56464
56465 THREE.MorphBlendMesh.prototype.setAnimationDirectionForward = function ( name ) {
56466
56467     var animation = this.animationsMap[ name ];
56468
56469     if ( animation ) {
56470
56471         animation.direction = 1;
56472         animation.directionBackwards = false;
56473
56474     }
56475
56476 };
56477
56478 THREE.MorphBlendMesh.prototype.setAnimationDirectionBackward = function ( name ) {
56479
56480     var animation = this.animationsMap[ name ];
56481
56482     if ( animation ) {
56483
56484         animation.direction = -1;
56485         animation.directionBackwards = true;
56486
56487     }
56488
56489 };
56490
56491 THREE.MorphBlendMesh.prototype.setAnimationFPS = function ( name, fps ) {
56492
56493     var animation = this.animationsMap[ name ];
56494
56495     if ( animation ) {
56496
56497         animation.fps = fps;
56498         animation.duration = ( animation.end - animation.start ) / animation.fps;
56499
56500     }
56501
56502 };
56503
56504 THREE.MorphBlendMesh.prototype.setAnimationDuration = function ( name, duration ) {
56505
56506     var animation = this.animationsMap[ name ];
56507
56508     if ( animation ) {
56509
56510         animation.duration = duration;
56511         animation.fps = ( animation.end - animation.start ) / animation.duration;
56512
56513     }
56514
56515 };
56516
56517 THREE.MorphBlendMesh.prototype.setAnimationWeight = function ( name, weight ) {
56518
56519     var animation = this.animationsMap[ name ];
56520
56521     if ( animation ) {
56522
56523         animation.weight = weight;
56524
56525     }
56526
56527 };
56528
56529 THREE.MorphBlendMesh.prototype.setAnimationTime = function ( name, time ) {
56530
56531     var animation = this.animationsMap[ name ];
56532
56533     if ( animation ) {
56534
56535         animation.time = time;
56536
56537     }
56538
56539 };
56540
56541 THREE.MorphBlendMesh.prototype.getAnimationTime = function ( name ) {
56542
56543     var time = 0;
56544
56545     var animation = this.animationsMap[ name ];
56546
56547     if ( animation ) {
56548
56549         time = animation.time;
56550
56551     }
56552
56553     return time;
56554
56555 };
56556
56557 THREE.MorphBlendMesh.prototype.getAnimationDuration = function ( name ) {
56558
56559     var duration = -1;
56560
56561     var animation = this.animationsMap[ name ];
56562
56563     if ( animation ) {
56564
56565         duration = animation.duration;
56566
56567     }
56568
56569     return duration;
56570
56571 };
56572
56573 THREE.MorphBlendMesh.prototype.playAnimation = function ( name ) {
56574
56575     var animation = this.animationsMap[ name ];
56576
56577     if ( animation ) {
56578
56579         animation.time = 0;
56580         animation.active = true;
56581
56582     } else {
56583
56584         console.warn( "animation[" + name + "] undefined" );
56585
56586     }
56587
56588 };
56589
56590 THREE.MorphBlendMesh.prototype.stopAnimation = function ( name ) {
56591
56592     var animation = this.animationsMap[ name ];
56593
56594     if ( animation ) {
56595
56596         animation.active = false;
56597
56598     }
56599
56600 };
56601
56602 THREE.MorphBlendMesh.prototype.update = function ( delta ) {
56603
56604     for ( var i = 0, il = this.animationsList.length; i < il; i ++ ) {
56605
56606         var animation = this.animationsList[ i ];
56607
56608         if ( ! animation.active ) continue;
56609
56610         var frameTime = animation.duration / animation.length;
56611
56612         animation.time += animation.direction * delta;
56613
56614         if ( animation.mirroredLoop ) {
56615
56616             if ( animation.time > animation.duration || animation.time < 0 ) {
56617
56618                 animation.direction *= -1;
56619
56620                 if ( animation.time > animation.duration ) {
56621
56622                     animation.time = animation.duration;
56623                     animation.directionBackwards = true;
56624
56625                 }
56626
56627                 if ( animation.time < 0 ) {
56628
56629                     animation.time = 0;
56630                     animation.directionBackwards = false;
56631
56632                 }
56633
56634             }
56635
56636         } else {
56637
56638             animation.time = animation.time % animation.duration;
56639
56640             if ( animation.time < 0 ) animation.time += animation.duration;
56641
56642         }
56643
56644         var keyframe = animation.startFrame + THREE.Math.clamp( Math.floor( animation.time / frameTime ), 0, animation.length - 1 );
56645         var weight = animation.weight;
56646
56647         if ( keyframe !== animation.currentFrame ) {
56648
56649             this.morphTargetInfluences[ animation.lastFrame ] = 0;
56650             this.morphTargetInfluences[ animation.currentFrame ] = 1 * weight;
56651
56652             this.morphTargetInfluences[ keyframe ] = 0;
56653
56654             animation.lastFrame = animation.currentFrame;
56655             animation.currentFrame = keyframe;
56656
56657         }
56658
56659         var mix = ( animation.time % frameTime ) / frameTime;
56660
56661         if ( animation.directionBackwards ) mix = 1 - mix;
56662
56663         this.morphTargetInfluences[ animation.currentFrame ] = mix * weight;
56664         this.morphTargetInfluences[ animation.lastFrame ] = ( 1 - mix ) * weight;
56665
56666     }
56667
56668 };
56669 /**
56670  * @author mikael emtinger / http://gomo.se/
56671  * @author alteredq / http://alteredqualia.com/
56672  */
56673
56674 THREE.LensFlarePlugin = function ( ) {
56675
56676     var _gl, _renderer, _lensFlare = {};
56677
56678     this.init = function ( renderer ) {
56679
56680         _gl = renderer.context;
56681         _renderer = renderer;
56682
56683         _lensFlare.vertices = new Float32Array( 8 + 8 );
56684         _lensFlare.faces = new Uint16Array( 6 );
56685
56686         var i = 0;
56687         _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1;    // vertex
56688         _lensFlare.vertices[ i++ ] = 0;  _lensFlare.vertices[ i++ ] = 0;    // uv... etc.
56689
56690         _lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = -1;
56691         _lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 0;
56692
56693         _lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
56694         _lensFlare.vertices[ i++ ] = 1;  _lensFlare.vertices[ i++ ] = 1;
56695
56696         _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = 1;
56697         _lensFlare.vertices[ i++ ] = 0;  _lensFlare.vertices[ i++ ] = 1;
56698
56699         i = 0;
56700         _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 1; _lensFlare.faces[ i++ ] = 2;
56701         _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 2; _lensFlare.faces[ i++ ] = 3;
56702
56703         // buffers
56704
56705         _lensFlare.vertexBuffer     = _gl.createBuffer();
56706         _lensFlare.elementBuffer    = _gl.createBuffer();
56707
56708         _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
56709         _gl.bufferData( _gl.ARRAY_BUFFER, _lensFlare.vertices, _gl.STATIC_DRAW );
56710
56711         _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
56712         _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW );
56713
56714         // textures
56715
56716         _lensFlare.tempTexture      = _gl.createTexture();
56717         _lensFlare.occlusionTexture = _gl.createTexture();
56718
56719         _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
56720         _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, 16, 16, 0, _gl.RGB, _gl.UNSIGNED_BYTE, null );
56721         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
56722         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
56723         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
56724         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
56725
56726         _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
56727         _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, 16, 16, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
56728         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
56729         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
56730         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
56731         _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
56732
56733         if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
56734
56735             _lensFlare.hasVertexTexture = false;
56736             _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ] );
56737
56738         } else {
56739
56740             _lensFlare.hasVertexTexture = true;
56741             _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ] );
56742
56743         }
56744
56745         _lensFlare.attributes = {};
56746         _lensFlare.uniforms = {};
56747
56748         _lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
56749         _lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "uv" );
56750
56751         _lensFlare.uniforms.renderType     = _gl.getUniformLocation( _lensFlare.program, "renderType" );
56752         _lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
56753         _lensFlare.uniforms.occlusionMap   = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
56754         _lensFlare.uniforms.opacity        = _gl.getUniformLocation( _lensFlare.program, "opacity" );
56755         _lensFlare.uniforms.color          = _gl.getUniformLocation( _lensFlare.program, "color" );
56756         _lensFlare.uniforms.scale          = _gl.getUniformLocation( _lensFlare.program, "scale" );
56757         _lensFlare.uniforms.rotation       = _gl.getUniformLocation( _lensFlare.program, "rotation" );
56758         _lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );
56759
56760         _lensFlare.attributesEnabled = false;
56761
56762     };
56763
56764
56765     /*
56766      * Render lens flares
56767      * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
56768      *         reads these back and calculates occlusion.
56769      *         Then _lensFlare.update_lensFlares() is called to re-position and
56770      *         update transparency of flares. Then they are rendered.
56771      *
56772      */
56773
56774     this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
56775
56776         var flares = scene.__webglFlares,
56777             nFlares = flares.length;
56778
56779         if ( ! nFlares ) return;
56780
56781         var tempPosition = new THREE.Vector3();
56782
56783         var invAspect = viewportHeight / viewportWidth,
56784             halfViewportWidth = viewportWidth * 0.5,
56785             halfViewportHeight = viewportHeight * 0.5;
56786
56787         var size = 16 / viewportHeight,
56788             scale = new THREE.Vector2( size * invAspect, size );
56789
56790         var screenPosition = new THREE.Vector3( 1, 1, 0 ),
56791             screenPositionPixels = new THREE.Vector2( 1, 1 );
56792
56793         var uniforms = _lensFlare.uniforms,
56794             attributes = _lensFlare.attributes;
56795
56796         // set _lensFlare program and reset blending
56797
56798         _gl.useProgram( _lensFlare.program );
56799
56800         if ( ! _lensFlare.attributesEnabled ) {
56801
56802             _gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
56803             _gl.enableVertexAttribArray( _lensFlare.attributes.uv );
56804
56805             _lensFlare.attributesEnabled = true;
56806
56807         }
56808
56809         // loop through all lens flares to update their occlusion and positions
56810         // setup gl and common used attribs/unforms
56811
56812         _gl.uniform1i( uniforms.occlusionMap, 0 );
56813         _gl.uniform1i( uniforms.map, 1 );
56814
56815         _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
56816         _gl.vertexAttribPointer( attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 );
56817         _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
56818
56819         _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
56820
56821         _gl.disable( _gl.CULL_FACE );
56822         _gl.depthMask( false );
56823
56824         var i, j, jl, flare, sprite;
56825
56826         for ( i = 0; i < nFlares; i ++ ) {
56827
56828             size = 16 / viewportHeight;
56829             scale.set( size * invAspect, size );
56830
56831             // calc object screen position
56832
56833             flare = flares[ i ];
56834
56835             tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] );
56836
56837             camera.matrixWorldInverse.multiplyVector3( tempPosition );
56838             camera.projectionMatrix.multiplyVector3( tempPosition );
56839
56840             // setup arrays for gl programs
56841
56842             screenPosition.copy( tempPosition )
56843
56844             screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth;
56845             screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight;
56846
56847             // screen cull
56848
56849             if ( _lensFlare.hasVertexTexture || (
56850                 screenPositionPixels.x > 0 &&
56851                 screenPositionPixels.x < viewportWidth &&
56852                 screenPositionPixels.y > 0 &&
56853                 screenPositionPixels.y < viewportHeight ) ) {
56854
56855                 // save current RGB to temp texture
56856
56857                 _gl.activeTexture( _gl.TEXTURE1 );
56858                 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
56859                 _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
56860
56861
56862                 // render pink quad
56863
56864                 _gl.uniform1i( uniforms.renderType, 0 );
56865                 _gl.uniform2f( uniforms.scale, scale.x, scale.y );
56866                 _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
56867
56868                 _gl.disable( _gl.BLEND );
56869                 _gl.enable( _gl.DEPTH_TEST );
56870
56871                 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
56872
56873
56874                 // copy result to occlusionMap
56875
56876                 _gl.activeTexture( _gl.TEXTURE0 );
56877                 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
56878                 _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
56879
56880
56881                 // restore graphics
56882
56883                 _gl.uniform1i( uniforms.renderType, 1 );
56884                 _gl.disable( _gl.DEPTH_TEST );
56885
56886                 _gl.activeTexture( _gl.TEXTURE1 );
56887                 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
56888                 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
56889
56890
56891                 // update object positions
56892
56893                 flare.positionScreen.copy( screenPosition )
56894
56895                 if ( flare.customUpdateCallback ) {
56896
56897                     flare.customUpdateCallback( flare );
56898
56899                 } else {
56900
56901                     flare.updateLensFlares();
56902
56903                 }
56904
56905                 // render flares
56906
56907                 _gl.uniform1i( uniforms.renderType, 2 );
56908                 _gl.enable( _gl.BLEND );
56909
56910                 for ( j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
56911
56912                     sprite = flare.lensFlares[ j ];
56913
56914                     if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
56915
56916                         screenPosition.x = sprite.x;
56917                         screenPosition.y = sprite.y;
56918                         screenPosition.z = sprite.z;
56919
56920                         size = sprite.size * sprite.scale / viewportHeight;
56921
56922                         scale.x = size * invAspect;
56923                         scale.y = size;
56924
56925                         _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
56926                         _gl.uniform2f( uniforms.scale, scale.x, scale.y );
56927                         _gl.uniform1f( uniforms.rotation, sprite.rotation );
56928
56929                         _gl.uniform1f( uniforms.opacity, sprite.opacity );
56930                         _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
56931
56932                         _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
56933                         _renderer.setTexture( sprite.texture, 1 );
56934
56935                         _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
56936
56937                     }
56938
56939                 }
56940
56941             }
56942
56943         }
56944
56945         // restore gl
56946
56947         _gl.enable( _gl.CULL_FACE );
56948         _gl.enable( _gl.DEPTH_TEST );
56949         _gl.depthMask( true );
56950
56951     };
56952
56953     function createProgram ( shader ) {
56954
56955         var program = _gl.createProgram();
56956
56957         var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
56958         var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
56959
56960         _gl.shaderSource( fragmentShader, shader.fragmentShader );
56961         _gl.shaderSource( vertexShader, shader.vertexShader );
56962
56963         _gl.compileShader( fragmentShader );
56964         _gl.compileShader( vertexShader );
56965
56966         _gl.attachShader( program, fragmentShader );
56967         _gl.attachShader( program, vertexShader );
56968
56969         _gl.linkProgram( program );
56970
56971         return program;
56972
56973     };
56974
56975 };/**
56976  * @author alteredq / http://alteredqualia.com/
56977  */
56978
56979 THREE.ShadowMapPlugin = function ( ) {
56980
56981     var _gl,
56982     _renderer,
56983     _depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
56984
56985     _frustum = new THREE.Frustum(),
56986     _projScreenMatrix = new THREE.Matrix4(),
56987
56988     _min = new THREE.Vector3(),
56989     _max = new THREE.Vector3();
56990
56991     this.init = function ( renderer ) {
56992
56993         _gl = renderer.context;
56994         _renderer = renderer;
56995
56996         var depthShader = THREE.ShaderLib[ "depthRGBA" ];
56997         var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
56998
56999         _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
57000         _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
57001         _depthMaterialSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, skinning: true } );
57002         _depthMaterialMorphSkin = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true, skinning: true } );
57003
57004         _depthMaterial._shadowPass = true;
57005         _depthMaterialMorph._shadowPass = true;
57006         _depthMaterialSkin._shadowPass = true;
57007         _depthMaterialMorphSkin._shadowPass = true;
57008
57009     };
57010
57011     this.render = function ( scene, camera ) {
57012
57013         if ( ! ( _renderer.shadowMapEnabled && _renderer.shadowMapAutoUpdate ) ) return;
57014
57015         this.update( scene, camera );
57016
57017     };
57018
57019     this.update = function ( scene, camera ) {
57020
57021         var i, il, j, jl, n,
57022
57023         shadowMap, shadowMatrix, shadowCamera,
57024         program, buffer, material,
57025         webglObject, object, light,
57026         renderList,
57027
57028         lights = [],
57029         k = 0,
57030
57031         fog = null;
57032
57033         // set GL state for depth map
57034
57035         _gl.clearColor( 1, 1, 1, 1 );
57036         _gl.disable( _gl.BLEND );
57037
57038         _gl.enable( _gl.CULL_FACE );
57039         _gl.frontFace( _gl.CCW );
57040
57041         if ( _renderer.shadowMapCullFrontFaces ) {
57042
57043             _gl.cullFace( _gl.FRONT );
57044
57045         } else {
57046
57047             _gl.cullFace( _gl.BACK );
57048
57049         }
57050
57051         _renderer.setDepthTest( true );
57052
57053         // preprocess lights
57054         //     - skip lights that are not casting shadows
57055         //    - create virtual lights for cascaded shadow maps
57056
57057         for ( i = 0, il = scene.__lights.length; i < il; i ++ ) {
57058
57059             light = scene.__lights[ i ];
57060
57061             if ( ! light.castShadow ) continue;
57062
57063             if ( ( light instanceof THREE.DirectionalLight ) && light.shadowCascade ) {
57064
57065                 for ( n = 0; n < light.shadowCascadeCount; n ++ ) {
57066
57067                     var virtualLight;
57068
57069                     if ( ! light.shadowCascadeArray[ n ] ) {
57070
57071                         virtualLight = createVirtualLight( light, n );
57072                         virtualLight.originalCamera = camera;
57073
57074                         var gyro = new THREE.Gyroscope();
57075                         gyro.position = light.shadowCascadeOffset;
57076
57077                         gyro.add( virtualLight );
57078                         gyro.add( virtualLight.target );
57079
57080                         camera.add( gyro );
57081
57082                         light.shadowCascadeArray[ n ] = virtualLight;
57083
57084                         console.log( "Created virtualLight", virtualLight );
57085
57086                     } else {
57087
57088                         virtualLight = light.shadowCascadeArray[ n ];
57089
57090                     }
57091
57092                     updateVirtualLight( light, n );
57093
57094                     lights[ k ] = virtualLight;
57095                     k ++;
57096
57097                 }
57098
57099             } else {
57100
57101                 lights[ k ] = light;
57102                 k ++;
57103
57104             }
57105
57106         }
57107
57108         // render depth map
57109
57110         for ( i = 0, il = lights.length; i < il; i ++ ) {
57111
57112             light = lights[ i ];
57113
57114             if ( ! light.shadowMap ) {
57115
57116                 var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
57117
57118                 light.shadowMap = new THREE.WebGLRenderTarget( light.shadowMapWidth, light.shadowMapHeight, pars );
57119                 light.shadowMapSize = new THREE.Vector2( light.shadowMapWidth, light.shadowMapHeight );
57120
57121                 light.shadowMatrix = new THREE.Matrix4();
57122
57123             }
57124
57125             if ( ! light.shadowCamera ) {
57126
57127                 if ( light instanceof THREE.SpotLight ) {
57128
57129                     light.shadowCamera = new THREE.PerspectiveCamera( light.shadowCameraFov, light.shadowMapWidth / light.shadowMapHeight, light.shadowCameraNear, light.shadowCameraFar );
57130
57131                 } else if ( light instanceof THREE.DirectionalLight ) {
57132
57133                     light.shadowCamera = new THREE.OrthographicCamera( light.shadowCameraLeft, light.shadowCameraRight, light.shadowCameraTop, light.shadowCameraBottom, light.shadowCameraNear, light.shadowCameraFar );
57134
57135                 } else {
57136
57137                     console.error( "Unsupported light type for shadow" );
57138                     continue;
57139
57140                 }
57141
57142                 scene.add( light.shadowCamera );
57143
57144                 if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
57145
57146             }
57147
57148             if ( light.shadowCameraVisible && ! light.cameraHelper ) {
57149
57150                 light.cameraHelper = new THREE.CameraHelper( light.shadowCamera );
57151                 light.shadowCamera.add( light.cameraHelper );
57152
57153             }
57154
57155             if ( light.isVirtual && virtualLight.originalCamera == camera ) {
57156
57157                 updateShadowCamera( camera, light );
57158
57159             }
57160
57161             shadowMap = light.shadowMap;
57162             shadowMatrix = light.shadowMatrix;
57163             shadowCamera = light.shadowCamera;
57164
57165             shadowCamera.position.copy( light.matrixWorld.getPosition() );
57166             shadowCamera.lookAt( light.target.matrixWorld.getPosition() );
57167             shadowCamera.updateMatrixWorld();
57168
57169             shadowCamera.matrixWorldInverse.getInverse( shadowCamera.matrixWorld );
57170
57171             if ( light.cameraHelper ) light.cameraHelper.visible = light.shadowCameraVisible;
57172             if ( light.shadowCameraVisible ) light.cameraHelper.update();
57173
57174             // compute shadow matrix
57175
57176             shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
57177                               0.0, 0.5, 0.0, 0.5,
57178                               0.0, 0.0, 0.5, 0.5,
57179                               0.0, 0.0, 0.0, 1.0 );
57180
57181             shadowMatrix.multiplySelf( shadowCamera.projectionMatrix );
57182             shadowMatrix.multiplySelf( shadowCamera.matrixWorldInverse );
57183
57184             // update camera matrices and frustum
57185
57186             if ( ! shadowCamera._viewMatrixArray ) shadowCamera._viewMatrixArray = new Float32Array( 16 );
57187             if ( ! shadowCamera._projectionMatrixArray ) shadowCamera._projectionMatrixArray = new Float32Array( 16 );
57188
57189             shadowCamera.matrixWorldInverse.flattenToArray( shadowCamera._viewMatrixArray );
57190             shadowCamera.projectionMatrix.flattenToArray( shadowCamera._projectionMatrixArray );
57191
57192             _projScreenMatrix.multiply( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse );
57193             _frustum.setFromMatrix( _projScreenMatrix );
57194
57195             // render shadow map
57196
57197             _renderer.setRenderTarget( shadowMap );
57198             _renderer.clear();
57199
57200             // set object matrices & frustum culling
57201
57202             renderList = scene.__webglObjects;
57203
57204             for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57205
57206                 webglObject = renderList[ j ];
57207                 object = webglObject.object;
57208
57209                 webglObject.render = false;
57210
57211                 if ( object.visible && object.castShadow ) {
57212
57213                     if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
57214
57215                         object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
57216
57217                         webglObject.render = true;
57218
57219                     }
57220
57221                 }
57222
57223             }
57224
57225             // render regular objects
57226
57227             for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57228
57229                 webglObject = renderList[ j ];
57230
57231                 if ( webglObject.render ) {
57232
57233                     object = webglObject.object;
57234                     buffer = webglObject.buffer;
57235
57236                     // culling is overriden globally for all objects
57237                     // while rendering depth map
57238
57239                     if ( object.customDepthMaterial ) {
57240
57241                         material = object.customDepthMaterial;
57242
57243                     } else if ( object instanceof THREE.SkinnedMesh ) {
57244
57245                         material = object.geometry.morphTargets.length ? _depthMaterialMorphSkin : _depthMaterialSkin;
57246
57247                     } else if ( object.geometry.morphTargets.length ) {
57248
57249                         material = _depthMaterialMorph;
57250
57251                     } else {
57252
57253                         material = _depthMaterial;
57254
57255                     }
57256
57257                     if ( buffer instanceof THREE.BufferGeometry ) {
57258
57259                         _renderer.renderBufferDirect( shadowCamera, scene.__lights, fog, material, buffer, object );
57260
57261                     } else {
57262
57263                         _renderer.renderBuffer( shadowCamera, scene.__lights, fog, material, buffer, object );
57264
57265                     }
57266
57267                 }
57268
57269             }
57270
57271             // set matrices and render immediate objects
57272
57273             renderList = scene.__webglObjectsImmediate;
57274
57275             for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57276
57277                 webglObject = renderList[ j ];
57278                 object = webglObject.object;
57279
57280                 if ( object.visible && object.castShadow ) {
57281
57282                     object._modelViewMatrix.multiply( shadowCamera.matrixWorldInverse, object.matrixWorld );
57283
57284                     _renderer.renderImmediateObject( shadowCamera, scene.__lights, fog, _depthMaterial, object );
57285
57286                 }
57287
57288             }
57289
57290         }
57291
57292         // restore GL state
57293
57294         var clearColor = _renderer.getClearColor(),
57295         clearAlpha = _renderer.getClearAlpha();
57296
57297         _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
57298         _gl.enable( _gl.BLEND );
57299
57300         if ( _renderer.shadowMapCullFrontFaces ) {
57301
57302             _gl.cullFace( _gl.BACK );
57303
57304         }
57305
57306     };
57307
57308     function createVirtualLight( light, cascade ) {
57309
57310         var virtualLight = new THREE.DirectionalLight();
57311
57312         virtualLight.isVirtual = true;
57313
57314         virtualLight.onlyShadow = true;
57315         virtualLight.castShadow = true;
57316
57317         virtualLight.shadowCameraNear = light.shadowCameraNear;
57318         virtualLight.shadowCameraFar = light.shadowCameraFar;
57319
57320         virtualLight.shadowCameraLeft = light.shadowCameraLeft;
57321         virtualLight.shadowCameraRight = light.shadowCameraRight;
57322         virtualLight.shadowCameraBottom = light.shadowCameraBottom;
57323         virtualLight.shadowCameraTop = light.shadowCameraTop;
57324
57325         virtualLight.shadowCameraVisible = light.shadowCameraVisible;
57326
57327         virtualLight.shadowDarkness = light.shadowDarkness;
57328
57329         virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
57330         virtualLight.shadowMapWidth = light.shadowCascadeWidth[ cascade ];
57331         virtualLight.shadowMapHeight = light.shadowCascadeHeight[ cascade ];
57332
57333         virtualLight.pointsWorld = [];
57334         virtualLight.pointsFrustum = [];
57335
57336         var pointsWorld = virtualLight.pointsWorld,
57337             pointsFrustum = virtualLight.pointsFrustum;
57338
57339         for ( var i = 0; i < 8; i ++ ) {
57340
57341             pointsWorld[ i ] = new THREE.Vector3();
57342             pointsFrustum[ i ] = new THREE.Vector3();
57343
57344         }
57345
57346         var nearZ = light.shadowCascadeNearZ[ cascade ];
57347         var farZ = light.shadowCascadeFarZ[ cascade ];
57348
57349         pointsFrustum[ 0 ].set( -1, -1, nearZ );
57350         pointsFrustum[ 1 ].set(  1, -1, nearZ );
57351         pointsFrustum[ 2 ].set( -1,  1, nearZ );
57352         pointsFrustum[ 3 ].set(  1,  1, nearZ );
57353
57354         pointsFrustum[ 4 ].set( -1, -1, farZ );
57355         pointsFrustum[ 5 ].set(  1, -1, farZ );
57356         pointsFrustum[ 6 ].set( -1,  1, farZ );
57357         pointsFrustum[ 7 ].set(  1,  1, farZ );
57358
57359         return virtualLight;
57360
57361     }
57362
57363     // Synchronize virtual light with the original light
57364
57365     function updateVirtualLight( light, cascade ) {
57366
57367         var virtualLight = light.shadowCascadeArray[ cascade ];
57368
57369         virtualLight.position.copy( light.position );
57370         virtualLight.target.position.copy( light.target.position );
57371         virtualLight.lookAt( virtualLight.target );
57372
57373         virtualLight.shadowCameraVisible = light.shadowCameraVisible;
57374         virtualLight.shadowDarkness = light.shadowDarkness;
57375
57376         virtualLight.shadowBias = light.shadowCascadeBias[ cascade ];
57377
57378         var nearZ = light.shadowCascadeNearZ[ cascade ];
57379         var farZ = light.shadowCascadeFarZ[ cascade ];
57380
57381         var pointsFrustum = virtualLight.pointsFrustum;
57382
57383         pointsFrustum[ 0 ].z = nearZ;
57384         pointsFrustum[ 1 ].z = nearZ;
57385         pointsFrustum[ 2 ].z = nearZ;
57386         pointsFrustum[ 3 ].z = nearZ;
57387
57388         pointsFrustum[ 4 ].z = farZ;
57389         pointsFrustum[ 5 ].z = farZ;
57390         pointsFrustum[ 6 ].z = farZ;
57391         pointsFrustum[ 7 ].z = farZ;
57392
57393     }
57394
57395     // Fit shadow camera's ortho frustum to camera frustum
57396
57397     function updateShadowCamera( camera, light ) {
57398
57399         var shadowCamera = light.shadowCamera,
57400             pointsFrustum = light.pointsFrustum,
57401             pointsWorld = light.pointsWorld;
57402
57403         _min.set( Infinity, Infinity, Infinity );
57404         _max.set( -Infinity, -Infinity, -Infinity );
57405
57406         for ( var i = 0; i < 8; i ++ ) {
57407
57408             var p = pointsWorld[ i ];
57409
57410             p.copy( pointsFrustum[ i ] );
57411             THREE.ShadowMapPlugin.__projector.unprojectVector( p, camera );
57412
57413             shadowCamera.matrixWorldInverse.multiplyVector3( p );
57414
57415             if ( p.x < _min.x ) _min.x = p.x;
57416             if ( p.x > _max.x ) _max.x = p.x;
57417
57418             if ( p.y < _min.y ) _min.y = p.y;
57419             if ( p.y > _max.y ) _max.y = p.y;
57420
57421             if ( p.z < _min.z ) _min.z = p.z;
57422             if ( p.z > _max.z ) _max.z = p.z;
57423
57424         }
57425
57426         shadowCamera.left = _min.x;
57427         shadowCamera.right = _max.x;
57428         shadowCamera.top = _max.y;
57429         shadowCamera.bottom = _min.y;
57430
57431         // can't really fit near/far
57432         //shadowCamera.near = _min.z;
57433         //shadowCamera.far = _max.z;
57434
57435         shadowCamera.updateProjectionMatrix();
57436
57437     }
57438
57439 };
57440
57441 THREE.ShadowMapPlugin.__projector = new THREE.Projector();
57442 /**
57443  * @author mikael emtinger / http://gomo.se/
57444  * @author alteredq / http://alteredqualia.com/
57445  */
57446
57447 THREE.SpritePlugin = function ( ) {
57448
57449     var _gl, _renderer, _sprite = {};
57450
57451     this.init = function ( renderer ) {
57452
57453         _gl = renderer.context;
57454         _renderer = renderer;
57455
57456         _sprite.vertices = new Float32Array( 8 + 8 );
57457         _sprite.faces    = new Uint16Array( 6 );
57458
57459         var i = 0;
57460
57461         _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = -1;    // vertex 0
57462         _sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 0;    // uv 0
57463
57464         _sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = -1;    // vertex 1
57465         _sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 0;    // uv 1
57466
57467         _sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 1;    // vertex 2
57468         _sprite.vertices[ i++ ] = 1;  _sprite.vertices[ i++ ] = 1;    // uv 2
57469
57470         _sprite.vertices[ i++ ] = -1; _sprite.vertices[ i++ ] = 1;    // vertex 3
57471         _sprite.vertices[ i++ ] = 0;  _sprite.vertices[ i++ ] = 1;    // uv 3
57472
57473         i = 0;
57474
57475         _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 1; _sprite.faces[ i++ ] = 2;
57476         _sprite.faces[ i++ ] = 0; _sprite.faces[ i++ ] = 2; _sprite.faces[ i++ ] = 3;
57477
57478         _sprite.vertexBuffer  = _gl.createBuffer();
57479         _sprite.elementBuffer = _gl.createBuffer();
57480
57481         _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
57482         _gl.bufferData( _gl.ARRAY_BUFFER, _sprite.vertices, _gl.STATIC_DRAW );
57483
57484         _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
57485         _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _sprite.faces, _gl.STATIC_DRAW );
57486
57487         _sprite.program = createProgram( THREE.ShaderSprite[ "sprite" ] );
57488
57489         _sprite.attributes = {};
57490         _sprite.uniforms = {};
57491
57492         _sprite.attributes.position           = _gl.getAttribLocation ( _sprite.program, "position" );
57493         _sprite.attributes.uv                 = _gl.getAttribLocation ( _sprite.program, "uv" );
57494
57495         _sprite.uniforms.uvOffset             = _gl.getUniformLocation( _sprite.program, "uvOffset" );
57496         _sprite.uniforms.uvScale              = _gl.getUniformLocation( _sprite.program, "uvScale" );
57497
57498         _sprite.uniforms.rotation             = _gl.getUniformLocation( _sprite.program, "rotation" );
57499         _sprite.uniforms.scale                = _gl.getUniformLocation( _sprite.program, "scale" );
57500         _sprite.uniforms.alignment            = _gl.getUniformLocation( _sprite.program, "alignment" );
57501
57502         _sprite.uniforms.color                = _gl.getUniformLocation( _sprite.program, "color" );
57503         _sprite.uniforms.map                  = _gl.getUniformLocation( _sprite.program, "map" );
57504         _sprite.uniforms.opacity              = _gl.getUniformLocation( _sprite.program, "opacity" );
57505
57506         _sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" );
57507         _sprite.uniforms.affectedByDistance   = _gl.getUniformLocation( _sprite.program, "affectedByDistance" );
57508         _sprite.uniforms.screenPosition          = _gl.getUniformLocation( _sprite.program, "screenPosition" );
57509         _sprite.uniforms.modelViewMatrix      = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" );
57510         _sprite.uniforms.projectionMatrix     = _gl.getUniformLocation( _sprite.program, "projectionMatrix" );
57511
57512         _sprite.attributesEnabled = false;
57513
57514     };
57515
57516     this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
57517
57518         var sprites = scene.__webglSprites,
57519             nSprites = sprites.length;
57520
57521         if ( ! nSprites ) return;
57522
57523         var attributes = _sprite.attributes,
57524             uniforms = _sprite.uniforms;
57525
57526         var invAspect = viewportHeight / viewportWidth;
57527
57528         var halfViewportWidth = viewportWidth * 0.5,
57529             halfViewportHeight = viewportHeight * 0.5;
57530
57531         var mergeWith3D = true;
57532
57533         // setup gl
57534
57535         _gl.useProgram( _sprite.program );
57536
57537         if ( ! _sprite.attributesEnabled ) {
57538
57539             _gl.enableVertexAttribArray( attributes.position );
57540             _gl.enableVertexAttribArray( attributes.uv );
57541
57542             _sprite.attributesEnabled = true;
57543
57544         }
57545
57546         _gl.disable( _gl.CULL_FACE );
57547         _gl.enable( _gl.BLEND );
57548         _gl.depthMask( true );
57549
57550         _gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
57551         _gl.vertexAttribPointer( attributes.position, 2, _gl.FLOAT, false, 2 * 8, 0 );
57552         _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
57553
57554         _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
57555
57556         _gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera._projectionMatrixArray );
57557
57558         _gl.activeTexture( _gl.TEXTURE0 );
57559         _gl.uniform1i( uniforms.map, 0 );
57560
57561         // update positions and sort
57562
57563         var i, sprite, screenPosition, size, scale = [];
57564
57565         for( i = 0; i < nSprites; i ++ ) {
57566
57567             sprite = sprites[ i ];
57568
57569             if ( ! sprite.visible || sprite.opacity === 0 ) continue;
57570
57571             if( ! sprite.useScreenCoordinates ) {
57572
57573                 sprite._modelViewMatrix.multiply( camera.matrixWorldInverse, sprite.matrixWorld );
57574                 sprite.z = - sprite._modelViewMatrix.elements[14];
57575
57576             } else {
57577
57578                 sprite.z = - sprite.position.z;
57579
57580             }
57581
57582         }
57583
57584         sprites.sort( painterSort );
57585
57586         // render all sprites
57587
57588         for( i = 0; i < nSprites; i ++ ) {
57589
57590             sprite = sprites[ i ];
57591
57592             if ( ! sprite.visible || sprite.opacity === 0 ) continue;
57593
57594             if ( sprite.map && sprite.map.image && sprite.map.image.width ) {
57595
57596                 if ( sprite.useScreenCoordinates ) {
57597
57598                     _gl.uniform1i( uniforms.useScreenCoordinates, 1 );
57599                     _gl.uniform3f( uniforms.screenPosition, ( sprite.position.x - halfViewportWidth  ) / halfViewportWidth,
57600                                                             ( halfViewportHeight - sprite.position.y ) / halfViewportHeight,
57601                                                               Math.max( 0, Math.min( 1, sprite.position.z ) ) );
57602
57603                 } else {
57604
57605                     _gl.uniform1i( uniforms.useScreenCoordinates, 0 );
57606                     _gl.uniform1i( uniforms.affectedByDistance, sprite.affectedByDistance ? 1 : 0 );
57607                     _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite._modelViewMatrix.elements );
57608
57609                 }
57610
57611                 size = sprite.map.image.width / ( sprite.scaleByViewport ? viewportHeight : 1 );
57612
57613                 scale[ 0 ] = size * invAspect * sprite.scale.x;
57614                 scale[ 1 ] = size * sprite.scale.y;
57615
57616                 _gl.uniform2f( uniforms.uvScale, sprite.uvScale.x, sprite.uvScale.y );
57617                 _gl.uniform2f( uniforms.uvOffset, sprite.uvOffset.x, sprite.uvOffset.y );
57618                 _gl.uniform2f( uniforms.alignment, sprite.alignment.x, sprite.alignment.y );
57619
57620                 _gl.uniform1f( uniforms.opacity, sprite.opacity );
57621                 _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
57622
57623                 _gl.uniform1f( uniforms.rotation, sprite.rotation );
57624                 _gl.uniform2fv( uniforms.scale, scale );
57625
57626                 if ( sprite.mergeWith3D && !mergeWith3D ) {
57627
57628                     _gl.enable( _gl.DEPTH_TEST );
57629                     mergeWith3D = true;
57630
57631                 } else if ( ! sprite.mergeWith3D && mergeWith3D ) {
57632
57633                     _gl.disable( _gl.DEPTH_TEST );
57634                     mergeWith3D = false;
57635
57636                 }
57637
57638                 _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
57639                 _renderer.setTexture( sprite.map, 0 );
57640
57641                 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
57642
57643             }
57644
57645         }
57646
57647         // restore gl
57648
57649         _gl.enable( _gl.CULL_FACE );
57650         _gl.enable( _gl.DEPTH_TEST );
57651         _gl.depthMask( true );
57652
57653     };
57654
57655     function createProgram ( shader ) {
57656
57657         var program = _gl.createProgram();
57658
57659         var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
57660         var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
57661
57662         _gl.shaderSource( fragmentShader, shader.fragmentShader );
57663         _gl.shaderSource( vertexShader, shader.vertexShader );
57664
57665         _gl.compileShader( fragmentShader );
57666         _gl.compileShader( vertexShader );
57667
57668         _gl.attachShader( program, fragmentShader );
57669         _gl.attachShader( program, vertexShader );
57670
57671         _gl.linkProgram( program );
57672
57673         return program;
57674
57675     };
57676
57677     function painterSort ( a, b ) {
57678
57679         return b.z - a.z;
57680
57681     };
57682
57683 };/**
57684  * @author alteredq / http://alteredqualia.com/
57685  */
57686
57687 THREE.DepthPassPlugin = function ( ) {
57688
57689     this.enabled = false;
57690     this.renderTarget = null;
57691
57692     var _gl,
57693     _renderer,
57694     _depthMaterial, _depthMaterialMorph,
57695
57696     _frustum = new THREE.Frustum(),
57697     _projScreenMatrix = new THREE.Matrix4();
57698
57699     this.init = function ( renderer ) {
57700
57701         _gl = renderer.context;
57702         _renderer = renderer;
57703
57704         var depthShader = THREE.ShaderLib[ "depthRGBA" ];
57705         var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
57706
57707         _depthMaterial = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms } );
57708         _depthMaterialMorph = new THREE.ShaderMaterial( { fragmentShader: depthShader.fragmentShader, vertexShader: depthShader.vertexShader, uniforms: depthUniforms, morphTargets: true } );
57709
57710         _depthMaterial._shadowPass = true;
57711         _depthMaterialMorph._shadowPass = true;
57712
57713     };
57714
57715     this.render = function ( scene, camera ) {
57716
57717         if ( ! this.enabled ) return;
57718
57719         this.update( scene, camera );
57720
57721     };
57722
57723     this.update = function ( scene, camera ) {
57724
57725         var i, il, j, jl, n,
57726
57727         program, buffer, material,
57728         webglObject, object, light,
57729         renderList,
57730
57731         fog = null;
57732
57733         // set GL state for depth map
57734
57735         _gl.clearColor( 1, 1, 1, 1 );
57736         _gl.disable( _gl.BLEND );
57737
57738         _renderer.setDepthTest( true );
57739
57740         // update scene
57741
57742         if ( _renderer.autoUpdateScene ) scene.updateMatrixWorld();
57743
57744         // update camera matrices and frustum
57745
57746         if ( ! camera._viewMatrixArray ) camera._viewMatrixArray = new Float32Array( 16 );
57747         if ( ! camera._projectionMatrixArray ) camera._projectionMatrixArray = new Float32Array( 16 );
57748
57749         camera.matrixWorldInverse.getInverse( camera.matrixWorld );
57750
57751         camera.matrixWorldInverse.flattenToArray( camera._viewMatrixArray );
57752         camera.projectionMatrix.flattenToArray( camera._projectionMatrixArray );
57753
57754         _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
57755         _frustum.setFromMatrix( _projScreenMatrix );
57756
57757         // render depth map
57758
57759         _renderer.setRenderTarget( this.renderTarget );
57760         _renderer.clear();
57761
57762         // set object matrices & frustum culling
57763
57764         renderList = scene.__webglObjects;
57765
57766         for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57767
57768             webglObject = renderList[ j ];
57769             object = webglObject.object;
57770
57771             webglObject.render = false;
57772
57773             if ( object.visible ) {
57774
57775                 if ( ! ( object instanceof THREE.Mesh ) || ! ( object.frustumCulled ) || _frustum.contains( object ) ) {
57776
57777                     //object.matrixWorld.flattenToArray( object._modelMatrixArray );
57778                     object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
57779
57780                     webglObject.render = true;
57781
57782                 }
57783
57784             }
57785
57786         }
57787
57788         // render regular objects
57789
57790         for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57791
57792             webglObject = renderList[ j ];
57793
57794             if ( webglObject.render ) {
57795
57796                 object = webglObject.object;
57797                 buffer = webglObject.buffer;
57798
57799                 if ( object.material ) _renderer.setMaterialFaces( object.material );
57800
57801                 if ( object.customDepthMaterial ) {
57802
57803                     material = object.customDepthMaterial;
57804
57805                 } else if ( object.geometry.morphTargets.length ) {
57806
57807                     material = _depthMaterialMorph;
57808
57809                 } else {
57810
57811                     material = _depthMaterial;
57812
57813                 }
57814
57815                 if ( buffer instanceof THREE.BufferGeometry ) {
57816
57817                     _renderer.renderBufferDirect( camera, scene.__lights, fog, material, buffer, object );
57818
57819                 } else {
57820
57821                     _renderer.renderBuffer( camera, scene.__lights, fog, material, buffer, object );
57822
57823                 }
57824
57825             }
57826
57827         }
57828
57829         // set matrices and render immediate objects
57830
57831         renderList = scene.__webglObjectsImmediate;
57832
57833         for ( j = 0, jl = renderList.length; j < jl; j ++ ) {
57834
57835             webglObject = renderList[ j ];
57836             object = webglObject.object;
57837
57838             if ( object.visible && object.castShadow ) {
57839
57840                 /*
57841                 if ( object.matrixAutoUpdate ) {
57842
57843                     object.matrixWorld.flattenToArray( object._modelMatrixArray );
57844
57845                 }
57846                 */
57847
57848                 object._modelViewMatrix.multiply( camera.matrixWorldInverse, object.matrixWorld);
57849
57850                 _renderer.renderImmediateObject( camera, scene.__lights, fog, _depthMaterial, object );
57851
57852             }
57853
57854         }
57855
57856         // restore GL state
57857
57858         var clearColor = _renderer.getClearColor(),
57859         clearAlpha = _renderer.getClearAlpha();
57860
57861         _gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
57862         _gl.enable( _gl.BLEND );
57863
57864     };
57865
57866 };
57867
57868 /**
57869  * @author mikael emtinger / http://gomo.se/
57870  *
57871  */
57872
57873 THREE.ShaderFlares = {
57874
57875     'lensFlareVertexTexture': {
57876
57877         vertexShader: [
57878
57879             "uniform vec3 screenPosition;",
57880             "uniform vec2 scale;",
57881             "uniform float rotation;",
57882             "uniform int renderType;",
57883
57884             "uniform sampler2D occlusionMap;",
57885
57886             "attribute vec2 position;",
57887             "attribute vec2 uv;",
57888
57889             "varying vec2 vUV;",
57890             "varying float vVisibility;",
57891
57892             "void main() {",
57893
57894                 "vUV = uv;",
57895
57896                 "vec2 pos = position;",
57897
57898                 "if( renderType == 2 ) {",
57899
57900                     "vec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) ) +",
57901                                       "texture2D( occlusionMap, vec2( 0.5, 0.1 ) ) +",
57902                                       "texture2D( occlusionMap, vec2( 0.9, 0.1 ) ) +",
57903                                       "texture2D( occlusionMap, vec2( 0.9, 0.5 ) ) +",
57904                                       "texture2D( occlusionMap, vec2( 0.9, 0.9 ) ) +",
57905                                       "texture2D( occlusionMap, vec2( 0.5, 0.9 ) ) +",
57906                                       "texture2D( occlusionMap, vec2( 0.1, 0.9 ) ) +",
57907                                       "texture2D( occlusionMap, vec2( 0.1, 0.5 ) ) +",
57908                                       "texture2D( occlusionMap, vec2( 0.5, 0.5 ) );",
57909
57910                     "vVisibility = (       visibility.r / 9.0 ) *",
57911                                   "( 1.0 - visibility.g / 9.0 ) *",
57912                                   "(       visibility.b / 9.0 ) *",
57913                                   "( 1.0 - visibility.a / 9.0 );",
57914
57915                     "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
57916                     "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
57917
57918                 "}",
57919
57920                 "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
57921
57922             "}"
57923
57924         ].join( "\n" ),
57925
57926         fragmentShader: [
57927
57928             "precision mediump float;",
57929
57930             "uniform sampler2D map;",
57931             "uniform float opacity;",
57932             "uniform int renderType;",
57933             "uniform vec3 color;",
57934
57935             "varying vec2 vUV;",
57936             "varying float vVisibility;",
57937
57938             "void main() {",
57939
57940                 // pink square
57941
57942                 "if( renderType == 0 ) {",
57943
57944                     "gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
57945
57946                 // restore
57947
57948                 "} else if( renderType == 1 ) {",
57949
57950                     "gl_FragColor = texture2D( map, vUV );",
57951
57952                 // flare
57953
57954                 "} else {",
57955
57956                     "vec4 texture = texture2D( map, vUV );",
57957                     "texture.a *= opacity * vVisibility;",
57958                     "gl_FragColor = texture;",
57959                     "gl_FragColor.rgb *= color;",
57960
57961                 "}",
57962
57963             "}"
57964         ].join( "\n" )
57965
57966     },
57967
57968
57969     'lensFlare': {
57970
57971         vertexShader: [
57972
57973             "uniform vec3 screenPosition;",
57974             "uniform vec2 scale;",
57975             "uniform float rotation;",
57976             "uniform int renderType;",
57977
57978             "attribute vec2 position;",
57979             "attribute vec2 uv;",
57980
57981             "varying vec2 vUV;",
57982
57983             "void main() {",
57984
57985                 "vUV = uv;",
57986
57987                 "vec2 pos = position;",
57988
57989                 "if( renderType == 2 ) {",
57990
57991                     "pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
57992                     "pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
57993
57994                 "}",
57995
57996                 "gl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
57997
57998             "}"
57999
58000         ].join( "\n" ),
58001
58002         fragmentShader: [
58003
58004             "precision mediump float;",
58005
58006             "uniform sampler2D map;",
58007             "uniform sampler2D occlusionMap;",
58008             "uniform float opacity;",
58009             "uniform int renderType;",
58010             "uniform vec3 color;",
58011
58012             "varying vec2 vUV;",
58013
58014             "void main() {",
58015
58016                 // pink square
58017
58018                 "if( renderType == 0 ) {",
58019
58020                     "gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );",
58021
58022                 // restore
58023
58024                 "} else if( renderType == 1 ) {",
58025
58026                     "gl_FragColor = texture2D( map, vUV );",
58027
58028                 // flare
58029
58030                 "} else {",
58031
58032                     "float visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a +",
58033                                        "texture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a +",
58034                                        "texture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a +",
58035                                        "texture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;",
58036
58037                     "visibility = ( 1.0 - visibility / 4.0 );",
58038
58039                     "vec4 texture = texture2D( map, vUV );",
58040                     "texture.a *= opacity * visibility;",
58041                     "gl_FragColor = texture;",
58042                     "gl_FragColor.rgb *= color;",
58043
58044                 "}",
58045
58046             "}"
58047
58048         ].join( "\n" )
58049
58050     }
58051
58052 };
58053 /**
58054  * @author mikael emtinger / http://gomo.se/
58055  *
58056  */
58057
58058 THREE.ShaderSprite = {
58059
58060     'sprite': {
58061
58062         vertexShader: [
58063
58064             "uniform int useScreenCoordinates;",
58065             "uniform int affectedByDistance;",
58066             "uniform vec3 screenPosition;",
58067             "uniform mat4 modelViewMatrix;",
58068             "uniform mat4 projectionMatrix;",
58069             "uniform float rotation;",
58070             "uniform vec2 scale;",
58071             "uniform vec2 alignment;",
58072             "uniform vec2 uvOffset;",
58073             "uniform vec2 uvScale;",
58074
58075             "attribute vec2 position;",
58076             "attribute vec2 uv;",
58077
58078             "varying vec2 vUV;",
58079
58080             "void main() {",
58081
58082                 "vUV = uvOffset + uv * uvScale;",
58083
58084                 "vec2 alignedPosition = position + alignment;",
58085
58086                 "vec2 rotatedPosition;",
58087                 "rotatedPosition.x = ( cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y ) * scale.x;",
58088                 "rotatedPosition.y = ( sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y ) * scale.y;",
58089
58090                 "vec4 finalPosition;",
58091
58092                 "if( useScreenCoordinates != 0 ) {",
58093
58094                     "finalPosition = vec4( screenPosition.xy + rotatedPosition, screenPosition.z, 1.0 );",
58095
58096                 "} else {",
58097
58098                     "finalPosition = projectionMatrix * modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );",
58099                     "finalPosition.xy += rotatedPosition * ( affectedByDistance == 1 ? 1.0 : finalPosition.z );",
58100
58101                 "}",
58102
58103                 "gl_Position = finalPosition;",
58104
58105             "}"
58106
58107         ].join( "\n" ),
58108
58109         fragmentShader: [
58110
58111             "precision mediump float;",
58112
58113             "uniform vec3 color;",
58114             "uniform sampler2D map;",
58115             "uniform float opacity;",
58116
58117             "varying vec2 vUV;",
58118
58119             "void main() {",
58120
58121                 "vec4 texture = texture2D( map, vUV );",
58122                 "gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );",
58123
58124             "}"
58125
58126         ].join( "\n" )
58127
58128     }
58129
58130 };
58131 /**
58132  * @author alteredq / http://alteredqualia.com/
58133  *
58134  */
58135
58136
58137 THREE.ShaderSkin = {
58138
58139     /* ------------------------------------------------------------------------------------------
58140     //    Simple skin shader
58141     //        - per-pixel Blinn-Phong diffuse term mixed with half-Lambert wrap-around term (per color component)
58142     //        - physically based specular term (Kelemen/Szirmay-Kalos specular reflectance)
58143     //
58144     //        - diffuse map
58145     //        - bump map
58146     //        - specular map
58147     //        - point, directional and hemisphere lights (use with "lights: true" material option)
58148     //        - fog (use with "fog: true" material option)
58149     //        - shadow maps
58150     //
58151     // ------------------------------------------------------------------------------------------ */
58152
58153     'skinSimple' : {
58154
58155         uniforms: THREE.UniformsUtils.merge( [
58156
58157             THREE.UniformsLib[ "fog" ],
58158             THREE.UniformsLib[ "lights" ],
58159             THREE.UniformsLib[ "shadowmap" ],
58160
58161             {
58162
58163             "enableBump"    : { type: "i", value: 0 },
58164             "enableSpecular": { type: "i", value: 0 },
58165
58166             "tDiffuse"    : { type: "t", value: null },
58167             "tBeckmann"    : { type: "t", value: null },
58168
58169             "uDiffuseColor":  { type: "c", value: new THREE.Color( 0xeeeeee ) },
58170             "uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
58171             "uAmbientColor":  { type: "c", value: new THREE.Color( 0x050505 ) },
58172             "uOpacity":       { type: "f", value: 1 },
58173
58174             "uRoughness":               { type: "f", value: 0.15 },
58175             "uSpecularBrightness":     { type: "f", value: 0.75 },
58176
58177             "bumpMap"    : { type: "t", value: null },
58178             "bumpScale" : { type: "f", value: 1 },
58179
58180             "specularMap" : { type: "t", value: null },
58181
58182             "offsetRepeat" : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
58183
58184             "uWrapRGB":    { type: "v3", value: new THREE.Vector3( 0.75, 0.375, 0.1875 ) }
58185
58186             }
58187
58188         ] ),
58189
58190         fragmentShader: [
58191
58192             "#define USE_BUMPMAP",
58193             "#extension GL_OES_standard_derivatives : enable",
58194
58195             "uniform bool enableBump;",
58196             "uniform bool enableSpecular;",
58197
58198             "uniform vec3 uAmbientColor;",
58199             "uniform vec3 uDiffuseColor;",
58200             "uniform vec3 uSpecularColor;",
58201             "uniform float uOpacity;",
58202
58203             "uniform float uRoughness;",
58204             "uniform float uSpecularBrightness;",
58205
58206             "uniform vec3 uWrapRGB;",
58207
58208             "uniform sampler2D tDiffuse;",
58209             "uniform sampler2D tBeckmann;",
58210
58211             "uniform sampler2D specularMap;",
58212
58213             "varying vec3 vNormal;",
58214             "varying vec2 vUv;",
58215
58216             "uniform vec3 ambientLightColor;",
58217
58218             "#if MAX_DIR_LIGHTS > 0",
58219
58220                 "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
58221                 "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
58222
58223             "#endif",
58224
58225             "#if MAX_HEMI_LIGHTS > 0",
58226
58227                 "uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ];",
58228                 "uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ];",
58229                 "uniform vec3 hemisphereLightPosition[ MAX_HEMI_LIGHTS ];",
58230
58231             "#endif",
58232
58233             "#if MAX_POINT_LIGHTS > 0",
58234
58235                 "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
58236                 "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
58237                 "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
58238
58239             "#endif",
58240
58241             "varying vec3 vViewPosition;",
58242
58243             THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
58244             THREE.ShaderChunk[ "fog_pars_fragment" ],
58245             THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
58246
58247             // Fresnel term
58248
58249             "float fresnelReflectance( vec3 H, vec3 V, float F0 ) {",
58250
58251                 "float base = 1.0 - dot( V, H );",
58252                 "float exponential = pow( base, 5.0 );",
58253
58254                 "return exponential + F0 * ( 1.0 - exponential );",
58255
58256             "}",
58257
58258             // Kelemen/Szirmay-Kalos specular BRDF
58259
58260             "float KS_Skin_Specular( vec3 N,",         // Bumped surface normal
58261                                     "vec3 L,",         // Points to light
58262                                     "vec3 V,",         // Points to eye
58263                                     "float m,",      // Roughness
58264                                     "float rho_s",     // Specular brightness
58265                                     ") {",
58266
58267                 "float result = 0.0;",
58268                 "float ndotl = dot( N, L );",
58269
58270                 "if( ndotl > 0.0 ) {",
58271
58272                     "vec3 h = L + V;", // Unnormalized half-way vector
58273                     "vec3 H = normalize( h );",
58274
58275                     "float ndoth = dot( N, H );",
58276
58277                     "float PH = pow( 2.0 * texture2D( tBeckmann, vec2( ndoth, m ) ).x, 10.0 );",
58278
58279                     "float F = fresnelReflectance( H, V, 0.028 );",
58280                     "float frSpec = max( PH * F / dot( h, h ), 0.0 );",
58281
58282                     "result = ndotl * rho_s * frSpec;", // BRDF * dot(N,L) * rho_s
58283
58284                 "}",
58285
58286                 "return result;",
58287
58288             "}",
58289
58290             "void main() {",
58291
58292                 "gl_FragColor = vec4( vec3( 1.0 ), uOpacity );",
58293
58294                 "vec4 colDiffuse = texture2D( tDiffuse, vUv );",
58295                 "colDiffuse.rgb *= colDiffuse.rgb;",
58296
58297                 "gl_FragColor = gl_FragColor * colDiffuse;",
58298
58299                 "vec3 normal = normalize( vNormal );",
58300                 "vec3 viewPosition = normalize( vViewPosition );",
58301
58302                 "float specularStrength;",
58303
58304                 "if ( enableSpecular ) {",
58305
58306                     "vec4 texelSpecular = texture2D( specularMap, vUv );",
58307                     "specularStrength = texelSpecular.r;",
58308
58309                 "} else {",
58310
58311                     "specularStrength = 1.0;",
58312
58313                 "}",
58314
58315                 "#ifdef USE_BUMPMAP",
58316
58317                     "if ( enableBump ) normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );",
58318
58319                 "#endif",
58320
58321                 // point lights
58322
58323                 "vec3 specularTotal = vec3( 0.0 );",
58324
58325                 "#if MAX_POINT_LIGHTS > 0",
58326
58327                     "vec3 pointTotal = vec3( 0.0 );",
58328
58329                     "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
58330
58331                         "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
58332
58333                         "vec3 lVector = lPosition.xyz + vViewPosition.xyz;",
58334
58335                         "float lDistance = 1.0;",
58336
58337                         "if ( pointLightDistance[ i ] > 0.0 )",
58338                             "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
58339
58340                         "lVector = normalize( lVector );",
58341
58342                         "float pointDiffuseWeightFull = max( dot( normal, lVector ), 0.0 );",
58343                         "float pointDiffuseWeightHalf = max( 0.5 * dot( normal, lVector ) + 0.5, 0.0 );",
58344                         "vec3 pointDiffuseWeight = mix( vec3 ( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), uWrapRGB );",
58345
58346                         "float pointSpecularWeight = KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
58347
58348                         "pointTotal    += lDistance * uDiffuseColor * pointLightColor[ i ] * pointDiffuseWeight;",
58349                         "specularTotal += lDistance * uSpecularColor * pointLightColor[ i ] * pointSpecularWeight * specularStrength;",
58350
58351                     "}",
58352
58353                 "#endif",
58354
58355                 // directional lights
58356
58357                 "#if MAX_DIR_LIGHTS > 0",
58358
58359                     "vec3 dirTotal = vec3( 0.0 );",
58360
58361                     "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
58362
58363                         "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
58364
58365                         "vec3 dirVector = normalize( lDirection.xyz );",
58366
58367                         "float dirDiffuseWeightFull = max( dot( normal, dirVector ), 0.0 );",
58368                         "float dirDiffuseWeightHalf = max( 0.5 * dot( normal, dirVector ) + 0.5, 0.0 );",
58369                         "vec3 dirDiffuseWeight = mix( vec3 ( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), uWrapRGB );",
58370
58371                         "float dirSpecularWeight =  KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
58372
58373                         "dirTotal        += uDiffuseColor * directionalLightColor[ i ] * dirDiffuseWeight;",
58374                         "specularTotal += uSpecularColor * directionalLightColor[ i ] * dirSpecularWeight * specularStrength;",
58375
58376                     "}",
58377
58378                 "#endif",
58379
58380                 // hemisphere lights
58381
58382                 "#if MAX_HEMI_LIGHTS > 0",
58383
58384                     "vec3 hemiTotal = vec3( 0.0 );",
58385
58386                     "for ( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) {",
58387
58388                         "vec4 lPosition = viewMatrix * vec4( hemisphereLightPosition[ i ], 1.0 );",
58389                         "vec3 lVector = normalize( lPosition.xyz + vViewPosition.xyz );",
58390
58391                         "float dotProduct = dot( normal, lVector );",
58392                         "float hemiDiffuseWeight = 0.5 * dotProduct + 0.5;",
58393
58394                         "hemiTotal += uDiffuseColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight );",
58395
58396                         // specular (sky light)
58397
58398                         "float hemiSpecularWeight = 0.0;",
58399                         "hemiSpecularWeight += KS_Skin_Specular( normal, lVector, viewPosition, uRoughness, uSpecularBrightness );",
58400
58401                         // specular (ground light)
58402
58403                         "vec3 lVectorGround = normalize( -lPosition.xyz + vViewPosition.xyz );",
58404                         "hemiSpecularWeight += KS_Skin_Specular( normal, lVectorGround, viewPosition, uRoughness, uSpecularBrightness );",
58405
58406                         "specularTotal += uSpecularColor * mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ) * hemiSpecularWeight * specularStrength;",
58407
58408                     "}",
58409
58410                 "#endif",
58411
58412                 // all lights contribution summation
58413
58414                 "vec3 totalLight = vec3( 0.0 );",
58415
58416                 "#if MAX_DIR_LIGHTS > 0",
58417                     "totalLight += dirTotal;",
58418                 "#endif",
58419
58420                 "#if MAX_POINT_LIGHTS > 0",
58421                     "totalLight += pointTotal;",
58422                 "#endif",
58423
58424                 "#if MAX_HEMI_LIGHTS > 0",
58425                     "totalLight += hemiTotal;",
58426                 "#endif",
58427
58428                 "gl_FragColor.xyz = gl_FragColor.xyz * ( totalLight + ambientLightColor * uAmbientColor ) + specularTotal;",
58429
58430                 THREE.ShaderChunk[ "shadowmap_fragment" ],
58431                 THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
58432                 THREE.ShaderChunk[ "fog_fragment" ],
58433
58434             "}"
58435
58436         ].join("\n"),
58437
58438         vertexShader: [
58439
58440             "uniform vec4 offsetRepeat;",
58441
58442             "varying vec3 vNormal;",
58443             "varying vec2 vUv;",
58444
58445             "varying vec3 vViewPosition;",
58446
58447             THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
58448
58449             "void main() {",
58450
58451                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
58452                 "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
58453
58454                 "vViewPosition = -mvPosition.xyz;",
58455
58456                 "vNormal = normalMatrix * normal;",
58457
58458                 "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;",
58459
58460                 "gl_Position = projectionMatrix * mvPosition;",
58461
58462                 THREE.ShaderChunk[ "shadowmap_vertex" ],
58463
58464             "}"
58465
58466         ].join( "\n" )
58467
58468     },
58469
58470     /* ------------------------------------------------------------------------------------------
58471     //    Skin shader
58472     //        - Blinn-Phong diffuse term (using normal + diffuse maps)
58473     //        - subsurface scattering approximation by four blur layers
58474     //        - physically based specular term (Kelemen/Szirmay-Kalos specular reflectance)
58475     //
58476     //        - point and directional lights (use with "lights: true" material option)
58477     //
58478     //        - based on Nvidia Advanced Skin Rendering GDC 2007 presentation
58479     //          and GPU Gems 3 Chapter 14. Advanced Techniques for Realistic Real-Time Skin Rendering
58480     //
58481     //            http://developer.download.nvidia.com/presentations/2007/gdc/Advanced_Skin.pdf
58482     //            http://http.developer.nvidia.com/GPUGems3/gpugems3_ch14.html
58483     // ------------------------------------------------------------------------------------------ */
58484
58485     'skin' : {
58486
58487         uniforms: THREE.UniformsUtils.merge( [
58488
58489             THREE.UniformsLib[ "fog" ],
58490             THREE.UniformsLib[ "lights" ],
58491
58492             {
58493
58494             "passID": { type: "i", value: 0 },
58495
58496             "tDiffuse"    : { type: "t", value: null },
58497             "tNormal"    : { type: "t", value: null },
58498
58499             "tBlur1"    : { type: "t", value: null },
58500             "tBlur2"    : { type: "t", value: null },
58501             "tBlur3"    : { type: "t", value: null },
58502             "tBlur4"    : { type: "t", value: null },
58503
58504             "tBeckmann"    : { type: "t", value: null },
58505
58506             "uNormalScale": { type: "f", value: 1.0 },
58507
58508             "uDiffuseColor":  { type: "c", value: new THREE.Color( 0xeeeeee ) },
58509             "uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
58510             "uAmbientColor":  { type: "c", value: new THREE.Color( 0x050505 ) },
58511             "uOpacity":       { type: "f", value: 1 },
58512
58513             "uRoughness":               { type: "f", value: 0.15 },
58514             "uSpecularBrightness":     { type: "f", value: 0.75 }
58515
58516             }
58517
58518         ] ),
58519
58520         fragmentShader: [
58521
58522             "uniform vec3 uAmbientColor;",
58523             "uniform vec3 uDiffuseColor;",
58524             "uniform vec3 uSpecularColor;",
58525             "uniform float uOpacity;",
58526
58527             "uniform float uRoughness;",
58528             "uniform float uSpecularBrightness;",
58529
58530             "uniform int passID;",
58531
58532             "uniform sampler2D tDiffuse;",
58533             "uniform sampler2D tNormal;",
58534
58535             "uniform sampler2D tBlur1;",
58536             "uniform sampler2D tBlur2;",
58537             "uniform sampler2D tBlur3;",
58538             "uniform sampler2D tBlur4;",
58539
58540             "uniform sampler2D tBeckmann;",
58541
58542             "uniform float uNormalScale;",
58543
58544             "varying vec3 vTangent;",
58545             "varying vec3 vBinormal;",
58546             "varying vec3 vNormal;",
58547             "varying vec2 vUv;",
58548
58549             "uniform vec3 ambientLightColor;",
58550
58551             "#if MAX_DIR_LIGHTS > 0",
58552                 "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
58553                 "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
58554             "#endif",
58555
58556             "#if MAX_POINT_LIGHTS > 0",
58557                 "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
58558                 "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
58559             "#endif",
58560
58561             "varying vec3 vViewPosition;",
58562
58563             THREE.ShaderChunk[ "fog_pars_fragment" ],
58564
58565             "float fresnelReflectance( vec3 H, vec3 V, float F0 ) {",
58566
58567                 "float base = 1.0 - dot( V, H );",
58568                 "float exponential = pow( base, 5.0 );",
58569
58570                 "return exponential + F0 * ( 1.0 - exponential );",
58571
58572             "}",
58573
58574             // Kelemen/Szirmay-Kalos specular BRDF
58575
58576             "float KS_Skin_Specular( vec3 N,",         // Bumped surface normal
58577                                     "vec3 L,",         // Points to light
58578                                     "vec3 V,",         // Points to eye
58579                                     "float m,",      // Roughness
58580                                     "float rho_s",     // Specular brightness
58581                                     ") {",
58582
58583                 "float result = 0.0;",
58584                 "float ndotl = dot( N, L );",
58585
58586                 "if( ndotl > 0.0 ) {",
58587
58588                     "vec3 h = L + V;", // Unnormalized half-way vector
58589                     "vec3 H = normalize( h );",
58590
58591                     "float ndoth = dot( N, H );",
58592
58593                     "float PH = pow( 2.0 * texture2D( tBeckmann, vec2( ndoth, m ) ).x, 10.0 );",
58594                     "float F = fresnelReflectance( H, V, 0.028 );",
58595                     "float frSpec = max( PH * F / dot( h, h ), 0.0 );",
58596
58597                     "result = ndotl * rho_s * frSpec;", // BRDF * dot(N,L) * rho_s
58598
58599                 "}",
58600
58601                 "return result;",
58602
58603             "}",
58604
58605             "void main() {",
58606
58607                 "gl_FragColor = vec4( 1.0 );",
58608
58609                 "vec4 mColor = vec4( uDiffuseColor, uOpacity );",
58610                 "vec4 mSpecular = vec4( uSpecularColor, uOpacity );",
58611
58612                 "vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
58613                 "normalTex.xy *= uNormalScale;",
58614                 "normalTex = normalize( normalTex );",
58615
58616                 "vec4 colDiffuse = texture2D( tDiffuse, vUv );",
58617                 "colDiffuse *= colDiffuse;",
58618
58619                 "gl_FragColor = gl_FragColor * colDiffuse;",
58620
58621                 "mat3 tsb = mat3( vTangent, vBinormal, vNormal );",
58622                 "vec3 finalNormal = tsb * normalTex;",
58623
58624                 "vec3 normal = normalize( finalNormal );",
58625                 "vec3 viewPosition = normalize( vViewPosition );",
58626
58627                 // point lights
58628
58629                 "vec3 specularTotal = vec3( 0.0 );",
58630
58631                 "#if MAX_POINT_LIGHTS > 0",
58632
58633                     "vec4 pointTotal = vec4( vec3( 0.0 ), 1.0 );",
58634
58635                     "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
58636
58637                         "vec3 pointVector = normalize( vPointLight[ i ].xyz );",
58638                         "float pointDistance = vPointLight[ i ].w;",
58639
58640                         "float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
58641
58642                         "pointTotal  += pointDistance * vec4( pointLightColor[ i ], 1.0 ) * ( mColor * pointDiffuseWeight );",
58643
58644                         "if ( passID == 1 )",
58645                             "specularTotal += pointDistance * mSpecular.xyz * pointLightColor[ i ] * KS_Skin_Specular( normal, pointVector, viewPosition, uRoughness, uSpecularBrightness );",
58646
58647                     "}",
58648
58649                 "#endif",
58650
58651                 // directional lights
58652
58653                 "#if MAX_DIR_LIGHTS > 0",
58654
58655                     "vec4 dirTotal = vec4( vec3( 0.0 ), 1.0 );",
58656
58657                     "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
58658
58659                         "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
58660
58661                         "vec3 dirVector = normalize( lDirection.xyz );",
58662
58663                         "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
58664
58665                         "dirTotal  += vec4( directionalLightColor[ i ], 1.0 ) * ( mColor * dirDiffuseWeight );",
58666
58667                         "if ( passID == 1 )",
58668                             "specularTotal += mSpecular.xyz * directionalLightColor[ i ] * KS_Skin_Specular( normal, dirVector, viewPosition, uRoughness, uSpecularBrightness );",
58669
58670                     "}",
58671
58672                 "#endif",
58673
58674                 // all lights contribution summation
58675
58676                 "vec4 totalLight = vec4( vec3( 0.0 ), uOpacity );",
58677
58678                 "#if MAX_DIR_LIGHTS > 0",
58679                     "totalLight += dirTotal;",
58680                 "#endif",
58681
58682                 "#if MAX_POINT_LIGHTS > 0",
58683                     "totalLight += pointTotal;",
58684                 "#endif",
58685
58686                 "gl_FragColor = gl_FragColor * totalLight;",
58687
58688                 "if ( passID == 0 ) {",
58689
58690                     "gl_FragColor = vec4( sqrt( gl_FragColor.xyz ), gl_FragColor.w );",
58691
58692                 "} else if ( passID == 1 ) {",
58693
58694                     //"#define VERSION1",
58695
58696                     "#ifdef VERSION1",
58697
58698                         "vec3 nonblurColor = sqrt( gl_FragColor.xyz );",
58699
58700                     "#else",
58701
58702                         "vec3 nonblurColor = gl_FragColor.xyz;",
58703
58704                     "#endif",
58705
58706                     "vec3 blur1Color = texture2D( tBlur1, vUv ).xyz;",
58707                     "vec3 blur2Color = texture2D( tBlur2, vUv ).xyz;",
58708                     "vec3 blur3Color = texture2D( tBlur3, vUv ).xyz;",
58709                     "vec3 blur4Color = texture2D( tBlur4, vUv ).xyz;",
58710
58711
58712                     //"gl_FragColor = vec4( blur1Color, gl_FragColor.w );",
58713
58714                     //"gl_FragColor = vec4( vec3( 0.22, 0.5, 0.7 ) * nonblurColor + vec3( 0.2, 0.5, 0.3 ) * blur1Color + vec3( 0.58, 0.0, 0.0 ) * blur2Color, gl_FragColor.w );",
58715
58716                     //"gl_FragColor = vec4( vec3( 0.25, 0.6, 0.8 ) * nonblurColor + vec3( 0.15, 0.25, 0.2 ) * blur1Color + vec3( 0.15, 0.15, 0.0 ) * blur2Color + vec3( 0.45, 0.0, 0.0 ) * blur3Color, gl_FragColor.w );",
58717
58718
58719                     "gl_FragColor = vec4( vec3( 0.22,  0.437, 0.635 ) * nonblurColor + ",
58720                                          "vec3( 0.101, 0.355, 0.365 ) * blur1Color + ",
58721                                          "vec3( 0.119, 0.208, 0.0 )   * blur2Color + ",
58722                                          "vec3( 0.114, 0.0,   0.0 )   * blur3Color + ",
58723                                          "vec3( 0.444, 0.0,   0.0 )   * blur4Color",
58724                                          ", gl_FragColor.w );",
58725
58726                     "gl_FragColor.xyz *= pow( colDiffuse.xyz, vec3( 0.5 ) );",
58727
58728                     "gl_FragColor.xyz += ambientLightColor * uAmbientColor * colDiffuse.xyz + specularTotal;",
58729
58730                     "#ifndef VERSION1",
58731
58732                         "gl_FragColor.xyz = sqrt( gl_FragColor.xyz );",
58733
58734                     "#endif",
58735
58736                 "}",
58737
58738                 THREE.ShaderChunk[ "fog_fragment" ],
58739
58740             "}"
58741
58742         ].join("\n"),
58743
58744         vertexShader: [
58745
58746             "attribute vec4 tangent;",
58747
58748             "#ifdef VERTEX_TEXTURES",
58749
58750                 "uniform sampler2D tDisplacement;",
58751                 "uniform float uDisplacementScale;",
58752                 "uniform float uDisplacementBias;",
58753
58754             "#endif",
58755
58756             "varying vec3 vTangent;",
58757             "varying vec3 vBinormal;",
58758             "varying vec3 vNormal;",
58759             "varying vec2 vUv;",
58760
58761             "#if MAX_POINT_LIGHTS > 0",
58762
58763                 "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
58764                 "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
58765
58766                 "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
58767
58768             "#endif",
58769
58770             "varying vec3 vViewPosition;",
58771
58772             "void main() {",
58773
58774                 "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
58775
58776                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
58777
58778                 "vViewPosition = -mvPosition.xyz;",
58779
58780                 "vNormal = normalize( normalMatrix * normal );",
58781
58782                 // tangent and binormal vectors
58783
58784                 "vTangent = normalize( normalMatrix * tangent.xyz );",
58785
58786                 "vBinormal = cross( vNormal, vTangent ) * tangent.w;",
58787                 "vBinormal = normalize( vBinormal );",
58788
58789                 "vUv = uv;",
58790
58791                 // point lights
58792
58793                 "#if MAX_POINT_LIGHTS > 0",
58794
58795                     "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
58796
58797                         "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
58798
58799                         "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
58800
58801                         "float lDistance = 1.0;",
58802
58803                         "if ( pointLightDistance[ i ] > 0.0 )",
58804                             "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
58805
58806                         "lVector = normalize( lVector );",
58807
58808                         "vPointLight[ i ] = vec4( lVector, lDistance );",
58809
58810                     "}",
58811
58812                 "#endif",
58813
58814                 // displacement mapping
58815
58816                 "#ifdef VERTEX_TEXTURES",
58817
58818                     "vec3 dv = texture2D( tDisplacement, uv ).xyz;",
58819                     "float df = uDisplacementScale * dv.x + uDisplacementBias;",
58820                     "vec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;",
58821                     "gl_Position = projectionMatrix * displacedPosition;",
58822
58823                 "#else",
58824
58825                     "gl_Position = projectionMatrix * mvPosition;",
58826
58827                 "#endif",
58828
58829             "}"
58830
58831         ].join("\n"),
58832
58833         vertexShaderUV: [
58834
58835             "attribute vec4 tangent;",
58836
58837             "#ifdef VERTEX_TEXTURES",
58838
58839                 "uniform sampler2D tDisplacement;",
58840                 "uniform float uDisplacementScale;",
58841                 "uniform float uDisplacementBias;",
58842
58843             "#endif",
58844
58845             "varying vec3 vTangent;",
58846             "varying vec3 vBinormal;",
58847             "varying vec3 vNormal;",
58848             "varying vec2 vUv;",
58849
58850             "#if MAX_POINT_LIGHTS > 0",
58851
58852                 "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
58853                 "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
58854
58855                 "varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
58856
58857             "#endif",
58858
58859             "varying vec3 vViewPosition;",
58860
58861             "void main() {",
58862
58863                 "vec4 mPosition = modelMatrix * vec4( position, 1.0 );",
58864
58865                 "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
58866
58867                 "vViewPosition = -mvPosition.xyz;",
58868
58869                 "vNormal = normalize( normalMatrix * normal );",
58870
58871                 // tangent and binormal vectors
58872
58873                 "vTangent = normalize( normalMatrix * tangent.xyz );",
58874
58875                 "vBinormal = cross( vNormal, vTangent ) * tangent.w;",
58876                 "vBinormal = normalize( vBinormal );",
58877
58878                 "vUv = uv;",
58879
58880                 // point lights
58881
58882                 "#if MAX_POINT_LIGHTS > 0",
58883
58884                     "for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
58885
58886                         "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
58887
58888                         "vec3 lVector = lPosition.xyz - mvPosition.xyz;",
58889
58890                         "float lDistance = 1.0;",
58891
58892                         "if ( pointLightDistance[ i ] > 0.0 )",
58893                             "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
58894
58895                         "lVector = normalize( lVector );",
58896
58897                         "vPointLight[ i ] = vec4( lVector, lDistance );",
58898
58899                     "}",
58900
58901                 "#endif",
58902
58903                 "gl_Position = vec4( uv.x * 2.0 - 1.0, uv.y * 2.0 - 1.0, 0.0, 1.0 );",
58904
58905             "}"
58906
58907         ].join("\n")
58908
58909     },
58910
58911     /* ------------------------------------------------------------------------------------------
58912     // Beckmann distribution function
58913     //    - to be used in specular term of skin shader
58914     //    - render a screen-aligned quad to precompute a 512 x 512 texture
58915     //
58916     //        - from http://developer.nvidia.com/node/171
58917      ------------------------------------------------------------------------------------------ */
58918
58919     "beckmann" : {
58920
58921         uniforms: {},
58922
58923         vertexShader: [
58924
58925             "varying vec2 vUv;",
58926
58927             "void main() {",
58928
58929                 "vUv = uv;",
58930                 "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
58931
58932             "}"
58933
58934         ].join("\n"),
58935
58936         fragmentShader: [
58937
58938             "varying vec2 vUv;",
58939
58940             "float PHBeckmann( float ndoth, float m ) {",
58941
58942                 "float alpha = acos( ndoth );",
58943                 "float ta = tan( alpha );",
58944
58945                 "float val = 1.0 / ( m * m * pow( ndoth, 4.0 ) ) * exp( -( ta * ta ) / ( m * m ) );",
58946                 "return val;",
58947
58948             "}",
58949
58950             "float KSTextureCompute( vec2 tex ) {",
58951
58952                 // Scale the value to fit within [0,1]  invert upon lookup.
58953
58954                 "return 0.5 * pow( PHBeckmann( tex.x, tex.y ), 0.1 );",
58955
58956             "}",
58957
58958             "void main() {",
58959
58960                 "float x = KSTextureCompute( vUv );",
58961
58962                 "gl_FragColor = vec4( x, x, x, 1.0 );",
58963
58964             "}"
58965
58966         ].join("\n")
58967
58968     }
58969
58970 };
58971 //////////////////////////////////////////////////////////////////////////////
58972 //                                                                          //
58973 // Wii Opera SDK - Drawing Class v2.6.16 2008-12-14                         //
58974 // (c) 2007-2008 Daniel Gump. All Rights Reserved.                          //
58975 // http://wiioperasdk.com, http://hullbreachonline.com                      //
58976 // hullbreach@hullbreachonline.com                                          //
58977 //                                                                          //
58978 //  Wii is a trademark of Nintendo Co., Ltd.                                //
58979 //  Opera is a trademark of Opera, ASA.                                     //
58980 //  This software package is not associated with either company             //
58981 //  but was created to support users of both.  Its alternative name         //
58982 //  when supporting other products is the HULLBREACH SDK.                   //
58983 //                                                                          //
58984 //  Redistribution and use in source and binary forms, with or without      //
58985 //  modification, are permitted provided that the following conditions      //
58986 //  are met:                                                                //
58987 //    * Redistributions of source code must retain the above copyright      //
58988 //      notice, this list of conditions and the following disclaimer.       //
58989 //    * Redistributions in binary form must reproduce the above copyright   //
58990 //      notice, this list of conditions and the following disclaimer in     //
58991 //      the documentation and/or other materials provided with the          //
58992 //      distribution.                                                       //
58993 //    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names //
58994 //      of its contributors may be used to endorse or promote products      //
58995 //      derived from this software without specific prior written           //
58996 //      permission.                                                         //
58997 //    * If the explicit purpose of the software is not to support the       //
58998 //      Nintendo Wii or the Opera Web browser, then the names of such must  //
58999 //      not be used in any derived product. The name shall be the           //
59000 //      HULLBREACH SDK with a reference link to http://hullbreachonline.    //
59001 //                                                                          //
59002 //  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   //
59003 //  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          //
59004 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  //
59005 //  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     //
59006 //  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      //
59007 //  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      //
59008 //  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      //
59009 //  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     //
59010 //  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   //
59011 //  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      //
59012 //  POSSIBILITY OF SUCH DAMAGE.                                             //
59013 //////////////////////////////////////////////////////////////////////////////
59014
59015 function Drawing(){
59016         this.WIREFRAME = 1; this.FILL = 2;
59017         ZOOM = 1;
59018         CANVAS = null;
59019         TEXTURES = null;
59020 }
59021 Drawing.prototype.initialize = function(canvas){
59022         CANVAS = canvas.getContext("2d");
59023         CANVAS.lineJoin = "round";
59024         CANVAS.lineWidth = 1;
59025 }
59026 Drawing.prototype.loadTextures = function(textures){ TEXTURES = textures; }
59027 Drawing.prototype.setFillColor = function(r,g,b){ CANVAS.fillStyle = "rgb("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+")"; }
59028 Drawing.prototype.setFillColorA = function(r,g,b,a){ CANVAS.fillStyle = "rgba("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+", "+(a>255?1:(a<0?0:a/255))+")"; }
59029 Drawing.prototype.setLineColor = function(r,g,b){ CANVAS.strokeStyle = "rgb("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+")"; }
59030 Drawing.prototype.setLineColorA = function(r,g,b,a){ CANVAS.strokeStyle = "rgba("+(r>255?255:(r<0?0:r|0))+", "+(g>255?255:(g<0?0:g|0))+", "+(b>255?255:(b<0?0:b|0))+", "+(a>255?1:(a<0?0:a/255))+")"; }
59031 Drawing.prototype.clipCircle = function(centerx,centery,radius){ CANVAS.beginPath(); CANVAS.arc(centerx,centery,radius,0,6.28318531,false); CANVAS.clip(); }
59032 Drawing.prototype.clipRectangle = function(x1,y1,x2,y2){ CANVAS.beginPath(); CANVAS.strokeRect(x1,y1,x2-x1,y2-y1); CANVAS.clip(); }
59033 Drawing.prototype.drawCircle = function(centerx,centery,radius,style){
59034         CANVAS.beginPath();
59035         CANVAS.arc(centerx, centery, radius, 0, Math.PI*2, false);
59036         if(style & this.FILL) CANVAS.fill();
59037         if(style & this.WIREFRAME) CANVAS.stroke();
59038 }
59039 Drawing.prototype.drawImage = function(x1,y1,x2,y2,img,angle){
59040         if(img.complete){
59041                 x1|=0;
59042                 y1|=0;
59043                 x2|=0;
59044                 y2|=0;
59045                 if(x2<x1) x2=x1+1;
59046                 if(y2<y1) y2=y1+1;
59047                 var centerx = (x1+x2)>>1;
59048                 var centery = (y1+y2)>>1;
59049
59050                 CANVAS.save();
59051                 CANVAS.translate(centerx, centery);
59052                 if(angle) CANVAS.rotate(angle*0.01745329);
59053                 CANVAS.drawImage(img, x1-centerx, y1-centery, x2-x1, y2-y1);
59054                 CANVAS.restore();
59055         }
59056 }
59057 Drawing.prototype.drawLine = function(x1, y1, x2, y2){ CANVAS.beginPath(); CANVAS.moveTo(x1|0, y1|0); CANVAS.lineTo(x2|0, y2|0); CANVAS.stroke(); }
59058 Drawing.prototype.drawRectangle = function(x1, y1, x2, y2, style, angle){
59059         x1|=0;
59060         y1|=0;
59061         x2|=0;
59062         y2|=0;
59063         
59064         if(!angle){
59065                 if(style & this.FILL) CANVAS.fillRect(x1, y1, x2-x1, y2-y1);
59066                 if(style & this.WIREFRAME) CANVAS.strokeRect(x1, y1, x2-x1, y2-y1);
59067         }else{
59068                 var centerx = (x1+x2)>>1; var centery = (y1+y2)>>1;
59069
59070                 CANVAS.save();
59071                 CANVAS.translate(centerx, centery);
59072                 CANVAS.rotate(angle*DEGTORAD);
59073                 if(style & this.FILL) CANVAS.fillRect(x1-centerx, y1-centery, x2-x1, y2-y1);
59074                 if(style & this.WIREFRAME) CANVAS.strokeRect(x1-centerx, y1-centery, x2-x1, y2-y1);
59075                 CANVAS.restore();
59076         }
59077 }
59078 Drawing.prototype.drawScene = function(array,style){
59079         var piOver2 = 1.570796326794897;
59080         var piOver4 = 0.785398163397448;
59081         var sqrt2half = 1.414213562373095;
59082
59083         for(tri=array.length;--tri>=0;){
59084                 var x1 = array[tri][0];
59085                 var y1 = array[tri][1];
59086                 var x2 = array[tri][2];
59087                 var y2 = array[tri][3];
59088                 var x3 = array[tri][4];
59089                 var y3 = array[tri][5];
59090                 shade=array[tri][10];
59091
59092                 if(TEXTURES && array[tri][9]>=0){
59093                         CANVAS.save();
59094
59095                         var u = (x2-x3)*(x2-x3)+(y2-y3)*(y2-y3);
59096                         var v = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
59097                         var w = (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
59098
59099                         var canvasRot = 0.5*Math.acos((w+v-u)/(2*Math.sqrt(w*v)));
59100                         var scale = Math.cos(canvasRot)*sqrt2half;
59101
59102                         CANVAS.translate(x1,y1);
59103                         CANVAS.rotate(Math.atan2(y2-y1,x2-x1)-piOver2+canvasRot);
59104                         CANVAS.scale(Math.tan(canvasRot),1);
59105                         CANVAS.rotate(piOver4);
59106                         CANVAS.scale(Math.sqrt(w)*scale,Math.sqrt(v)*scale);
59107                         //CANVAS.transform(x2-x1,y2-y1,x3-x1,y3-y1, x1,y1);
59108                         CANVAS.drawImage((canvasimg = TEXTURES[array[tri][9]]), 0,0, canvasimg.width,canvasimg.height, 0,0, 1,1);
59109                         CANVAS.restore();
59110
59111                         if(shade!=0){
59112                                 CANVAS.beginPath();
59113                                 CANVAS.moveTo(x1,y1);
59114                                 CANVAS.lineTo(x2,y2);
59115                                 CANVAS.lineTo(x3,y3);
59116                                 CANVAS.lineTo(x1,y1);
59117                                 if(shade>0){
59118                                         if(shade>1) shade=1;
59119                                         CANVAS.fillStyle = "rgba(255,255,255,"+(shade)+")";
59120                                         CANVAS.strokeStyle = "rgba(255,255,255,"+(shade*.5)+")";
59121                                 }else if(shade<0){
59122                                         if(shade<-1) shade=-1;
59123                                         CANVAS.fillStyle = "rgba(0,0,0,"+(-shade)+")";
59124                                         CANVAS.strokeStyle = "rgba(0,0,0,"+(-shade*.5)+")";
59125                                 }
59126                                 if(style & this.FILL) CANVAS.fill();
59127                                 if(style & this.WIREFRAME) CANVAS.stroke();
59128                         }
59129                 }else{
59130                         var red = array[tri][6];
59131                         var green = array[tri][7];
59132                         var blue = array[tri][8];
59133                         if(shade!=0){
59134                                 red=(red*=++shade)>255?255:(red<0?0:red);
59135                                 green=(green*=shade)>255?255:(green<0?0:green);
59136                                 blue=(blue*=shade)>255?255:(blue<0?0:blue);
59137                         }
59138                         var color = "rgb("+(red|0)+","+(green|0)+","+(blue|0)+")";
59139                         CANVAS.beginPath();
59140                         CANVAS.moveTo(x1,y1);
59141                         CANVAS.lineTo(x2,y2);
59142                         CANVAS.lineTo(x3,y3);
59143                         CANVAS.lineTo(x1,y1);
59144                         if(style & this.FILL){ CANVAS.fillStyle = color; CANVAS.fill(); }
59145                         if(style & this.WIREFRAME){ CANVAS.strokeStyle = color; CANVAS.stroke(); }
59146                 }
59147         }
59148 }
59149
59150 Drawing.prototype.drawFloor = function(x1,x2,y1,x3,x4,y2,img){
59151         if((x2|=0)==(x1|=0)) x2++;
59152         if((y2|=0)==(y1|=0)) y2++;
59153         if((x4|=0)==(x3|=0)) x4++;
59154         var absdy=(dy = y2-y1)<0?-dy:dy;
59155
59156         var sourceD = img.width-1, sourceY = (img.height-1)*(dx2 = x4-x3)/dy;
59157         var destX = (x3-x1)/dy;
59158         var tempY = 0;
59159         var destW2 = (dx1 = x2-x1);
59160
59161         var absscale = (fullscale = 1.5*(dy>>31?-1:1)+dy/img.height)>>31?-(fullscale-1):(fullscale+1);
59162         var destwfullscale = fullscale*(dx2-dx1+1)/dy;
59163
59164         while(tempY<0?-tempY:tempY<=absdy){
59165                 CANVAS.drawImage(img, 0, sourceY*tempY/destW2, sourceD, 1, x1+destX*tempY, tempY+y1, destW2, absscale);
59166                 tempY+=fullscale;
59167                 destW2+=destwfullscale;
59168         }       
59169 }
59170 Drawing.prototype.drawWall = function(x1,y1,y2,x2,y3,y4,img){
59171         if(x2==x1) x2++;
59172         if(y2==y1) y2++;
59173         if(y4==y3) y4++;
59174         var dx = x2-x1, dy1 = y2-y1, dy2 = y4-y3;
59175         var absdx=dx<0?-dx:dx;
59176
59177         var sourceH = img.height-1, sourceX = (img.width-1)*dy2/dx;
59178         var destY = (y3-y1)/dx;
59179         var tempX = 0;
59180
59181         var fullscale = 1.5*(dx<0?-1:1)+dx/img.width;
59182         var absscale = fullscale<0?(-fullscale-1):(fullscale+1);
59183         var desthfullscale = fullscale*(dy2-dy1+1)/dx;
59184
59185         while(tempX<0?-tempX:tempX<=absdx){
59186                 CANVAS.drawImage(img, sourceX*tempX/dy1, 0, 1, sourceH, tempX+x1, y1+destY*tempX, absscale, dy1);
59187                 tempX+=fullscale;
59188                 dy1+=desthfullscale;
59189         }       
59190 }
59191 Drawing.prototype.zoom = function(zoom,width,height){
59192         ZOOM = zoom;
59193         CANVAS.translate(width>>1, height>>1);
59194         CANVAS.scale(ZOOM, ZOOM);
59195         CANVAS.translate(-width>>1, -height>>1);
59196 }
59197 Drawing.prototype.unZoom = function(width,height){
59198         CANVAS.translate(width>>1, height>>1);
59199         CANVAS.scale(1/ZOOM, 1/ZOOM);
59200         CANVAS.translate(-width>>1, -height>>1);
59201         ZOOM = 1;
59202 }
59203 Drawing.prototype.clear = function(x1, y1, x2, y2){ CANVAS.clearRect(x1, y1, x2-x1, y2-y1); }
59204
59205 Draw = new Drawing();var jWorkflow=function(){return{order:function(h,j){var i=[],f,d=null,g=function(){var a=false;return{take:function(){a=true},pass:function(b){var c;a=false;if(f.length){c=f.shift();b=c.func.apply(c.context,[b,g]);a||g.pass(b)}else d.func&&d.func.apply(d.context,[])}}}(),e={andThen:function(a,b){if(typeof a!=="function")throw"expected function but was "+typeof a;i.push({func:a,context:b});return e},chill:function(a){return e.andThen(function(b,c){c.take();setTimeout(function(){c.pass(b)},a)})},start:function(a,
59206 b){d={func:a,context:b};f=i.slice();g.pass()}};return h?e.andThen(h,j):e}}}();if(typeof module==="object"&&typeof require==="function")module.exports=jWorkflow;
59207 /*
59208   OpenLayers.js -- OpenLayers Map Viewer Library
59209
59210   Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
59211   license. Full license text below taken from http://svn.openlayers.org/trunk/openlayers/license.txt
59212
59213         Copyright 2005-2011 OpenLayers Contributors. All rights reserved. See
59214         authors.txt for full list.
59215          
59216         Redistribution and use in source and binary forms, with or without modification,
59217         are permitted provided that the following conditions are met:
59218          
59219         1. Redistributions of source code must retain the above copyright notice, this
59220         list of conditions and the following disclaimer.
59221          
59222         2. Redistributions in binary form must reproduce the above copyright notice,
59223         this list of conditions and the following disclaimer in the documentation and/or
59224         other materials provided with the distribution.
59225          
59226         THIS SOFTWARE IS PROVIDED BY OPENLAYERS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
59227         OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
59228         MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
59229         SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
59230         INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
59231         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
59232         PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
59233         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
59234         OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
59235         ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59236          
59237         The views and conclusions contained in the software and documentation are those
59238         of the authors and should not be interpreted as representing official policies,
59239         either expressed or implied, of OpenLayers Contributors.
59240
59241   Includes compressed code under the following licenses:
59242
59243   (For uncompressed versions of the code used please see the
59244   OpenLayers SVN repository: <http://openlayers.org/>)
59245
59246 */
59247
59248 /**  
59249 *  
59250 *  Contains portions of Rico <http://openrico.org/>
59251
59252 *  Copyright 2005 Sabre Airline Solutions  
59253 *  
59254 *  Licensed under the Apache License, Version 2.0 (the "License"); you
59255 *  may not use this file except in compliance with the License. You
59256 *  may obtain a copy of the License at
59257 *  
59258 *         http://www.apache.org/licenses/LICENSE-2.0  
59259 *  
59260 *  Unless required by applicable law or agreed to in writing, software
59261 *  distributed under the License is distributed on an "AS IS" BASIS,
59262 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
59263 *  implied. See the License for the specific language governing
59264 *  permissions and limitations under the License. 
59265 *
59266 **/
59267
59268 /**
59269  * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
59270  * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
59271  *
59272  * Licensed under the Apache License, Version 2.0 (the "License");
59273  * you may not use this file except in compliance with the License.
59274  * You may obtain a copy of the License at
59275  * http://www.apache.org/licenses/LICENSE-2.0
59276  */
59277
59278 /**
59279  * Contains portions of Gears <http://code.google.com/apis/gears/>
59280  *
59281  * Copyright 2007, Google Inc.
59282  *
59283  * Redistribution and use in source and binary forms, with or without
59284  * modification, are permitted provided that the following conditions are met:
59285  *
59286  *  1. Redistributions of source code must retain the above copyright notice,
59287  *     this list of conditions and the following disclaimer.
59288  *  2. Redistributions in binary form must reproduce the above copyright notice,
59289  *     this list of conditions and the following disclaimer in the documentation
59290  *     and/or other materials provided with the distribution.
59291  *  3. Neither the name of Google Inc. nor the names of its contributors may be
59292  *     used to endorse or promote products derived from this software without
59293  *     specific prior written permission.
59294  *
59295  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
59296  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
59297  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
59298  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59299  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59300  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
59301  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59302  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
59303  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
59304  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59305  *
59306  * Sets up google.gears.*, which is *the only* supported way to access Gears.
59307  *
59308  * Circumvent this file at your own risk!
59309  *
59310  * In the future, Gears may automatically define google.gears.* without this
59311  * file. Gears may use these objects to transparently fix bugs and compatibility
59312  * issues. Applications that use the code below will continue to work seamlessly
59313  * when that happens.
59314  */
59315 var OpenLayers={singleFile:true};(function(){var singleFile=(typeof OpenLayers=="object"&&OpenLayers.singleFile);var scriptLocation;window.OpenLayers={_scriptName:(!singleFile)?"lib/OpenLayers.js":"OpenLayers.js",_getScriptLocation:function(){if(scriptLocation!=undefined){return scriptLocation;}
59316 scriptLocation="";var isOL=new RegExp("(^|(.*?\\/))("+OpenLayers._scriptName+")(\\?|$)");var scripts=document.getElementsByTagName('script');for(var i=0,len=scripts.length;i<len;i++){var src=scripts[i].getAttribute('src');if(src){var match=src.match(isOL);if(match){scriptLocation=match[1];break;}}}
59317 return scriptLocation;}};if(!singleFile){var jsfiles=new Array("OpenLayers/Util.js","OpenLayers/BaseTypes.js","OpenLayers/BaseTypes/Class.js","OpenLayers/BaseTypes/Bounds.js","OpenLayers/BaseTypes/Element.js","OpenLayers/BaseTypes/LonLat.js","OpenLayers/BaseTypes/Pixel.js","OpenLayers/BaseTypes/Size.js","OpenLayers/Console.js","OpenLayers/Tween.js","Rico/Corner.js","Rico/Color.js","OpenLayers/Ajax.js","OpenLayers/Events.js","OpenLayers/Request.js","OpenLayers/Request/XMLHttpRequest.js","OpenLayers/Projection.js","OpenLayers/Map.js","OpenLayers/Layer.js","OpenLayers/Icon.js","OpenLayers/Marker.js","OpenLayers/Marker/Box.js","OpenLayers/Popup.js","OpenLayers/Tile.js","OpenLayers/Tile/Image.js","OpenLayers/Tile/Image/IFrame.js","OpenLayers/Tile/WFS.js","OpenLayers/Layer/Image.js","OpenLayers/Layer/SphericalMercator.js","OpenLayers/Layer/EventPane.js","OpenLayers/Layer/FixedZoomLevels.js","OpenLayers/Layer/Google.js","OpenLayers/Layer/Google/v3.js","OpenLayers/Layer/VirtualEarth.js","OpenLayers/Layer/Yahoo.js","OpenLayers/Layer/HTTPRequest.js","OpenLayers/Layer/Grid.js","OpenLayers/Layer/MapGuide.js","OpenLayers/Layer/MapServer.js","OpenLayers/Layer/MapServer/Untiled.js","OpenLayers/Layer/KaMap.js","OpenLayers/Layer/KaMapCache.js","OpenLayers/Layer/MultiMap.js","OpenLayers/Layer/Markers.js","OpenLayers/Layer/Text.js","OpenLayers/Layer/WorldWind.js","OpenLayers/Layer/ArcGIS93Rest.js","OpenLayers/Layer/WMS.js","OpenLayers/Layer/WMS/Untiled.js","OpenLayers/Layer/WMS/Post.js","OpenLayers/Layer/WMTS.js","OpenLayers/Layer/ArcIMS.js","OpenLayers/Layer/GeoRSS.js","OpenLayers/Layer/Boxes.js","OpenLayers/Layer/XYZ.js","OpenLayers/Layer/TMS.js","OpenLayers/Layer/TileCache.js","OpenLayers/Layer/Zoomify.js","OpenLayers/Popup/Anchored.js","OpenLayers/Popup/AnchoredBubble.js","OpenLayers/Popup/Framed.js","OpenLayers/Popup/FramedCloud.js","OpenLayers/Feature.js","OpenLayers/Feature/Vector.js","OpenLayers/Feature/WFS.js","OpenLayers/Handler.js","OpenLayers/Handler/Click.js","OpenLayers/Handler/Hover.js","OpenLayers/Handler/Point.js","OpenLayers/Handler/Path.js","OpenLayers/Handler/Polygon.js","OpenLayers/Handler/Feature.js","OpenLayers/Handler/Drag.js","OpenLayers/Handler/RegularPolygon.js","OpenLayers/Handler/Box.js","OpenLayers/Handler/MouseWheel.js","OpenLayers/Handler/Keyboard.js","OpenLayers/Control.js","OpenLayers/Control/Attribution.js","OpenLayers/Control/Button.js","OpenLayers/Control/ZoomBox.js","OpenLayers/Control/ZoomToMaxExtent.js","OpenLayers/Control/DragPan.js","OpenLayers/Control/Navigation.js","OpenLayers/Control/MouseDefaults.js","OpenLayers/Control/MousePosition.js","OpenLayers/Control/OverviewMap.js","OpenLayers/Control/KeyboardDefaults.js","OpenLayers/Control/PanZoom.js","OpenLayers/Control/PanZoomBar.js","OpenLayers/Control/ArgParser.js","OpenLayers/Control/Permalink.js","OpenLayers/Control/Scale.js","OpenLayers/Control/ScaleLine.js","OpenLayers/Control/Snapping.js","OpenLayers/Control/Split.js","OpenLayers/Control/LayerSwitcher.js","OpenLayers/Control/DrawFeature.js","OpenLayers/Control/DragFeature.js","OpenLayers/Control/ModifyFeature.js","OpenLayers/Control/Panel.js","OpenLayers/Control/SelectFeature.js","OpenLayers/Control/NavigationHistory.js","OpenLayers/Control/Measure.js","OpenLayers/Control/WMSGetFeatureInfo.js","OpenLayers/Control/WMTSGetFeatureInfo.js","OpenLayers/Control/Graticule.js","OpenLayers/Control/TransformFeature.js","OpenLayers/Control/SLDSelect.js","OpenLayers/Geometry.js","OpenLayers/Geometry/Rectangle.js","OpenLayers/Geometry/Collection.js","OpenLayers/Geometry/Point.js","OpenLayers/Geometry/MultiPoint.js","OpenLayers/Geometry/Curve.js","OpenLayers/Geometry/LineString.js","OpenLayers/Geometry/LinearRing.js","OpenLayers/Geometry/Polygon.js","OpenLayers/Geometry/MultiLineString.js","OpenLayers/Geometry/MultiPolygon.js","OpenLayers/Geometry/Surface.js","OpenLayers/Renderer.js","OpenLayers/Renderer/Elements.js","OpenLayers/Renderer/SVG.js","OpenLayers/Renderer/Canvas.js","OpenLayers/Renderer/VML.js","OpenLayers/Layer/Vector.js","OpenLayers/Layer/Vector/RootContainer.js","OpenLayers/Strategy.js","OpenLayers/Strategy/Filter.js","OpenLayers/Strategy/Fixed.js","OpenLayers/Strategy/Cluster.js","OpenLayers/Strategy/Paging.js","OpenLayers/Strategy/BBOX.js","OpenLayers/Strategy/Save.js","OpenLayers/Strategy/Refresh.js","OpenLayers/Filter.js","OpenLayers/Filter/FeatureId.js","OpenLayers/Filter/Logical.js","OpenLayers/Filter/Comparison.js","OpenLayers/Filter/Spatial.js","OpenLayers/Protocol.js","OpenLayers/Protocol/HTTP.js","OpenLayers/Protocol/SQL.js","OpenLayers/Protocol/SQL/Gears.js","OpenLayers/Protocol/WFS.js","OpenLayers/Protocol/WFS/v1.js","OpenLayers/Protocol/WFS/v1_0_0.js","OpenLayers/Protocol/WFS/v1_1_0.js","OpenLayers/Protocol/SOS.js","OpenLayers/Protocol/SOS/v1_0_0.js","OpenLayers/Layer/PointTrack.js","OpenLayers/Layer/GML.js","OpenLayers/Style.js","OpenLayers/Style2.js","OpenLayers/StyleMap.js","OpenLayers/Rule.js","OpenLayers/Format.js","OpenLayers/Format/XML.js","OpenLayers/Format/Context.js","OpenLayers/Format/ArcXML.js","OpenLayers/Format/ArcXML/Features.js","OpenLayers/Format/GML.js","OpenLayers/Format/GML/Base.js","OpenLayers/Format/GML/v2.js","OpenLayers/Format/GML/v3.js","OpenLayers/Format/Atom.js","OpenLayers/Format/KML.js","OpenLayers/Format/GeoRSS.js","OpenLayers/Format/WFS.js","OpenLayers/Format/WFSCapabilities.js","OpenLayers/Format/WFSCapabilities/v1.js","OpenLayers/Format/WFSCapabilities/v1_0_0.js","OpenLayers/Format/WFSCapabilities/v1_1_0.js","OpenLayers/Format/WFSDescribeFeatureType.js","OpenLayers/Format/WMSDescribeLayer.js","OpenLayers/Format/WMSDescribeLayer/v1_1.js","OpenLayers/Format/WKT.js","OpenLayers/Format/OSM.js","OpenLayers/Format/GPX.js","OpenLayers/Format/Filter.js","OpenLayers/Format/Filter/v1.js","OpenLayers/Format/Filter/v1_0_0.js","OpenLayers/Format/Filter/v1_1_0.js","OpenLayers/Format/SLD.js","OpenLayers/Format/SLD/v1.js","OpenLayers/Format/SLD/v1_0_0.js","OpenLayers/Format/OWSCommon/v1.js","OpenLayers/Format/OWSCommon/v1_0_0.js","OpenLayers/Format/OWSCommon/v1_1_0.js","OpenLayers/Format/CSWGetDomain.js","OpenLayers/Format/CSWGetDomain/v2_0_2.js","OpenLayers/Format/CSWGetRecords.js","OpenLayers/Format/CSWGetRecords/v2_0_2.js","OpenLayers/Format/WFST.js","OpenLayers/Format/WFST/v1.js","OpenLayers/Format/WFST/v1_0_0.js","OpenLayers/Format/WFST/v1_1_0.js","OpenLayers/Format/Text.js","OpenLayers/Format/JSON.js","OpenLayers/Format/GeoJSON.js","OpenLayers/Format/WMC.js","OpenLayers/Format/WMC/v1.js","OpenLayers/Format/WMC/v1_0_0.js","OpenLayers/Format/WMC/v1_1_0.js","OpenLayers/Format/WMSCapabilities.js","OpenLayers/Format/WMSCapabilities/v1.js","OpenLayers/Format/WMSCapabilities/v1_1.js","OpenLayers/Format/WMSCapabilities/v1_1_0.js","OpenLayers/Format/WMSCapabilities/v1_1_1.js","OpenLayers/Format/WMSCapabilities/v1_3.js","OpenLayers/Format/WMSCapabilities/v1_3_0.js","OpenLayers/Format/WMSGetFeatureInfo.js","OpenLayers/Format/SOSCapabilities.js","OpenLayers/Format/SOSCapabilities/v1_0_0.js","OpenLayers/Format/SOSGetObservation.js","OpenLayers/Format/SOSGetFeatureOfInterest.js","OpenLayers/Format/OWSContext.js","OpenLayers/Format/OWSContext/v0_3_1.js","OpenLayers/Format/WMTSCapabilities.js","OpenLayers/Format/WMTSCapabilities/v1_0_0.js","OpenLayers/Layer/WFS.js","OpenLayers/Control/GetFeature.js","OpenLayers/Control/MouseToolbar.js","OpenLayers/Control/NavToolbar.js","OpenLayers/Control/PanPanel.js","OpenLayers/Control/Pan.js","OpenLayers/Control/ZoomIn.js","OpenLayers/Control/ZoomOut.js","OpenLayers/Control/ZoomPanel.js","OpenLayers/Control/EditingToolbar.js","OpenLayers/Symbolizer.js","OpenLayers/Symbolizer/Point.js","OpenLayers/Symbolizer/Line.js","OpenLayers/Symbolizer/Polygon.js","OpenLayers/Symbolizer/Text.js","OpenLayers/Symbolizer/Raster.js","OpenLayers/Lang.js","OpenLayers/Lang/en.js");var agent=navigator.userAgent;var docWrite=(agent.match("MSIE")||agent.match("Safari"));if(docWrite){var allScriptTags=new Array(jsfiles.length);}
59318 var host=OpenLayers._getScriptLocation()+"lib/";for(var i=0,len=jsfiles.length;i<len;i++){if(docWrite){allScriptTags[i]="<script src='"+host+jsfiles[i]+"'></script>";}else{var s=document.createElement("script");s.src=host+jsfiles[i];var h=document.getElementsByTagName("head").length?document.getElementsByTagName("head")[0]:document.body;h.appendChild(s);}}
59319 if(docWrite){document.write(allScriptTags.join(""));}}})();OpenLayers.VERSION_NUMBER="OpenLayers 2.10 -- $Revision: 10721 $";OpenLayers.String={startsWith:function(str,sub){return(str.indexOf(sub)==0);},contains:function(str,sub){return(str.indexOf(sub)!=-1);},trim:function(str){return str.replace(/^\s\s*/,'').replace(/\s\s*$/,'');},camelize:function(str){var oStringList=str.split('-');var camelizedString=oStringList[0];for(var i=1,len=oStringList.length;i<len;i++){var s=oStringList[i];camelizedString+=s.charAt(0).toUpperCase()+s.substring(1);}
59320 return camelizedString;},format:function(template,context,args){if(!context){context=window;}
59321 var replacer=function(str,match){var replacement;var subs=match.split(/\.+/);for(var i=0;i<subs.length;i++){if(i==0){replacement=context;}
59322 replacement=replacement[subs[i]];}
59323 if(typeof replacement=="function"){replacement=args?replacement.apply(null,args):replacement();}
59324 if(typeof replacement=='undefined'){return'undefined';}else{return replacement;}};return template.replace(OpenLayers.String.tokenRegEx,replacer);},tokenRegEx:/\$\{([\w.]+?)\}/g,numberRegEx:/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/,isNumeric:function(value){return OpenLayers.String.numberRegEx.test(value);},numericIf:function(value){return OpenLayers.String.isNumeric(value)?parseFloat(value):value;}};if(!String.prototype.startsWith){String.prototype.startsWith=function(sStart){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.startsWith'}));return OpenLayers.String.startsWith(this,sStart);};}
59325 if(!String.prototype.contains){String.prototype.contains=function(str){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.contains'}));return OpenLayers.String.contains(this,str);};}
59326 if(!String.prototype.trim){String.prototype.trim=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.trim'}));return OpenLayers.String.trim(this);};}
59327 if(!String.prototype.camelize){String.prototype.camelize=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.String.camelize'}));return OpenLayers.String.camelize(this);};}
59328 OpenLayers.Number={decimalSeparator:".",thousandsSeparator:",",limitSigDigs:function(num,sig){var fig=0;if(sig>0){fig=parseFloat(num.toPrecision(sig));}
59329 return fig;},format:function(num,dec,tsep,dsep){dec=(typeof dec!="undefined")?dec:0;tsep=(typeof tsep!="undefined")?tsep:OpenLayers.Number.thousandsSeparator;dsep=(typeof dsep!="undefined")?dsep:OpenLayers.Number.decimalSeparator;if(dec!=null){num=parseFloat(num.toFixed(dec));}
59330 var parts=num.toString().split(".");if(parts.length==1&&dec==null){dec=0;}
59331 var integer=parts[0];if(tsep){var thousands=/(-?[0-9]+)([0-9]{3})/;while(thousands.test(integer)){integer=integer.replace(thousands,"$1"+tsep+"$2");}}
59332 var str;if(dec==0){str=integer;}else{var rem=parts.length>1?parts[1]:"0";if(dec!=null){rem=rem+new Array(dec-rem.length+1).join("0");}
59333 str=integer+dsep+rem;}
59334 return str;}};if(!Number.prototype.limitSigDigs){Number.prototype.limitSigDigs=function(sig){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Number.limitSigDigs'}));return OpenLayers.Number.limitSigDigs(this,sig);};}
59335 OpenLayers.Function={bind:function(func,object){var args=Array.prototype.slice.apply(arguments,[2]);return function(){var newArgs=args.concat(Array.prototype.slice.apply(arguments,[0]));return func.apply(object,newArgs);};},bindAsEventListener:function(func,object){return function(event){return func.call(object,event||window.event);};},False:function(){return false;},True:function(){return true;}};if(!Function.prototype.bind){Function.prototype.bind=function(){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Function.bind'}));Array.prototype.unshift.apply(arguments,[this]);return OpenLayers.Function.bind.apply(null,arguments);};}
59336 if(!Function.prototype.bindAsEventListener){Function.prototype.bindAsEventListener=function(object){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Function.bindAsEventListener'}));return OpenLayers.Function.bindAsEventListener(this,object);};}
59337 OpenLayers.Array={filter:function(array,callback,caller){var selected=[];if(Array.prototype.filter){selected=array.filter(callback,caller);}else{var len=array.length;if(typeof callback!="function"){throw new TypeError();}
59338 for(var i=0;i<len;i++){if(i in array){var val=array[i];if(callback.call(caller,val,i,array)){selected.push(val);}}}}
59339 return selected;}};OpenLayers.Date={toISOString:(function(){if("toISOString"in Date.prototype){return function(date){return date.toISOString();}}else{function pad(num,len){var str=num+"";while(str.length<len){str="0"+str;}
59340 return str;}
59341 return function(date){var str;if(isNaN(date.getTime())){str="Invalid Date";}else{str=date.getUTCFullYear()+"-"+
59342 pad(date.getUTCMonth()+1,2)+"-"+
59343 pad(date.getUTCDate(),2)+"T"+
59344 pad(date.getUTCHours(),2)+":"+
59345 pad(date.getUTCMinutes(),2)+":"+
59346 pad(date.getUTCSeconds(),2)+"."+
59347 pad(date.getUTCMilliseconds(),3)+"Z";}
59348 return str;}}})(),parse:function(str){var date;var elapsed=Date.parse(str);if(!isNaN(elapsed)){date=new Date(elapsed);}else{var match=str.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))?$/);var date;if(match&&(match[1]||match[7])){var year=parseInt(match[1],10)||0;var month=(parseInt(match[2],10)-1)||0;var day=parseInt(match[3],10)||1;date=new Date(Date.UTC(year,month,day));var type=match[7];if(type){var hours=parseInt(match[4],10);var minutes=parseInt(match[5],10);var secFrac=parseFloat(match[6]);var seconds=secFrac|0;var milliseconds=Math.round(1000*(secFrac-seconds));date.setUTCHours(hours,minutes,seconds,milliseconds);if(type!=="Z"){var hoursOffset=parseInt(type,10);var minutesOffset=parseInt(match[8])||0;var offset=-1000*(60*(hoursOffset*60)+minutesOffset*60);date=new Date(date.getTime()+offset);}}}else{date=new Date("invalid");}}
59349 return date;}};OpenLayers.Class=function(){var Class=function(){if(arguments&&arguments[0]!=OpenLayers.Class.isPrototype){this.initialize.apply(this,arguments);}};var extended={};var parent,initialize,Type;for(var i=0,len=arguments.length;i<len;++i){Type=arguments[i];if(typeof Type=="function"){if(i==0&&len>1){initialize=Type.prototype.initialize;Type.prototype.initialize=function(){};extended=new Type();if(initialize===undefined){delete Type.prototype.initialize;}else{Type.prototype.initialize=initialize;}}
59350 parent=Type.prototype;}else{parent=Type;}
59351 OpenLayers.Util.extend(extended,parent);}
59352 Class.prototype=extended;return Class;};OpenLayers.Class.isPrototype=function(){};OpenLayers.Class.create=function(){return function(){if(arguments&&arguments[0]!=OpenLayers.Class.isPrototype){this.initialize.apply(this,arguments);}};};OpenLayers.Class.inherit=function(){var superClass=arguments[0];var proto=new superClass(OpenLayers.Class.isPrototype);for(var i=1,len=arguments.length;i<len;i++){if(typeof arguments[i]=="function"){var mixin=arguments[i];arguments[i]=new mixin(OpenLayers.Class.isPrototype);}
59353 OpenLayers.Util.extend(proto,arguments[i]);}
59354 return proto;};OpenLayers.Util={};OpenLayers.Util.getElement=function(){var elements=[];for(var i=0,len=arguments.length;i<len;i++){var element=arguments[i];if(typeof element=='string'){element=document.getElementById(element);}
59355 if(arguments.length==1){return element;}
59356 elements.push(element);}
59357 return elements;};OpenLayers.Util.isElement=function(o){return!!(o&&o.nodeType===1);};if(typeof window.$==="undefined"){window.$=OpenLayers.Util.getElement;}
59358 OpenLayers.Util.extend=function(destination,source){destination=destination||{};if(source){for(var property in source){var value=source[property];if(value!==undefined){destination[property]=value;}}
59359 var sourceIsEvt=typeof window.Event=="function"&&source instanceof window.Event;if(!sourceIsEvt&&source.hasOwnProperty&&source.hasOwnProperty('toString')){destination.toString=source.toString;}}
59360 return destination;};OpenLayers.Util.removeItem=function(array,item){for(var i=array.length-1;i>=0;i--){if(array[i]==item){array.splice(i,1);}}
59361 return array;};OpenLayers.Util.clearArray=function(array){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'array = []'}));array.length=0;};OpenLayers.Util.indexOf=function(array,obj){if(typeof array.indexOf=="function"){return array.indexOf(obj);}else{for(var i=0,len=array.length;i<len;i++){if(array[i]==obj){return i;}}
59362 return-1;}};OpenLayers.Util.modifyDOMElement=function(element,id,px,sz,position,border,overflow,opacity){if(id){element.id=id;}
59363 if(px){element.style.left=px.x+"px";element.style.top=px.y+"px";}
59364 if(sz){element.style.width=sz.w+"px";element.style.height=sz.h+"px";}
59365 if(position){element.style.position=position;}
59366 if(border){element.style.border=border;}
59367 if(overflow){element.style.overflow=overflow;}
59368 if(parseFloat(opacity)>=0.0&&parseFloat(opacity)<1.0){element.style.filter='alpha(opacity='+(opacity*100)+')';element.style.opacity=opacity;}else if(parseFloat(opacity)==1.0){element.style.filter='';element.style.opacity='';}};OpenLayers.Util.createDiv=function(id,px,sz,imgURL,position,border,overflow,opacity){var dom=document.createElement('div');if(imgURL){dom.style.backgroundImage='url('+imgURL+')';}
59369 if(!id){id=OpenLayers.Util.createUniqueID("OpenLayersDiv");}
59370 if(!position){position="absolute";}
59371 OpenLayers.Util.modifyDOMElement(dom,id,px,sz,position,border,overflow,opacity);return dom;};OpenLayers.Util.createImage=function(id,px,sz,imgURL,position,border,opacity,delayDisplay){var image=document.createElement("img");if(!id){id=OpenLayers.Util.createUniqueID("OpenLayersDiv");}
59372 if(!position){position="relative";}
59373 OpenLayers.Util.modifyDOMElement(image,id,px,sz,position,border,null,opacity);if(delayDisplay){image.style.display="none";OpenLayers.Event.observe(image,"load",OpenLayers.Function.bind(OpenLayers.Util.onImageLoad,image));OpenLayers.Event.observe(image,"error",OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError,image));}
59374 image.style.alt=id;image.galleryImg="no";if(imgURL){image.src=imgURL;}
59375 return image;};OpenLayers.Util.setOpacity=function(element,opacity){OpenLayers.Util.modifyDOMElement(element,null,null,null,null,null,null,opacity);};OpenLayers.Util.onImageLoad=function(){if(!this.viewRequestID||(this.map&&this.viewRequestID==this.map.viewRequestID)){this.style.display="";}
59376 OpenLayers.Element.removeClass(this,"olImageLoadError");};OpenLayers.IMAGE_RELOAD_ATTEMPTS=0;OpenLayers.Util.onImageLoadError=function(){this._attempts=(this._attempts)?(this._attempts+1):1;if(this._attempts<=OpenLayers.IMAGE_RELOAD_ATTEMPTS){var urls=this.urls;if(urls&&urls instanceof Array&&urls.length>1){var src=this.src.toString();var current_url,k;for(k=0;current_url=urls[k];k++){if(src.indexOf(current_url)!=-1){break;}}
59377 var guess=Math.floor(urls.length*Math.random());var new_url=urls[guess];k=0;while(new_url==current_url&&k++<4){guess=Math.floor(urls.length*Math.random());new_url=urls[guess];}
59378 this.src=src.replace(current_url,new_url);}else{this.src=this.src;}}else{OpenLayers.Element.addClass(this,"olImageLoadError");}
59379 this.style.display="";};OpenLayers.Util.alphaHackNeeded=null;OpenLayers.Util.alphaHack=function(){if(OpenLayers.Util.alphaHackNeeded==null){var arVersion=navigator.appVersion.split("MSIE");var version=parseFloat(arVersion[1]);var filter=false;try{filter=!!(document.body.filters);}catch(e){}
59380 OpenLayers.Util.alphaHackNeeded=(filter&&(version>=5.5)&&(version<7));}
59381 return OpenLayers.Util.alphaHackNeeded;};OpenLayers.Util.modifyAlphaImageDiv=function(div,id,px,sz,imgURL,position,border,sizing,opacity){OpenLayers.Util.modifyDOMElement(div,id,px,sz,position,null,null,opacity);var img=div.childNodes[0];if(imgURL){img.src=imgURL;}
59382 OpenLayers.Util.modifyDOMElement(img,div.id+"_innerImage",null,sz,"relative",border);if(OpenLayers.Util.alphaHack()){if(div.style.display!="none"){div.style.display="inline-block";}
59383 if(sizing==null){sizing="scale";}
59384 div.style.filter="progid:DXImageTransform.Microsoft"+".AlphaImageLoader(src='"+img.src+"', "+"sizingMethod='"+sizing+"')";if(parseFloat(div.style.opacity)>=0.0&&parseFloat(div.style.opacity)<1.0){div.style.filter+=" alpha(opacity="+div.style.opacity*100+")";}
59385 img.style.filter="alpha(opacity=0)";}};OpenLayers.Util.createAlphaImageDiv=function(id,px,sz,imgURL,position,border,sizing,opacity,delayDisplay){var div=OpenLayers.Util.createDiv();var img=OpenLayers.Util.createImage(null,null,null,null,null,null,null,false);div.appendChild(img);if(delayDisplay){img.style.display="none";OpenLayers.Event.observe(img,"load",OpenLayers.Function.bind(OpenLayers.Util.onImageLoad,div));OpenLayers.Event.observe(img,"error",OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError,div));}
59386 OpenLayers.Util.modifyAlphaImageDiv(div,id,px,sz,imgURL,position,border,sizing,opacity);return div;};OpenLayers.Util.upperCaseObject=function(object){var uObject={};for(var key in object){uObject[key.toUpperCase()]=object[key];}
59387 return uObject;};OpenLayers.Util.applyDefaults=function(to,from){to=to||{};var fromIsEvt=typeof window.Event=="function"&&from instanceof window.Event;for(var key in from){if(to[key]===undefined||(!fromIsEvt&&from.hasOwnProperty&&from.hasOwnProperty(key)&&!to.hasOwnProperty(key))){to[key]=from[key];}}
59388 if(!fromIsEvt&&from&&from.hasOwnProperty&&from.hasOwnProperty('toString')&&!to.hasOwnProperty('toString')){to.toString=from.toString;}
59389 return to;};OpenLayers.Util.getParameterString=function(params){var paramsArray=[];for(var key in params){var value=params[key];if((value!=null)&&(typeof value!='function')){var encodedValue;if(typeof value=='object'&&value.constructor==Array){var encodedItemArray=[];var item;for(var itemIndex=0,len=value.length;itemIndex<len;itemIndex++){item=value[itemIndex];encodedItemArray.push(encodeURIComponent((item===null||item===undefined)?"":item));}
59390 encodedValue=encodedItemArray.join(",");}
59391 else{encodedValue=encodeURIComponent(value);}
59392 paramsArray.push(encodeURIComponent(key)+"="+encodedValue);}}
59393 return paramsArray.join("&");};OpenLayers.Util.urlAppend=function(url,paramStr){var newUrl=url;if(paramStr){var parts=(url+" ").split(/[?&]/);newUrl+=(parts.pop()===" "?paramStr:parts.length?"&"+paramStr:"?"+paramStr);}
59394 return newUrl;};OpenLayers.ImgPath='';OpenLayers.Util.getImagesLocation=function(){return OpenLayers.ImgPath||(OpenLayers._getScriptLocation()+"img/");};OpenLayers.Util.Try=function(){var returnValue=null;for(var i=0,len=arguments.length;i<len;i++){var lambda=arguments[i];try{returnValue=lambda();break;}catch(e){}}
59395 return returnValue;};OpenLayers.Util.getNodes=function(p,tagName){var nodes=OpenLayers.Util.Try(function(){return OpenLayers.Util._getNodes(p.documentElement.childNodes,tagName);},function(){return OpenLayers.Util._getNodes(p.childNodes,tagName);});return nodes;};OpenLayers.Util._getNodes=function(nodes,tagName){var retArray=[];for(var i=0,len=nodes.length;i<len;i++){if(nodes[i].nodeName==tagName){retArray.push(nodes[i]);}}
59396 return retArray;};OpenLayers.Util.getTagText=function(parent,item,index){var result=OpenLayers.Util.getNodes(parent,item);if(result&&(result.length>0))
59397 {if(!index){index=0;}
59398 if(result[index].childNodes.length>1){return result.childNodes[1].nodeValue;}
59399 else if(result[index].childNodes.length==1){return result[index].firstChild.nodeValue;}}else{return"";}};OpenLayers.Util.getXmlNodeValue=function(node){var val=null;OpenLayers.Util.Try(function(){val=node.text;if(!val){val=node.textContent;}
59400 if(!val){val=node.firstChild.nodeValue;}},function(){val=node.textContent;});return val;};OpenLayers.Util.mouseLeft=function(evt,div){var target=(evt.relatedTarget)?evt.relatedTarget:evt.toElement;while(target!=div&&target!=null){target=target.parentNode;}
59401 return(target!=div);};OpenLayers.Util.DEFAULT_PRECISION=14;OpenLayers.Util.toFloat=function(number,precision){if(precision==null){precision=OpenLayers.Util.DEFAULT_PRECISION;}
59402 var number;if(precision==0){number=parseFloat(number);}else{number=parseFloat(parseFloat(number).toPrecision(precision));}
59403 return number;};OpenLayers.Util.rad=function(x){return x*Math.PI/180;};OpenLayers.Util.deg=function(x){return x*180/Math.PI;};OpenLayers.Util.VincentyConstants={a:6378137,b:6356752.3142,f:1/298.257223563};OpenLayers.Util.distVincenty=function(p1,p2){var ct=OpenLayers.Util.VincentyConstants;var a=ct.a,b=ct.b,f=ct.f;var L=OpenLayers.Util.rad(p2.lon-p1.lon);var U1=Math.atan((1-f)*Math.tan(OpenLayers.Util.rad(p1.lat)));var U2=Math.atan((1-f)*Math.tan(OpenLayers.Util.rad(p2.lat)));var sinU1=Math.sin(U1),cosU1=Math.cos(U1);var sinU2=Math.sin(U2),cosU2=Math.cos(U2);var lambda=L,lambdaP=2*Math.PI;var iterLimit=20;while(Math.abs(lambda-lambdaP)>1e-12&&--iterLimit>0){var sinLambda=Math.sin(lambda),cosLambda=Math.cos(lambda);var sinSigma=Math.sqrt((cosU2*sinLambda)*(cosU2*sinLambda)+
59404 (cosU1*sinU2-sinU1*cosU2*cosLambda)*(cosU1*sinU2-sinU1*cosU2*cosLambda));if(sinSigma==0){return 0;}
59405 var cosSigma=sinU1*sinU2+cosU1*cosU2*cosLambda;var sigma=Math.atan2(sinSigma,cosSigma);var alpha=Math.asin(cosU1*cosU2*sinLambda/sinSigma);var cosSqAlpha=Math.cos(alpha)*Math.cos(alpha);var cos2SigmaM=cosSigma-2*sinU1*sinU2/cosSqAlpha;var C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));lambdaP=lambda;lambda=L+(1-C)*f*Math.sin(alpha)*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));}
59406 if(iterLimit==0){return NaN;}
59407 var uSq=cosSqAlpha*(a*a-b*b)/(b*b);var A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));var B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)));var deltaSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
59408 B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));var s=b*A*(sigma-deltaSigma);var d=s.toFixed(3)/1000;return d;};OpenLayers.Util.destinationVincenty=function(lonlat,brng,dist){var u=OpenLayers.Util;var ct=u.VincentyConstants;var a=ct.a,b=ct.b,f=ct.f;var lon1=lonlat.lon;var lat1=lonlat.lat;var s=dist;var alpha1=u.rad(brng);var sinAlpha1=Math.sin(alpha1);var cosAlpha1=Math.cos(alpha1);var tanU1=(1-f)*Math.tan(u.rad(lat1));var cosU1=1/Math.sqrt((1+tanU1*tanU1)),sinU1=tanU1*cosU1;var sigma1=Math.atan2(tanU1,cosAlpha1);var sinAlpha=cosU1*sinAlpha1;var cosSqAlpha=1-sinAlpha*sinAlpha;var uSq=cosSqAlpha*(a*a-b*b)/(b*b);var A=1+uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));var B=uSq/1024*(256+uSq*(-128+uSq*(74-47*uSq)));var sigma=s/(b*A),sigmaP=2*Math.PI;while(Math.abs(sigma-sigmaP)>1e-12){var cos2SigmaM=Math.cos(2*sigma1+sigma);var sinSigma=Math.sin(sigma);var cosSigma=Math.cos(sigma);var deltaSigma=B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
59409 B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));sigmaP=sigma;sigma=s/(b*A)+deltaSigma;}
59410 var tmp=sinU1*sinSigma-cosU1*cosSigma*cosAlpha1;var lat2=Math.atan2(sinU1*cosSigma+cosU1*sinSigma*cosAlpha1,(1-f)*Math.sqrt(sinAlpha*sinAlpha+tmp*tmp));var lambda=Math.atan2(sinSigma*sinAlpha1,cosU1*cosSigma-sinU1*sinSigma*cosAlpha1);var C=f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));var L=lambda-(1-C)*f*sinAlpha*(sigma+C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));var revAz=Math.atan2(sinAlpha,-tmp);return new OpenLayers.LonLat(lon1+u.deg(L),u.deg(lat2));};OpenLayers.Util.getParameters=function(url){url=url||window.location.href;var paramsString="";if(OpenLayers.String.contains(url,'?')){var start=url.indexOf('?')+1;var end=OpenLayers.String.contains(url,"#")?url.indexOf('#'):url.length;paramsString=url.substring(start,end);}
59411 var parameters={};var pairs=paramsString.split(/[&;]/);for(var i=0,len=pairs.length;i<len;++i){var keyValue=pairs[i].split('=');if(keyValue[0]){var key=decodeURIComponent(keyValue[0]);var value=keyValue[1]||'';value=decodeURIComponent(value.replace(/\+/g," ")).split(",");if(value.length==1){value=value[0];}
59412 parameters[key]=value;}}
59413 return parameters;};OpenLayers.Util.getArgs=function(url){OpenLayers.Console.warn(OpenLayers.i18n("methodDeprecated",{'newMethod':'OpenLayers.Util.getParameters'}));return OpenLayers.Util.getParameters(url);};OpenLayers.Util.lastSeqID=0;OpenLayers.Util.createUniqueID=function(prefix){if(prefix==null){prefix="id_";}
59414 OpenLayers.Util.lastSeqID+=1;return prefix+OpenLayers.Util.lastSeqID;};OpenLayers.INCHES_PER_UNIT={'inches':1.0,'ft':12.0,'mi':63360.0,'m':39.3701,'km':39370.1,'dd':4374754,'yd':36};OpenLayers.INCHES_PER_UNIT["in"]=OpenLayers.INCHES_PER_UNIT.inches;OpenLayers.INCHES_PER_UNIT["degrees"]=OpenLayers.INCHES_PER_UNIT.dd;OpenLayers.INCHES_PER_UNIT["nmi"]=1852*OpenLayers.INCHES_PER_UNIT.m;OpenLayers.METERS_PER_INCH=0.02540005080010160020;OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT,{"Inch":OpenLayers.INCHES_PER_UNIT.inches,"Meter":1.0/OpenLayers.METERS_PER_INCH,"Foot":0.30480060960121920243/OpenLayers.METERS_PER_INCH,"IFoot":0.30480000000000000000/OpenLayers.METERS_PER_INCH,"ClarkeFoot":0.3047972651151/OpenLayers.METERS_PER_INCH,"SearsFoot":0.30479947153867624624/OpenLayers.METERS_PER_INCH,"GoldCoastFoot":0.30479971018150881758/OpenLayers.METERS_PER_INCH,"IInch":0.02540000000000000000/OpenLayers.METERS_PER_INCH,"MicroInch":0.00002540000000000000/OpenLayers.METERS_PER_INCH,"Mil":0.00000002540000000000/OpenLayers.METERS_PER_INCH,"Centimeter":0.01000000000000000000/OpenLayers.METERS_PER_INCH,"Kilometer":1000.00000000000000000000/OpenLayers.METERS_PER_INCH,"Yard":0.91440182880365760731/OpenLayers.METERS_PER_INCH,"SearsYard":0.914398414616029/OpenLayers.METERS_PER_INCH,"IndianYard":0.91439853074444079983/OpenLayers.METERS_PER_INCH,"IndianYd37":0.91439523/OpenLayers.METERS_PER_INCH,"IndianYd62":0.9143988/OpenLayers.METERS_PER_INCH,"IndianYd75":0.9143985/OpenLayers.METERS_PER_INCH,"IndianFoot":0.30479951/OpenLayers.METERS_PER_INCH,"IndianFt37":0.30479841/OpenLayers.METERS_PER_INCH,"IndianFt62":0.3047996/OpenLayers.METERS_PER_INCH,"IndianFt75":0.3047995/OpenLayers.METERS_PER_INCH,"Mile":1609.34721869443738887477/OpenLayers.METERS_PER_INCH,"IYard":0.91440000000000000000/OpenLayers.METERS_PER_INCH,"IMile":1609.34400000000000000000/OpenLayers.METERS_PER_INCH,"NautM":1852.00000000000000000000/OpenLayers.METERS_PER_INCH,"Lat-66":110943.316488932731/OpenLayers.METERS_PER_INCH,"Lat-83":110946.25736872234125/OpenLayers.METERS_PER_INCH,"Decimeter":0.10000000000000000000/OpenLayers.METERS_PER_INCH,"Millimeter":0.00100000000000000000/OpenLayers.METERS_PER_INCH,"Dekameter":10.00000000000000000000/OpenLayers.METERS_PER_INCH,"Decameter":10.00000000000000000000/OpenLayers.METERS_PER_INCH,"Hectometer":100.00000000000000000000/OpenLayers.METERS_PER_INCH,"GermanMeter":1.0000135965/OpenLayers.METERS_PER_INCH,"CaGrid":0.999738/OpenLayers.METERS_PER_INCH,"ClarkeChain":20.1166194976/OpenLayers.METERS_PER_INCH,"GunterChain":20.11684023368047/OpenLayers.METERS_PER_INCH,"BenoitChain":20.116782494375872/OpenLayers.METERS_PER_INCH,"SearsChain":20.11676512155/OpenLayers.METERS_PER_INCH,"ClarkeLink":0.201166194976/OpenLayers.METERS_PER_INCH,"GunterLink":0.2011684023368047/OpenLayers.METERS_PER_INCH,"BenoitLink":0.20116782494375872/OpenLayers.METERS_PER_INCH,"SearsLink":0.2011676512155/OpenLayers.METERS_PER_INCH,"Rod":5.02921005842012/OpenLayers.METERS_PER_INCH,"IntnlChain":20.1168/OpenLayers.METERS_PER_INCH,"IntnlLink":0.201168/OpenLayers.METERS_PER_INCH,"Perch":5.02921005842012/OpenLayers.METERS_PER_INCH,"Pole":5.02921005842012/OpenLayers.METERS_PER_INCH,"Furlong":201.1684023368046/OpenLayers.METERS_PER_INCH,"Rood":3.778266898/OpenLayers.METERS_PER_INCH,"CapeFoot":0.3047972615/OpenLayers.METERS_PER_INCH,"Brealey":375.00000000000000000000/OpenLayers.METERS_PER_INCH,"ModAmFt":0.304812252984505969011938/OpenLayers.METERS_PER_INCH,"Fathom":1.8288/OpenLayers.METERS_PER_INCH,"NautM-UK":1853.184/OpenLayers.METERS_PER_INCH,"50kilometers":50000.0/OpenLayers.METERS_PER_INCH,"150kilometers":150000.0/OpenLayers.METERS_PER_INCH});OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT,{"mm":OpenLayers.INCHES_PER_UNIT["Meter"]/1000.0,"cm":OpenLayers.INCHES_PER_UNIT["Meter"]/100.0,"dm":OpenLayers.INCHES_PER_UNIT["Meter"]*100.0,"km":OpenLayers.INCHES_PER_UNIT["Meter"]*1000.0,"kmi":OpenLayers.INCHES_PER_UNIT["nmi"],"fath":OpenLayers.INCHES_PER_UNIT["Fathom"],"ch":OpenLayers.INCHES_PER_UNIT["IntnlChain"],"link":OpenLayers.INCHES_PER_UNIT["IntnlLink"],"us-in":OpenLayers.INCHES_PER_UNIT["inches"],"us-ft":OpenLayers.INCHES_PER_UNIT["Foot"],"us-yd":OpenLayers.INCHES_PER_UNIT["Yard"],"us-ch":OpenLayers.INCHES_PER_UNIT["GunterChain"],"us-mi":OpenLayers.INCHES_PER_UNIT["Mile"],"ind-yd":OpenLayers.INCHES_PER_UNIT["IndianYd37"],"ind-ft":OpenLayers.INCHES_PER_UNIT["IndianFt37"],"ind-ch":20.11669506/OpenLayers.METERS_PER_INCH});OpenLayers.DOTS_PER_INCH=72;OpenLayers.Util.normalizeScale=function(scale){var normScale=(scale>1.0)?(1.0/scale):scale;return normScale;};OpenLayers.Util.getResolutionFromScale=function(scale,units){var resolution;if(scale){if(units==null){units="degrees";}
59415 var normScale=OpenLayers.Util.normalizeScale(scale);resolution=1/(normScale*OpenLayers.INCHES_PER_UNIT[units]*OpenLayers.DOTS_PER_INCH);}
59416 return resolution;};OpenLayers.Util.getScaleFromResolution=function(resolution,units){if(units==null){units="degrees";}
59417 var scale=resolution*OpenLayers.INCHES_PER_UNIT[units]*OpenLayers.DOTS_PER_INCH;return scale;};OpenLayers.Util.safeStopPropagation=function(evt){OpenLayers.Event.stop(evt,true);};OpenLayers.Util.pagePosition=function(forElement){var valueT=0,valueL=0;var element=forElement;var child=forElement;while(element){if(element==document.body){if(OpenLayers.Element.getStyle(child,'position')=='absolute'){break;}}
59418 valueT+=element.offsetTop||0;valueL+=element.offsetLeft||0;child=element;try{element=element.offsetParent;}catch(e){OpenLayers.Console.error(OpenLayers.i18n("pagePositionFailed",{'elemId':element.id}));break;}}
59419 element=forElement;while(element){valueT-=element.scrollTop||0;valueL-=element.scrollLeft||0;element=element.parentNode;}
59420 return[valueL,valueT];};OpenLayers.Util.isEquivalentUrl=function(url1,url2,options){options=options||{};OpenLayers.Util.applyDefaults(options,{ignoreCase:true,ignorePort80:true,ignoreHash:true});var urlObj1=OpenLayers.Util.createUrlObject(url1,options);var urlObj2=OpenLayers.Util.createUrlObject(url2,options);for(var key in urlObj1){if(key!=="args"){if(urlObj1[key]!=urlObj2[key]){return false;}}}
59421 for(var key in urlObj1.args){if(urlObj1.args[key]!=urlObj2.args[key]){return false;}
59422 delete urlObj2.args[key];}
59423 for(var key in urlObj2.args){return false;}
59424 return true;};OpenLayers.Util.createUrlObject=function(url,options){options=options||{};if(!(/^\w+:\/\//).test(url)){var loc=window.location;var port=loc.port?":"+loc.port:"";var fullUrl=loc.protocol+"//"+loc.host.split(":").shift()+port;if(url.indexOf("/")===0){url=fullUrl+url;}else{var parts=loc.pathname.split("/");parts.pop();url=fullUrl+parts.join("/")+"/"+url;}}
59425 if(options.ignoreCase){url=url.toLowerCase();}
59426 var a=document.createElement('a');a.href=url;var urlObject={};urlObject.host=a.host.split(":").shift();urlObject.protocol=a.protocol;if(options.ignorePort80){urlObject.port=(a.port=="80"||a.port=="0")?"":a.port;}else{urlObject.port=(a.port==""||a.port=="0")?"80":a.port;}
59427 urlObject.hash=(options.ignoreHash||a.hash==="#")?"":a.hash;var queryString=a.search;if(!queryString){var qMark=url.indexOf("?");queryString=(qMark!=-1)?url.substr(qMark):"";}
59428 urlObject.args=OpenLayers.Util.getParameters(queryString);urlObject.pathname=(a.pathname.charAt(0)=="/")?a.pathname:"/"+a.pathname;return urlObject;};OpenLayers.Util.removeTail=function(url){var head=null;var qMark=url.indexOf("?");var hashMark=url.indexOf("#");if(qMark==-1){head=(hashMark!=-1)?url.substr(0,hashMark):url;}else{head=(hashMark!=-1)?url.substr(0,Math.min(qMark,hashMark)):url.substr(0,qMark);}
59429 return head;};OpenLayers.Util.getBrowserName=function(){var browserName="";var ua=navigator.userAgent.toLowerCase();if(ua.indexOf("opera")!=-1){browserName="opera";}else if(ua.indexOf("msie")!=-1){browserName="msie";}else if(ua.indexOf("safari")!=-1){browserName="safari";}else if(ua.indexOf("mozilla")!=-1){if(ua.indexOf("firefox")!=-1){browserName="firefox";}else{browserName="mozilla";}}
59430 return browserName;};OpenLayers.Util.getRenderedDimensions=function(contentHTML,size,options){var w,h;var container=document.createElement("div");container.style.visibility="hidden";var containerElement=(options&&options.containerElement)?options.containerElement:document.body;if(size){if(size.w){w=size.w;container.style.width=w+"px";}else if(size.h){h=size.h;container.style.height=h+"px";}}
59431 if(options&&options.displayClass){container.className=options.displayClass;}
59432 var content=document.createElement("div");content.innerHTML=contentHTML;content.style.overflow="visible";if(content.childNodes){for(var i=0,l=content.childNodes.length;i<l;i++){if(!content.childNodes[i].style)continue;content.childNodes[i].style.overflow="visible";}}
59433 container.appendChild(content);containerElement.appendChild(container);var parentHasPositionAbsolute=false;var parent=container.parentNode;while(parent&&parent.tagName.toLowerCase()!="body"){var parentPosition=OpenLayers.Element.getStyle(parent,"position");if(parentPosition=="absolute"){parentHasPositionAbsolute=true;break;}else if(parentPosition&&parentPosition!="static"){break;}
59434 parent=parent.parentNode;}
59435 if(!parentHasPositionAbsolute){container.style.position="absolute";}
59436 if(!w){w=parseInt(content.scrollWidth);container.style.width=w+"px";}
59437 if(!h){h=parseInt(content.scrollHeight);}
59438 container.removeChild(content);containerElement.removeChild(container);return new OpenLayers.Size(w,h);};OpenLayers.Util.getScrollbarWidth=function(){var scrollbarWidth=OpenLayers.Util._scrollbarWidth;if(scrollbarWidth==null){var scr=null;var inn=null;var wNoScroll=0;var wScroll=0;scr=document.createElement('div');scr.style.position='absolute';scr.style.top='-1000px';scr.style.left='-1000px';scr.style.width='100px';scr.style.height='50px';scr.style.overflow='hidden';inn=document.createElement('div');inn.style.width='100%';inn.style.height='200px';scr.appendChild(inn);document.body.appendChild(scr);wNoScroll=inn.offsetWidth;scr.style.overflow='scroll';wScroll=inn.offsetWidth;document.body.removeChild(document.body.lastChild);OpenLayers.Util._scrollbarWidth=(wNoScroll-wScroll);scrollbarWidth=OpenLayers.Util._scrollbarWidth;}
59439 return scrollbarWidth;};OpenLayers.Util.getFormattedLonLat=function(coordinate,axis,dmsOption){if(!dmsOption){dmsOption='dms';}
59440 var abscoordinate=Math.abs(coordinate)
59441 var coordinatedegrees=Math.floor(abscoordinate);var coordinateminutes=(abscoordinate-coordinatedegrees)/(1/60);var tempcoordinateminutes=coordinateminutes;coordinateminutes=Math.floor(coordinateminutes);var coordinateseconds=(tempcoordinateminutes-coordinateminutes)/(1/60);coordinateseconds=Math.round(coordinateseconds*10);coordinateseconds/=10;if(coordinatedegrees<10){coordinatedegrees="0"+coordinatedegrees;}
59442 var str=coordinatedegrees+"\u00B0";if(dmsOption.indexOf('dm')>=0){if(coordinateminutes<10){coordinateminutes="0"+coordinateminutes;}
59443 str+=coordinateminutes+"'";if(dmsOption.indexOf('dms')>=0){if(coordinateseconds<10){coordinateseconds="0"+coordinateseconds;}
59444 str+=coordinateseconds+'"';}}
59445 if(axis=="lon"){str+=coordinate<0?OpenLayers.i18n("W"):OpenLayers.i18n("E");}else{str+=coordinate<0?OpenLayers.i18n("S"):OpenLayers.i18n("N");}
59446 return str;};OpenLayers.Rico=new Object();OpenLayers.Rico.Corner={round:function(e,options){e=OpenLayers.Util.getElement(e);this._setOptions(options);var color=this.options.color;if(this.options.color=="fromElement"){color=this._background(e);}
59447 var bgColor=this.options.bgColor;if(this.options.bgColor=="fromParent"){bgColor=this._background(e.offsetParent);}
59448 this._roundCornersImpl(e,color,bgColor);},changeColor:function(theDiv,newColor){theDiv.style.backgroundColor=newColor;var spanElements=theDiv.parentNode.getElementsByTagName("span");for(var currIdx=0;currIdx<spanElements.length;currIdx++){spanElements[currIdx].style.backgroundColor=newColor;}},changeOpacity:function(theDiv,newOpacity){var mozillaOpacity=newOpacity;var ieOpacity='alpha(opacity='+newOpacity*100+')';theDiv.style.opacity=mozillaOpacity;theDiv.style.filter=ieOpacity;var spanElements=theDiv.parentNode.getElementsByTagName("span");for(var currIdx=0;currIdx<spanElements.length;currIdx++){spanElements[currIdx].style.opacity=mozillaOpacity;spanElements[currIdx].style.filter=ieOpacity;}},reRound:function(theDiv,options){var topRico=theDiv.parentNode.childNodes[0];var bottomRico=theDiv.parentNode.childNodes[2];theDiv.parentNode.removeChild(topRico);theDiv.parentNode.removeChild(bottomRico);this.round(theDiv.parentNode,options);},_roundCornersImpl:function(e,color,bgColor){if(this.options.border){this._renderBorder(e,bgColor);}
59449 if(this._isTopRounded()){this._roundTopCorners(e,color,bgColor);}
59450 if(this._isBottomRounded()){this._roundBottomCorners(e,color,bgColor);}},_renderBorder:function(el,bgColor){var borderValue="1px solid "+this._borderColor(bgColor);var borderL="border-left: "+borderValue;var borderR="border-right: "+borderValue;var style="style='"+borderL+";"+borderR+"'";el.innerHTML="<div "+style+">"+el.innerHTML+"</div>";},_roundTopCorners:function(el,color,bgColor){var corner=this._createCorner(bgColor);for(var i=0;i<this.options.numSlices;i++){corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));}
59451 el.style.paddingTop=0;el.insertBefore(corner,el.firstChild);},_roundBottomCorners:function(el,color,bgColor){var corner=this._createCorner(bgColor);for(var i=(this.options.numSlices-1);i>=0;i--){corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));}
59452 el.style.paddingBottom=0;el.appendChild(corner);},_createCorner:function(bgColor){var corner=document.createElement("div");corner.style.backgroundColor=(this._isTransparent()?"transparent":bgColor);return corner;},_createCornerSlice:function(color,bgColor,n,position){var slice=document.createElement("span");var inStyle=slice.style;inStyle.backgroundColor=color;inStyle.display="block";inStyle.height="1px";inStyle.overflow="hidden";inStyle.fontSize="1px";var borderColor=this._borderColor(color,bgColor);if(this.options.border&&n==0){inStyle.borderTopStyle="solid";inStyle.borderTopWidth="1px";inStyle.borderLeftWidth="0px";inStyle.borderRightWidth="0px";inStyle.borderBottomWidth="0px";inStyle.height="0px";inStyle.borderColor=borderColor;}
59453 else if(borderColor){inStyle.borderColor=borderColor;inStyle.borderStyle="solid";inStyle.borderWidth="0px 1px";}
59454 if(!this.options.compact&&(n==(this.options.numSlices-1))){inStyle.height="2px";}
59455 this._setMargin(slice,n,position);this._setBorder(slice,n,position);return slice;},_setOptions:function(options){this.options={corners:"all",color:"fromElement",bgColor:"fromParent",blend:true,border:false,compact:false};OpenLayers.Util.extend(this.options,options||{});this.options.numSlices=this.options.compact?2:4;if(this._isTransparent()){this.options.blend=false;}},_whichSideTop:function(){if(this._hasString(this.options.corners,"all","top")){return"";}
59456 if(this.options.corners.indexOf("tl")>=0&&this.options.corners.indexOf("tr")>=0){return"";}
59457 if(this.options.corners.indexOf("tl")>=0){return"left";}else if(this.options.corners.indexOf("tr")>=0){return"right";}
59458 return"";},_whichSideBottom:function(){if(this._hasString(this.options.corners,"all","bottom")){return"";}
59459 if(this.options.corners.indexOf("bl")>=0&&this.options.corners.indexOf("br")>=0){return"";}
59460 if(this.options.corners.indexOf("bl")>=0){return"left";}else if(this.options.corners.indexOf("br")>=0){return"right";}
59461 return"";},_borderColor:function(color,bgColor){if(color=="transparent"){return bgColor;}else if(this.options.border){return this.options.border;}else if(this.options.blend){return this._blend(bgColor,color);}else{return"";}},_setMargin:function(el,n,corners){var marginSize=this._marginSize(n);var whichSide=corners=="top"?this._whichSideTop():this._whichSideBottom();if(whichSide=="left"){el.style.marginLeft=marginSize+"px";el.style.marginRight="0px";}
59462 else if(whichSide=="right"){el.style.marginRight=marginSize+"px";el.style.marginLeft="0px";}
59463 else{el.style.marginLeft=marginSize+"px";el.style.marginRight=marginSize+"px";}},_setBorder:function(el,n,corners){var borderSize=this._borderSize(n);var whichSide=corners=="top"?this._whichSideTop():this._whichSideBottom();if(whichSide=="left"){el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth="0px";}
59464 else if(whichSide=="right"){el.style.borderRightWidth=borderSize+"px";el.style.borderLeftWidth="0px";}
59465 else{el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth=borderSize+"px";}
59466 if(this.options.border!=false){el.style.borderLeftWidth=borderSize+"px";el.style.borderRightWidth=borderSize+"px";}},_marginSize:function(n){if(this._isTransparent()){return 0;}
59467 var marginSizes=[5,3,2,1];var blendedMarginSizes=[3,2,1,0];var compactMarginSizes=[2,1];var smBlendedMarginSizes=[1,0];if(this.options.compact&&this.options.blend){return smBlendedMarginSizes[n];}else if(this.options.compact){return compactMarginSizes[n];}else if(this.options.blend){return blendedMarginSizes[n];}else{return marginSizes[n];}},_borderSize:function(n){var transparentBorderSizes=[5,3,2,1];var blendedBorderSizes=[2,1,1,1];var compactBorderSizes=[1,0];var actualBorderSizes=[0,2,0,0];if(this.options.compact&&(this.options.blend||this._isTransparent())){return 1;}else if(this.options.compact){return compactBorderSizes[n];}else if(this.options.blend){return blendedBorderSizes[n];}else if(this.options.border){return actualBorderSizes[n];}else if(this._isTransparent()){return transparentBorderSizes[n];}
59468 return 0;},_hasString:function(str){for(var i=1;i<arguments.length;i++)if(str.indexOf(arguments[i])>=0){return true;}return false;},_blend:function(c1,c2){var cc1=OpenLayers.Rico.Color.createFromHex(c1);cc1.blend(OpenLayers.Rico.Color.createFromHex(c2));return cc1;},_background:function(el){try{return OpenLayers.Rico.Color.createColorFromBackground(el).asHex();}catch(err){return"#ffffff";}},_isTransparent:function(){return this.options.color=="transparent";},_isTopRounded:function(){return this._hasString(this.options.corners,"all","top","tl","tr");},_isBottomRounded:function(){return this._hasString(this.options.corners,"all","bottom","bl","br");},_hasSingleTextChild:function(el){return el.childNodes.length==1&&el.childNodes[0].nodeType==3;}};(function(){if(window.google&&google.gears){return;}
59469 var factory=null;if(typeof GearsFactory!='undefined'){factory=new GearsFactory();}else{try{factory=new ActiveXObject('Gears.Factory');if(factory.getBuildInfo().indexOf('ie_mobile')!=-1){factory.privateSetGlobalObject(this);}}catch(e){if((typeof navigator.mimeTypes!='undefined')&&navigator.mimeTypes["application/x-googlegears"]){factory=document.createElement("object");factory.style.display="none";factory.width=0;factory.height=0;factory.type="application/x-googlegears";document.documentElement.appendChild(factory);}}}
59470 if(!factory){return;}
59471 if(!window.google){google={};}
59472 if(!google.gears){google.gears={factory:factory};}})();OpenLayers.Element={visible:function(element){return OpenLayers.Util.getElement(element).style.display!='none';},toggle:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);var display=OpenLayers.Element.visible(element)?'hide':'show';OpenLayers.Element[display](element);}},hide:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);if(element){element.style.display='none';}}},show:function(){for(var i=0,len=arguments.length;i<len;i++){var element=OpenLayers.Util.getElement(arguments[i]);if(element){element.style.display='';}}},remove:function(element){element=OpenLayers.Util.getElement(element);element.parentNode.removeChild(element);},getHeight:function(element){element=OpenLayers.Util.getElement(element);return element.offsetHeight;},getDimensions:function(element){element=OpenLayers.Util.getElement(element);if(OpenLayers.Element.getStyle(element,'display')!='none'){return{width:element.offsetWidth,height:element.offsetHeight};}
59473 var els=element.style;var originalVisibility=els.visibility;var originalPosition=els.position;var originalDisplay=els.display;els.visibility='hidden';els.position='absolute';els.display='';var originalWidth=element.clientWidth;var originalHeight=element.clientHeight;els.display=originalDisplay;els.position=originalPosition;els.visibility=originalVisibility;return{width:originalWidth,height:originalHeight};},hasClass:function(element,name){var names=element.className;return(!!names&&new RegExp("(^|\\s)"+name+"(\\s|$)").test(names));},addClass:function(element,name){if(!OpenLayers.Element.hasClass(element,name)){element.className+=(element.className?" ":"")+name;}
59474 return element;},removeClass:function(element,name){var names=element.className;if(names){element.className=OpenLayers.String.trim(names.replace(new RegExp("(^|\\s+)"+name+"(\\s+|$)")," "));}
59475 return element;},toggleClass:function(element,name){if(OpenLayers.Element.hasClass(element,name)){OpenLayers.Element.removeClass(element,name);}else{OpenLayers.Element.addClass(element,name);}
59476 return element;},getStyle:function(element,style){element=OpenLayers.Util.getElement(element);var value=null;if(element&&element.style){value=element.style[OpenLayers.String.camelize(style)];if(!value){if(document.defaultView&&document.defaultView.getComputedStyle){var css=document.defaultView.getComputedStyle(element,null);value=css?css.getPropertyValue(style):null;}else if(element.currentStyle){value=element.currentStyle[OpenLayers.String.camelize(style)];}}
59477 var positions=['left','top','right','bottom'];if(window.opera&&(OpenLayers.Util.indexOf(positions,style)!=-1)&&(OpenLayers.Element.getStyle(element,'position')=='static')){value='auto';}}
59478 return value=='auto'?null:value;}};OpenLayers.Size=OpenLayers.Class({w:0.0,h:0.0,initialize:function(w,h){this.w=parseFloat(w);this.h=parseFloat(h);},toString:function(){return("w="+this.w+",h="+this.h);},clone:function(){return new OpenLayers.Size(this.w,this.h);},equals:function(sz){var equals=false;if(sz!=null){equals=((this.w==sz.w&&this.h==sz.h)||(isNaN(this.w)&&isNaN(this.h)&&isNaN(sz.w)&&isNaN(sz.h)));}
59479 return equals;},CLASS_NAME:"OpenLayers.Size"});OpenLayers.Console={log:function(){},debug:function(){},info:function(){},warn:function(){},error:function(){},userError:function(error){alert(error);},assert:function(){},dir:function(){},dirxml:function(){},trace:function(){},group:function(){},groupEnd:function(){},time:function(){},timeEnd:function(){},profile:function(){},profileEnd:function(){},count:function(){},CLASS_NAME:"OpenLayers.Console"};(function(){var scripts=document.getElementsByTagName("script");for(var i=0,len=scripts.length;i<len;++i){if(scripts[i].src.indexOf("firebug.js")!=-1){if(console){OpenLayers.Util.extend(OpenLayers.Console,console);break;}}}})();OpenLayers.Icon=OpenLayers.Class({url:null,size:null,offset:null,calculateOffset:null,imageDiv:null,px:null,initialize:function(url,size,offset,calculateOffset){this.url=url;this.size=(size)?size:new OpenLayers.Size(20,20);this.offset=offset?offset:new OpenLayers.Pixel(-(this.size.w/2),-(this.size.h/2));this.calculateOffset=calculateOffset;var id=OpenLayers.Util.createUniqueID("OL_Icon_");this.imageDiv=OpenLayers.Util.createAlphaImageDiv(id);},destroy:function(){this.erase();OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);this.imageDiv.innerHTML="";this.imageDiv=null;},clone:function(){return new OpenLayers.Icon(this.url,this.size,this.offset,this.calculateOffset);},setSize:function(size){if(size!=null){this.size=size;}
59480 this.draw();},setUrl:function(url){if(url!=null){this.url=url;}
59481 this.draw();},draw:function(px){OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,null,this.size,this.url,"absolute");this.moveTo(px);return this.imageDiv;},erase:function(){if(this.imageDiv!=null&&this.imageDiv.parentNode!=null){OpenLayers.Element.remove(this.imageDiv);}},setOpacity:function(opacity){OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,null,null,null,null,null,null,opacity);},moveTo:function(px){if(px!=null){this.px=px;}
59482 if(this.imageDiv!=null){if(this.px==null){this.display(false);}else{if(this.calculateOffset){this.offset=this.calculateOffset(this.size);}
59483 var offsetPx=this.px.offset(this.offset);OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,offsetPx);}}},display:function(display){this.imageDiv.style.display=(display)?"":"none";},isDrawn:function(){var isDrawn=(this.imageDiv&&this.imageDiv.parentNode&&(this.imageDiv.parentNode.nodeType!=11));return isDrawn;},CLASS_NAME:"OpenLayers.Icon"});OpenLayers.Popup=OpenLayers.Class({events:null,id:"",lonlat:null,div:null,contentSize:null,size:null,contentHTML:null,backgroundColor:"",opacity:"",border:"",contentDiv:null,groupDiv:null,closeDiv:null,autoSize:false,minSize:null,maxSize:null,displayClass:"olPopup",contentDisplayClass:"olPopupContent",padding:0,disableFirefoxOverflowHack:false,fixPadding:function(){if(typeof this.padding=="number"){this.padding=new OpenLayers.Bounds(this.padding,this.padding,this.padding,this.padding);}},panMapIfOutOfView:false,keepInMap:false,closeOnMove:false,map:null,initialize:function(id,lonlat,contentSize,contentHTML,closeBox,closeBoxCallback){if(id==null){id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");}
59484 this.id=id;this.lonlat=lonlat;this.contentSize=(contentSize!=null)?contentSize:new OpenLayers.Size(OpenLayers.Popup.WIDTH,OpenLayers.Popup.HEIGHT);if(contentHTML!=null){this.contentHTML=contentHTML;}
59485 this.backgroundColor=OpenLayers.Popup.COLOR;this.opacity=OpenLayers.Popup.OPACITY;this.border=OpenLayers.Popup.BORDER;this.div=OpenLayers.Util.createDiv(this.id,null,null,null,null,null,"hidden");this.div.className=this.displayClass;var groupDivId=this.id+"_GroupDiv";this.groupDiv=OpenLayers.Util.createDiv(groupDivId,null,null,null,"relative",null,"hidden");var id=this.div.id+"_contentDiv";this.contentDiv=OpenLayers.Util.createDiv(id,null,this.contentSize.clone(),null,"relative");this.contentDiv.className=this.contentDisplayClass;this.groupDiv.appendChild(this.contentDiv);this.div.appendChild(this.groupDiv);if(closeBox){this.addCloseBox(closeBoxCallback);}
59486 this.registerEvents();},destroy:function(){this.id=null;this.lonlat=null;this.size=null;this.contentHTML=null;this.backgroundColor=null;this.opacity=null;this.border=null;if(this.closeOnMove&&this.map){this.map.events.unregister("movestart",this,this.hide);}
59487 this.events.destroy();this.events=null;if(this.closeDiv){OpenLayers.Event.stopObservingElement(this.closeDiv);this.groupDiv.removeChild(this.closeDiv);}
59488 this.closeDiv=null;this.div.removeChild(this.groupDiv);this.groupDiv=null;if(this.map!=null){this.map.removePopup(this);}
59489 this.map=null;this.div=null;this.autoSize=null;this.minSize=null;this.maxSize=null;this.padding=null;this.panMapIfOutOfView=null;},draw:function(px){if(px==null){if((this.lonlat!=null)&&(this.map!=null)){px=this.map.getLayerPxFromLonLat(this.lonlat);}}
59490 if(this.closeOnMove){this.map.events.register("movestart",this,this.hide);}
59491 if(!this.disableFirefoxOverflowHack&&OpenLayers.Util.getBrowserName()=='firefox'){this.map.events.register("movestart",this,function(){var style=document.defaultView.getComputedStyle(this.contentDiv,null);var currentOverflow=style.getPropertyValue("overflow");if(currentOverflow!="hidden"){this.contentDiv._oldOverflow=currentOverflow;this.contentDiv.style.overflow="hidden";}});this.map.events.register("moveend",this,function(){var oldOverflow=this.contentDiv._oldOverflow;if(oldOverflow){this.contentDiv.style.overflow=oldOverflow;this.contentDiv._oldOverflow=null;}});}
59492 this.moveTo(px);if(!this.autoSize&&!this.size){this.setSize(this.contentSize);}
59493 this.setBackgroundColor();this.setOpacity();this.setBorder();this.setContentHTML();if(this.panMapIfOutOfView){this.panIntoView();}
59494 return this.div;},updatePosition:function(){if((this.lonlat)&&(this.map)){var px=this.map.getLayerPxFromLonLat(this.lonlat);if(px){this.moveTo(px);}}},moveTo:function(px){if((px!=null)&&(this.div!=null)){this.div.style.left=px.x+"px";this.div.style.top=px.y+"px";}},visible:function(){return OpenLayers.Element.visible(this.div);},toggle:function(){if(this.visible()){this.hide();}else{this.show();}},show:function(){OpenLayers.Element.show(this.div);if(this.panMapIfOutOfView){this.panIntoView();}},hide:function(){OpenLayers.Element.hide(this.div);},setSize:function(contentSize){this.size=contentSize.clone();var contentDivPadding=this.getContentDivPadding();var wPadding=contentDivPadding.left+contentDivPadding.right;var hPadding=contentDivPadding.top+contentDivPadding.bottom;this.fixPadding();wPadding+=this.padding.left+this.padding.right;hPadding+=this.padding.top+this.padding.bottom;if(this.closeDiv){var closeDivWidth=parseInt(this.closeDiv.style.width);wPadding+=closeDivWidth+contentDivPadding.right;}
59495 this.size.w+=wPadding;this.size.h+=hPadding;if(OpenLayers.Util.getBrowserName()=="msie"){this.contentSize.w+=contentDivPadding.left+contentDivPadding.right;this.contentSize.h+=contentDivPadding.bottom+contentDivPadding.top;}
59496 if(this.div!=null){this.div.style.width=this.size.w+"px";this.div.style.height=this.size.h+"px";}
59497 if(this.contentDiv!=null){this.contentDiv.style.width=contentSize.w+"px";this.contentDiv.style.height=contentSize.h+"px";}},updateSize:function(){var preparedHTML="<div class='"+this.contentDisplayClass+"'>"+
59498 this.contentDiv.innerHTML+"</div>";var containerElement=(this.map)?this.map.layerContainerDiv:document.body;var realSize=OpenLayers.Util.getRenderedDimensions(preparedHTML,null,{displayClass:this.displayClass,containerElement:containerElement});var safeSize=this.getSafeContentSize(realSize);var newSize=null;if(safeSize.equals(realSize)){newSize=realSize;}else{var fixedSize=new OpenLayers.Size();fixedSize.w=(safeSize.w<realSize.w)?safeSize.w:null;fixedSize.h=(safeSize.h<realSize.h)?safeSize.h:null;if(fixedSize.w&&fixedSize.h){newSize=safeSize;}else{var clippedSize=OpenLayers.Util.getRenderedDimensions(preparedHTML,fixedSize,{displayClass:this.contentDisplayClass,containerElement:containerElement});var currentOverflow=OpenLayers.Element.getStyle(this.contentDiv,"overflow");if((currentOverflow!="hidden")&&(clippedSize.equals(safeSize))){var scrollBar=OpenLayers.Util.getScrollbarWidth();if(fixedSize.w){clippedSize.h+=scrollBar;}else{clippedSize.w+=scrollBar;}}
59499 newSize=this.getSafeContentSize(clippedSize);}}
59500 this.setSize(newSize);},setBackgroundColor:function(color){if(color!=undefined){this.backgroundColor=color;}
59501 if(this.div!=null){this.div.style.backgroundColor=this.backgroundColor;}},setOpacity:function(opacity){if(opacity!=undefined){this.opacity=opacity;}
59502 if(this.div!=null){this.div.style.opacity=this.opacity;this.div.style.filter='alpha(opacity='+this.opacity*100+')';}},setBorder:function(border){if(border!=undefined){this.border=border;}
59503 if(this.div!=null){this.div.style.border=this.border;}},setContentHTML:function(contentHTML){if(contentHTML!=null){this.contentHTML=contentHTML;}
59504 if((this.contentDiv!=null)&&(this.contentHTML!=null)&&(this.contentHTML!=this.contentDiv.innerHTML)){this.contentDiv.innerHTML=this.contentHTML;if(this.autoSize){this.registerImageListeners();this.updateSize();}}},registerImageListeners:function(){var onImgLoad=function(){this.popup.updateSize();if(this.popup.visible()&&this.popup.panMapIfOutOfView){this.popup.panIntoView();}
59505 OpenLayers.Event.stopObserving(this.img,"load",this.img._onImageLoad);};var images=this.contentDiv.getElementsByTagName("img");for(var i=0,len=images.length;i<len;i++){var img=images[i];if(img.width==0||img.height==0){var context={'popup':this,'img':img};img._onImgLoad=OpenLayers.Function.bind(onImgLoad,context);OpenLayers.Event.observe(img,'load',img._onImgLoad);}}},getSafeContentSize:function(size){var safeContentSize=size.clone();var contentDivPadding=this.getContentDivPadding();var wPadding=contentDivPadding.left+contentDivPadding.right;var hPadding=contentDivPadding.top+contentDivPadding.bottom;this.fixPadding();wPadding+=this.padding.left+this.padding.right;hPadding+=this.padding.top+this.padding.bottom;if(this.closeDiv){var closeDivWidth=parseInt(this.closeDiv.style.width);wPadding+=closeDivWidth+contentDivPadding.right;}
59506 if(this.minSize){safeContentSize.w=Math.max(safeContentSize.w,(this.minSize.w-wPadding));safeContentSize.h=Math.max(safeContentSize.h,(this.minSize.h-hPadding));}
59507 if(this.maxSize){safeContentSize.w=Math.min(safeContentSize.w,(this.maxSize.w-wPadding));safeContentSize.h=Math.min(safeContentSize.h,(this.maxSize.h-hPadding));}
59508 if(this.map&&this.map.size){var extraX=0,extraY=0;if(this.keepInMap&&!this.panMapIfOutOfView){var px=this.map.getPixelFromLonLat(this.lonlat);switch(this.relativePosition){case"tr":extraX=px.x;extraY=this.map.size.h-px.y;break;case"tl":extraX=this.map.size.w-px.x;extraY=this.map.size.h-px.y;break;case"bl":extraX=this.map.size.w-px.x;extraY=px.y;break;case"br":extraX=px.x;extraY=px.y;break;default:extraX=px.x;extraY=this.map.size.h-px.y;break;}}
59509 var maxY=this.map.size.h-
59510 this.map.paddingForPopups.top-
59511 this.map.paddingForPopups.bottom-
59512 hPadding-extraY;var maxX=this.map.size.w-
59513 this.map.paddingForPopups.left-
59514 this.map.paddingForPopups.right-
59515 wPadding-extraX;safeContentSize.w=Math.min(safeContentSize.w,maxX);safeContentSize.h=Math.min(safeContentSize.h,maxY);}
59516 return safeContentSize;},getContentDivPadding:function(){var contentDivPadding=this._contentDivPadding;if(!contentDivPadding){if(this.div.parentNode==null){this.div.style.display="none";document.body.appendChild(this.div);}
59517 contentDivPadding=new OpenLayers.Bounds(OpenLayers.Element.getStyle(this.contentDiv,"padding-left"),OpenLayers.Element.getStyle(this.contentDiv,"padding-bottom"),OpenLayers.Element.getStyle(this.contentDiv,"padding-right"),OpenLayers.Element.getStyle(this.contentDiv,"padding-top"));this._contentDivPadding=contentDivPadding;if(this.div.parentNode==document.body){document.body.removeChild(this.div);this.div.style.display="";}}
59518 return contentDivPadding;},addCloseBox:function(callback){this.closeDiv=OpenLayers.Util.createDiv(this.id+"_close",null,new OpenLayers.Size(17,17));this.closeDiv.className="olPopupCloseBox";var contentDivPadding=this.getContentDivPadding();this.closeDiv.style.right=contentDivPadding.right+"px";this.closeDiv.style.top=contentDivPadding.top+"px";this.groupDiv.appendChild(this.closeDiv);var closePopup=callback||function(e){this.hide();OpenLayers.Event.stop(e);};OpenLayers.Event.observe(this.closeDiv,"click",OpenLayers.Function.bindAsEventListener(closePopup,this));},panIntoView:function(){var mapSize=this.map.getSize();var origTL=this.map.getViewPortPxFromLayerPx(new OpenLayers.Pixel(parseInt(this.div.style.left),parseInt(this.div.style.top)));var newTL=origTL.clone();if(origTL.x<this.map.paddingForPopups.left){newTL.x=this.map.paddingForPopups.left;}else
59519 if((origTL.x+this.size.w)>(mapSize.w-this.map.paddingForPopups.right)){newTL.x=mapSize.w-this.map.paddingForPopups.right-this.size.w;}
59520 if(origTL.y<this.map.paddingForPopups.top){newTL.y=this.map.paddingForPopups.top;}else
59521 if((origTL.y+this.size.h)>(mapSize.h-this.map.paddingForPopups.bottom)){newTL.y=mapSize.h-this.map.paddingForPopups.bottom-this.size.h;}
59522 var dx=origTL.x-newTL.x;var dy=origTL.y-newTL.y;this.map.pan(dx,dy);},registerEvents:function(){this.events=new OpenLayers.Events(this,this.div,null,true);this.events.on({"mousedown":this.onmousedown,"mousemove":this.onmousemove,"mouseup":this.onmouseup,"click":this.onclick,"mouseout":this.onmouseout,"dblclick":this.ondblclick,scope:this});},onmousedown:function(evt){this.mousedown=true;OpenLayers.Event.stop(evt,true);},onmousemove:function(evt){if(this.mousedown){OpenLayers.Event.stop(evt,true);}},onmouseup:function(evt){if(this.mousedown){this.mousedown=false;OpenLayers.Event.stop(evt,true);}},onclick:function(evt){OpenLayers.Event.stop(evt,true);},onmouseout:function(evt){this.mousedown=false;},ondblclick:function(evt){OpenLayers.Event.stop(evt,true);},CLASS_NAME:"OpenLayers.Popup"});OpenLayers.Popup.WIDTH=200;OpenLayers.Popup.HEIGHT=200;OpenLayers.Popup.COLOR="white";OpenLayers.Popup.OPACITY=1;OpenLayers.Popup.BORDER="0px";OpenLayers.Protocol=OpenLayers.Class({format:null,options:null,autoDestroy:true,defaultFilter:null,initialize:function(options){options=options||{};OpenLayers.Util.extend(this,options);this.options=options;},mergeWithDefaultFilter:function(filter){var merged;if(filter&&this.defaultFilter){merged=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,filters:[this.defaultFilter,filter]});}else{merged=filter||this.defaultFilter||undefined;}
59523 return merged;},destroy:function(){this.options=null;this.format=null;},read:function(options){options=options||{};options.filter=this.mergeWithDefaultFilter(options.filter);},create:function(){},update:function(){},"delete":function(){},commit:function(){},abort:function(response){},createCallback:function(method,response,options){return OpenLayers.Function.bind(function(){method.apply(this,[response,options]);},this);},CLASS_NAME:"OpenLayers.Protocol"});OpenLayers.Protocol.Response=OpenLayers.Class({code:null,requestType:null,last:true,features:null,reqFeatures:null,priv:null,initialize:function(options){OpenLayers.Util.extend(this,options);},success:function(){return this.code>0;},CLASS_NAME:"OpenLayers.Protocol.Response"});OpenLayers.Protocol.Response.SUCCESS=1;OpenLayers.Protocol.Response.FAILURE=0;OpenLayers.Renderer=OpenLayers.Class({container:null,root:null,extent:null,locked:false,size:null,resolution:null,map:null,initialize:function(containerID,options){this.container=OpenLayers.Util.getElement(containerID);},destroy:function(){this.container=null;this.extent=null;this.size=null;this.resolution=null;this.map=null;},supported:function(){return false;},setExtent:function(extent,resolutionChanged){this.extent=extent.clone();if(resolutionChanged){this.resolution=null;}},setSize:function(size){this.size=size.clone();this.resolution=null;},getResolution:function(){this.resolution=this.resolution||this.map.getResolution();return this.resolution;},drawFeature:function(feature,style){if(style==null){style=feature.style;}
59524 if(feature.geometry){var bounds=feature.geometry.getBounds();if(bounds){if(!bounds.intersectsBounds(this.extent)){style={display:"none"};}
59525 var rendered=this.drawGeometry(feature.geometry,style,feature.id);if(style.display!="none"&&style.label&&rendered!==false){var location=feature.geometry.getCentroid();if(style.labelXOffset||style.labelYOffset){xOffset=isNaN(style.labelXOffset)?0:style.labelXOffset;yOffset=isNaN(style.labelYOffset)?0:style.labelYOffset;var res=this.getResolution();location.move(xOffset*res,yOffset*res);}
59526 this.drawText(feature.id,style,location);}else{this.removeText(feature.id);}
59527 return rendered;}}},drawGeometry:function(geometry,style,featureId){},drawText:function(featureId,style,location){},removeText:function(featureId){},clear:function(){},getFeatureIdFromEvent:function(evt){},eraseFeatures:function(features){if(!(features instanceof Array)){features=[features];}
59528 for(var i=0,len=features.length;i<len;++i){var feature=features[i];this.eraseGeometry(feature.geometry,feature.id);this.removeText(feature.id);}},eraseGeometry:function(geometry,featureId){},moveRoot:function(renderer){},getRenderLayerId:function(){return this.container.id;},applyDefaultSymbolizer:function(symbolizer){var result=OpenLayers.Util.extend({},OpenLayers.Renderer.defaultSymbolizer);if(symbolizer.stroke===false){delete result.strokeWidth;delete result.strokeColor;}
59529 if(symbolizer.fill===false){delete result.fillColor;}
59530 OpenLayers.Util.extend(result,symbolizer);return result;},CLASS_NAME:"OpenLayers.Renderer"});OpenLayers.Renderer.defaultSymbolizer={fillColor:"#000000",strokeColor:"#000000",strokeWidth:2,fillOpacity:1,strokeOpacity:1,pointRadius:0};OpenLayers.Strategy=OpenLayers.Class({layer:null,options:null,active:null,autoActivate:true,autoDestroy:true,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;this.active=false;},destroy:function(){this.deactivate();this.layer=null;this.options=null;},setLayer:function(layer){this.layer=layer;},activate:function(){if(!this.active){this.active=true;return true;}
59531 return false;},deactivate:function(){if(this.active){this.active=false;return true;}
59532 return false;},CLASS_NAME:"OpenLayers.Strategy"});OpenLayers.Symbolizer=OpenLayers.Class({zIndex:0,initialize:function(config){OpenLayers.Util.extend(this,config);},clone:function(){var Type=eval(this.CLASS_NAME);return new Type(OpenLayers.Util.extend({},this));},CLASS_NAME:"OpenLayers.Symbolizer"});OpenLayers.Rico.Color=OpenLayers.Class({initialize:function(red,green,blue){this.rgb={r:red,g:green,b:blue};},setRed:function(r){this.rgb.r=r;},setGreen:function(g){this.rgb.g=g;},setBlue:function(b){this.rgb.b=b;},setHue:function(h){var hsb=this.asHSB();hsb.h=h;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},setSaturation:function(s){var hsb=this.asHSB();hsb.s=s;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},setBrightness:function(b){var hsb=this.asHSB();hsb.b=b;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,hsb.b);},darken:function(percent){var hsb=this.asHSB();this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,Math.max(hsb.b-percent,0));},brighten:function(percent){var hsb=this.asHSB();this.rgb=OpenLayers.Rico.Color.HSBtoRGB(hsb.h,hsb.s,Math.min(hsb.b+percent,1));},blend:function(other){this.rgb.r=Math.floor((this.rgb.r+other.rgb.r)/2);this.rgb.g=Math.floor((this.rgb.g+other.rgb.g)/2);this.rgb.b=Math.floor((this.rgb.b+other.rgb.b)/2);},isBright:function(){var hsb=this.asHSB();return this.asHSB().b>0.5;},isDark:function(){return!this.isBright();},asRGB:function(){return"rgb("+this.rgb.r+","+this.rgb.g+","+this.rgb.b+")";},asHex:function(){return"#"+this.rgb.r.toColorPart()+this.rgb.g.toColorPart()+this.rgb.b.toColorPart();},asHSB:function(){return OpenLayers.Rico.Color.RGBtoHSB(this.rgb.r,this.rgb.g,this.rgb.b);},toString:function(){return this.asHex();}});OpenLayers.Rico.Color.createFromHex=function(hexCode){if(hexCode.length==4){var shortHexCode=hexCode;var hexCode='#';for(var i=1;i<4;i++){hexCode+=(shortHexCode.charAt(i)+
59533 shortHexCode.charAt(i));}}
59534 if(hexCode.indexOf('#')==0){hexCode=hexCode.substring(1);}
59535 var red=hexCode.substring(0,2);var green=hexCode.substring(2,4);var blue=hexCode.substring(4,6);return new OpenLayers.Rico.Color(parseInt(red,16),parseInt(green,16),parseInt(blue,16));};OpenLayers.Rico.Color.createColorFromBackground=function(elem){var actualColor=RicoUtil.getElementsComputedStyle(OpenLayers.Util.getElement(elem),"backgroundColor","background-color");if(actualColor=="transparent"&&elem.parentNode){return OpenLayers.Rico.Color.createColorFromBackground(elem.parentNode);}
59536 if(actualColor==null){return new OpenLayers.Rico.Color(255,255,255);}
59537 if(actualColor.indexOf("rgb(")==0){var colors=actualColor.substring(4,actualColor.length-1);var colorArray=colors.split(",");return new OpenLayers.Rico.Color(parseInt(colorArray[0]),parseInt(colorArray[1]),parseInt(colorArray[2]));}
59538 else if(actualColor.indexOf("#")==0){return OpenLayers.Rico.Color.createFromHex(actualColor);}
59539 else{return new OpenLayers.Rico.Color(255,255,255);}};OpenLayers.Rico.Color.HSBtoRGB=function(hue,saturation,brightness){var red=0;var green=0;var blue=0;if(saturation==0){red=parseInt(brightness*255.0+0.5);green=red;blue=red;}
59540 else{var h=(hue-Math.floor(hue))*6.0;var f=h-Math.floor(h);var p=brightness*(1.0-saturation);var q=brightness*(1.0-saturation*f);var t=brightness*(1.0-(saturation*(1.0-f)));switch(parseInt(h)){case 0:red=(brightness*255.0+0.5);green=(t*255.0+0.5);blue=(p*255.0+0.5);break;case 1:red=(q*255.0+0.5);green=(brightness*255.0+0.5);blue=(p*255.0+0.5);break;case 2:red=(p*255.0+0.5);green=(brightness*255.0+0.5);blue=(t*255.0+0.5);break;case 3:red=(p*255.0+0.5);green=(q*255.0+0.5);blue=(brightness*255.0+0.5);break;case 4:red=(t*255.0+0.5);green=(p*255.0+0.5);blue=(brightness*255.0+0.5);break;case 5:red=(brightness*255.0+0.5);green=(p*255.0+0.5);blue=(q*255.0+0.5);break;}}
59541 return{r:parseInt(red),g:parseInt(green),b:parseInt(blue)};};OpenLayers.Rico.Color.RGBtoHSB=function(r,g,b){var hue;var saturation;var brightness;var cmax=(r>g)?r:g;if(b>cmax){cmax=b;}
59542 var cmin=(r<g)?r:g;if(b<cmin){cmin=b;}
59543 brightness=cmax/255.0;if(cmax!=0){saturation=(cmax-cmin)/cmax;}else{saturation=0;}
59544 if(saturation==0){hue=0;}else{var redc=(cmax-r)/(cmax-cmin);var greenc=(cmax-g)/(cmax-cmin);var bluec=(cmax-b)/(cmax-cmin);if(r==cmax){hue=bluec-greenc;}else if(g==cmax){hue=2.0+redc-bluec;}else{hue=4.0+greenc-redc;}
59545 hue=hue/6.0;if(hue<0){hue=hue+1.0;}}
59546 return{h:hue,s:saturation,b:brightness};};OpenLayers.Bounds=OpenLayers.Class({left:null,bottom:null,right:null,top:null,centerLonLat:null,initialize:function(left,bottom,right,top){if(left!=null){this.left=OpenLayers.Util.toFloat(left);}
59547 if(bottom!=null){this.bottom=OpenLayers.Util.toFloat(bottom);}
59548 if(right!=null){this.right=OpenLayers.Util.toFloat(right);}
59549 if(top!=null){this.top=OpenLayers.Util.toFloat(top);}},clone:function(){return new OpenLayers.Bounds(this.left,this.bottom,this.right,this.top);},equals:function(bounds){var equals=false;if(bounds!=null){equals=((this.left==bounds.left)&&(this.right==bounds.right)&&(this.top==bounds.top)&&(this.bottom==bounds.bottom));}
59550 return equals;},toString:function(){return("left-bottom=("+this.left+","+this.bottom+")"
59551 +" right-top=("+this.right+","+this.top+")");},toArray:function(reverseAxisOrder){if(reverseAxisOrder===true){return[this.bottom,this.left,this.top,this.right];}else{return[this.left,this.bottom,this.right,this.top];}},toBBOX:function(decimal,reverseAxisOrder){if(decimal==null){decimal=6;}
59552 var mult=Math.pow(10,decimal);var xmin=Math.round(this.left*mult)/mult;var ymin=Math.round(this.bottom*mult)/mult;var xmax=Math.round(this.right*mult)/mult;var ymax=Math.round(this.top*mult)/mult;if(reverseAxisOrder===true){return ymin+","+xmin+","+ymax+","+xmax;}else{return xmin+","+ymin+","+xmax+","+ymax;}},toGeometry:function(){return new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(this.left,this.bottom),new OpenLayers.Geometry.Point(this.right,this.bottom),new OpenLayers.Geometry.Point(this.right,this.top),new OpenLayers.Geometry.Point(this.left,this.top)])]);},getWidth:function(){return(this.right-this.left);},getHeight:function(){return(this.top-this.bottom);},getSize:function(){return new OpenLayers.Size(this.getWidth(),this.getHeight());},getCenterPixel:function(){return new OpenLayers.Pixel((this.left+this.right)/2,(this.bottom+this.top)/2);},getCenterLonLat:function(){if(!this.centerLonLat){this.centerLonLat=new OpenLayers.LonLat((this.left+this.right)/2,(this.bottom+this.top)/2);}
59553 return this.centerLonLat;},scale:function(ratio,origin){if(origin==null){origin=this.getCenterLonLat();}
59554 var origx,origy;if(origin.CLASS_NAME=="OpenLayers.LonLat"){origx=origin.lon;origy=origin.lat;}else{origx=origin.x;origy=origin.y;}
59555 var left=(this.left-origx)*ratio+origx;var bottom=(this.bottom-origy)*ratio+origy;var right=(this.right-origx)*ratio+origx;var top=(this.top-origy)*ratio+origy;return new OpenLayers.Bounds(left,bottom,right,top);},add:function(x,y){if((x==null)||(y==null)){var msg=OpenLayers.i18n("boundsAddError");OpenLayers.Console.error(msg);return null;}
59556 return new OpenLayers.Bounds(this.left+x,this.bottom+y,this.right+x,this.top+y);},extend:function(object){var bounds=null;if(object){switch(object.CLASS_NAME){case"OpenLayers.LonLat":bounds=new OpenLayers.Bounds(object.lon,object.lat,object.lon,object.lat);break;case"OpenLayers.Geometry.Point":bounds=new OpenLayers.Bounds(object.x,object.y,object.x,object.y);break;case"OpenLayers.Bounds":bounds=object;break;}
59557 if(bounds){this.centerLonLat=null;if((this.left==null)||(bounds.left<this.left)){this.left=bounds.left;}
59558 if((this.bottom==null)||(bounds.bottom<this.bottom)){this.bottom=bounds.bottom;}
59559 if((this.right==null)||(bounds.right>this.right)){this.right=bounds.right;}
59560 if((this.top==null)||(bounds.top>this.top)){this.top=bounds.top;}}}},containsLonLat:function(ll,inclusive){return this.contains(ll.lon,ll.lat,inclusive);},containsPixel:function(px,inclusive){return this.contains(px.x,px.y,inclusive);},contains:function(x,y,inclusive){if(inclusive==null){inclusive=true;}
59561 if(x==null||y==null){return false;}
59562 x=OpenLayers.Util.toFloat(x);y=OpenLayers.Util.toFloat(y);var contains=false;if(inclusive){contains=((x>=this.left)&&(x<=this.right)&&(y>=this.bottom)&&(y<=this.top));}else{contains=((x>this.left)&&(x<this.right)&&(y>this.bottom)&&(y<this.top));}
59563 return contains;},intersectsBounds:function(bounds,inclusive){if(inclusive==null){inclusive=true;}
59564 var intersects=false;var mightTouch=(this.left==bounds.right||this.right==bounds.left||this.top==bounds.bottom||this.bottom==bounds.top);if(inclusive||!mightTouch){var inBottom=(((bounds.bottom>=this.bottom)&&(bounds.bottom<=this.top))||((this.bottom>=bounds.bottom)&&(this.bottom<=bounds.top)));var inTop=(((bounds.top>=this.bottom)&&(bounds.top<=this.top))||((this.top>bounds.bottom)&&(this.top<bounds.top)));var inLeft=(((bounds.left>=this.left)&&(bounds.left<=this.right))||((this.left>=bounds.left)&&(this.left<=bounds.right)));var inRight=(((bounds.right>=this.left)&&(bounds.right<=this.right))||((this.right>=bounds.left)&&(this.right<=bounds.right)));intersects=((inBottom||inTop)&&(inLeft||inRight));}
59565 return intersects;},containsBounds:function(bounds,partial,inclusive){if(partial==null){partial=false;}
59566 if(inclusive==null){inclusive=true;}
59567 var bottomLeft=this.contains(bounds.left,bounds.bottom,inclusive);var bottomRight=this.contains(bounds.right,bounds.bottom,inclusive);var topLeft=this.contains(bounds.left,bounds.top,inclusive);var topRight=this.contains(bounds.right,bounds.top,inclusive);return(partial)?(bottomLeft||bottomRight||topLeft||topRight):(bottomLeft&&bottomRight&&topLeft&&topRight);},determineQuadrant:function(lonlat){var quadrant="";var center=this.getCenterLonLat();quadrant+=(lonlat.lat<center.lat)?"b":"t";quadrant+=(lonlat.lon<center.lon)?"l":"r";return quadrant;},transform:function(source,dest){this.centerLonLat=null;var ll=OpenLayers.Projection.transform({'x':this.left,'y':this.bottom},source,dest);var lr=OpenLayers.Projection.transform({'x':this.right,'y':this.bottom},source,dest);var ul=OpenLayers.Projection.transform({'x':this.left,'y':this.top},source,dest);var ur=OpenLayers.Projection.transform({'x':this.right,'y':this.top},source,dest);this.left=Math.min(ll.x,ul.x);this.bottom=Math.min(ll.y,lr.y);this.right=Math.max(lr.x,ur.x);this.top=Math.max(ul.y,ur.y);return this;},wrapDateLine:function(maxExtent,options){options=options||{};var leftTolerance=options.leftTolerance||0;var rightTolerance=options.rightTolerance||0;var newBounds=this.clone();if(maxExtent){while(newBounds.left<maxExtent.left&&(newBounds.right-rightTolerance)<=maxExtent.left){newBounds=newBounds.add(maxExtent.getWidth(),0);}
59568 while((newBounds.left+leftTolerance)>=maxExtent.right&&newBounds.right>maxExtent.right){newBounds=newBounds.add(-maxExtent.getWidth(),0);}}
59569 return newBounds;},CLASS_NAME:"OpenLayers.Bounds"});OpenLayers.Bounds.fromString=function(str){var bounds=str.split(",");return OpenLayers.Bounds.fromArray(bounds);};OpenLayers.Bounds.fromArray=function(bbox){return new OpenLayers.Bounds(parseFloat(bbox[0]),parseFloat(bbox[1]),parseFloat(bbox[2]),parseFloat(bbox[3]));};OpenLayers.Bounds.fromSize=function(size){return new OpenLayers.Bounds(0,size.h,size.w,0);};OpenLayers.Bounds.oppositeQuadrant=function(quadrant){var opp="";opp+=(quadrant.charAt(0)=='t')?'b':'t';opp+=(quadrant.charAt(1)=='l')?'r':'l';return opp;};OpenLayers.LonLat=OpenLayers.Class({lon:0.0,lat:0.0,initialize:function(lon,lat){this.lon=OpenLayers.Util.toFloat(lon);this.lat=OpenLayers.Util.toFloat(lat);},toString:function(){return("lon="+this.lon+",lat="+this.lat);},toShortString:function(){return(this.lon+", "+this.lat);},clone:function(){return new OpenLayers.LonLat(this.lon,this.lat);},add:function(lon,lat){if((lon==null)||(lat==null)){var msg=OpenLayers.i18n("lonlatAddError");OpenLayers.Console.error(msg);return null;}
59570 return new OpenLayers.LonLat(this.lon+OpenLayers.Util.toFloat(lon),this.lat+OpenLayers.Util.toFloat(lat));},equals:function(ll){var equals=false;if(ll!=null){equals=((this.lon==ll.lon&&this.lat==ll.lat)||(isNaN(this.lon)&&isNaN(this.lat)&&isNaN(ll.lon)&&isNaN(ll.lat)));}
59571 return equals;},transform:function(source,dest){var point=OpenLayers.Projection.transform({'x':this.lon,'y':this.lat},source,dest);this.lon=point.x;this.lat=point.y;return this;},wrapDateLine:function(maxExtent){var newLonLat=this.clone();if(maxExtent){while(newLonLat.lon<maxExtent.left){newLonLat.lon+=maxExtent.getWidth();}
59572 while(newLonLat.lon>maxExtent.right){newLonLat.lon-=maxExtent.getWidth();}}
59573 return newLonLat;},CLASS_NAME:"OpenLayers.LonLat"});OpenLayers.LonLat.fromString=function(str){var pair=str.split(",");return new OpenLayers.LonLat(pair[0],pair[1]);};OpenLayers.Pixel=OpenLayers.Class({x:0.0,y:0.0,initialize:function(x,y){this.x=parseFloat(x);this.y=parseFloat(y);},toString:function(){return("x="+this.x+",y="+this.y);},clone:function(){return new OpenLayers.Pixel(this.x,this.y);},equals:function(px){var equals=false;if(px!=null){equals=((this.x==px.x&&this.y==px.y)||(isNaN(this.x)&&isNaN(this.y)&&isNaN(px.x)&&isNaN(px.y)));}
59574 return equals;},add:function(x,y){if((x==null)||(y==null)){var msg=OpenLayers.i18n("pixelAddError");OpenLayers.Console.error(msg);return null;}
59575 return new OpenLayers.Pixel(this.x+x,this.y+y);},offset:function(px){var newPx=this.clone();if(px){newPx=this.add(px.x,px.y);}
59576 return newPx;},CLASS_NAME:"OpenLayers.Pixel"});OpenLayers.Control=OpenLayers.Class({id:null,map:null,div:null,type:null,allowSelection:false,displayClass:"",title:"",autoActivate:false,active:null,handler:null,eventListeners:null,events:null,EVENT_TYPES:["activate","deactivate"],initialize:function(options){this.displayClass=this.CLASS_NAME.replace("OpenLayers.","ol").replace(/\./g,"");OpenLayers.Util.extend(this,options);this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}
59577 if(this.id==null){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");}},destroy:function(){if(this.events){if(this.eventListeners){this.events.un(this.eventListeners);}
59578 this.events.destroy();this.events=null;}
59579 this.eventListeners=null;if(this.handler){this.handler.destroy();this.handler=null;}
59580 if(this.handlers){for(var key in this.handlers){if(this.handlers.hasOwnProperty(key)&&typeof this.handlers[key].destroy=="function"){this.handlers[key].destroy();}}
59581 this.handlers=null;}
59582 if(this.map){this.map.removeControl(this);this.map=null;}},setMap:function(map){this.map=map;if(this.handler){this.handler.setMap(map);}},draw:function(px){if(this.div==null){this.div=OpenLayers.Util.createDiv(this.id);this.div.className=this.displayClass;if(!this.allowSelection){this.div.className+=" olControlNoSelect";this.div.setAttribute("unselectable","on",0);this.div.onselectstart=OpenLayers.Function.False;}
59583 if(this.title!=""){this.div.title=this.title;}}
59584 if(px!=null){this.position=px.clone();}
59585 this.moveTo(this.position);return this.div;},moveTo:function(px){if((px!=null)&&(this.div!=null)){this.div.style.left=px.x+"px";this.div.style.top=px.y+"px";}},activate:function(){if(this.active){return false;}
59586 if(this.handler){this.handler.activate();}
59587 this.active=true;if(this.map){OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");}
59588 this.events.triggerEvent("activate");return true;},deactivate:function(){if(this.active){if(this.handler){this.handler.deactivate();}
59589 this.active=false;if(this.map){OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");}
59590 this.events.triggerEvent("deactivate");return true;}
59591 return false;},CLASS_NAME:"OpenLayers.Control"});OpenLayers.Control.TYPE_BUTTON=1;OpenLayers.Control.TYPE_TOGGLE=2;OpenLayers.Control.TYPE_TOOL=3;OpenLayers.Lang={code:null,defaultCode:"en",getCode:function(){if(!OpenLayers.Lang.code){OpenLayers.Lang.setCode();}
59592 return OpenLayers.Lang.code;},setCode:function(code){var lang;if(!code){code=(OpenLayers.Util.getBrowserName()=="msie")?navigator.userLanguage:navigator.language;}
59593 var parts=code.split('-');parts[0]=parts[0].toLowerCase();if(typeof OpenLayers.Lang[parts[0]]=="object"){lang=parts[0];}
59594 if(parts[1]){var testLang=parts[0]+'-'+parts[1].toUpperCase();if(typeof OpenLayers.Lang[testLang]=="object"){lang=testLang;}}
59595 if(!lang){OpenLayers.Console.warn('Failed to find OpenLayers.Lang.'+parts.join("-")+' dictionary, falling back to default language');lang=OpenLayers.Lang.defaultCode;}
59596 OpenLayers.Lang.code=lang;},translate:function(key,context){var dictionary=OpenLayers.Lang[OpenLayers.Lang.getCode()];var message=dictionary[key];if(!message){message=key;}
59597 if(context){message=OpenLayers.String.format(message,context);}
59598 return message;}};OpenLayers.i18n=OpenLayers.Lang.translate;OpenLayers.Popup.Anchored=OpenLayers.Class(OpenLayers.Popup,{relativePosition:null,keepInMap:true,anchor:null,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){var newArguments=[id,lonlat,contentSize,contentHTML,closeBox,closeBoxCallback];OpenLayers.Popup.prototype.initialize.apply(this,newArguments);this.anchor=(anchor!=null)?anchor:{size:new OpenLayers.Size(0,0),offset:new OpenLayers.Pixel(0,0)};},destroy:function(){this.anchor=null;this.relativePosition=null;OpenLayers.Popup.prototype.destroy.apply(this,arguments);},show:function(){this.updatePosition();OpenLayers.Popup.prototype.show.apply(this,arguments);},moveTo:function(px){var oldRelativePosition=this.relativePosition;this.relativePosition=this.calculateRelativePosition(px);var newPx=this.calculateNewPx(px);var newArguments=new Array(newPx);OpenLayers.Popup.prototype.moveTo.apply(this,newArguments);if(this.relativePosition!=oldRelativePosition){this.updateRelativePosition();}},setSize:function(contentSize){OpenLayers.Popup.prototype.setSize.apply(this,arguments);if((this.lonlat)&&(this.map)){var px=this.map.getLayerPxFromLonLat(this.lonlat);this.moveTo(px);}},calculateRelativePosition:function(px){var lonlat=this.map.getLonLatFromLayerPx(px);var extent=this.map.getExtent();var quadrant=extent.determineQuadrant(lonlat);return OpenLayers.Bounds.oppositeQuadrant(quadrant);},updateRelativePosition:function(){},calculateNewPx:function(px){var newPx=px.offset(this.anchor.offset);var size=this.size||this.contentSize;var top=(this.relativePosition.charAt(0)=='t');newPx.y+=(top)?-(size.h+this.anchor.size.h):this.anchor.size.h;var left=(this.relativePosition.charAt(1)=='l');newPx.x+=(left)?-(size.w+this.anchor.size.w):this.anchor.size.w;return newPx;},CLASS_NAME:"OpenLayers.Popup.Anchored"});OpenLayers.Protocol.SOS=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Protocol.SOS.DEFAULTS);var cls=OpenLayers.Protocol.SOS["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported SOS version: "+options.version;}
59599 return new cls(options);};OpenLayers.Protocol.SOS.DEFAULTS={"version":"1.0.0"};OpenLayers.Protocol.SQL=OpenLayers.Class(OpenLayers.Protocol,{databaseName:'ol',tableName:"ol_vector_features",postReadFiltering:true,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);},destroy:function(){OpenLayers.Protocol.prototype.destroy.apply(this);},supported:function(){return false;},evaluateFilter:function(feature,filter){return filter&&this.postReadFiltering?filter.evaluate(feature):true;},CLASS_NAME:"OpenLayers.Protocol.SQL"});OpenLayers.Protocol.WFS=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Protocol.WFS.DEFAULTS);var cls=OpenLayers.Protocol.WFS["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported WFS version: "+options.version;}
59600 return new cls(options);};OpenLayers.Protocol.WFS.fromWMSLayer=function(layer,options){var typeName,featurePrefix;var param=layer.params["LAYERS"];var parts=(param instanceof Array?param[0]:param).split(":");if(parts.length>1){featurePrefix=parts[0];}
59601 typeName=parts.pop();var protocolOptions={url:layer.url,featureType:typeName,featurePrefix:featurePrefix,srsName:layer.projection&&layer.projection.getCode()||layer.map&&layer.map.getProjectionObject().getCode(),version:"1.1.0"};return new OpenLayers.Protocol.WFS(OpenLayers.Util.applyDefaults(options,protocolOptions));};OpenLayers.Protocol.WFS.DEFAULTS={"version":"1.0.0"};OpenLayers.Renderer.Canvas=OpenLayers.Class(OpenLayers.Renderer,{canvas:null,features:null,initialize:function(containerID){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.root=document.createElement("canvas");this.container.appendChild(this.root);this.canvas=this.root.getContext("2d");this.features={};},eraseGeometry:function(geometry,featureId){this.eraseFeatures(this.features[featureId][0]);},supported:function(){var canvas=document.createElement("canvas");return!!canvas.getContext;},setExtent:function(extent){this.extent=extent.clone();this.resolution=null;this.redraw();},setSize:function(size){this.size=size.clone();this.root.style.width=size.w+"px";this.root.style.height=size.h+"px";this.root.width=size.w;this.root.height=size.h;this.resolution=null;},drawFeature:function(feature,style){style=style||feature.style;style=this.applyDefaultSymbolizer(style);this.features[feature.id]=[feature,style];this.redraw();},drawGeometry:function(geometry,style){var className=geometry.CLASS_NAME;if((className=="OpenLayers.Geometry.Collection")||(className=="OpenLayers.Geometry.MultiPoint")||(className=="OpenLayers.Geometry.MultiLineString")||(className=="OpenLayers.Geometry.MultiPolygon")){for(var i=0;i<geometry.components.length;i++){this.drawGeometry(geometry.components[i],style);}
59602 return;}
59603 switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":this.drawPoint(geometry,style);break;case"OpenLayers.Geometry.LineString":this.drawLineString(geometry,style);break;case"OpenLayers.Geometry.LinearRing":this.drawLinearRing(geometry,style);break;case"OpenLayers.Geometry.Polygon":this.drawPolygon(geometry,style);break;default:break;}},drawExternalGraphic:function(pt,style){var img=new Image();if(style.graphicTitle){img.title=style.graphicTitle;}
59604 var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);var context={img:img,x:(pt[0]+xOffset),y:(pt[1]+yOffset),width:width,height:height,opacity:style.graphicOpacity||style.fillOpacity,canvas:this.canvas};img.onload=OpenLayers.Function.bind(function(){this.canvas.globalAlpha=this.opacity;this.canvas.drawImage(this.img,this.x,this.y,this.width,this.height);},context);img.src=style.externalGraphic;},setCanvasStyle:function(type,style){if(type=="fill"){this.canvas.globalAlpha=style['fillOpacity'];this.canvas.fillStyle=style['fillColor'];}else if(type=="stroke"){this.canvas.globalAlpha=style['strokeOpacity'];this.canvas.strokeStyle=style['strokeColor'];this.canvas.lineWidth=style['strokeWidth'];}else{this.canvas.globalAlpha=0;this.canvas.lineWidth=1;}},drawPoint:function(geometry,style){if(style.graphic!==false){var pt=this.getLocalXY(geometry);if(style.externalGraphic){this.drawExternalGraphic(pt,style);}else{if(style.fill!==false){this.setCanvasStyle("fill",style);this.canvas.beginPath();this.canvas.arc(pt[0],pt[1],style.pointRadius,0,Math.PI*2,true);this.canvas.fill();}
59605 if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();this.canvas.arc(pt[0],pt[1],style.pointRadius,0,Math.PI*2,true);this.canvas.stroke();this.setCanvasStyle("reset");}}}},drawLineString:function(geometry,style){if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
59606 this.canvas.stroke();}
59607 this.setCanvasStyle("reset");},drawLinearRing:function(geometry,style){if(style.fill!==false){this.setCanvasStyle("fill",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length-1;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
59608 this.canvas.fill();}
59609 if(style.stroke!==false){this.setCanvasStyle("stroke",style);this.canvas.beginPath();var start=this.getLocalXY(geometry.components[0]);this.canvas.moveTo(start[0],start[1]);for(var i=1;i<geometry.components.length;i++){var pt=this.getLocalXY(geometry.components[i]);this.canvas.lineTo(pt[0],pt[1]);}
59610 this.canvas.stroke();}
59611 this.setCanvasStyle("reset");},drawPolygon:function(geometry,style){this.drawLinearRing(geometry.components[0],style);for(var i=1;i<geometry.components.length;i++){this.drawLinearRing(geometry.components[i],{fillOpacity:0,strokeWidth:0,strokeOpacity:0,strokeColor:'#000000',fillColor:'#000000'});}},drawText:function(location,style){style=OpenLayers.Util.extend({fontColor:"#000000",labelAlign:"cm"},style);var pt=this.getLocalXY(location);this.setCanvasStyle("reset");this.canvas.fillStyle=style.fontColor;this.canvas.globalAlpha=style.fontOpacity||1.0;var fontStyle=style.fontWeight+" "+style.fontSize+" "+style.fontFamily;if(this.canvas.fillText){var labelAlign=OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[0]]||"center";this.canvas.font=fontStyle;this.canvas.textAlign=labelAlign;this.canvas.fillText(style.label,pt[0],pt[1]);}else if(this.canvas.mozDrawText){this.canvas.mozTextStyle=fontStyle;var len=this.canvas.mozMeasureText(style.label);switch(style.labelAlign[0]){case"l":break;case"r":pt[0]-=len;break;case"c":default:pt[0]-=len/2;}
59612 this.canvas.translate(pt[0],pt[1]);this.canvas.mozDrawText(style.label);this.canvas.translate(-1*pt[0],-1*pt[1]);}
59613 this.setCanvasStyle("reset");},getLocalXY:function(point){var resolution=this.getResolution();var extent=this.extent;var x=(point.x/resolution+(-extent.left/resolution));var y=((extent.top/resolution)-point.y/resolution);return[x,y];},clear:function(){this.canvas.clearRect(0,0,this.root.width,this.root.height);this.features={};},getFeatureIdFromEvent:function(evt){var loc=this.map.getLonLatFromPixel(evt.xy);var resolution=this.getResolution();var bounds=new OpenLayers.Bounds(loc.lon-resolution*5,loc.lat-resolution*5,loc.lon+resolution*5,loc.lat+resolution*5);var geom=bounds.toGeometry();for(var feat in this.features){if(!this.features.hasOwnProperty(feat)){continue;}
59614 if(this.features[feat][0].geometry.intersects(geom)){return feat;}}
59615 return null;},eraseFeatures:function(features){if(!(features instanceof Array)){features=[features];}
59616 for(var i=0;i<features.length;++i){delete this.features[features[i].id];}
59617 this.redraw();},redraw:function(){if(!this.locked){this.canvas.clearRect(0,0,this.root.width,this.root.height);var labelMap=[];var feature,style;for(var id in this.features){if(!this.features.hasOwnProperty(id)){continue;}
59618 feature=this.features[id][0];style=this.features[id][1];if(!feature.geometry){continue;}
59619 this.drawGeometry(feature.geometry,style);if(style.label){labelMap.push([feature,style]);}}
59620 var item;for(var i=0,len=labelMap.length;i<len;++i){item=labelMap[i];this.drawText(item[0].geometry.getCentroid(),item[1]);}}},CLASS_NAME:"OpenLayers.Renderer.Canvas"});OpenLayers.Renderer.Canvas.LABEL_ALIGN={"l":"left","r":"right"};OpenLayers.ElementsIndexer=OpenLayers.Class({maxZIndex:null,order:null,indices:null,compare:null,initialize:function(yOrdering){this.compare=yOrdering?OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_Y_ORDER:OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_DRAWING_ORDER;this.order=[];this.indices={};this.maxZIndex=0;},insert:function(newNode){if(this.exists(newNode)){this.remove(newNode);}
59621 var nodeId=newNode.id;this.determineZIndex(newNode);var leftIndex=-1;var rightIndex=this.order.length;var middle;while(rightIndex-leftIndex>1){middle=parseInt((leftIndex+rightIndex)/2);var placement=this.compare(this,newNode,OpenLayers.Util.getElement(this.order[middle]));if(placement>0){leftIndex=middle;}else{rightIndex=middle;}}
59622 this.order.splice(rightIndex,0,nodeId);this.indices[nodeId]=this.getZIndex(newNode);return this.getNextElement(rightIndex);},remove:function(node){var nodeId=node.id;var arrayIndex=OpenLayers.Util.indexOf(this.order,nodeId);if(arrayIndex>=0){this.order.splice(arrayIndex,1);delete this.indices[nodeId];if(this.order.length>0){var lastId=this.order[this.order.length-1];this.maxZIndex=this.indices[lastId];}else{this.maxZIndex=0;}}},clear:function(){this.order=[];this.indices={};this.maxZIndex=0;},exists:function(node){return(this.indices[node.id]!=null);},getZIndex:function(node){return node._style.graphicZIndex;},determineZIndex:function(node){var zIndex=node._style.graphicZIndex;if(zIndex==null){zIndex=this.maxZIndex;node._style.graphicZIndex=zIndex;}else if(zIndex>this.maxZIndex){this.maxZIndex=zIndex;}},getNextElement:function(index){var nextIndex=index+1;if(nextIndex<this.order.length){var nextElement=OpenLayers.Util.getElement(this.order[nextIndex]);if(nextElement==undefined){nextElement=this.getNextElement(nextIndex);}
59623 return nextElement;}else{return null;}},CLASS_NAME:"OpenLayers.ElementsIndexer"});OpenLayers.ElementsIndexer.IndexingMethods={Z_ORDER:function(indexer,newNode,nextNode){var newZIndex=indexer.getZIndex(newNode);var returnVal=0;if(nextNode){var nextZIndex=indexer.getZIndex(nextNode);returnVal=newZIndex-nextZIndex;}
59624 return returnVal;},Z_ORDER_DRAWING_ORDER:function(indexer,newNode,nextNode){var returnVal=OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(indexer,newNode,nextNode);if(nextNode&&returnVal==0){returnVal=1;}
59625 return returnVal;},Z_ORDER_Y_ORDER:function(indexer,newNode,nextNode){var returnVal=OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(indexer,newNode,nextNode);if(nextNode&&returnVal===0){var result=nextNode._boundsBottom-newNode._boundsBottom;returnVal=(result===0)?1:result;}
59626 return returnVal;}};OpenLayers.Renderer.Elements=OpenLayers.Class(OpenLayers.Renderer,{rendererRoot:null,root:null,vectorRoot:null,textRoot:null,xmlns:null,indexer:null,BACKGROUND_ID_SUFFIX:"_background",LABEL_ID_SUFFIX:"_label",initialize:function(containerID,options){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.rendererRoot=this.createRenderRoot();this.root=this.createRoot("_root");this.vectorRoot=this.createRoot("_vroot");this.textRoot=this.createRoot("_troot");this.root.appendChild(this.vectorRoot);this.root.appendChild(this.textRoot);this.rendererRoot.appendChild(this.root);this.container.appendChild(this.rendererRoot);if(options&&(options.zIndexing||options.yOrdering)){this.indexer=new OpenLayers.ElementsIndexer(options.yOrdering);}},destroy:function(){this.clear();this.rendererRoot=null;this.root=null;this.xmlns=null;OpenLayers.Renderer.prototype.destroy.apply(this,arguments);},clear:function(){var child;var root=this.vectorRoot;if(root){while(child=root.firstChild){root.removeChild(child);}}
59627 root=this.textRoot;if(root){while(child=root.firstChild){root.removeChild(child);}}
59628 if(this.indexer){this.indexer.clear();}},getNodeType:function(geometry,style){},drawGeometry:function(geometry,style,featureId){var className=geometry.CLASS_NAME;var rendered=true;if((className=="OpenLayers.Geometry.Collection")||(className=="OpenLayers.Geometry.MultiPoint")||(className=="OpenLayers.Geometry.MultiLineString")||(className=="OpenLayers.Geometry.MultiPolygon")){for(var i=0,len=geometry.components.length;i<len;i++){rendered=this.drawGeometry(geometry.components[i],style,featureId)&&rendered;}
59629 return rendered;};rendered=false;if(style.display!="none"){if(style.backgroundGraphic){this.redrawBackgroundNode(geometry.id,geometry,style,featureId);}
59630 rendered=this.redrawNode(geometry.id,geometry,style,featureId);}
59631 if(rendered==false){var node=document.getElementById(geometry.id);if(node){if(node._style.backgroundGraphic){node.parentNode.removeChild(document.getElementById(geometry.id+this.BACKGROUND_ID_SUFFIX));}
59632 node.parentNode.removeChild(node);}}
59633 return rendered;},redrawNode:function(id,geometry,style,featureId){style=this.applyDefaultSymbolizer(style);var node=this.nodeFactory(id,this.getNodeType(geometry,style));node._featureId=featureId;node._boundsBottom=geometry.getBounds().bottom;node._geometryClass=geometry.CLASS_NAME;node._style=style;var drawResult=this.drawGeometryNode(node,geometry,style);if(drawResult===false){return false;}
59634 node=drawResult.node;if(this.indexer){var insert=this.indexer.insert(node);if(insert){this.vectorRoot.insertBefore(node,insert);}else{this.vectorRoot.appendChild(node);}}else{if(node.parentNode!==this.vectorRoot){this.vectorRoot.appendChild(node);}}
59635 this.postDraw(node);return drawResult.complete;},redrawBackgroundNode:function(id,geometry,style,featureId){var backgroundStyle=OpenLayers.Util.extend({},style);backgroundStyle.externalGraphic=backgroundStyle.backgroundGraphic;backgroundStyle.graphicXOffset=backgroundStyle.backgroundXOffset;backgroundStyle.graphicYOffset=backgroundStyle.backgroundYOffset;backgroundStyle.graphicZIndex=backgroundStyle.backgroundGraphicZIndex;backgroundStyle.graphicWidth=backgroundStyle.backgroundWidth||backgroundStyle.graphicWidth;backgroundStyle.graphicHeight=backgroundStyle.backgroundHeight||backgroundStyle.graphicHeight;backgroundStyle.backgroundGraphic=null;backgroundStyle.backgroundXOffset=null;backgroundStyle.backgroundYOffset=null;backgroundStyle.backgroundGraphicZIndex=null;return this.redrawNode(id+this.BACKGROUND_ID_SUFFIX,geometry,backgroundStyle,null);},drawGeometryNode:function(node,geometry,style){style=style||node._style;var options={'isFilled':style.fill===undefined?true:style.fill,'isStroked':style.stroke===undefined?!!style.strokeWidth:style.stroke};var drawn;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.graphic===false){options.isFilled=false;options.isStroked=false;}
59636 drawn=this.drawPoint(node,geometry);break;case"OpenLayers.Geometry.LineString":options.isFilled=false;drawn=this.drawLineString(node,geometry);break;case"OpenLayers.Geometry.LinearRing":drawn=this.drawLinearRing(node,geometry);break;case"OpenLayers.Geometry.Polygon":drawn=this.drawPolygon(node,geometry);break;case"OpenLayers.Geometry.Surface":drawn=this.drawSurface(node,geometry);break;case"OpenLayers.Geometry.Rectangle":drawn=this.drawRectangle(node,geometry);break;default:break;}
59637 node._options=options;if(drawn!=false){return{node:this.setStyle(node,style,options,geometry),complete:drawn};}else{return false;}},postDraw:function(node){},drawPoint:function(node,geometry){},drawLineString:function(node,geometry){},drawLinearRing:function(node,geometry){},drawPolygon:function(node,geometry){},drawRectangle:function(node,geometry){},drawCircle:function(node,geometry){},drawSurface:function(node,geometry){},removeText:function(featureId){var label=document.getElementById(featureId+this.LABEL_ID_SUFFIX);if(label){this.textRoot.removeChild(label);}},getFeatureIdFromEvent:function(evt){var target=evt.target;var useElement=target&&target.correspondingUseElement;var node=useElement?useElement:(target||evt.srcElement);var featureId=node._featureId;return featureId;},eraseGeometry:function(geometry,featureId){if((geometry.CLASS_NAME=="OpenLayers.Geometry.MultiPoint")||(geometry.CLASS_NAME=="OpenLayers.Geometry.MultiLineString")||(geometry.CLASS_NAME=="OpenLayers.Geometry.MultiPolygon")||(geometry.CLASS_NAME=="OpenLayers.Geometry.Collection")){for(var i=0,len=geometry.components.length;i<len;i++){this.eraseGeometry(geometry.components[i],featureId);}}else{var element=OpenLayers.Util.getElement(geometry.id);if(element&&element.parentNode){if(element.geometry){element.geometry.destroy();element.geometry=null;}
59638 element.parentNode.removeChild(element);if(this.indexer){this.indexer.remove(element);}
59639 if(element._style.backgroundGraphic){var backgroundId=geometry.id+this.BACKGROUND_ID_SUFFIX;var bElem=OpenLayers.Util.getElement(backgroundId);if(bElem&&bElem.parentNode){bElem.parentNode.removeChild(bElem);}}}}},nodeFactory:function(id,type){var node=OpenLayers.Util.getElement(id);if(node){if(!this.nodeTypeCompare(node,type)){node.parentNode.removeChild(node);node=this.nodeFactory(id,type);}}else{node=this.createNode(type,id);}
59640 return node;},nodeTypeCompare:function(node,type){},createNode:function(type,id){},moveRoot:function(renderer){var root=this.root;if(renderer.root.parentNode==this.rendererRoot){root=renderer.root;}
59641 root.parentNode.removeChild(root);renderer.rendererRoot.appendChild(root);},getRenderLayerId:function(){return this.root.parentNode.parentNode.id;},isComplexSymbol:function(graphicName){return(graphicName!="circle")&&!!graphicName;},CLASS_NAME:"OpenLayers.Renderer.Elements"});OpenLayers.Renderer.symbol={"star":[350,75,379,161,469,161,397,215,423,301,350,250,277,301,303,215,231,161,321,161,350,75],"cross":[4,0,6,0,6,4,10,4,10,6,6,6,6,10,4,10,4,6,0,6,0,4,4,4,4,0],"x":[0,0,25,0,50,35,75,0,100,0,65,50,100,100,75,100,50,65,25,100,0,100,35,50,0,0],"square":[0,0,0,1,1,1,1,0,0,0],"triangle":[0,10,10,10,5,0,0,10]};OpenLayers.Strategy.Cluster=OpenLayers.Class(OpenLayers.Strategy,{distance:20,threshold:null,features:null,clusters:null,clustering:false,resolution:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"beforefeaturesadded":this.cacheFeatures,"moveend":this.cluster,scope:this});}
59642 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.clearCache();this.layer.events.un({"beforefeaturesadded":this.cacheFeatures,"moveend":this.cluster,scope:this});}
59643 return deactivated;},cacheFeatures:function(event){var propagate=true;if(!this.clustering){this.clearCache();this.features=event.features;this.cluster();propagate=false;}
59644 return propagate;},clearCache:function(){this.features=null;},cluster:function(event){if((!event||event.zoomChanged)&&this.features){var resolution=this.layer.map.getResolution();if(resolution!=this.resolution||!this.clustersExist()){this.resolution=resolution;var clusters=[];var feature,clustered,cluster;for(var i=0;i<this.features.length;++i){feature=this.features[i];if(feature.geometry){clustered=false;for(var j=clusters.length-1;j>=0;--j){cluster=clusters[j];if(this.shouldCluster(cluster,feature)){this.addToCluster(cluster,feature);clustered=true;break;}}
59645 if(!clustered){clusters.push(this.createCluster(this.features[i]));}}}
59646 this.layer.removeAllFeatures();if(clusters.length>0){if(this.threshold>1){var clone=clusters.slice();clusters=[];var candidate;for(var i=0,len=clone.length;i<len;++i){candidate=clone[i];if(candidate.attributes.count<this.threshold){Array.prototype.push.apply(clusters,candidate.cluster);}else{clusters.push(candidate);}}}
59647 this.clustering=true;this.layer.addFeatures(clusters);this.clustering=false;}
59648 this.clusters=clusters;}}},clustersExist:function(){var exist=false;if(this.clusters&&this.clusters.length>0&&this.clusters.length==this.layer.features.length){exist=true;for(var i=0;i<this.clusters.length;++i){if(this.clusters[i]!=this.layer.features[i]){exist=false;break;}}}
59649 return exist;},shouldCluster:function(cluster,feature){var cc=cluster.geometry.getBounds().getCenterLonLat();var fc=feature.geometry.getBounds().getCenterLonLat();var distance=(Math.sqrt(Math.pow((cc.lon-fc.lon),2)+Math.pow((cc.lat-fc.lat),2))/this.resolution);return(distance<=this.distance);},addToCluster:function(cluster,feature){cluster.cluster.push(feature);cluster.attributes.count+=1;},createCluster:function(feature){var center=feature.geometry.getBounds().getCenterLonLat();var cluster=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(center.lon,center.lat),{count:1});cluster.cluster=[feature];return cluster;},CLASS_NAME:"OpenLayers.Strategy.Cluster"});OpenLayers.Strategy.Fixed=OpenLayers.Class(OpenLayers.Strategy,{preload:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},destroy:function(){OpenLayers.Strategy.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Strategy.prototype.activate.apply(this,arguments)){this.layer.events.on({"refresh":this.load,scope:this});if(this.layer.visibility==true||this.preload){this.load();}else{this.layer.events.on({"visibilitychanged":this.load,scope:this});}
59650 return true;}
59651 return false;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.layer.events.un({"refresh":this.load,"visibilitychanged":this.load,scope:this});}
59652 return deactivated;},load:function(options){this.layer.events.triggerEvent("loadstart");this.layer.protocol.read(OpenLayers.Util.applyDefaults({callback:this.merge,filter:this.layer.filter,scope:this},options));this.layer.events.un({"visibilitychanged":this.load,scope:this});},merge:function(resp){this.layer.destroyFeatures();var features=resp.features;if(features&&features.length>0){var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var geom;for(var i=0,len=features.length;i<len;++i){geom=features[i].geometry;if(geom){geom.transform(remote,local);}}}
59653 this.layer.addFeatures(features);}
59654 this.layer.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Strategy.Fixed"});OpenLayers.Strategy.Paging=OpenLayers.Class(OpenLayers.Strategy,{features:null,length:10,num:null,paging:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"beforefeaturesadded":this.cacheFeatures,scope:this});}
59655 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.clearCache();this.layer.events.un({"beforefeaturesadded":this.cacheFeatures,scope:this});}
59656 return deactivated;},cacheFeatures:function(event){if(!this.paging){this.clearCache();this.features=event.features;this.pageNext(event);}},clearCache:function(){if(this.features){for(var i=0;i<this.features.length;++i){this.features[i].destroy();}}
59657 this.features=null;this.num=null;},pageCount:function(){var numFeatures=this.features?this.features.length:0;return Math.ceil(numFeatures/this.length);},pageNum:function(){return this.num;},pageLength:function(newLength){if(newLength&&newLength>0){this.length=newLength;}
59658 return this.length;},pageNext:function(event){var changed=false;if(this.features){if(this.num===null){this.num=-1;}
59659 var start=(this.num+1)*this.length;changed=this.page(start,event);}
59660 return changed;},pagePrevious:function(){var changed=false;if(this.features){if(this.num===null){this.num=this.pageCount();}
59661 var start=(this.num-1)*this.length;changed=this.page(start);}
59662 return changed;},page:function(start,event){var changed=false;if(this.features){if(start>=0&&start<this.features.length){var num=Math.floor(start/this.length);if(num!=this.num){this.paging=true;var features=this.features.slice(start,start+this.length);this.layer.removeFeatures(this.layer.features);this.num=num;if(event&&event.features){event.features=features;}else{this.layer.addFeatures(features);}
59663 this.paging=false;changed=true;}}}
59664 return changed;},CLASS_NAME:"OpenLayers.Strategy.Paging"});OpenLayers.Strategy.Refresh=OpenLayers.Class(OpenLayers.Strategy,{force:false,interval:0,timer:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){if(this.layer.visibility===true){this.start();}
59665 this.layer.events.on({"visibilitychanged":this.reset,scope:this});}
59666 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.stop();}
59667 return deactivated;},reset:function(){if(this.layer.visibility===true){this.start();}else{this.stop();}},start:function(){if(this.interval&&typeof this.interval==="number"&&this.interval>0){this.timer=window.setInterval(OpenLayers.Function.bind(this.refresh,this),this.interval);}},refresh:function(){if(this.layer&&this.layer.refresh&&typeof this.layer.refresh=="function"){this.layer.refresh({force:this.force});}},stop:function(){if(this.timer!==null){window.clearInterval(this.timer);this.timer=null;}},CLASS_NAME:"OpenLayers.Strategy.Refresh"});OpenLayers.Strategy.Save=OpenLayers.Class(OpenLayers.Strategy,{EVENT_TYPES:["start","success","fail"],events:null,auto:false,timer:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){if(this.auto){if(typeof this.auto==="number"){this.timer=window.setInterval(OpenLayers.Function.bind(this.save,this),this.auto*1000);}else{this.layer.events.on({"featureadded":this.triggerSave,"afterfeaturemodified":this.triggerSave,scope:this});}}}
59668 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){if(this.auto){if(typeof this.auto==="number"){window.clearInterval(this.timer);}else{this.layer.events.un({"featureadded":this.triggerSave,"afterfeaturemodified":this.triggerSave,scope:this});}}}
59669 return deactivated;},triggerSave:function(event){var feature=event.feature;if(feature.state===OpenLayers.State.INSERT||feature.state===OpenLayers.State.UPDATE||feature.state===OpenLayers.State.DELETE){this.save([event.feature]);}},save:function(features){if(!features){features=this.layer.features;}
59670 this.events.triggerEvent("start",{features:features});var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var len=features.length;var clones=new Array(len);var orig,clone;for(var i=0;i<len;++i){orig=features[i];clone=orig.clone();clone.fid=orig.fid;clone.state=orig.state;if(orig.url){clone.url=orig.url;}
59671 clone._original=orig;clone.geometry.transform(local,remote);clones[i]=clone;}
59672 features=clones;}
59673 this.layer.protocol.commit(features,{callback:this.onCommit,scope:this});},onCommit:function(response){var evt={"response":response};if(response.success()){var features=response.reqFeatures;var state,feature;var destroys=[];var insertIds=response.insertIds||[];var j=0;for(var i=0,len=features.length;i<len;++i){feature=features[i];feature=feature._original||feature;state=feature.state;if(state){if(state==OpenLayers.State.DELETE){destroys.push(feature);}else if(state==OpenLayers.State.INSERT){feature.fid=insertIds[j];++j;}
59674 feature.state=null;}}
59675 if(destroys.length>0){this.layer.destroyFeatures(destroys);}
59676 this.events.triggerEvent("success",evt);}else{this.events.triggerEvent("fail",evt);}},CLASS_NAME:"OpenLayers.Strategy.Save"});OpenLayers.Symbolizer.Line=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Line"});OpenLayers.Symbolizer.Point=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,fillColor:null,fillOpacity:null,pointRadius:null,externalGraphic:null,graphicWidth:null,graphicHeight:null,graphicOpacity:null,graphicXOffset:null,graphicYOffset:null,rotation:null,graphicName:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Point"});OpenLayers.Symbolizer.Polygon=OpenLayers.Class(OpenLayers.Symbolizer,{strokeColor:null,strokeOpacity:null,strokeWidth:null,strokeLinecap:null,strokeDashstyle:null,fillColor:null,fillOpacity:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Polygon"});OpenLayers.Symbolizer.Raster=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Raster"});OpenLayers.Symbolizer.Text=OpenLayers.Class(OpenLayers.Symbolizer,{label:null,fontFamily:null,fontSize:null,fontWeight:null,fontStyle:null,initialize:function(config){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Symbolizer.Text"});OpenLayers.Tween=OpenLayers.Class({INTERVAL:10,easing:null,begin:null,finish:null,duration:null,callbacks:null,time:null,interval:null,playing:false,initialize:function(easing){this.easing=(easing)?easing:OpenLayers.Easing.Expo.easeOut;},start:function(begin,finish,duration,options){this.playing=true;this.begin=begin;this.finish=finish;this.duration=duration;this.callbacks=options.callbacks;this.time=0;if(this.interval){window.clearInterval(this.interval);this.interval=null;}
59677 if(this.callbacks&&this.callbacks.start){this.callbacks.start.call(this,this.begin);}
59678 this.interval=window.setInterval(OpenLayers.Function.bind(this.play,this),this.INTERVAL);},stop:function(){if(!this.playing){return;}
59679 if(this.callbacks&&this.callbacks.done){this.callbacks.done.call(this,this.finish);}
59680 window.clearInterval(this.interval);this.interval=null;this.playing=false;},play:function(){var value={};for(var i in this.begin){var b=this.begin[i];var f=this.finish[i];if(b==null||f==null||isNaN(b)||isNaN(f)){OpenLayers.Console.error('invalid value for Tween');}
59681 var c=f-b;value[i]=this.easing.apply(this,[this.time,b,c,this.duration]);}
59682 this.time++;if(this.callbacks&&this.callbacks.eachStep){this.callbacks.eachStep.call(this,value);}
59683 if(this.time>this.duration){this.stop();}},CLASS_NAME:"OpenLayers.Tween"});OpenLayers.Easing={CLASS_NAME:"OpenLayers.Easing"};OpenLayers.Easing.Linear={easeIn:function(t,b,c,d){return c*t/d+b;},easeOut:function(t,b,c,d){return c*t/d+b;},easeInOut:function(t,b,c,d){return c*t/d+b;},CLASS_NAME:"OpenLayers.Easing.Linear"};OpenLayers.Easing.Expo={easeIn:function(t,b,c,d){return(t==0)?b:c*Math.pow(2,10*(t/d-1))+b;},easeOut:function(t,b,c,d){return(t==d)?b+c:c*(-Math.pow(2,-10*t/d)+1)+b;},easeInOut:function(t,b,c,d){if(t==0)return b;if(t==d)return b+c;if((t/=d/2)<1)return c/2*Math.pow(2,10*(t-1))+b;return c/2*(-Math.pow(2,-10*--t)+2)+b;},CLASS_NAME:"OpenLayers.Easing.Expo"};OpenLayers.Easing.Quad={easeIn:function(t,b,c,d){return c*(t/=d)*t+b;},easeOut:function(t,b,c,d){return-c*(t/=d)*(t-2)+b;},easeInOut:function(t,b,c,d){if((t/=d/2)<1)return c/2*t*t+b;return-c/2*((--t)*(t-2)-1)+b;},CLASS_NAME:"OpenLayers.Easing.Quad"};OpenLayers.Control.ArgParser=OpenLayers.Class(OpenLayers.Control,{center:null,zoom:null,layers:null,displayProjection:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var i=0,len=this.map.controls.length;i<len;i++){var control=this.map.controls[i];if((control!=this)&&(control.CLASS_NAME=="OpenLayers.Control.ArgParser")){if(control.displayProjection!=this.displayProjection){this.displayProjection=control.displayProjection;}
59684 break;}}
59685 if(i==this.map.controls.length){var args=OpenLayers.Util.getParameters();if(args.layers){this.layers=args.layers;this.map.events.register('addlayer',this,this.configureLayers);this.configureLayers();}
59686 if(args.lat&&args.lon){this.center=new OpenLayers.LonLat(parseFloat(args.lon),parseFloat(args.lat));if(args.zoom){this.zoom=parseInt(args.zoom);}
59687 this.map.events.register('changebaselayer',this,this.setCenter);this.setCenter();}}},setCenter:function(){if(this.map.baseLayer){this.map.events.unregister('changebaselayer',this,this.setCenter);if(this.displayProjection){this.center.transform(this.displayProjection,this.map.getProjectionObject());}
59688 this.map.setCenter(this.center,this.zoom);}},configureLayers:function(){if(this.layers.length==this.map.layers.length){this.map.events.unregister('addlayer',this,this.configureLayers);for(var i=0,len=this.layers.length;i<len;i++){var layer=this.map.layers[i];var c=this.layers.charAt(i);if(c=="B"){this.map.setBaseLayer(layer);}else if((c=="T")||(c=="F")){layer.setVisibility(c=="T");}}}},CLASS_NAME:"OpenLayers.Control.ArgParser"});OpenLayers.Control.Attribution=OpenLayers.Class(OpenLayers.Control,{separator:", ",initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.map.events.un({"removelayer":this.updateAttribution,"addlayer":this.updateAttribution,"changelayer":this.updateAttribution,"changebaselayer":this.updateAttribution,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.map.events.on({'changebaselayer':this.updateAttribution,'changelayer':this.updateAttribution,'addlayer':this.updateAttribution,'removelayer':this.updateAttribution,scope:this});this.updateAttribution();return this.div;},updateAttribution:function(){var attributions=[];if(this.map&&this.map.layers){for(var i=0,len=this.map.layers.length;i<len;i++){var layer=this.map.layers[i];if(layer.attribution&&layer.getVisibility()){if(OpenLayers.Util.indexOf(attributions,layer.attribution)===-1){attributions.push(layer.attribution);}}}
59689 this.div.innerHTML=attributions.join(this.separator);}},CLASS_NAME:"OpenLayers.Control.Attribution"});OpenLayers.Control.Button=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){},CLASS_NAME:"OpenLayers.Control.Button"});OpenLayers.Control.Graticule=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,intervals:[45,30,20,10,5,2,1,0.5,0.2,0.1,0.05,0.01,0.005,0.002,0.001],displayInLayerSwitcher:true,visible:true,numPoints:50,targetSize:200,layerName:null,labelled:true,labelFormat:'dm',lineSymbolizer:{strokeColor:"#333",strokeWidth:1,strokeOpacity:0.5},labelSymbolizer:{},gratLayer:null,initialize:function(options){options=options||{};options.layerName=options.layerName||OpenLayers.i18n("graticule");OpenLayers.Control.prototype.initialize.apply(this,[options]);this.labelSymbolizer.stroke=false;this.labelSymbolizer.fill=false;this.labelSymbolizer.label="${label}";this.labelSymbolizer.labelAlign="${labelAlign}";this.labelSymbolizer.labelXOffset="${xOffset}";this.labelSymbolizer.labelYOffset="${yOffset}";},destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments);if(this.gratLayer){this.gratLayer.destroy();this.gratLayer=null;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.gratLayer){var gratStyle=new OpenLayers.Style({},{rules:[new OpenLayers.Rule({'symbolizer':{"Point":this.labelSymbolizer,"Line":this.lineSymbolizer}})]});this.gratLayer=new OpenLayers.Layer.Vector(this.layerName,{styleMap:new OpenLayers.StyleMap({'default':gratStyle}),visibility:this.visible,displayInLayerSwitcher:this.displayInLayerSwitcher});}
59690 return this.div;},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.map.addLayer(this.gratLayer);this.map.events.register('moveend',this,this.update);this.update();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.map.events.unregister('moveend',this,this.update);this.map.removeLayer(this.gratLayer);return true;}else{return false;}},update:function(){var mapBounds=this.map.getExtent();if(!mapBounds){return;}
59691 this.gratLayer.destroyFeatures();var llProj=new OpenLayers.Projection("EPSG:4326");var mapProj=this.map.getProjectionObject();var mapRes=this.map.getResolution();if(mapProj.proj&&mapProj.proj.projName=="longlat"){this.numPoints=1;}
59692 var mapCenter=this.map.getCenter();var mapCenterLL=new OpenLayers.Pixel(mapCenter.lon,mapCenter.lat);OpenLayers.Projection.transform(mapCenterLL,mapProj,llProj);var testSq=this.targetSize*mapRes;testSq*=testSq;var llInterval;for(var i=0;i<this.intervals.length;++i){llInterval=this.intervals[i];var delta=llInterval/2;var p1=mapCenterLL.offset(new OpenLayers.Pixel(-delta,-delta));var p2=mapCenterLL.offset(new OpenLayers.Pixel(delta,delta));OpenLayers.Projection.transform(p1,llProj,mapProj);OpenLayers.Projection.transform(p2,llProj,mapProj);var distSq=(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);if(distSq<=testSq){break;}}
59693 mapCenterLL.x=Math.floor(mapCenterLL.x/llInterval)*llInterval;mapCenterLL.y=Math.floor(mapCenterLL.y/llInterval)*llInterval;var iter=0;var centerLonPoints=[mapCenterLL.clone()];var newPoint=mapCenterLL.clone();var mapXY;do{newPoint=newPoint.offset(new OpenLayers.Pixel(0,llInterval));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLonPoints.unshift(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(0,-llInterval));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLonPoints.push(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);iter=0;var centerLatPoints=[mapCenterLL.clone()];newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(-llInterval,0));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLatPoints.unshift(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);newPoint=mapCenterLL.clone();do{newPoint=newPoint.offset(new OpenLayers.Pixel(llInterval,0));mapXY=OpenLayers.Projection.transform(newPoint.clone(),llProj,mapProj);centerLatPoints.push(newPoint);}while(mapBounds.containsPixel(mapXY)&&++iter<1000);var lines=[];for(var i=0;i<centerLatPoints.length;++i){var lon=centerLatPoints[i].x;var pointList=[];var labelPoint=null;var latEnd=Math.min(centerLonPoints[0].y,90);var latStart=Math.max(centerLonPoints[centerLonPoints.length-1].y,-90);var latDelta=(latEnd-latStart)/this.numPoints;var lat=latStart;for(var j=0;j<=this.numPoints;++j){var gridPoint=new OpenLayers.Geometry.Point(lon,lat);gridPoint.transform(llProj,mapProj);pointList.push(gridPoint);lat+=latDelta;if(gridPoint.y>=mapBounds.bottom&&!labelPoint){labelPoint=gridPoint;}}
59694 if(this.labelled){var labelPos=new OpenLayers.Geometry.Point(labelPoint.x,mapBounds.bottom);var labelAttrs={value:lon,label:this.labelled?OpenLayers.Util.getFormattedLonLat(lon,"lon",this.labelFormat):"",labelAlign:"cb",xOffset:0,yOffset:2};this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));}
59695 var geom=new OpenLayers.Geometry.LineString(pointList);lines.push(new OpenLayers.Feature.Vector(geom));}
59696 for(var j=0;j<centerLonPoints.length;++j){lat=centerLonPoints[j].y;if(lat<-90||lat>90){continue;}
59697 var pointList=[];var lonStart=centerLatPoints[0].x;var lonEnd=centerLatPoints[centerLatPoints.length-1].x;var lonDelta=(lonEnd-lonStart)/this.numPoints;var lon=lonStart;var labelPoint=null;for(var i=0;i<=this.numPoints;++i){var gridPoint=new OpenLayers.Geometry.Point(lon,lat);gridPoint.transform(llProj,mapProj);pointList.push(gridPoint);lon+=lonDelta;if(gridPoint.x<mapBounds.right){labelPoint=gridPoint;}}
59698 if(this.labelled){var labelPos=new OpenLayers.Geometry.Point(mapBounds.right,labelPoint.y);var labelAttrs={value:lat,label:this.labelled?OpenLayers.Util.getFormattedLonLat(lat,"lat",this.labelFormat):"",labelAlign:"rb",xOffset:-2,yOffset:2};this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(labelPos,labelAttrs));}
59699 var geom=new OpenLayers.Geometry.LineString(pointList);lines.push(new OpenLayers.Feature.Vector(geom));}
59700 this.gratLayer.addFeatures(lines);},CLASS_NAME:"OpenLayers.Control.Graticule"});OpenLayers.Control.LayerSwitcher=OpenLayers.Class(OpenLayers.Control,{roundedCorner:true,roundedCornerColor:"darkblue",layerStates:null,layersDiv:null,baseLayersDiv:null,baseLayers:null,dataLbl:null,dataLayersDiv:null,dataLayers:null,minimizeDiv:null,maximizeDiv:null,ascending:true,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.layerStates=[];},destroy:function(){OpenLayers.Event.stopObservingElement(this.div);OpenLayers.Event.stopObservingElement(this.minimizeDiv);OpenLayers.Event.stopObservingElement(this.maximizeDiv);this.clearLayersArray("base");this.clearLayersArray("data");this.map.events.un({"addlayer":this.redraw,"changelayer":this.redraw,"removelayer":this.redraw,"changebaselayer":this.redraw,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);this.map.events.on({"addlayer":this.redraw,"changelayer":this.redraw,"removelayer":this.redraw,"changebaselayer":this.redraw,scope:this});},draw:function(){OpenLayers.Control.prototype.draw.apply(this);this.loadContents();if(!this.outsideViewport){this.minimizeControl();}
59701 this.redraw();return this.div;},clearLayersArray:function(layersType){var layers=this[layersType+"Layers"];if(layers){for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];OpenLayers.Event.stopObservingElement(layer.inputElem);OpenLayers.Event.stopObservingElement(layer.labelSpan);}}
59702 this[layersType+"LayersDiv"].innerHTML="";this[layersType+"Layers"]=[];},checkRedraw:function(){var redraw=false;if(!this.layerStates.length||(this.map.layers.length!=this.layerStates.length)){redraw=true;}else{for(var i=0,len=this.layerStates.length;i<len;i++){var layerState=this.layerStates[i];var layer=this.map.layers[i];if((layerState.name!=layer.name)||(layerState.inRange!=layer.inRange)||(layerState.id!=layer.id)||(layerState.visibility!=layer.visibility)){redraw=true;break;}}}
59703 return redraw;},redraw:function(){if(!this.checkRedraw()){return this.div;}
59704 this.clearLayersArray("base");this.clearLayersArray("data");var containsOverlays=false;var containsBaseLayers=false;var len=this.map.layers.length;this.layerStates=new Array(len);for(var i=0;i<len;i++){var layer=this.map.layers[i];this.layerStates[i]={'name':layer.name,'visibility':layer.visibility,'inRange':layer.inRange,'id':layer.id};}
59705 var layers=this.map.layers.slice();if(!this.ascending){layers.reverse();}
59706 for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];var baseLayer=layer.isBaseLayer;if(layer.displayInLayerSwitcher){if(baseLayer){containsBaseLayers=true;}else{containsOverlays=true;}
59707 var checked=(baseLayer)?(layer==this.map.baseLayer):layer.getVisibility();var inputElem=document.createElement("input");inputElem.id=this.id+"_input_"+layer.name;inputElem.name=(baseLayer)?this.id+"_baseLayers":layer.name;inputElem.type=(baseLayer)?"radio":"checkbox";inputElem.value=layer.name;inputElem.checked=checked;inputElem.defaultChecked=checked;if(!baseLayer&&!layer.inRange){inputElem.disabled=true;}
59708 var context={'inputElem':inputElem,'layer':layer,'layerSwitcher':this};OpenLayers.Event.observe(inputElem,"mouseup",OpenLayers.Function.bindAsEventListener(this.onInputClick,context));var labelSpan=document.createElement("span");OpenLayers.Element.addClass(labelSpan,"labelSpan")
59709 if(!baseLayer&&!layer.inRange){labelSpan.style.color="gray";}
59710 labelSpan.innerHTML=layer.name;labelSpan.style.verticalAlign=(baseLayer)?"bottom":"baseline";OpenLayers.Event.observe(labelSpan,"click",OpenLayers.Function.bindAsEventListener(this.onInputClick,context));var br=document.createElement("br");var groupArray=(baseLayer)?this.baseLayers:this.dataLayers;groupArray.push({'layer':layer,'inputElem':inputElem,'labelSpan':labelSpan});var groupDiv=(baseLayer)?this.baseLayersDiv:this.dataLayersDiv;groupDiv.appendChild(inputElem);groupDiv.appendChild(labelSpan);groupDiv.appendChild(br);}}
59711 this.dataLbl.style.display=(containsOverlays)?"":"none";this.baseLbl.style.display=(containsBaseLayers)?"":"none";return this.div;},onInputClick:function(e){if(!this.inputElem.disabled){if(this.inputElem.type=="radio"){this.inputElem.checked=true;this.layer.map.setBaseLayer(this.layer);}else{this.inputElem.checked=!this.inputElem.checked;this.layerSwitcher.updateMap();}}
59712 OpenLayers.Event.stop(e);},onLayerClick:function(e){this.updateMap();},updateMap:function(){for(var i=0,len=this.baseLayers.length;i<len;i++){var layerEntry=this.baseLayers[i];if(layerEntry.inputElem.checked){this.map.setBaseLayer(layerEntry.layer,false);}}
59713 for(var i=0,len=this.dataLayers.length;i<len;i++){var layerEntry=this.dataLayers[i];layerEntry.layer.setVisibility(layerEntry.inputElem.checked);}},maximizeControl:function(e){this.div.style.width="";this.div.style.height="";this.showControls(false);if(e!=null){OpenLayers.Event.stop(e);}},minimizeControl:function(e){this.div.style.width="0px";this.div.style.height="0px";this.showControls(true);if(e!=null){OpenLayers.Event.stop(e);}},showControls:function(minimize){this.maximizeDiv.style.display=minimize?"":"none";this.minimizeDiv.style.display=minimize?"none":"";this.layersDiv.style.display=minimize?"none":"";},loadContents:function(){OpenLayers.Event.observe(this.div,"mouseup",OpenLayers.Function.bindAsEventListener(this.mouseUp,this));OpenLayers.Event.observe(this.div,"click",this.ignoreEvent);OpenLayers.Event.observe(this.div,"mousedown",OpenLayers.Function.bindAsEventListener(this.mouseDown,this));OpenLayers.Event.observe(this.div,"dblclick",this.ignoreEvent);this.layersDiv=document.createElement("div");this.layersDiv.id=this.id+"_layersDiv";OpenLayers.Element.addClass(this.layersDiv,"layersDiv");this.baseLbl=document.createElement("div");this.baseLbl.innerHTML=OpenLayers.i18n("baseLayer");OpenLayers.Element.addClass(this.baseLbl,"baseLbl");this.baseLayersDiv=document.createElement("div");OpenLayers.Element.addClass(this.baseLayersDiv,"baseLayersDiv");this.dataLbl=document.createElement("div");this.dataLbl.innerHTML=OpenLayers.i18n("overlays");OpenLayers.Element.addClass(this.dataLbl,"dataLbl");this.dataLayersDiv=document.createElement("div");OpenLayers.Element.addClass(this.dataLayersDiv,"dataLayersDiv");if(this.ascending){this.layersDiv.appendChild(this.baseLbl);this.layersDiv.appendChild(this.baseLayersDiv);this.layersDiv.appendChild(this.dataLbl);this.layersDiv.appendChild(this.dataLayersDiv);}else{this.layersDiv.appendChild(this.dataLbl);this.layersDiv.appendChild(this.dataLayersDiv);this.layersDiv.appendChild(this.baseLbl);this.layersDiv.appendChild(this.baseLayersDiv);}
59714 this.div.appendChild(this.layersDiv);if(this.roundedCorner){OpenLayers.Rico.Corner.round(this.div,{corners:"tl bl",bgColor:"transparent",color:this.roundedCornerColor,blend:false});OpenLayers.Rico.Corner.changeOpacity(this.layersDiv,0.75);}
59715 var imgLocation=OpenLayers.Util.getImagesLocation();var sz=new OpenLayers.Size(18,18);var img=imgLocation+'layer-switcher-maximize.png';this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MaximizeDiv",null,sz,img,"absolute");OpenLayers.Element.addClass(this.maximizeDiv,"maximizeDiv");this.maximizeDiv.style.display="none";OpenLayers.Event.observe(this.maximizeDiv,"click",OpenLayers.Function.bindAsEventListener(this.maximizeControl,this));this.div.appendChild(this.maximizeDiv);var img=imgLocation+'layer-switcher-minimize.png';var sz=new OpenLayers.Size(18,18);this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MinimizeDiv",null,sz,img,"absolute");OpenLayers.Element.addClass(this.minimizeDiv,"minimizeDiv");this.minimizeDiv.style.display="none";OpenLayers.Event.observe(this.minimizeDiv,"click",OpenLayers.Function.bindAsEventListener(this.minimizeControl,this));this.div.appendChild(this.minimizeDiv);},ignoreEvent:function(evt){OpenLayers.Event.stop(evt);},mouseDown:function(evt){this.isMouseDown=true;this.ignoreEvent(evt);},mouseUp:function(evt){if(this.isMouseDown){this.isMouseDown=false;this.ignoreEvent(evt);}},CLASS_NAME:"OpenLayers.Control.LayerSwitcher"});OpenLayers.Control.MouseDefaults=OpenLayers.Class(OpenLayers.Control,{performedDrag:false,wheelObserver:null,initialize:function(){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){if(this.handler){this.handler.destroy();}
59716 this.handler=null;this.map.events.un({"click":this.defaultClick,"dblclick":this.defaultDblClick,"mousedown":this.defaultMouseDown,"mouseup":this.defaultMouseUp,"mousemove":this.defaultMouseMove,"mouseout":this.defaultMouseOut,scope:this});OpenLayers.Event.stopObserving(window,"DOMMouseScroll",this.wheelObserver);OpenLayers.Event.stopObserving(window,"mousewheel",this.wheelObserver);OpenLayers.Event.stopObserving(document,"mousewheel",this.wheelObserver);this.wheelObserver=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){this.map.events.on({"click":this.defaultClick,"dblclick":this.defaultDblClick,"mousedown":this.defaultMouseDown,"mouseup":this.defaultMouseUp,"mousemove":this.defaultMouseMove,"mouseout":this.defaultMouseOut,scope:this});this.registerWheelEvents();},registerWheelEvents:function(){this.wheelObserver=OpenLayers.Function.bindAsEventListener(this.onWheelEvent,this);OpenLayers.Event.observe(window,"DOMMouseScroll",this.wheelObserver);OpenLayers.Event.observe(window,"mousewheel",this.wheelObserver);OpenLayers.Event.observe(document,"mousewheel",this.wheelObserver);},defaultClick:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59717 var notAfterDrag=!this.performedDrag;this.performedDrag=false;return notAfterDrag;},defaultDblClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);OpenLayers.Event.stop(evt);return false;},defaultMouseDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59718 this.mouseDragStart=evt.xy.clone();this.performedDrag=false;if(evt.shiftKey){this.map.div.style.cursor="crosshair";this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.mouseDragStart,null,null,"absolute","2px solid red");this.zoomBox.style.backgroundColor="white";this.zoomBox.style.filter="alpha(opacity=50)";this.zoomBox.style.opacity="0.50";this.zoomBox.style.fontSize="1px";this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);}
59719 document.onselectstart=OpenLayers.Function.False;OpenLayers.Event.stop(evt);},defaultMouseMove:function(evt){this.mousePosition=evt.xy.clone();if(this.mouseDragStart!=null){if(this.zoomBox){var deltaX=Math.abs(this.mouseDragStart.x-evt.xy.x);var deltaY=Math.abs(this.mouseDragStart.y-evt.xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";if(evt.xy.x<this.mouseDragStart.x){this.zoomBox.style.left=evt.xy.x+"px";}
59720 if(evt.xy.y<this.mouseDragStart.y){this.zoomBox.style.top=evt.xy.y+"px";}}else{var deltaX=this.mouseDragStart.x-evt.xy.x;var deltaY=this.mouseDragStart.y-evt.xy.y;var size=this.map.getSize();var newXY=new OpenLayers.Pixel(size.w/2+deltaX,size.h/2+deltaY);var newCenter=this.map.getLonLatFromViewPortPx(newXY);this.map.setCenter(newCenter,null,true);this.mouseDragStart=evt.xy.clone();this.map.div.style.cursor="move";}
59721 this.performedDrag=true;}},defaultMouseUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59722 if(this.zoomBox){this.zoomBoxEnd(evt);}else{if(this.performedDrag){this.map.setCenter(this.map.center);}}
59723 document.onselectstart=null;this.mouseDragStart=null;this.map.div.style.cursor="";},defaultMouseOut:function(evt){if(this.mouseDragStart!=null&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.zoomBox){this.removeZoomBox();}
59724 this.mouseDragStart=null;}},defaultWheelUp:function(evt){if(this.map.getZoom()<=this.map.getNumZoomLevels()){this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),this.map.getZoom()+1);}},defaultWheelDown:function(evt){if(this.map.getZoom()>0){this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),this.map.getZoom()-1);}},zoomBoxEnd:function(evt){if(this.mouseDragStart!=null){if(Math.abs(this.mouseDragStart.x-evt.xy.x)>5||Math.abs(this.mouseDragStart.y-evt.xy.y)>5){var start=this.map.getLonLatFromViewPortPx(this.mouseDragStart);var end=this.map.getLonLatFromViewPortPx(evt.xy);var top=Math.max(start.lat,end.lat);var bottom=Math.min(start.lat,end.lat);var left=Math.min(start.lon,end.lon);var right=Math.max(start.lon,end.lon);var bounds=new OpenLayers.Bounds(left,bottom,right,top);this.map.zoomToExtent(bounds);}else{var end=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(new OpenLayers.LonLat((end.lon),(end.lat)),this.map.getZoom()+1);}
59725 this.removeZoomBox();}},removeZoomBox:function(){this.map.viewPortDiv.removeChild(this.zoomBox);this.zoomBox=null;},onWheelEvent:function(e){var inMap=false;var elem=OpenLayers.Event.element(e);while(elem!=null){if(this.map&&elem==this.map.div){inMap=true;break;}
59726 elem=elem.parentNode;}
59727 if(inMap){var delta=0;if(!e){e=window.event;}
59728 if(e.wheelDelta){delta=e.wheelDelta/120;if(window.opera&&window.opera.version()<9.2){delta=-delta;}}else if(e.detail){delta=-e.detail/3;}
59729 if(delta){e.xy=this.mousePosition;if(delta<0){this.defaultWheelDown(e);}else{this.defaultWheelUp(e);}}
59730 OpenLayers.Event.stop(e);}},CLASS_NAME:"OpenLayers.Control.MouseDefaults"});OpenLayers.Control.MousePosition=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,element:null,prefix:'',separator:', ',suffix:'',numDigits:5,granularity:10,emptyString:null,lastXy:null,displayProjection:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.map.events.register('mousemove',this,this.redraw);this.map.events.register('mouseout',this,this.reset);this.redraw();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.map.events.unregister('mousemove',this,this.redraw);this.map.events.unregister('mouseout',this,this.reset);this.element.innerHTML="";return true;}else{return false;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.div.left="";this.div.top="";this.element=this.div;}
59731 return this.div;},redraw:function(evt){var lonLat;if(evt==null){this.reset();return;}else{if(this.lastXy==null||Math.abs(evt.xy.x-this.lastXy.x)>this.granularity||Math.abs(evt.xy.y-this.lastXy.y)>this.granularity)
59732 {this.lastXy=evt.xy;return;}
59733 lonLat=this.map.getLonLatFromPixel(evt.xy);if(!lonLat){return;}
59734 if(this.displayProjection){lonLat.transform(this.map.getProjectionObject(),this.displayProjection);}
59735 this.lastXy=evt.xy;}
59736 var newHtml=this.formatOutput(lonLat);if(newHtml!=this.element.innerHTML){this.element.innerHTML=newHtml;}},reset:function(evt){if(this.emptyString!=null){this.element.innerHTML=this.emptyString;}},formatOutput:function(lonLat){var digits=parseInt(this.numDigits);var newHtml=this.prefix+
59737 lonLat.lon.toFixed(digits)+
59738 this.separator+
59739 lonLat.lat.toFixed(digits)+
59740 this.suffix;return newHtml;},CLASS_NAME:"OpenLayers.Control.MousePosition"});OpenLayers.Control.Pan=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,direction:null,type:OpenLayers.Control.TYPE_BUTTON,initialize:function(direction,options){this.direction=direction;this.CLASS_NAME+=this.direction;OpenLayers.Control.prototype.initialize.apply(this,[options]);},trigger:function(){switch(this.direction){case OpenLayers.Control.Pan.NORTH:this.map.pan(0,-this.slideFactor);break;case OpenLayers.Control.Pan.SOUTH:this.map.pan(0,this.slideFactor);break;case OpenLayers.Control.Pan.WEST:this.map.pan(-this.slideFactor,0);break;case OpenLayers.Control.Pan.EAST:this.map.pan(this.slideFactor,0);break;}},CLASS_NAME:"OpenLayers.Control.Pan"});OpenLayers.Control.Pan.NORTH="North";OpenLayers.Control.Pan.SOUTH="South";OpenLayers.Control.Pan.EAST="East";OpenLayers.Control.Pan.WEST="West";OpenLayers.Control.PanZoom=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,slideRatio:null,buttons:null,position:null,initialize:function(options){this.position=new OpenLayers.Pixel(OpenLayers.Control.PanZoom.X,OpenLayers.Control.PanZoom.Y);OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this,arguments);this.removeButtons();this.buttons=null;this.position=null;},draw:function(px){OpenLayers.Control.prototype.draw.apply(this,arguments);px=this.position;this.buttons=[];var sz=new OpenLayers.Size(18,18);var centered=new OpenLayers.Pixel(px.x+sz.w/2,px.y);this._addButton("panup","north-mini.png",centered,sz);px.y=centered.y+sz.h;this._addButton("panleft","west-mini.png",px,sz);this._addButton("panright","east-mini.png",px.add(sz.w,0),sz);this._addButton("pandown","south-mini.png",centered.add(0,sz.h*2),sz);this._addButton("zoomin","zoom-plus-mini.png",centered.add(0,sz.h*3+5),sz);this._addButton("zoomworld","zoom-world-mini.png",centered.add(0,sz.h*4+5),sz);this._addButton("zoomout","zoom-minus-mini.png",centered.add(0,sz.h*5+5),sz);return this.div;},_addButton:function(id,img,xy,sz){var imgLocation=OpenLayers.Util.getImagesLocation()+img;var btn=OpenLayers.Util.createAlphaImageDiv(this.id+"_"+id,xy,sz,imgLocation,"absolute");this.div.appendChild(btn);OpenLayers.Event.observe(btn,"mousedown",OpenLayers.Function.bindAsEventListener(this.buttonDown,btn));OpenLayers.Event.observe(btn,"dblclick",OpenLayers.Function.bindAsEventListener(this.doubleClick,btn));OpenLayers.Event.observe(btn,"click",OpenLayers.Function.bindAsEventListener(this.doubleClick,btn));btn.action=id;btn.map=this.map;if(!this.slideRatio){var slideFactorPixels=this.slideFactor;var getSlideFactor=function(){return slideFactorPixels;};}else{var slideRatio=this.slideRatio;var getSlideFactor=function(dim){return this.map.getSize()[dim]*slideRatio;};}
59741 btn.getSlideFactor=getSlideFactor;this.buttons.push(btn);return btn;},_removeButton:function(btn){OpenLayers.Event.stopObservingElement(btn);btn.map=null;btn.getSlideFactor=null;this.div.removeChild(btn);OpenLayers.Util.removeItem(this.buttons,btn);},removeButtons:function(){for(var i=this.buttons.length-1;i>=0;--i){this._removeButton(this.buttons[i]);}},doubleClick:function(evt){OpenLayers.Event.stop(evt);return false;},buttonDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59742 switch(this.action){case"panup":this.map.pan(0,-this.getSlideFactor("h"));break;case"pandown":this.map.pan(0,this.getSlideFactor("h"));break;case"panleft":this.map.pan(-this.getSlideFactor("w"),0);break;case"panright":this.map.pan(this.getSlideFactor("w"),0);break;case"zoomin":this.map.zoomIn();break;case"zoomout":this.map.zoomOut();break;case"zoomworld":this.map.zoomToMaxExtent();break;}
59743 OpenLayers.Event.stop(evt);},CLASS_NAME:"OpenLayers.Control.PanZoom"});OpenLayers.Control.PanZoom.X=4;OpenLayers.Control.PanZoom.Y=4;OpenLayers.Control.Panel=OpenLayers.Class(OpenLayers.Control,{controls:null,autoActivate:true,defaultControl:null,saveState:false,activeState:null,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.controls=[];this.activeState={};},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this,arguments);for(var i=this.controls.length-1;i>=0;i--){if(this.controls[i].events){this.controls[i].events.un({"activate":this.redraw,"deactivate":this.redraw,scope:this});}
59744 OpenLayers.Event.stopObservingElement(this.controls[i].panel_div);this.controls[i].panel_div=null;}
59745 this.activeState=null;},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){var control;for(var i=0,len=this.controls.length;i<len;i++){control=this.controls[i];if(control===this.defaultControl||(this.saveState&&this.activeState[control.id])){control.activate();}}
59746 if(this.saveState===true){this.defaultControl=null;}
59747 this.redraw();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){var control;for(var i=0,len=this.controls.length;i<len;i++){control=this.controls[i];this.activeState[control.id]=control.deactivate();}
59748 return true;}else{return false;}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.addControlsToMap(this.controls);return this.div;},redraw:function(){if(this.div.children.length>0){for(var l=this.div.children.length,i=l-1;i>=0;i--){this.div.removeChild(this.div.children[i]);}}
59749 this.div.innerHTML="";if(this.active){for(var i=0,len=this.controls.length;i<len;i++){var element=this.controls[i].panel_div;if(this.controls[i].active){element.className=this.controls[i].displayClass+"ItemActive";}else{element.className=this.controls[i].displayClass+"ItemInactive";}
59750 this.div.appendChild(element);}}},activateControl:function(control){if(!this.active){return false;}
59751 if(control.type==OpenLayers.Control.TYPE_BUTTON){control.trigger();this.redraw();return;}
59752 if(control.type==OpenLayers.Control.TYPE_TOGGLE){if(control.active){control.deactivate();}else{control.activate();}
59753 this.redraw();return;}
59754 var c;for(var i=0,len=this.controls.length;i<len;i++){c=this.controls[i];if(c!=control&&(c.type===OpenLayers.Control.TYPE_TOOL||c.type==null)){c.deactivate();}}
59755 control.activate();},addControls:function(controls){if(!(controls instanceof Array)){controls=[controls];}
59756 this.controls=this.controls.concat(controls);for(var i=0,len=controls.length;i<len;i++){var element=document.createElement("div");controls[i].panel_div=element;if(controls[i].title!=""){controls[i].panel_div.title=controls[i].title;}
59757 OpenLayers.Event.observe(controls[i].panel_div,"click",OpenLayers.Function.bind(this.onClick,this,controls[i]));OpenLayers.Event.observe(controls[i].panel_div,"dblclick",OpenLayers.Function.bind(this.onDoubleClick,this,controls[i]));OpenLayers.Event.observe(controls[i].panel_div,"mousedown",OpenLayers.Function.bindAsEventListener(OpenLayers.Event.stop));}
59758 if(this.map){this.addControlsToMap(controls);this.redraw();}},addControlsToMap:function(controls){var control;for(var i=0,len=controls.length;i<len;i++){control=controls[i];if(control.autoActivate===true){control.autoActivate=false;this.map.addControl(control);control.autoActivate=true;}else{this.map.addControl(control);control.deactivate();}
59759 control.events.on({"activate":this.redraw,"deactivate":this.redraw,scope:this});}},onClick:function(ctrl,evt){OpenLayers.Event.stop(evt?evt:window.event);this.activateControl(ctrl);},onDoubleClick:function(ctrl,evt){OpenLayers.Event.stop(evt?evt:window.event);},getControlsBy:function(property,match){var test=(typeof match.test=="function");var found=OpenLayers.Array.filter(this.controls,function(item){return item[property]==match||(test&&match.test(item[property]));});return found;},getControlsByName:function(match){return this.getControlsBy("name",match);},getControlsByClass:function(match){return this.getControlsBy("CLASS_NAME",match);},CLASS_NAME:"OpenLayers.Control.Panel"});OpenLayers.Control.Scale=OpenLayers.Class(OpenLayers.Control,{element:null,geodesic:false,initialize:function(element,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.element=OpenLayers.Util.getElement(element);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.element=document.createElement("div");this.div.appendChild(this.element);}
59760 this.map.events.register('moveend',this,this.updateScale);this.updateScale();return this.div;},updateScale:function(){var scale;if(this.geodesic===true){var units=this.map.getUnits();if(!units){return;}
59761 var inches=OpenLayers.INCHES_PER_UNIT;scale=(this.map.getGeodesicPixelSize().w||0.000001)*inches["km"]*OpenLayers.DOTS_PER_INCH;}else{scale=this.map.getScale();}
59762 if(!scale){return;}
59763 if(scale>=9500&&scale<=950000){scale=Math.round(scale/1000)+"K";}else if(scale>=950000){scale=Math.round(scale/1000000)+"M";}else{scale=Math.round(scale);}
59764 this.element.innerHTML=OpenLayers.i18n("scale",{'scaleDenom':scale});},CLASS_NAME:"OpenLayers.Control.Scale"});OpenLayers.Control.ScaleLine=OpenLayers.Class(OpenLayers.Control,{maxWidth:100,topOutUnits:"km",topInUnits:"m",bottomOutUnits:"mi",bottomInUnits:"ft",eTop:null,eBottom:null,geodesic:false,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.eTop){this.eTop=document.createElement("div");this.eTop.className=this.displayClass+"Top";var theLen=this.topInUnits.length;this.div.appendChild(this.eTop);if((this.topOutUnits=="")||(this.topInUnits=="")){this.eTop.style.visibility="hidden";}else{this.eTop.style.visibility="visible";}
59765 this.eBottom=document.createElement("div");this.eBottom.className=this.displayClass+"Bottom";this.div.appendChild(this.eBottom);if((this.bottomOutUnits=="")||(this.bottomInUnits=="")){this.eBottom.style.visibility="hidden";}else{this.eBottom.style.visibility="visible";}}
59766 this.map.events.register('moveend',this,this.update);this.update();return this.div;},getBarLen:function(maxLen){var digits=parseInt(Math.log(maxLen)/Math.log(10));var pow10=Math.pow(10,digits);var firstChar=parseInt(maxLen/pow10);var barLen;if(firstChar>5){barLen=5;}else if(firstChar>2){barLen=2;}else{barLen=1;}
59767 return barLen*pow10;},update:function(){var res=this.map.getResolution();if(!res){return;}
59768 var curMapUnits=this.map.getUnits();var inches=OpenLayers.INCHES_PER_UNIT;var maxSizeData=this.maxWidth*res*inches[curMapUnits];var geodesicRatio=1;if(this.geodesic===true){var maxSizeGeodesic=(this.map.getGeodesicPixelSize().w||0.000001)*this.maxWidth;var maxSizeKilometers=maxSizeData/inches["km"];geodesicRatio=maxSizeGeodesic/maxSizeKilometers;maxSizeData*=geodesicRatio;}
59769 var topUnits;var bottomUnits;if(maxSizeData>100000){topUnits=this.topOutUnits;bottomUnits=this.bottomOutUnits;}else{topUnits=this.topInUnits;bottomUnits=this.bottomInUnits;}
59770 var topMax=maxSizeData/inches[topUnits];var bottomMax=maxSizeData/inches[bottomUnits];var topRounded=this.getBarLen(topMax);var bottomRounded=this.getBarLen(bottomMax);topMax=topRounded/inches[curMapUnits]*inches[topUnits];bottomMax=bottomRounded/inches[curMapUnits]*inches[bottomUnits];var topPx=topMax/res/geodesicRatio;var bottomPx=bottomMax/res/geodesicRatio;if(this.eBottom.style.visibility=="visible"){this.eBottom.style.width=Math.round(bottomPx)+"px";this.eBottom.innerHTML=bottomRounded+" "+bottomUnits;}
59771 if(this.eTop.style.visibility=="visible"){this.eTop.style.width=Math.round(topPx)+"px";this.eTop.innerHTML=topRounded+" "+topUnits;}},CLASS_NAME:"OpenLayers.Control.ScaleLine"});OpenLayers.Control.ZoomIn=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomIn();},CLASS_NAME:"OpenLayers.Control.ZoomIn"});OpenLayers.Control.ZoomOut=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomOut();},CLASS_NAME:"OpenLayers.Control.ZoomOut"});OpenLayers.Control.ZoomToMaxExtent=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){if(this.map){this.map.zoomToMaxExtent();}},CLASS_NAME:"OpenLayers.Control.ZoomToMaxExtent"});OpenLayers.Event={observers:false,KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,element:function(event){return event.target||event.srcElement;},isLeftClick:function(event){return(((event.which)&&(event.which==1))||((event.button)&&(event.button==1)));},isRightClick:function(event){return(((event.which)&&(event.which==3))||((event.button)&&(event.button==2)));},stop:function(event,allowDefault){if(!allowDefault){if(event.preventDefault){event.preventDefault();}else{event.returnValue=false;}}
59772 if(event.stopPropagation){event.stopPropagation();}else{event.cancelBubble=true;}},findElement:function(event,tagName){var element=OpenLayers.Event.element(event);while(element.parentNode&&(!element.tagName||(element.tagName.toUpperCase()!=tagName.toUpperCase()))){element=element.parentNode;}
59773 return element;},observe:function(elementParam,name,observer,useCapture){var element=OpenLayers.Util.getElement(elementParam);useCapture=useCapture||false;if(name=='keypress'&&(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||element.attachEvent)){name='keydown';}
59774 if(!this.observers){this.observers={};}
59775 if(!element._eventCacheID){var idPrefix="eventCacheID_";if(element.id){idPrefix=element.id+"_"+idPrefix;}
59776 element._eventCacheID=OpenLayers.Util.createUniqueID(idPrefix);}
59777 var cacheID=element._eventCacheID;if(!this.observers[cacheID]){this.observers[cacheID]=[];}
59778 this.observers[cacheID].push({'element':element,'name':name,'observer':observer,'useCapture':useCapture});if(element.addEventListener){element.addEventListener(name,observer,useCapture);}else if(element.attachEvent){element.attachEvent('on'+name,observer);}},stopObservingElement:function(elementParam){var element=OpenLayers.Util.getElement(elementParam);var cacheID=element._eventCacheID;this._removeElementObservers(OpenLayers.Event.observers[cacheID]);},_removeElementObservers:function(elementObservers){if(elementObservers){for(var i=elementObservers.length-1;i>=0;i--){var entry=elementObservers[i];var args=new Array(entry.element,entry.name,entry.observer,entry.useCapture);var removed=OpenLayers.Event.stopObserving.apply(this,args);}}},stopObserving:function(elementParam,name,observer,useCapture){useCapture=useCapture||false;var element=OpenLayers.Util.getElement(elementParam);var cacheID=element._eventCacheID;if(name=='keypress'){if(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||element.detachEvent){name='keydown';}}
59779 var foundEntry=false;var elementObservers=OpenLayers.Event.observers[cacheID];if(elementObservers){var i=0;while(!foundEntry&&i<elementObservers.length){var cacheEntry=elementObservers[i];if((cacheEntry.name==name)&&(cacheEntry.observer==observer)&&(cacheEntry.useCapture==useCapture)){elementObservers.splice(i,1);if(elementObservers.length==0){delete OpenLayers.Event.observers[cacheID];}
59780 foundEntry=true;break;}
59781 i++;}}
59782 if(foundEntry){if(element.removeEventListener){element.removeEventListener(name,observer,useCapture);}else if(element&&element.detachEvent){element.detachEvent('on'+name,observer);}}
59783 return foundEntry;},unloadCache:function(){if(OpenLayers.Event&&OpenLayers.Event.observers){for(var cacheID in OpenLayers.Event.observers){var elementObservers=OpenLayers.Event.observers[cacheID];OpenLayers.Event._removeElementObservers.apply(this,[elementObservers]);}
59784 OpenLayers.Event.observers=false;}},CLASS_NAME:"OpenLayers.Event"};OpenLayers.Event.observe(window,'unload',OpenLayers.Event.unloadCache,false);if(window.Event){OpenLayers.Util.applyDefaults(window.Event,OpenLayers.Event);}else{var Event=OpenLayers.Event;}
59785 OpenLayers.Events=OpenLayers.Class({BROWSER_EVENTS:["mouseover","mouseout","mousedown","mouseup","mousemove","click","dblclick","rightclick","dblrightclick","resize","focus","blur"],listeners:null,object:null,element:null,eventTypes:null,eventHandler:null,fallThrough:null,includeXY:false,clearMouseListener:null,initialize:function(object,element,eventTypes,fallThrough,options){OpenLayers.Util.extend(this,options);this.object=object;this.fallThrough=fallThrough;this.listeners={};this.eventHandler=OpenLayers.Function.bindAsEventListener(this.handleBrowserEvent,this);this.clearMouseListener=OpenLayers.Function.bind(this.clearMouseCache,this);this.eventTypes=[];if(eventTypes!=null){for(var i=0,len=eventTypes.length;i<len;i++){this.addEventType(eventTypes[i]);}}
59786 if(element!=null){this.attachToElement(element);}},destroy:function(){if(this.element){OpenLayers.Event.stopObservingElement(this.element);if(this.element.hasScrollEvent){OpenLayers.Event.stopObserving(window,"scroll",this.clearMouseListener);}}
59787 this.element=null;this.listeners=null;this.object=null;this.eventTypes=null;this.fallThrough=null;this.eventHandler=null;},addEventType:function(eventName){if(!this.listeners[eventName]){this.eventTypes.push(eventName);this.listeners[eventName]=[];}},attachToElement:function(element){if(this.element){OpenLayers.Event.stopObservingElement(this.element);}
59788 this.element=element;for(var i=0,len=this.BROWSER_EVENTS.length;i<len;i++){var eventType=this.BROWSER_EVENTS[i];this.addEventType(eventType);OpenLayers.Event.observe(element,eventType,this.eventHandler);}
59789 OpenLayers.Event.observe(element,"dragstart",OpenLayers.Event.stop);},on:function(object){for(var type in object){if(type!="scope"){this.register(type,object.scope,object[type]);}}},register:function(type,obj,func){if((func!=null)&&(OpenLayers.Util.indexOf(this.eventTypes,type)!=-1)){if(obj==null){obj=this.object;}
59790 var listeners=this.listeners[type];listeners.push({obj:obj,func:func});}},registerPriority:function(type,obj,func){if(func!=null){if(obj==null){obj=this.object;}
59791 var listeners=this.listeners[type];if(listeners!=null){listeners.unshift({obj:obj,func:func});}}},un:function(object){for(var type in object){if(type!="scope"){this.unregister(type,object.scope,object[type]);}}},unregister:function(type,obj,func){if(obj==null){obj=this.object;}
59792 var listeners=this.listeners[type];if(listeners!=null){for(var i=0,len=listeners.length;i<len;i++){if(listeners[i].obj==obj&&listeners[i].func==func){listeners.splice(i,1);break;}}}},remove:function(type){if(this.listeners[type]!=null){this.listeners[type]=[];}},triggerEvent:function(type,evt){var listeners=this.listeners[type];if(!listeners||listeners.length==0){return;}
59793 if(evt==null){evt={};}
59794 evt.object=this.object;evt.element=this.element;if(!evt.type){evt.type=type;}
59795 var listeners=listeners.slice(),continueChain;for(var i=0,len=listeners.length;i<len;i++){var callback=listeners[i];continueChain=callback.func.apply(callback.obj,[evt]);if((continueChain!=undefined)&&(continueChain==false)){break;}}
59796 if(!this.fallThrough){OpenLayers.Event.stop(evt,true);}
59797 return continueChain;},handleBrowserEvent:function(evt){if(this.includeXY){evt.xy=this.getMousePosition(evt);}
59798 this.triggerEvent(evt.type,evt);},clearMouseCache:function(){this.element.scrolls=null;this.element.lefttop=null;this.element.offsets=null;},getMousePosition:function(evt){if(!this.includeXY){this.clearMouseCache();}else if(!this.element.hasScrollEvent){OpenLayers.Event.observe(window,"scroll",this.clearMouseListener);this.element.hasScrollEvent=true;}
59799 if(!this.element.scrolls){this.element.scrolls=[(document.documentElement.scrollLeft||document.body.scrollLeft),(document.documentElement.scrollTop||document.body.scrollTop)];}
59800 if(!this.element.lefttop){this.element.lefttop=[(document.documentElement.clientLeft||0),(document.documentElement.clientTop||0)];}
59801 if(!this.element.offsets){this.element.offsets=OpenLayers.Util.pagePosition(this.element);this.element.offsets[0]+=this.element.scrolls[0];this.element.offsets[1]+=this.element.scrolls[1];}
59802 return new OpenLayers.Pixel((evt.clientX+this.element.scrolls[0])-this.element.offsets[0]
59803 -this.element.lefttop[0],(evt.clientY+this.element.scrolls[1])-this.element.offsets[1]
59804 -this.element.lefttop[1]);},CLASS_NAME:"OpenLayers.Events"});OpenLayers.Format=OpenLayers.Class({options:null,externalProjection:null,internalProjection:null,data:null,keepData:false,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;},destroy:function(){},read:function(data){OpenLayers.Console.userError(OpenLayers.i18n("readNotImplemented"));},write:function(object){OpenLayers.Console.userError(OpenLayers.i18n("writeNotImplemented"));},CLASS_NAME:"OpenLayers.Format"});OpenLayers.Lang["ar"]=OpenLayers.Util.applyDefaults({'permalink':"وصلة دائمة",'baseLayer':"الطبقة الاساسية",'readNotImplemented':"القراءة غير محققة.",'writeNotImplemented':"الكتابة غير محققة",'errorLoadingGML':"خطأ عند تحميل الملف جي ام ال ${url}",'scale':"النسبة = 1 : ${scaleDenom}",'W':"غ",'E':"شر",'N':"شم",'S':"ج"});OpenLayers.Lang["be-tarask"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Неапрацаваны вынік запыту ${statusText}",'permalink':"Сталая спасылка",'overlays':"Слаі",'baseLayer':"Базавы слой",'sameProjection':"Аглядная мапа працуе толькі калі яна мае тую ж праекцыю, што і асноўная мапа",'readNotImplemented':"Функцыянальнасьць чытаньня ня створаная.",'writeNotImplemented':"Функцыянальнасьць запісу ня створаная.",'noFID':"Немагчыма абнавіць магчымасьць, для якога не існуе FID.",'errorLoadingGML':"Памылка загрузкі файла GML ${url}",'browserNotSupported':"Ваш браўзэр не падтрымлівае вэктарную графіку. У цяперашні момант падтрымліваюцца: ${renderers}",'componentShouldBe':"addFeatures : кампанэнт павінен быць ${geomType}",'getFeatureError':"getFeatureFromEvent выкліканы для слоя бяз рэндэру. Звычайна гэта азначае, што Вы зьнішчылі слой, але пакінулі зьвязаны зь ім апрацоўшчык.",'minZoomLevelError':"Уласьцівасьць minZoomLevel прызначана толькі для выкарыстаньня са слаямі вытворнымі ад FixedZoomLevels. Тое, што  гэты wfs-слой правяраецца на minZoomLevel — рэха прошлага. Але мы ня можам выдаліць гэтую магчымасьць, таму што ад яе залежаць некаторыя заснаваныя на OL дастасаваньні. Тым ня менш, праверка minZoomLevel будзе выдаленая ў вэрсіі 3.0. Калі ласка, выкарыстоўваеце замест яе ўстаноўкі мінімальнага/максымальнага памераў, як апісана тут: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-транзакцыя: ПОСЬПЕХ ${response}",'commitFailed':"WFS-транзакцыя: ПАМЫЛКА ${response}",'googleWarning':"Не атрымалася загрузіць слой Google. \x3cbr\x3e\x3cbr\x3eКаб пазбавіцца гэтага паведамленьня, выберыце новы базавы слой у сьпісе ў верхнім правым куце.\x3cbr\x3e\x3cbr\x3e Хутчэй за ўсё, прычына ў тым, што скрыпт бібліятэкі Google Maps ня быў уключаныя альбо не ўтрымлівае слушны API-ключ для Вашага сайта.\x3cbr\x3e\x3cbr\x3eРаспрацоўшчыкам: Для таго, каб даведацца як зрабіць так, каб усё працавала, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eнацісьніце тут\x3c/a\x3e",'getLayerWarning':"Немагчыма загрузіць слой ${layerType}.\x3cbr\x3e\x3cbr\x3eКаб пазбавіцца гэтага паведамленьня, выберыце новы базавы слой у сьпісе ў верхнім правым куце.\x3cbr\x3e\x3cbr\x3eХутчэй за ўсё, прычына ў тым, што скрыпт бібліятэкі ${layerLib} ня быў слушна ўключаны.\x3cbr\x3e\x3cbr\x3eРаспрацоўшчыкам: Для таго, каб даведацца як зрабіць так, каб усё працавала, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eнацісьніце тут\x3c/a\x3e",'scale':"Маштаб = 1 : ${scaleDenom}",'W':"З",'E':"У",'N':"Пн",'S':"Пд",'layerAlreadyAdded':"Вы паспрабавалі дадаць слой ${layerName} на мапу, але ён ужо дададзены",'reprojectDeprecated':"Вы выкарыстоўваеце ўстаноўку \'reproject\' для слоя ${layerName}. Гэтая ўстаноўка зьяўляецца састарэлай: яна выкарыстоўвалася для падтрымкі паказу зьвестак на камэрцыйных базавых мапах, але гэта функцыя цяпер рэалізаваная ў убудаванай падтрымцы сфэрычнай праекцыі Мэркатара. Дадатковая інфармацыя ёсьць на http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Гэты мэтад састарэлы і будзе выдалены ў вэрсіі 3.0. Калі ласка, замест яго выкарыстоўвайце ${newMethod}.",'boundsAddError':"Вам неабходна падаць абодва значэньні x і y для функцыі складаньня.",'lonlatAddError':"Вам неабходна падаць абодва значэньні lon і lat для функцыі складаньня.",'pixelAddError':"Вам неабходна падаць абодва значэньні x і y для функцыі складаньня.",'unsupportedGeometryType':"Тып геамэтрыі не падтрымліваецца: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: верагодна элемэнт з ідэнтыфікатарам ${elemId} займае няслушнае месца.",'filterEvaluateNotImplemented':"evaluate не рэалізаваны для гэтага тыпу фільтру."});OpenLayers.Lang["bg"]=OpenLayers.Util.applyDefaults({'permalink':"Постоянна препратка",'baseLayer':"Основен слой",'errorLoadingGML':"Грешка при зареждане на GML файл ${url}",'scale':"Мащаб = 1 : ${scaleDenom}",'layerAlreadyAdded':"Опитахте да добавите слой ${layerName} в картата, но той вече е добавен",'methodDeprecated':"Този метод е остарял и ще бъде премахват в 3.0. Вместо него използвайте ${newMethod}."});OpenLayers.Lang["br"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Distro evel reked anveret ${statusText}",'permalink':"Peurliamm",'overlays':"Gwiskadoù",'baseLayer':"Gwiskad diazez",'sameProjection':"Ne\'z ar gartenn lec\'hiañ en-dro nemet pa vez heñvel ar banndres anezhi ha hini ar gartenn bennañ",'readNotImplemented':"N\'eo ket emplementet al lenn.",'writeNotImplemented':"N\'eo ket emplementet ar skrivañ.",'noFID':"N\'haller ket hizivaat un elfenn ma n\'eus ket a niverenn-anaout (FID) eviti.",'errorLoadingGML':"Fazi e-ser kargañ ar restr GML ${url}",'browserNotSupported':"N\'eo ket skoret an daskor vektorel gant ho merdeer. Setu aze an daskorerioù skoret evit ar poent :\n${renderers}",'componentShouldBe':"addFeatures : bez\' e tlefe ar parzh besañ eus ar seurt ${geomType}",'getFeatureError':"Galvet eo bet getFeatureFromEvent called war ur gwiskad hep daskorer. Kement-se a dalvez ez eus bet freuzet ur gwiskad hag hoc\'h eus miret un embreger bennak stag outañ.",'minZoomLevelError':"Ne zleer implijout ar perzh minZoomLevel nemet evit gwiskadoù FixedZoomLevels-descendent. Ar fed ma wiria ar gwiskad WHS-se hag-eñ ez eus eus minZoomLevel zo un aspadenn gozh. Koulskoude n\'omp ket evit e ziverkañ kuit da derriñ arloadoù diazezet war OL a c\'hallfe bezañ stag outañ. Setu perak eo dispredet -- Lamet kuit e vo ar gwiriañ minZoomLevel a-is er stumm 3.0. Ober gant an arventennoù bihanañ/brasañ evel deskrivet amañ e plas : http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Treuzgread WFS : MAT EO ${response}",'commitFailed':"Treuzgread WFS Transaction: C\'HWITET ${response}",'googleWarning':"N\'eus ket bet gallet kargañ ar gwiskad Google ent reizh.\x3cbr\x3e\x3cbr\x3eEvit en em zizober eus ar c\'hemenn-mañ, dibabit ur BaseLayer nevez en diuzer gwiskadoù er c\'horn dehoù el laez.\x3cbr\x3e\x3cbr\x3eSur a-walc\'h eo peogwir n\'eo ket bet ensoc\'het levraoueg Google Maps pe neuze ne glot ket an alc\'hwez API gant ho lec\'hienn.\x3cbr\x3e\x3cbr\x3eDiorroerien : Evit reizhañ an dra-se, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclick here\x3c/a\x3e",'getLayerWarning':"N\'haller ket kargañ ar gwiskad ${layerType} ent reizh.\x3cbr\x3e\x3cbr\x3eEvit en em zizober eus ar c\'hemenn-mañ, dibabit ur BaseLayer nevez en diuzer gwiskadoù er c\'horn dehoù el laez.\x3cbr\x3e\x3cbr\x3eSur a-walc\'h eo peogwir n\'eo ket bet ensoc\'het mat al levraoueg ${layerLib}.\x3cbr\x3e\x3cbr\x3eDiorroerien : Evit gouzout penaos reizhañ an dra-se, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclick here\x3c/a\x3e",'scale':"Skeul = 1 : ${scaleDenom}",'W':"K",'E':"R",'N':"N",'S':"S",'layerAlreadyAdded':"Klasket hoc\'h eus ouzhpennañ ar gwiskad : ${layerName} d\'ar gartenn, met ouzhpennet e oa bet c\'hoazh",'reprojectDeprecated':"Emaoc\'h oc\'h implijout an dibarzh \'reproject\' war ar gwiskad ${layerName}. Dispredet eo an dibarzh-mañ : bet eo hag e talveze da ziskwel roadennoù war-c\'horre kartennoù diazez kenwerzhel, un dra hag a c\'haller ober bremañ gant an arc\'hwel dre skor banndres boullek Mercator. Muioc\'h a ditouroù a c\'haller da gaout war http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Dispredet eo an daore-se ha tennet e vo kuit eus ar stumm 3.0. Grit gant ${newMethod} e plas.",'boundsAddError':"Rekis eo tremen an div dalvoudenn x ha y d\'an arc\'hwel add.",'lonlatAddError':"Rekis eo tremen an div dalvoudenn hedred ha ledred d\'an arc\'hwel add.",'pixelAddError':"Rekis eo tremen an div dalvoudenn x ha y d\'an arc\'hwel add.",'unsupportedGeometryType':"Seurt mentoniezh anskoret : ${geomType}",'pagePositionFailed':"C\'hwitet eo OpenLayers.Util.pagePosition : marteze emañ lec\'hiet fall an elfenn id ${elemId}.",'filterEvaluateNotImplemented':"N\'eo ket bet emplementet ar priziañ evit seurt siloù c\'hoazh."});OpenLayers.Lang["el"]=OpenLayers.Util.applyDefaults({'scale':"Κλίμακα ~ 1 : ${scaleDenom}"});OpenLayers.Lang.en={'unhandledRequest':"Unhandled request return ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Base Layer",'sameProjection':"The overview map only works when it is in the same projection as the main map",'readNotImplemented':"Read not implemented.",'writeNotImplemented':"Write not implemented.",'noFID':"Can't update a feature for which there is no FID.",'errorLoadingGML':"Error in loading GML file ${url}",'browserNotSupported':"Your browser does not support vector rendering. Currently supported renderers are:\n${renderers}",'componentShouldBe':"addFeatures : component should be an ${geomType}",'getFeatureError':"getFeatureFromEvent called on layer with no renderer. This usually means you "+"destroyed a layer, but not some handler which is associated with it.",'minZoomLevelError':"The minZoomLevel property is only intended for use "+"with the FixedZoomLevels-descendent layers. That this "+"wfs layer checks for minZoomLevel is a relic of the"+"past. We cannot, however, remove it without possibly "+"breaking OL based applications that may depend on it."+" Therefore we are deprecating it -- the minZoomLevel "+"check below will be removed at 3.0. Please instead "+"use min/max resolution setting as described here: "+"http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS Transaction: SUCCESS ${response}",'commitFailed':"WFS Transaction: FAILED ${response}",'googleWarning':"The Google Layer was unable to load correctly.<br><br>"+"To get rid of this message, select a new BaseLayer "+"in the layer switcher in the upper-right corner.<br><br>"+"Most likely, this is because the Google Maps library "+"script was either not included, or does not contain the "+"correct API key for your site.<br><br>"+"Developers: For help getting this working correctly, "+"<a href='http://trac.openlayers.org/wiki/Google' "+"target='_blank'>click here</a>",'getLayerWarning':"The ${layerType} Layer was unable to load correctly.<br><br>"+"To get rid of this message, select a new BaseLayer "+"in the layer switcher in the upper-right corner.<br><br>"+"Most likely, this is because the ${layerLib} library "+"script was not correctly included.<br><br>"+"Developers: For help getting this working correctly, "+"<a href='http://trac.openlayers.org/wiki/${layerLib}' "+"target='_blank'>click here</a>",'scale':"Scale = 1 : ${scaleDenom}",'W':'W','E':'E','N':'N','S':'S','graticule':'Graticule','layerAlreadyAdded':"You tried to add the layer: ${layerName} to the map, but it has already been added",'reprojectDeprecated':"You are using the 'reproject' option "+"on the ${layerName} layer. This option is deprecated: "+"its use was designed to support displaying data over commercial "+"basemaps, but that functionality should now be achieved by using "+"Spherical Mercator support. More information is available from "+"http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"This method has been deprecated and will be removed in 3.0. "+"Please use ${newMethod} instead.",'boundsAddError':"You must pass both x and y values to the add function.",'lonlatAddError':"You must pass both lon and lat values to the add function.",'pixelAddError':"You must pass both x and y values to the add function.",'unsupportedGeometryType':"Unsupported geometry type: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: element with id ${elemId} may be misplaced.",'filterEvaluateNotImplemented':"evaluate is not implemented for this filter type.",'end':''};OpenLayers.Lang["fi"]=OpenLayers.Util.applyDefaults({'permalink':"Ikilinkki",'overlays':"Kerrokset",'baseLayer':"Peruskerros",'sameProjection':"Yleiskuvakarttaa voi käyttää vain, kun sillä on sama projektio kuin pääkartalla.",'W':"L",'E':"I",'N':"P",'S':"E"});OpenLayers.Lang["fur"]=OpenLayers.Util.applyDefaults({'permalink':"Leam Permanent",'overlays':"Livei parsore",'baseLayer':"Livel di base",'browserNotSupported':"Il to sgarfadôr nol supuarte la renderizazion vetoriâl. Al moment a son supuartâts:\n${renderers}",'scale':"Scjale = 1 : ${scaleDenom}",'W':"O",'E':"E",'N':"N",'S':"S"});OpenLayers.Lang["gl"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Solicitude non xerada; a resposta foi: ${statusText}",'permalink':"Ligazón permanente",'overlays':"Capas superpostas",'baseLayer':"Capa base",'sameProjection':"A vista xeral do mapa só funciona cando está na mesma proxección có mapa principal",'readNotImplemented':"Lectura non implementada.",'writeNotImplemented':"Escritura non implementada.",'noFID':"Non se pode actualizar a funcionalidade para a que non hai FID.",'errorLoadingGML':"Erro ao cargar o ficheiro GML ${url}",'browserNotSupported':"O seu navegador non soporta a renderización de vectores. Os renderizadores soportados actualmente son:\n${renderers}",'componentShouldBe':"addFeatures: o compoñente debera ser de tipo ${geomType}",'getFeatureError':"getFeatureFromEvent ten sido chamado a unha capa sen renderizador. Isto normalmente significa que destruíu unha capa, mais non o executador que está asociado con ela.",'minZoomLevelError':"A propiedade minZoomLevel é só para uso conxuntamente coas capas FixedZoomLevels-descendent. O feito de que esa capa wfs verifique o minZoomLevel é unha reliquia do pasado. Non podemos, con todo, eliminala sen a posibilidade de non romper as aplicacións baseadas en OL que poidan depender dela. Por iso a estamos deixando obsoleta (a comprobación minZoomLevel de embaixo será eliminada na versión 3.0). Por favor, no canto diso use o axuste de resolución mín/máx tal e como está descrito aquí: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transacción WFS: ÉXITO ${response}",'commitFailed':"Transacción WFS: FALLIDA ${response}",'googleWarning':"A capa do Google non puido cargarse correctamente.\x3cbr\x3e\x3cbr\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\x3cbr\x3e\x3cbr\x3eProbablemente, isto acontece porque a escritura da libraría do Google Maps ou ben non foi incluída ou ben non contén a clave API correcta para o seu sitio.\x3cbr\x3e\x3cbr\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3epremede aquí\x3c/a\x3e",'getLayerWarning':"A capa ${layerType} foi incapaz de cargarse correctamente.\x3cbr\x3e\x3cbr\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\x3cbr\x3e\x3cbr\x3eProbablemente, isto acontece porque a escritura da libraría ${layerLib} non foi ben incluída.\x3cbr\x3e\x3cbr\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3epremede aquí\x3c/a\x3e",'scale':"Escala = 1 : ${scaleDenom}",'W':"O",'E':"L",'N':"N",'S':"S",'layerAlreadyAdded':"Intentou engadir a capa: ${layerName} ao mapa, pero xa fora engadida",'reprojectDeprecated':"Está usando a opción \"reproject\" na capa ${layerName}. Esta opción está obsoleta: o seu uso foi deseñado para a visualización de datos sobre mapas base comerciais, pero esta funcionalidade debera agora ser obtida utilizando a proxección Spherical Mercator. Hai dispoñible máis información en http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Este método está obsoleto e será eliminado na versión 3.0. Por favor, no canto deste use ${newMethod}.",'boundsAddError':"Debe achegar os valores x e y á función add.",'lonlatAddError':"Debe achegar tanto o valor lon coma o lat á función add.",'pixelAddError':"Debe achegar os valores x e y á función add.",'unsupportedGeometryType':"Tipo xeométrico non soportado: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition fallou: o elemento con id ${elemId} pode non estar na súa posición.",'filterEvaluateNotImplemented':"avaliar non está implementado para este tipo de filtro."});OpenLayers.Lang["gsw"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nit behandleti Aafrogsruckmäldig ${statusText}",'permalink':"Permalink",'overlays':"Iberlagerige",'baseLayer':"Grundcharte",'sameProjection':"D Ibersichts-Charte funktioniert nume, wänn si di glych Projäktion brucht wie d Hauptcharte",'readNotImplemented':"Läse nit implementiert.",'writeNotImplemented':"Schrybe nit implementiert.",'noFID':"E Feature, wu s kei FID derfir git, cha nit aktualisiert wäre.",'errorLoadingGML':"Fähler bim Lade vu dr GML-Datei ${url}",'browserNotSupported':"Dyy Browser unterstitzt kei Vektordarstellig. Aktuäll unterstitzti Renderer:\n${renderers}",'componentShouldBe':"addFeatures : Komponänt sott dr Typ ${geomType} syy",'getFeatureError':"getFeatureFromEvent isch uf eme Layer ohni Renderer ufgruefe wore. Des heisst normalerwys, ass Du e Layer kaputt gmacht hesch, aber nit dr Handler, wu derzue ghert.",'minZoomLevelError':"D minZoomLevel-Eigeschaft isch nume dänk fir d Layer, wu vu dr FixedZoomLevels abstamme. Ass dää wfs-Layer minZoomLevel prieft, scih e Relikt us dr Vergangeheit. Mir chenne s aber nit ändere ohni OL_basierti Aawändige villicht kaputt gehn, wu dervu abhänge.  Us däm Grund het die Funktion d Eigeschaft \'deprecated\' iberchuu. D minZoomLevel-Priefig unte wird in dr Version 3.0 usegnuu. Bitte verwänd statt däm e min/max-Uflesig wie s do bschriben isch: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-Transaktion: ERFOLGRYCH ${response}",'commitFailed':"WFS-Transaktion: FÄHLGSCHLAA ${response}",'googleWarning':"Dr Google-Layer het nit korräkt chenne glade wäre.\x3cbr\x3e\x3cbr\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\x3cbr\x3e\x3cbr\x3eDää Fähler git s seli hyfig, wel s Skript vu dr Google-Maps-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\x3cbr\x3e\x3cbr\x3eEntwickler: Fir Hilf zum korräkte Yybinde vum Google-Layer \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3edoo drucke\x3c/a\x3e",'getLayerWarning':"Dr ${layerType}-Layer het nit korräkt chenne glade wäre.\x3cbr\x3e\x3cbr\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\x3cbr\x3e\x3cbr\x3eDää Fähler git s seli hyfig, wel s Skript vu dr \'${layerLib}\'-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\x3cbr\x3e\x3cbr\x3eEntwickler: Fir Hilf zum korräkte Yybinde vu Layer \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3edoo drucke\x3c/a\x3e",'scale':"Maßstab = 1 : ${scaleDenom}",'W':"W",'E':"O",'N':"N",'S':"S",'layerAlreadyAdded':"Du hesch versuecht dää Layer in d Charte yyzfiege: ${layerName}, aber är isch schoi yygfiegt",'reprojectDeprecated':"Du bruchsch d \'reproject\'-Option bim ${layerName}-Layer. Die Option isch nimi giltig: si isch aagleit wore go   Date iber kommerziälli Grundcharte lege, aber des sott mer jetz mache mit dr Unterstitzig vu Spherical Mercator. Meh Informatione git s uf http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Die Methode isch veraltet un wird us dr Version 3.0 usegnuu. Bitte verwäbnd statt däm ${newMethod}.",'boundsAddError':"Du muesch e x-Wärt un e y-Wärt yygee bi dr Zuefieg-Funktion",'lonlatAddError':"Du meusch e Lengi- un e Breiti-Grad yygee bi dr Zuefieg-Funktion.",'pixelAddError':"Du muesch x- un y-Wärt aagee bi dr Zuefieg-Funktion.",'unsupportedGeometryType':"Nit unterstitze Geometrii-Typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition fählgschlaa: Elemänt mit ID ${elemId} isch villicht falsch gsetzt.",'filterEvaluateNotImplemented':"evaluiere isch nit implemäntiert in däm Filtertyp."});OpenLayers.Lang["hr"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nepodržani zahtjev ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Osnovna karta",'sameProjection':"Pregledna karta radi jedino kao je u istoj projekciji kao i glava karta",'readNotImplemented':"Čitanje nije implementirano.",'writeNotImplemented':"Pisanje nije implementirano.",'noFID':"Ne mogu ažurirati značajku za koju ne postoji FID.",'errorLoadingGML':"Greška u učitavanju GML datoteke ${url}",'browserNotSupported':"Vaš preglednik ne podržava vektorsko renderiranje. Trenutno podržani rendereri su: ${renderers}",'componentShouldBe':"addFeatures : komponenta bi trebala biti ${geomType}",'getFeatureError':"getFeatureFromEvent je pozvao Layer bez renderera. Ovo obično znači da ste uništiili Layer, a ne neki Handler koji je povezan s njim.",'commitSuccess':"WFS Transakcija: USPJEŠNA ${response}",'commitFailed':"WFS Transakcija: NEUSPJEŠNA ${response}",'scale':"Mjerilo = 1 : ${scaleDenom}",'layerAlreadyAdded':"Pokušali ste dodati layer:  ${layerName} na kartu, ali je već dodan",'methodDeprecated':"Ova metoda nije odobrena i biti će maknuta u 3.0. Koristite ${newMethod}.",'boundsAddError':"Morate dati obje vrijednosti ,  x i y  da bi dodali funkciju.",'lonlatAddError':"Morate dati obje vrijednosti , (lon i lat) da bi dodali funkciju.",'pixelAddError':"Morate dati obje vrijednosti ,  x i y  da bi dodali funkciju.",'unsupportedGeometryType':"Nepodržani tip geometrije: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition nije uspjelo: element sa id ${elemId} može biti krivo smješten."});OpenLayers.Lang["hsb"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Wotmołwa njewobdźěłaneho naprašowanja ${statusText}",'permalink':"Trajny wotkaz",'overlays':"Naworštowanja",'baseLayer':"Zakładna runina",'sameProjection':"Přehladowa karta jenož funguje, hdyž je w samsnej projekciji kaž hłowna karta",'readNotImplemented':"Čitanje njeimplementowane.",'writeNotImplemented':"Pisanje njeimplementowane.",'noFID':"Funkcija, za kotruž FID njeje, njeda so aktualizować.",'errorLoadingGML':"Zmylk při začitowanju dataje ${url}",'browserNotSupported':"Twój wobhladowak wektorowe rysowanje njepodpěruje. Tuchwilu podpěrowane rysowaki su:\n${renderers}",'componentShouldBe':"addFeatures: komponenta měła ${geomType} być",'getFeatureError':"getFeatureFromEvent bu na woršće bjez rysowak zawołany. To zwjetša woznamjenja, zo sy worštu zničił, ale nic wobdźěłak, kotryž je z njej zwjazany.",'minZoomLevelError':"Kajkosć minZoomLevel je jenož za wužiwanje z worštami myslena, kotrež wot FixedZoomLevels pochadźeja. Zo tuta woršta wfs za minZoomLevel přepruwuje, je relikt zańdźenosće. Njemóžemy wšak ju wotstronić, bjeztoho zo aplikacije, kotrež na OpenLayers bazěruja a snano tutu kajkosć wužiwaja, hižo njefunguja. Tohodla smy ju jako zestarjenu woznamjenili -- přepruwowanje za minZoomLevel budu so we wersiji 3.0 wotstronjeć. Prošu wužij město toho nastajenje min/max, kaž je tu wopisane: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS-Transakcija: WUSPĚŠNA ${response}",'commitFailed':"WFS-Transakcija: NJEPORADŹENA ${response}",'googleWarning':"Woršta Google njemóžeše so korektnje začitać.\x3cbr\x3e\x3cbr\x3eZo by tutu zdźělenku wotbył, wubjer nowy BaseLayer z wuběra worštow horjeka naprawo.\x3cbr\x3e\x3cbr\x3eNajskerje so to stawa, dokelž skript biblioteki Google Maps pak njebu zapřijaty pak njewobsahuje korektny kluč API za twoje sydło.\x3cbr\x3e\x3cbr\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worštow\n\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3etu kliknyć\x3c/a\x3e",'getLayerWarning':"Woršta ${layerType} njemóžeše so korektnje začitać.\x3cbr\x3e\x3cbr\x3eZo by tutu zdźělenku wotbył, wubjer nowy BaseLayer z wuběra worštow horjeka naprawo.\x3cbr\x3e\x3cbr\x3eNajskerje so to stawa, dokelž skript biblioteki ${layerLib} njebu korektnje zapřijaty.\x3cbr\x3e\x3cbr\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worštow\n\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3etu kliknyć\x3c/a\x3e",'scale':"Měritko = 1 : ${scaleDenom}",'W':"Z",'E':"W",'N':"S",'S':"J",'layerAlreadyAdded':"Sy spytał runinu ${layerName} karće dodać, ale je so hižo dodała",'reprojectDeprecated':"Wužiwaš opciju \"reproject\" wořšty ${layerName}. Tuta opcija je zestarjena: jeje wužiwanje bě myslene, zo by zwobraznjenje datow nad komercielnymi bazowymi kartami podpěrało, ale funkcionalnosć měła so nětko z pomocu Sperical Mercator docpěć. Dalše informacije steja na http://trac.openlayers.org/wiki/SphericalMercator k dispoziciji.",'methodDeprecated':"Tuta metoda je so njeschwaliła a budźe so w 3.0 wotstronjeć. Prošu wužij ${newMethod} město toho.",'boundsAddError':"Dyrbiš hódnotu x kaž tež y funkciji \"add\" přepodać.",'lonlatAddError':"Dyrbiš hódnotu lon kaž tež lat funkciji \"add\" přepodać.",'pixelAddError':"Dyrbiš hódnotu x kaž tež y funkciji \"add\" přepodać.",'unsupportedGeometryType':"Njepodpěrowany geometrijowy typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition je so njeporadźił: element z id ${elemId} bu snano wopak zaměstnjeny.",'filterEvaluateNotImplemented':"wuhódnoćenje njeje za tutón filtrowy typ implementowany."});OpenLayers.Lang["hu"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Nem kezelt kérés visszatérése ${statusText}",'permalink':"Permalink",'overlays':"Rávetítések",'baseLayer':"Alapréteg",'sameProjection':"Az áttekintő térkép csak abban az esetben működik, ha ugyanazon a vetületen van, mint a fő térkép.",'readNotImplemented':"Olvasás nincs végrehajtva.",'writeNotImplemented':"Írás nincs végrehajtva.",'noFID':"Nem frissíthető olyan jellemző, amely nem rendelkezik FID-del.",'errorLoadingGML':"Hiba GML-fájl betöltésekor ${url}",'browserNotSupported':"A böngészője nem támogatja a vektoros renderelést. A jelenleg támogatott renderelők:\n${renderers}",'componentShouldBe':"addFeatures : az összetevőnek ilyen típusúnak kell lennie: ${geomType}",'getFeatureError':"getFeatureFromEvent réteget hívott meg renderelő nélkül. Ez rendszerint azt jelenti, hogy megsemmisített egy fóliát, de néhány ahhoz társított kezelőt nem.",'minZoomLevelError':"A minZoomLevel tulajdonságot csak a következővel való használatra szánták: FixedZoomLevels-leszármazott fóliák. Ez azt jelenti, hogy a minZoomLevel wfs fólia jelölőnégyzetei már a múlté. Mi azonban nem távolíthatjuk el annak a veszélye nélkül, hogy az esetlegesen ettől függő OL alapú alkalmazásokat tönkretennénk. Ezért ezt érvénytelenítjük -- a minZoomLevel az alul levő jelölőnégyzet a 3.0-s verzióból el lesz távolítva. Kérjük, helyette használja a  min/max felbontás beállítást, amelyről az alábbi helyen talál leírást: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS tranzakció: SIKERES ${response}",'commitFailed':"WFS tranzakció: SIKERTELEN ${response}",'googleWarning':"A Google fólia betöltése sikertelen.\x3cbr\x3e\x3cbr\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felső sarokban található fóliakapcsoló segítségével.\x3cbr\x3e\x3cbr\x3eNagy valószínűséggel ez azért van, mert a Google Maps könyvtár parancsfájlja nem található, vagy nem tartalmazza az Ön oldalához tartozó megfelelő API-kulcsot.\x3cbr\x3e\x3cbr\x3eFejlesztőknek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhető el, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3ekattintson ide\x3c/a\x3e",'getLayerWarning':"A(z) ${layerType} fólia nem töltődött be helyesen.\x3cbr\x3e\x3cbr\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felső sarokban található fóliakapcsoló segítségével.\x3cbr\x3e\x3cbr\x3eNagy valószínűséggel ez azért van, mert a(z) ${layerLib} könyvtár parancsfájlja helytelen.\x3cbr\x3e\x3cbr\x3eFejlesztőknek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhető el, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3ekattintson ide\x3c/a\x3e",'scale':"Lépték = 1 : ${scaleDenom}",'W':"Ny",'E':"K",'N':"É",'S':"D",'layerAlreadyAdded':"Megpróbálta hozzáadni a(z) ${layerName} fóliát a térképhez, de az már hozzá van adva",'reprojectDeprecated':"Ön a \'reproject\' beállítást használja a(z) ${layerName} fólián. Ez a beállítás érvénytelen: használata az üzleti alaptérképek fölötti adatok megjelenítésének támogatására szolgált, de ezt a funkció ezentúl a Gömbi Mercator használatával érhető el. További információ az alábbi helyen érhető el: http://trac.openlayers.org/wiki/SphericalMercator",'methodDeprecated':"Ez a módszer érvénytelenítve lett és a 3.0-s verzióból el lesz távolítva. Használja a(z) ${newMethod} módszert helyette.",'boundsAddError':"Az x és y értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'lonlatAddError':"A hossz. és szél. értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'pixelAddError':"Az x és y értékeknek egyaránt meg kell felelnie, hogy a funkciót hozzáadhassa.",'unsupportedGeometryType':"Nem támogatott geometriatípus: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition sikertelen: lehetséges, hogy a(z) ${elemId} azonosítójú elem téves helyre került.",'filterEvaluateNotImplemented':"ennél a szűrőtípusnál kiértékelés nem hajtódik végre."});OpenLayers.Lang["ia"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Le responsa a un requesta non esseva maneate: ${statusText}",'permalink':"Permaligamine",'overlays':"Superpositiones",'baseLayer':"Strato de base",'sameProjection':"Le mini-carta functiona solmente si illo es in le mesme projection que le carta principal",'readNotImplemented':"Lectura non implementate.",'writeNotImplemented':"Scriptura non implementate.",'noFID':"Non pote actualisar un elemento sin FID.",'errorLoadingGML':"Error al cargamento del file GML ${url}",'browserNotSupported':"Tu navigator non supporta le rendition de vectores. Le renditores actualmente supportate es:\n${renderers}",'componentShouldBe':"addFeatures: le componente debe esser del typo ${geomType}",'getFeatureError':"getFeatureFromEvent ha essite appellate in un strato sin renditor. Isto significa generalmente que tu ha destruite un strato, ma lassava un gestor associate con illo.",'minZoomLevelError':"Le proprietate minZoomLevel es solmente pro uso con le stratos descendente de FixedZoomLevels. Le facto que iste strato WFS verifica minZoomLevel es un reliquia del passato. Nonobstante, si nos lo remove immediatemente, nos pote rumper applicationes a base de OL que depende de illo. Ergo nos lo declara obsolete; le verification de minZoomLevel in basso essera removite in version 3.0. Per favor usa in su loco le configuration de resolutiones min/max como describite a: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transaction WFS: SUCCESSO ${response}",'commitFailed':"Transaction WFS: FALLEVA ${response}",'googleWarning':"Le strato Google non poteva esser cargate correctemente.\x3cbr\x3e\x3cbr\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\x3cbr\x3e\x3cbr\x3eMulto probabilemente, isto es proque le script del libreria de Google Maps non esseva includite o non contine le clave API correcte pro tu sito.\x3cbr\x3e\x3cbr\x3eDisveloppatores: Pro adjuta de corriger isto, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclicca hic\x3c/a",'getLayerWarning':"Le strato ${layerType} non poteva esser cargate correctemente.\x3cbr\x3e\x3cbr\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\x3cbr\x3e\x3cbr\x3eMulto probabilemente, isto es proque le script del libreria de ${layerLib} non esseva correctemente includite.\x3cbr\x3e\x3cbr\x3eDisveloppatores: Pro adjuta de corriger isto, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclicca hic\x3c/a\x3e",'scale':"Scala = 1 : ${scaleDenom}",'W':"W",'E':"E",'N':"N",'S':"S",'layerAlreadyAdded':"Tu tentava adder le strato: ${layerName} al carta, ma illo es ja presente",'reprojectDeprecated':"Tu usa le option \'reproject\' in le strato ${layerName} layer. Iste option es obsolescente: illo esseva pro poter monstrar datos super cartas de base commercial, ma iste functionalitate pote ora esser attingite con le uso de Spherical Mercator. Ulterior information es disponibile a http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Iste methodo ha essite declarate obsolescente e essera removite in version 3.0. Per favor usa ${newMethod} in su loco.",'boundsAddError':"Tu debe passar le duo valores x e y al function add.",'lonlatAddError':"Tu debe passar le duo valores lon e lat al function add.",'pixelAddError':"Tu debe passar le duo valores x e y al function add.",'unsupportedGeometryType':"Typo de geometria non supportate: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition falleva: le elemento con id ${elemId} pote esser mal placiate.",'filterEvaluateNotImplemented':"\"evaluate\" non es implementate pro iste typo de filtro."});OpenLayers.Lang["id"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Permintaan yang tak tertangani menghasilkan ${statusText}",'permalink':"Pranala permanen",'overlays':"Hamparan",'baseLayer':"Lapisan Dasar",'sameProjection':"Peta tinjauan hanya bekerja bila dalam proyeksi yang sama dengan peta utama",'readNotImplemented':"Membaca tidak diterapkan.",'writeNotImplemented':"Menyimpan tidak diterapkan.",'noFID':"Tidak dapat memperbarui fitur yang tidak memiliki FID.",'errorLoadingGML':"Kesalahan dalam memuat berkas GML ${url}",'browserNotSupported':"Peramban Anda tidak mendukung penggambaran vektor. Penggambar yang didukung saat ini adalah:\n${renderers}",'componentShouldBe':"addFeatures : komponen harus berupa ${geomType}",'getFeatureError':"getFeatureFromEvent diterapkan pada lapisan tanpa penggambar. Ini biasanya berarti Anda menghapus sebuah lapisan, tetapi tidak menghapus penangan yang terkait dengannya.",'minZoomLevelError':"Properti minZoomLevel hanya ditujukan bekerja dengan lapisan FixedZoomLevels-descendent. Pengecekan minZoomLevel oleh lapisan wfs adalah peninggalan masa lalu. Kami tidak dapat menghapusnya tanpa kemungkinan merusak aplikasi berbasis OL yang mungkin bergantung padanya. Karenanya, kami menganggapnya tidak berlaku -- Cek minZoomLevel di bawah ini akan dihapus pada 3.0. Silakan gunakan penyetelan resolusi min/maks seperti dijabarkan di sini: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"WFS Transaksi: BERHASIL ${respon}",'commitFailed':"WFS Transaksi: GAGAL ${respon}",'googleWarning':"Lapisan Google tidak dapat dimuat dengan benar.\x3cbr\x3e\x3cbr\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\x3cbr\x3e\x3cbr\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan atau tidak mengandung kunci API yang tepat untuk situs Anda.\x3cbr\x3e\x3cbr\x3ePengembang: Untuk bantuan mengatasi masalah ini, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eklik di sini\x3c/a\x3e",'getLayerWarning':"Lapisan ${layerType} tidak dapat dimuat dengan benar.\x3cbr\x3e\x3cbr\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\x3cbr\x3e\x3cbr\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan dengan benar.\x3cbr\x3e\x3cbr\x3ePengembang: Untuk bantuan mengatasi masalah ini, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eklik di sini\x3c/a\x3e",'scale':"Sekala = 1 : ${scaleDenom}",'W':"B",'E':"T",'N':"U",'S':"S",'layerAlreadyAdded':"Anda mencoba menambahkan lapisan: ${layerName} ke dalam peta, tapi lapisan itu telah ditambahkan",'reprojectDeprecated':"Anda menggunakan opsi \'reproject\' pada lapisan ${layerName}. Opsi ini telah ditinggalkan: penggunaannya dirancang untuk mendukung tampilan data melalui peta dasar komersial, tapi fungsionalitas tersebut saat ini harus dilakukan dengan menggunakan dukungan Spherical Mercator. Informasi lebih lanjut tersedia di http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Metode ini telah usang dan akan dihapus di 3.0. Sebaliknya, harap gunakan ${newMethod}.",'boundsAddError':"Anda harus memberikan kedua nilai x dan y ke fungsi penambah.",'lonlatAddError':"Anda harus memberikan kedua nilai lon dan lat ke fungsi penambah.",'pixelAddError':"Anda harus memberikan kedua nilai x dan y ke fungsi penambah.",'unsupportedGeometryType':"Tipe geometri tak didukung: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition gagal: elemen dengan id ${elemId} mungkin salah tempat.",'filterEvaluateNotImplemented':"evaluasi tidak tersedia untuk tipe filter ini."});OpenLayers.Lang["io"]=OpenLayers.Util.applyDefaults({'scale':"Skalo = 1 : ${scaleDenom}"});OpenLayers.Lang["is"]=OpenLayers.Util.applyDefaults({'permalink':"Varanlegur tengill",'overlays':"Þekjur",'baseLayer':"Grunnlag",'sameProjection':"Yfirlitskortið virkar aðeins ef það er í sömu vörpun og aðalkortið",'readNotImplemented':"Skrifun er óútfærð.",'writeNotImplemented':"Lestur er óútfærður.",'errorLoadingGML':"Villa kom upp við að hlaða inn GML skránni ${url}",'scale':"Skali = 1 : ${scaleDenom}",'layerAlreadyAdded':"Þú reyndir að bæta laginu ${layerName} á kortið en það er þegar búið að bæta því við",'methodDeprecated':"Þetta fall hefur verið úrelt og verður fjarlægt í 3.0. Notaðu ${newMethod} í staðin."});OpenLayers.Lang["ja"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"未処理の要求は ${statusText} を返します",'permalink':"パーマリンク",'overlays':"オーバーレイ",'baseLayer':"基底レイヤー",'sameProjection':"概観地図はメインの地図と同じ投影法をとる場合のみ機能します",'readNotImplemented':"読み込みは実装されていません。",'writeNotImplemented':"書き込みは実装されていません。",'noFID':"FID のない地物は更新できません。",'errorLoadingGML':"GML ファイル ${url} の読み込みエラー",'browserNotSupported':"あなたのブラウザはベクターグラフィックスの描写に対応していません。現時点で対応しているソフトウェアは以下のものです。\n${renderers}",'componentShouldBe':"addFeatures: 要素は ${geomType} であるべきです",'getFeatureError':"getFeatureFromEvent がレンダラーのないレイヤーから呼ばれました。通常、これはあなたがレイヤーを、それに関連づけられたいくつかのハンドラを除いて、破壊してしまったことを意味します。",'minZoomLevelError':"minZoomLevel プロパティは FixedZoomLevels を継承するレイヤーでの使用のみを想定しています。この minZoomLevel に対する WFS レイヤーの検査は歴史的なものです。しかしながら、この検査を除去するとそれに依存する OpenLayers ベースのアプリケーションを破壊してしまう可能性があります。よって廃止が予定されており、この minZoomLevel 検査はバージョン3.0で除去されます。代わりに、http://trac.openlayers.org/wiki/SettingZoomLevels で解説されている、最小および最大解像度設定を使用してください。",'commitSuccess':"WFS トランザクション: 成功 ${response}",'commitFailed':"WFS トランザクション: 失敗 ${response}",'googleWarning':"Google レイヤーが正しく読み込みを行えませんでした。\x3cbr\x3e\x3cbr\x3eこのメッセージを消すには、右上の隅にあるレイヤー切り替え部分で新しい基底レイヤーを選んでください。\x3cbr\x3e\x3cbr\x3eおそらく、これは Google マップ用ライブラリのスクリプトが組み込まれていないか、あなたのサイトに対応する正しい API キーが設定されていないためです。\x3cbr\x3e\x3cbr\x3e開発者の方へ: 正しい動作をさせるために\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eこちらのウィキ\x3c/a\x3eを参照してください。",'getLayerWarning':"${layerType} レイヤーが正しく読み込みを行えませんでした。\x3cbr\x3e\x3cbr\x3eこのメッセージを消すには、右上の隅にあるレイヤー切り替え部分で新しい基底レイヤーを選んでください。\x3cbr\x3e\x3cbr\x3eおそらく、これは ${layerLib} ライブラリのスクリプトが正しく組み込まれていないためです。\x3cbr\x3e\x3cbr\x3e開発者の方へ: 正しい動作をさせるために\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eこちらのウィキ\x3c/a\x3eを参照してください。",'scale':"縮尺 = 1 : ${scaleDenom}",'W':"西",'E':"東",'N':"北",'S':"南",'layerAlreadyAdded':"あなたは「${layerName}」を地図に追加しようと試みましたが、そのレイヤーは既に追加されています",'reprojectDeprecated':"あなたは「${layerName}」レイヤーで reproject オプションを使っています。このオプションは商用の基底地図上に情報を表示する目的で設計されましたが、現在ではその機能は Spherical Mercator サポートを利用して実現されており、このオプションの使用は非推奨です。追加の情報は http://trac.openlayers.org/wiki/SphericalMercator で入手できます。",'methodDeprecated':"このメソッドは廃止が予定されており、バージョン3.0で除去されます。代わりに ${newMethod} を使用してください。",'boundsAddError':"x と y 両方の値を add 関数に渡さなければなりません。",'lonlatAddError':"lon と lat 両方の値を add 関数に渡さなければなりません。",'pixelAddError':"x と y の値両方を add 関数に渡さなければなりません。",'unsupportedGeometryType':"未対応の形状型: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition が失敗しました: id ${elemId} をもつ要素が誤った位置にある可能性があります。",'filterEvaluateNotImplemented':"このフィルター型について evaluate は実装されていません。"});OpenLayers.Lang["km"]=OpenLayers.Util.applyDefaults({'permalink':"តំណភ្ជាប់អចិន្ត្រៃយ៍",'baseLayer':"ស្រទាប់បាត​",'errorLoadingGML':"កំហុសកំឡុងពេលផ្ទុកឯកសារ GML ${url}",'scale':"មាត្រដ្ឋាន = ១ ៖ ${scaleDenom}"});OpenLayers.Lang["ksh"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Met dä Antwoot op en Aanfrooch ham_mer nix aanjefange: ${statusText}",'permalink':"Lengk op Duuer",'overlays':"Drövver jelaat",'baseLayer':"Jrund-Nivoh",'sameProjection':"De Övverseeschs_Kaat deiht et bloß, wann se de sälve Projäxjuhn bruche deiht, wi de Houp_Kaat",'readNotImplemented':"„\x3ccode lang=\"en\"\x3eread\x3c/code\x3e“ is em Projramm nit fürjesinn.",'writeNotImplemented':"„\x3ccode lang=\"en\"\x3ewrite\x3c/code\x3e“ is em Projramm nit fürjesinn.",'noFID':"En Saach, woh kein \x3ci lang=\"en\"\x3eFID\x3c/i\x3e för doh es, löht sesch nit ändere.",'errorLoadingGML':"Fähler beim \x3ci lang=\"en\"\x3eGML\x3c/i\x3e-Datei-Laade vun \x3ccode\x3e${url}\x3c/code\x3e",'browserNotSupported':"Dinge Brauser kann kein Väktore ußjävve. De Zoote Ußjaabe, di em Momang jon, sen:\n${renderers}",'componentShouldBe':"\x3ccode lang=\"en\"\x3eaddFeatures\x3c/code\x3e: dä Aandeil sullt vun dä Zoot „\x3ccode lang=\"en\"\x3e${geomType}\x3c/code\x3e“ sin.",'getFeatureError':"\x3ccode lang=\"en\"\x3egetFeatureFromEvent\x3c/code\x3e es vun enem Nivoh opjeroofe woode, woh et kei Projramm zom Ußjävve jit. Dat bedügg för jewöhnlesch, dat De e Nivoh kapott jemaat häs, ävver nit e Projramm för domet ömzejonn, wat domet verbonge es.",'minZoomLevelError':"De Eijeschaff „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“ es bloß doför jedaach, dat mer se met dä Nivvohß bruch, di vun \x3ccode lang=\"en\"\x3eFixedZoomLevels\x3c/code\x3e affhange don. Dat dat \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Nivvoh övverhoup de Eijeschaff „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“ pröhfe deiht, es noch övveresch vun fröhjer. Mer künne dat ävver jez nit fott lohße, oohne dat mer Jevaa loufe, dat Aanwendunge vun OpenLayers nit mieh loufe, di sesch doh velleijsch noch drop am verlohße sin. Dröm sare mer, dat mer et nit mieh han welle, un de „\x3ccode lang=\"en\"\x3eminZoomLevel\x3c/code\x3e“-Eijeschaff weed hee vun de Version 3.0 af nit mieh jeprööf wäde. Nemm doför de Enstellung för de hühßte un de kleinßte Oplöhsung, esu wi et en http://trac.openlayers.org/wiki/SettingZoomLevels opjeschrevve es.",'commitSuccess':"Dä \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Vörjang es joot jeloufe: ${response}",'commitFailed':"Dä \x3ci lang=\"en\"\x3eWFS\x3c/i\x3e-Vörjang es scheif jejange: ${response}",'googleWarning':"Dat Nivvoh \x3ccode lang=\"en\"\x3eGoogle\x3c/code\x3e kunnt nit reschtesch jelaade wääde.\x3cbr /\x3e\x3cbr /\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhke, rähß bovve en de Äk.\x3cbr /\x3e\x3cbr /\x3eWascheinlesch es dat wiel dat \x3ci lang=\"en\"\x3eGoogle-Maps\x3c/i\x3e-Skrepp entweeder nit reschtesch enjebonge wood, udder nit dä reschtejje \x3ci lang=\"en\"\x3eAPI\x3c/i\x3e-Schlößel för Ding Web-ßait scheke deiht.\x3cbr /\x3e\x3cbr /\x3eFör Projrammierer jidd_et Hölp do_drövver, \x3ca href=\"http://trac.openlayers.org/wiki/Google\" target=\"_blank\"\x3ewi mer dat aan et Loufe brengk\x3c/a\x3e.",'getLayerWarning':"Dat Nivvoh \x3ccode\x3e${layerType}\x3c/code\x3e kunnt nit reschtesch jelaade wääde.\x3cbr /\x3e\x3cbr /\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhkre, rähß bovve en de Äk.\x3cbr /\x3e\x3cbr /\x3eWascheinlesch es dat, wiel dat Skrepp \x3ccode\x3e${layerLib}\x3c/code\x3e nit reschtesch enjebonge wood.\x3cbr /\x3e\x3cbr /\x3eFör Projrammierer jidd_Et Hölp do_drövver, \x3ca href=\"http://trac.openlayers.org/wiki/${layerLib}\" target=\"_blank\"\x3ewi mer dat aan et Loufe brengk\x3c/a\x3e.",'scale':"Mohßshtaab = 1 : ${scaleDenom}",'W':"W",'E':"O",'N':"N",'S':"S",'layerAlreadyAdded':"Do häß versöhk, dat Nivvoh \x3ccode\x3e${layerName}\x3c/code\x3e en di Kaat eren ze bränge, et wohr ävver ald do dren.",'reprojectDeprecated':"Do bruchs de Ußwahl \x3ccode\x3ereproject\x3c/code\x3e op däm Nivvoh \x3ccode\x3e${layerName}\x3c/code\x3e. Di Ußwahl es nit mieh jähn jesinn. Se wohr doför jedaach, öm Date op jeschääfsmäßesch eruß jejovve Kaate bovve drop ze moole, wat ävver enzwesche besser met dä Öngershtözung för de ßfääresche Mäkaator Beldscher jeiht. Doh kanns De mieh drövver fenge op dä Sigg: http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Hee di Metood es nim_mih aktoäll un et weed se en dä Version 3.0 nit mieh jävve. Nemm \x3ccode\x3e${newMethod}\x3c/code\x3e doföör.",'boundsAddError':"Do moß beeds vun de \x3ccode\x3ex\x3c/code\x3e un \x3ccode\x3ey\x3c/code\x3e Wääte aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'lonlatAddError':"Do moß beeds \x3ccode\x3elon\x3c/code\x3e un \x3ccode\x3elat\x3c/code\x3e aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'pixelAddError':"Do moß beeds \x3ccode\x3ex\x3c/code\x3e un \x3ccode\x3ey\x3c/code\x3e aan de Fungkßjohn \x3ccode\x3eadd\x3c/code\x3e jävve.",'unsupportedGeometryType':"De Zoot Jommetrii dom_mer nit ongershtöze: \x3ccode\x3e${geomType}\x3c/code\x3e",'pagePositionFailed':"\x3ccode lang=\"en\"\x3eOpenLayers.Util.pagePosition\x3c/code\x3e es donevve jejange: dat Denge met dä Kännong \x3ccode\x3e${elemId}\x3c/code\x3e künnt am verkeehte Plaz sin.",'filterEvaluateNotImplemented':"„\x3ccode lang=\"en\"\x3eevaluate\x3c/code\x3e“ es för di Zoot Fellter nit enjereschdt."});OpenLayers.Lang["nds"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Unbehannelt Trüchmellels för de Anfraag ${statusText}",'permalink':"Permalink",'overlays':"Overlays",'baseLayer':"Achtergrundkoort",'sameProjection':"De Översichtskoort geiht blot, wenn de sülve Projekschoon as bi de Hööftkoort bruukt warrt",'readNotImplemented':"Lesen is nich inricht.",'writeNotImplemented':"Schrieven is nich inricht.",'noFID':"En Feature, dat keen FID hett, kann nich aktuell maakt warrn.",'errorLoadingGML':"Fehler bi’t Laden vun de GML-Datei ${url}",'browserNotSupported':"Dien Browser ünnerstütt keen Vektorbiller. Ünnerstütt Renderers:\n${renderers}",'componentShouldBe':"addFeatures : Kumponent schull man den Typ ${geomType} hebben",'getFeatureError':"getFeatureFromEvent is von en Laag ahn Render opropen worrn. Dat bedüüdt normalerwies, dat en Laag wegmaakt worrn is, aver nich de Handler, de dor op verwiest.",'commitSuccess':"WFS-Transakschoon: hett klappt ${response}",'commitFailed':"WFS-Transakschoon: hett nich klappt ${response}",'scale':"Skaal = 1 : ${scaleDenom}",'layerAlreadyAdded':"Du versöchst de Laag „${layerName}“ to de Koort totofögen, man de is al toföögt",'methodDeprecated':"Disse Methood is oold un schall dat in 3.0 nich mehr geven. Bruuk dor man beter ${newMethod} för.",'boundsAddError':"De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",'lonlatAddError':"De Weert lon un lat, de mööt all beid an de add-Funkschoon övergeven warrn.",'pixelAddError':"De Weert x un y, de mööt all beid an de add-Funkschoon övergeven warrn.",'unsupportedGeometryType':"Nich ünnerstütt Geometrie-Typ: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition güng nich: Element mit de Id ${elemId} is villicht an’n verkehrten Platz."});OpenLayers.Lang["nn"]=OpenLayers.Util.applyDefaults({'scale':"Skala = 1 : ${scaleDenom}",'layerAlreadyAdded':"Du freista å leggja til laget «${layerName}» på kartet, men det har alt vorte lagt til.",'boundsAddError':"Du er nøydd til å gje både ein x- og ein y-verdi til «add»-funksjonen.",'lonlatAddError':"Du er nøydd til å gje både lon- og lat-verdiar til «add»-funksjonen.",'pixelAddError':"Du er nøydd til å gje både ein x- og ein y-verdi til «add»-funksjonen."});OpenLayers.Lang["oc"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Requèsta pas gerida, retorna ${statusText}",'permalink':"Permaligam",'overlays':"Calques",'baseLayer':"Calc de basa",'sameProjection':"La carta de situacion fonciona pas que quora sa projeccion es la meteissa que la de la carta principala",'readNotImplemented':"Lectura pas implementada.",'writeNotImplemented':"Escritura pas implementada.",'noFID':"Impossible de metre a jorn un objècte sens identificant (fid).",'errorLoadingGML':"Error al cargament del fichièr GML ${url}",'browserNotSupported':"Vòstre navegidor supòrta pas lo rendut vectorial. Los renderers actualament suportats son : \n${renderers}",'componentShouldBe':"addFeatures : lo compausant deuriá èsser de tipe ${geomType}",'getFeatureError':"getFeatureFromEvent es estat apelat sus un calc sens renderer. Aquò significa generalament qu\'avètz destruch aqueste jaç, mas qu\'avètz conservat un handler que li èra associat.",'minZoomLevelError':"La proprietat minZoomLevel deu èsser utilizada solament per de jaces FixedZoomLevels-descendent. Lo fach qu\'aqueste jaç WFS verifique la preséncia de minZoomLevel es una relica del passat. Çaquelà, la podèm suprimir sens copar d\'aplicacions que ne poirián dependre. Es per aquò que la depreciam -- la verificacion del minZoomLevel serà suprimida en version 3.0. A la plaça, mercés d\'utilizar los paramètres de resolucions min/max tal coma descrich sus : http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transaccion WFS : SUCCES ${response}",'commitFailed':"Transaccion WFS : FRACAS ${response}",'googleWarning':"Lo jaç Google es pas estat en mesura de se cargar corrèctament.\x3cbr\x3e\x3cbr\x3ePer suprimir aqueste messatge, causissètz una BaseLayer novèla dins lo selector de jaç en naut a drecha.\x3cbr\x3e\x3cbr\x3eAquò es possiblament causat par la non-inclusion de la librariá Google Maps, o alara perque que la clau de l\'API correspond pas a vòstre site.\x3cbr\x3e\x3cbr\x3eDesvolopaires : per saber cossí corregir aquò, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclicatz aicí\x3c/a\x3e",'getLayerWarning':"Lo jaç ${layerType} es pas en mesura de se cargar corrèctament.\x3cbr\x3e\x3cbr\x3ePer suprimir aqueste messatge, causissètz una  BaseLayer novèla dins lo selector de jaç en naut a drecha.\x3cbr\x3e\x3cbr\x3eAquò es possiblament causat per la non-inclusion de la librariá ${layerLib}.\x3cbr\x3e\x3cbr\x3eDesvolopaires : per saber cossí corregir aquí, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclicatz aicí\x3c/a\x3e",'scale':"Escala ~ 1 : ${scaleDenom}",'W':"O",'E':"È",'N':"N",'S':"S",'layerAlreadyAdded':"Avètz ensajat d\'apondre a la carta lo calc : ${layerName}, mas ja es present",'reprojectDeprecated':"Utilizatz l\'opcion \'reproject\' sul jaç ${layerName}. Aquesta opcion es despreciada : Son usatge permetiá d\'afichar de donadas al dessús de jaces raster comercials. Aquesta foncionalitat ara es suportada en utilizant lo supòrt de la projeccion Mercator Esferica. Mai d\'informacion es disponibla sus http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Aqueste metòde es despreciada, e serà suprimida a la version 3.0. Mercés d\'utilizar ${newMethod} a la plaça.",'boundsAddError':"Vos cal passar las doas valors x e y a la foncion add.",'lonlatAddError':"Vos cal passar las doas valors lon e lat a la foncion add.",'pixelAddError':"Vos cal passar las doas valors x e y a la foncion add.",'unsupportedGeometryType':"Tipe de geometria pas suportat : ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition a fracassat : l\'element d\'id ${elemId} poiriá èsser mal posicionat.",'filterEvaluateNotImplemented':"evaluar es pas encara estat implementat per aqueste tipe de filtre."});OpenLayers.Lang["pt"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Servidor devolveu erro não contemplado ${statusText}",'permalink':"Ligação permanente",'overlays':"Sobreposições",'baseLayer':"Camada Base",'sameProjection':"O mapa panorâmico só funciona quando está na mesma projeção que o mapa principal",'readNotImplemented':"Leitura não implementada.",'writeNotImplemented':"Escrita não implementada.",'noFID':"Não é possível atualizar um elemento para a qual não há FID.",'errorLoadingGML':"Erro ao carregar ficheiro GML ${url}",'browserNotSupported':"O seu navegador não suporta renderização vetorial. Actualmente os renderizadores suportados são:\n${renderers}",'componentShouldBe':"addFeatures: componente deve ser um(a) ${geomType}",'getFeatureError':"getFeatureFromEvent foi chamado numa camada sem renderizador. Isto normalmente significa que destruiu uma camada, mas não um manipulador \'\'(handler)\'\' que lhe está associado.",'minZoomLevelError':"A propriedade minZoomLevel só deve ser usada com as camadas descendentes da FixedZoomLevels. A verificação da propriedade por esta camada wfs é uma relíquia do passado. No entanto, não podemos removê-la sem correr o risco de afectar aplicações OL que dependam dela. Portanto, estamos a torná-la obsoleta -- a verificação minZoomLevel será removida na versão 3.0. Em vez dela, por favor, use as opções de resolução min/max descritas aqui: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transacção WFS: SUCESSO ${response}",'commitFailed':"Transacção WFS: FALHOU ${response}",'googleWarning':"A Camada Google não foi correctamente carregada.\x3cbr\x3e\x3cbr\x3ePara deixar de receber esta mensagem, seleccione uma nova Camada-Base no \'\'switcher\'\' de camadas no canto superior direito.\x3cbr\x3e\x3cbr\x3eProvavelmente, isto acontece porque o \'\'script\'\' da biblioteca do Google Maps não foi incluído ou não contém a chave API correcta para o seu sítio.\x3cbr\x3e\x3cbr\x3eProgramadores: Para ajuda sobre como solucionar o problema \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eclique aqui\x3c/a\x3e .",'getLayerWarning':"A camada ${layerType} não foi correctamente carregada.\x3cbr\x3e\x3cbr\x3ePara desactivar esta mensagem, seleccione uma nova Camada-Base no \'\'switcher\'\' de camadas no canto superior direito.\x3cbr\x3e\x3cbr\x3eProvavelmente, isto acontece porque o \'\'script\'\' da biblioteca ${layerLib} não foi incluído correctamente.\x3cbr\x3e\x3cbr\x3eProgramadores: Para ajuda sobre como solucionar o problema \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eclique aqui\x3c/a\x3e .",'scale':"Escala = 1 : ${scaleDenom}",'W':"O",'E':"E",'N':"N",'S':"S",'layerAlreadyAdded':"Você tentou adicionar a camada: ${layerName} ao mapa, mas ela já tinha sido adicionada antes",'reprojectDeprecated':"Está usando a opção \'reproject\' na camada ${layerName}. Esta opção é obsoleta: foi concebida para permitir a apresentação de dados sobre mapas-base comerciais, mas esta funcionalidade é agora suportada pelo Mercator Esférico. Mais informação está disponível em http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Este método foi declarado obsoleto e será removido na versão 3.0. Por favor, use ${newMethod} em vez disso.",'boundsAddError':"Você deve passar tanto o valor x como o y à função de adição.",'lonlatAddError':"Você deve passar tanto o valor lon como o lat à função de adição.",'pixelAddError':"Você deve passar tanto o valor x como o y à função de adição.",'unsupportedGeometryType':"Tipo de geometria não suportado: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition falhou: o elemento com o id ${elemId} poderá estar mal-posicionado.",'filterEvaluateNotImplemented':"avaliar não está implementado para este tipo de filtro."});OpenLayers.Lang["ru"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Необработанный запрос вернул ${statusText}",'permalink':"Постоянная ссылка",'overlays':"Слои",'baseLayer':"Основной слой",'sameProjection':"Обзорная карта работает только тогда, когда имеет ту же проекцию, что и основная",'readNotImplemented':"Чтение не реализовано.",'writeNotImplemented':"Запись не реализована.",'noFID':"Невозможно обновить объект, для которого нет FID.",'errorLoadingGML':"Ошибка при загрузке файла GML ${url}",'browserNotSupported':"Ваш браузер не поддерживает векторную графику. На данный момент поддерживаются:\n${renderers}",'componentShouldBe':"addFeatures: компонент должен быть ${geomType}",'getFeatureError':"getFeatureFromEvent вызван для слоя без рендерера. Обычно это говорит о том, что вы уничтожили слой, но оставили связанный с ним обработчик.",'minZoomLevelError':"Свойство minZoomLevel предназначено только для использования со слоями, являющимися потомками FixedZoomLevels. То, что этот WFS-слой проверяется на minZoomLevel — реликт прошлого. Однако мы не можем удалить эту функцию, так как, возможно, от неё зависят некоторые основанные на OpenLayers приложения. Функция объявлена устаревшей — проверка minZoomLevel будет удалена в 3.0. Пожалуйста, используйте вместо неё настройку мин/макс разрешения, описанную здесь: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Транзакция WFS: УСПЕШНО ${response}",'commitFailed':"Транзакция WFS: ОШИБКА ${response}",'googleWarning':"Слой Google не удалось нормально загрузить.\x3cbr\x3e\x3cbr\x3eЧтобы избавиться от этого сообщения, выбите другой основной слой в переключателе в правом верхнем углу.\x3cbr\x3e\x3cbr\x3eСкорее всего, причина в том, что библиотека Google Maps не была включена или не содержит корректного API-ключа для вашего сайта.\x3cbr\x3e\x3cbr\x3eРазработчикам: чтобы узнать, как сделать, чтобы всё заработало, \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eщёлкните тут\x3c/a\x3e",'getLayerWarning':"Слой ${layerType} не удалось нормально загрузить. \x3cbr\x3e\x3cbr\x3eЧтобы избавиться от этого сообщения, выбите другой основной слой в переключателе в правом верхнем углу.\x3cbr\x3e\x3cbr\x3eСкорее всего, причина в том, что библиотека ${layerLib} не была включена или была включена некорректно.\x3cbr\x3e\x3cbr\x3eРазработчикам: чтобы узнать, как сделать, чтобы всё заработало, \x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eщёлкните тут\x3c/a\x3e",'scale':"Масштаб = 1 : ${scaleDenom}",'W':"З",'E':"В",'N':"С",'S':"Ю",'layerAlreadyAdded':"Вы попытались добавить слой «${layerName}» на карту, но он уже был добавлен",'reprojectDeprecated':"Вы используете опцию \'reproject\' для слоя ${layerName}. Эта опция является устаревшей: ее использование предполагалось для поддержки показа данных поверх коммерческих базовых карт, но теперь этот функционал несёт встроенная поддержка сферической проекции Меркатора. Больше сведений доступно на http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Этот метод считается устаревшим и будет удалён в версии 3.0. Пожалуйста, пользуйтесь ${newMethod}.",'boundsAddError':"Функции add надо передавать оба значения, x и y.",'lonlatAddError':"Функции add надо передавать оба значения, lon и lat.",'pixelAddError':"Функции add надо передавать оба значения, x и y.",'unsupportedGeometryType':"Неподдерживаемый тип геометрии: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition failed: элемент с id ${elemId} может находиться не в нужном месте.",'filterEvaluateNotImplemented':"evaluate не реализовано для фильтра данного типа."});OpenLayers.Lang["sk"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Neobslúžené požiadavky vracajú ${statusText}",'permalink':"Trvalý odkaz",'overlays':"Prekrytia",'baseLayer':"Základná vrstva",'sameProjection':"Prehľadová mapka funguje iba vtedy, keď je v rovnakej projekcii ako hlavná mapa",'readNotImplemented':"Čítanie nie je implementované.",'writeNotImplemented':"Zápis nie je implementovaný.",'noFID':"Nie je možné aktualizovať vlastnosť, pre ktorú neexistuje FID.",'errorLoadingGML':"Chyba pri načítaní súboru GML ${url}",'browserNotSupported':"Váš prehliadač nepodporuje vykresľovanie vektorov. Momentálne podporované vykresľovače sú:\n${renderers}",'componentShouldBe':"addFeatures: komponent by mal byť ${geomType}",'getFeatureError':"getFeatureFromEvent bola zavolaná na vrstve bez vykresľovača. To zvyčajne znamená, že ste odstránili vrstvu, ale nie niektorú z obslúh, ktorá je s ňou asociovaná.",'minZoomLevelError':"Vlastnosť minZoomLevel je určený iba na použitie s vrstvami odvodenými od FixedZoomLevels. To, že táto wfs vrstva kontroluje minZoomLevel je pozostatok z minulosti. Nemôžeme ho však odstrániť, aby sme sa vyhli možnému porušeniu aplikácií založených na Open Layers, ktoré na tomto môže závisieť. Preto ho označujeme ako zavrhovaný - dolu uvedená kontrola minZoomLevel bude odstránená vo verzii 3.0. Použite prosím namiesto toho kontrolu min./max. rozlíšenia podľa tu uvedeného popisu: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Transakcia WFS: ÚSPEŠNÁ ${response}",'commitFailed':"Transakcia WFS: ZLYHALA ${response}",'googleWarning':"Vrstvu Google nebolo možné správne načítať.\x3cbr\x3e\x3cbr\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínači vrstiev v pravom hornom rohu.\x3cbr\x3e\x3cbr\x3eToto sa stalo pravdepodobne preto, že skript knižnice Google Maps buď nebol načítaný alebo neobsahuje správny kľúč API pre vašu lokalitu.\x3cbr\x3e\x3cbr\x3eVývojári: Tu môžete získať \x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3epomoc so sfunkčnením\x3c/a\x3e",'getLayerWarning':"Vrstvu ${layerType} nebolo možné správne načítať.\x3cbr\x3e\x3cbr\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínači vrstiev v pravom hornom rohu.\x3cbr\x3e\x3cbr\x3eToto sa stalo pravdepodobne preto, že skript knižnice ${layerType} buď nebol načítaný alebo neobsahuje správny kľúč API pre vašu lokalitu.\x3cbr\x3e\x3cbr\x3eVývojári: Tu môžete získať \x3ca href=\'http://trac.openlayers.org/wiki/${layerType}\' target=\'_blank\'\x3epomoc so sfunkčnením\x3c/a\x3e",'scale':"Mierka = 1 : ${scaleDenom}",'layerAlreadyAdded':"Pokúsili ste sa do mapy pridať vrstvu ${layerName}, ale tá už bola pridaná",'reprojectDeprecated':"Používate voľby „reproject“ vrstvy ${layerType}. Táto voľba je zzavrhovaná: jej použitie bolo navrhnuté na podporu zobrazovania údajov nad komerčnými základovými mapami, ale túto funkcionalitu je teraz možné dosiahnuť pomocou Spherical Mercator. Ďalšie informácie získate na stránke http://trac.openlayers.org/wiki/SphericalMercator.",'methodDeprecated':"Táto metóda je zavrhovaná a bude odstránená vo verzii 3.0. Použite prosím namiesto nej metódu ${newMethod}.",'boundsAddError':"Sčítacej funkcii musíte dať hodnoty x aj y.",'lonlatAddError':"Sčítacej funkcii musíte dať hodnoty lon (zem. dĺžka) aj lat (zem. šírka).",'pixelAddError':"Sčítacej funkcii musíte dať hodnoty x aj y.",'unsupportedGeometryType':"Nepodporovaný typ geometrie: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition zlyhalo: prvok s id ${elemId} môže byť zle umiestnený.",'filterEvaluateNotImplemented':"evaluate nie je implementovaný pre tento typ filtra"});OpenLayers.Lang["te"]=OpenLayers.Util.applyDefaults({'permalink':"స్థిరలింకు",'W':"ప",'E':"తూ",'N':"ఉ",'S':"ద"});OpenLayers.Lang["vi"]=OpenLayers.Util.applyDefaults({'unhandledRequest':"Không xử lý được phản hồi ${statusText} cho yêu cầu",'permalink':"Liên kết thường trực",'overlays':"Lấp bản đồ",'baseLayer':"Lớp nền",'sameProjection':"Bản đồ toàn cảnh chỉ hoạt động khi cùng phép chiếu với bản đồ chính",'readNotImplemented':"Chưa hỗ trợ chức năng đọc.",'writeNotImplemented':"Chưa hỗ trợ chức năng viết.",'noFID':"Không thể cập nhật tính năng thiếu FID.",'errorLoadingGML':"Lỗi tải tập tin GML tại ${url}",'browserNotSupported':"Trình duyệt của bạn không hỗ trợ chức năng vẽ bằng vectơ. Hiện hỗ trợ các bộ kết xuất:\n${renderers}",'componentShouldBe':"addFeatures: bộ phận cần phải là ${geomType}",'getFeatureError':"getFeatureFromEvent được gọi từ lớp không có bộ kết xuất. Thường thì có lẽ lớp bị xóa nhưng một phần xử lý của nó vẫn còn.",'minZoomLevelError':"Chỉ nên sử dụng thuộc tính minZoomLevel với các lớp FixedZoomLevels-descendent. Việc lớp wfs này tìm cho minZoomLevel là di tích còn lại từ xưa. Tuy nhiên, nếu chúng tôi dời nó thì sẽ vỡ các chương trình OpenLayers mà dựa trên nó. Bởi vậy chúng tôi phản đối sử dụng nó\x26nbsp;– bước tìm cho minZoomLevel sẽ được dời vào phiên bản 3.0. Xin sử dụng thiết lập độ phân tích tối thiểu / tối đa thay thế, theo hướng dẫn này: http://trac.openlayers.org/wiki/SettingZoomLevels",'commitSuccess':"Giao dịch WFS: THÀNH CÔNG ${response}",'commitFailed':"Giao dịch WFS: THẤT BẠI ${response}",'googleWarning':"Không thể tải lớp Google đúng đắn.\x3cbr\x3e\x3cbr\x3eĐể tránh thông báo này lần sau, hãy chọn BaseLayer mới dùng điều khiển chọn lớp ở góc trên phải.\x3cbr\x3e\x3cbr\x3eChắc script thư viện Google Maps hoặc không được bao gồm hoặc không chứa khóa API hợp với website của bạn.\x3cbr\x3e\x3cbr\x3e\x3ca href=\'http://trac.openlayers.org/wiki/Google\' target=\'_blank\'\x3eTrợ giúp về tính năng này\x3c/a\x3e cho người phát triển.",'getLayerWarning':"Không thể tải lớp ${layerType} đúng đắn.\x3cbr\x3e\x3cbr\x3eĐể tránh thông báo này lần sau, hãy chọn BaseLayer mới dùng điều khiển chọn lớp ở góc trên phải.\x3cbr\x3e\x3cbr\x3eChắc script thư viện ${layerLib} không được bao gồm đúng kiểu.\x3cbr\x3e\x3cbr\x3e\x3ca href=\'http://trac.openlayers.org/wiki/${layerLib}\' target=\'_blank\'\x3eTrợ giúp về tính năng này\x3c/a\x3e cho người phát triển.",'scale':"Tỷ lệ = 1 : ${scaleDenom}",'W':"T",'E':"Đ",'N':"B",'S':"N",'layerAlreadyAdded':"Bạn muốn thêm lớp ${layerName} vào bản đồ, nhưng lớp này đã được thêm",'reprojectDeprecated':"Bạn đang áp dụng chế độ “reproject” vào lớp ${layerName}. Chế độ này đã bị phản đối: nó có mục đích hỗ trợ lấp dữ liệu trên các nền bản đồ thương mại; nên thực hiện hiệu ứng đó dùng tính năng Mercator Hình cầu. Có sẵn thêm chi tiết tại http://trac.openlayers.org/wiki/SphericalMercator .",'methodDeprecated':"Phương thức này đã bị phản đối và sẽ bị dời vào phiên bản 3.0. Xin hãy sử dụng ${newMethod} thay thế.",'boundsAddError':"Cần phải cho cả giá trị x và y vào hàm add.",'lonlatAddError':"Cần phải cho cả giá trị lon và lat vào hàm add.",'pixelAddError':"Cần phải cho cả giá trị x và y vào hàm add.",'unsupportedGeometryType':"Không hỗ trợ kiểu địa lý: ${geomType}",'pagePositionFailed':"OpenLayers.Util.pagePosition bị thất bại: nguyên tố với ID ${elemId} có thể ở chỗ sai.",'filterEvaluateNotImplemented':"chưa hỗ trợ evaluate cho loại bộ lọc này."});OpenLayers.Popup.AnchoredBubble=OpenLayers.Class(OpenLayers.Popup.Anchored,{rounded:false,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){this.padding=new OpenLayers.Bounds(0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE);OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);},draw:function(px){OpenLayers.Popup.Anchored.prototype.draw.apply(this,arguments);this.setContentHTML();this.setBackgroundColor();this.setOpacity();return this.div;},updateRelativePosition:function(){this.setRicoCorners();},setSize:function(contentSize){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.setRicoCorners();},setBackgroundColor:function(color){if(color!=undefined){this.backgroundColor=color;}
59805 if(this.div!=null){if(this.contentDiv!=null){this.div.style.background="transparent";OpenLayers.Rico.Corner.changeColor(this.groupDiv,this.backgroundColor);}}},setOpacity:function(opacity){OpenLayers.Popup.Anchored.prototype.setOpacity.call(this,opacity);if(this.div!=null){if(this.groupDiv!=null){OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,this.opacity);}}},setBorder:function(border){this.border=0;},setRicoCorners:function(){var corners=this.getCornersToRound(this.relativePosition);var options={corners:corners,color:this.backgroundColor,bgColor:"transparent",blend:false};if(!this.rounded){OpenLayers.Rico.Corner.round(this.div,options);this.rounded=true;}else{OpenLayers.Rico.Corner.reRound(this.groupDiv,options);this.setBackgroundColor();this.setOpacity();}},getCornersToRound:function(){var corners=['tl','tr','bl','br'];var corner=OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);OpenLayers.Util.removeItem(corners,corner);return corners.join(" ");},CLASS_NAME:"OpenLayers.Popup.AnchoredBubble"});OpenLayers.Popup.AnchoredBubble.CORNER_SIZE=5;OpenLayers.Popup.Framed=OpenLayers.Class(OpenLayers.Popup.Anchored,{imageSrc:null,imageSize:null,isAlphaImage:false,positionBlocks:null,blocks:null,fixedRelativePosition:false,initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);if(this.fixedRelativePosition){this.updateRelativePosition();this.calculateRelativePosition=function(px){return this.relativePosition;};}
59806 this.contentDiv.style.position="absolute";this.contentDiv.style.zIndex=1;if(closeBox){this.closeDiv.style.zIndex=1;}
59807 this.groupDiv.style.position="absolute";this.groupDiv.style.top="0px";this.groupDiv.style.left="0px";this.groupDiv.style.height="100%";this.groupDiv.style.width="100%";},destroy:function(){this.imageSrc=null;this.imageSize=null;this.isAlphaImage=null;this.fixedRelativePosition=false;this.positionBlocks=null;for(var i=0;i<this.blocks.length;i++){var block=this.blocks[i];if(block.image){block.div.removeChild(block.image);}
59808 block.image=null;if(block.div){this.groupDiv.removeChild(block.div);}
59809 block.div=null;}
59810 this.blocks=null;OpenLayers.Popup.Anchored.prototype.destroy.apply(this,arguments);},setBackgroundColor:function(color){},setBorder:function(){},setOpacity:function(opacity){},setSize:function(contentSize){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.updateBlocks();},updateRelativePosition:function(){this.padding=this.positionBlocks[this.relativePosition].padding;if(this.closeDiv){var contentDivPadding=this.getContentDivPadding();this.closeDiv.style.right=contentDivPadding.right+
59811 this.padding.right+"px";this.closeDiv.style.top=contentDivPadding.top+
59812 this.padding.top+"px";}
59813 this.updateBlocks();},calculateNewPx:function(px){var newPx=OpenLayers.Popup.Anchored.prototype.calculateNewPx.apply(this,arguments);newPx=newPx.offset(this.positionBlocks[this.relativePosition].offset);return newPx;},createBlocks:function(){this.blocks=[];var firstPosition=null;for(var key in this.positionBlocks){firstPosition=key;break;}
59814 var position=this.positionBlocks[firstPosition];for(var i=0;i<position.blocks.length;i++){var block={};this.blocks.push(block);var divId=this.id+'_FrameDecorationDiv_'+i;block.div=OpenLayers.Util.createDiv(divId,null,null,null,"absolute",null,"hidden",null);var imgId=this.id+'_FrameDecorationImg_'+i;var imageCreator=(this.isAlphaImage)?OpenLayers.Util.createAlphaImageDiv:OpenLayers.Util.createImage;block.image=imageCreator(imgId,null,this.imageSize,this.imageSrc,"absolute",null,null,null);block.div.appendChild(block.image);this.groupDiv.appendChild(block.div);}},updateBlocks:function(){if(!this.blocks){this.createBlocks();}
59815 if(this.size&&this.relativePosition){var position=this.positionBlocks[this.relativePosition];for(var i=0;i<position.blocks.length;i++){var positionBlock=position.blocks[i];var block=this.blocks[i];var l=positionBlock.anchor.left;var b=positionBlock.anchor.bottom;var r=positionBlock.anchor.right;var t=positionBlock.anchor.top;var w=(isNaN(positionBlock.size.w))?this.size.w-(r+l):positionBlock.size.w;var h=(isNaN(positionBlock.size.h))?this.size.h-(b+t):positionBlock.size.h;block.div.style.width=(w<0?0:w)+'px';block.div.style.height=(h<0?0:h)+'px';block.div.style.left=(l!=null)?l+'px':'';block.div.style.bottom=(b!=null)?b+'px':'';block.div.style.right=(r!=null)?r+'px':'';block.div.style.top=(t!=null)?t+'px':'';block.image.style.left=positionBlock.position.x+'px';block.image.style.top=positionBlock.position.y+'px';}
59816 this.contentDiv.style.left=this.padding.left+"px";this.contentDiv.style.top=this.padding.top+"px";}},CLASS_NAME:"OpenLayers.Popup.Framed"});OpenLayers.Projection=OpenLayers.Class({proj:null,projCode:null,initialize:function(projCode,options){OpenLayers.Util.extend(this,options);this.projCode=projCode;if(window.Proj4js){this.proj=new Proj4js.Proj(projCode);}},getCode:function(){return this.proj?this.proj.srsCode:this.projCode;},getUnits:function(){return this.proj?this.proj.units:null;},toString:function(){return this.getCode();},equals:function(projection){if(projection&&projection.getCode){return this.getCode()==projection.getCode();}else{return false;}},destroy:function(){delete this.proj;delete this.projCode;},CLASS_NAME:"OpenLayers.Projection"});OpenLayers.Projection.transforms={};OpenLayers.Projection.addTransform=function(from,to,method){if(!OpenLayers.Projection.transforms[from]){OpenLayers.Projection.transforms[from]={};}
59817 OpenLayers.Projection.transforms[from][to]=method;};OpenLayers.Projection.transform=function(point,source,dest){if(source.proj&&dest.proj){point=Proj4js.transform(source.proj,dest.proj,point);}else if(source&&dest&&OpenLayers.Projection.transforms[source.getCode()]&&OpenLayers.Projection.transforms[source.getCode()][dest.getCode()]){OpenLayers.Projection.transforms[source.getCode()][dest.getCode()](point);}
59818 return point;};OpenLayers.Protocol.WFS.v1=OpenLayers.Class(OpenLayers.Protocol,{version:null,srsName:"EPSG:4326",featureType:null,featureNS:null,geometryName:"the_geom",schema:null,featurePrefix:"feature",formatOptions:null,readFormat:null,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);if(!options.format){this.format=OpenLayers.Format.WFST(OpenLayers.Util.extend({version:this.version,featureType:this.featureType,featureNS:this.featureNS,featurePrefix:this.featurePrefix,geometryName:this.geometryName,srsName:this.srsName,schema:this.schema},this.formatOptions));}
59819 if(!this.featureNS&&this.featurePrefix){var readNode=this.format.readNode;this.format.readNode=function(node,obj){if(!this.featureNS&&node.prefix==this.featurePrefix){this.featureNS=node.namespaceURI;this.setNamespace("feature",this.featureNS);}
59820 return readNode.apply(this,arguments);};}},destroy:function(){if(this.options&&!this.options.format){this.format.destroy();}
59821 this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options||{});var response=new OpenLayers.Protocol.Response({requestType:"read"});var data=OpenLayers.Format.XML.prototype.write.apply(this.format,[this.format.writeNode("wfs:GetFeature",options)]);response.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,response,options),params:options.params,headers:options.headers,data:data});return response;},handleRead:function(response,options){if(options.callback){var request=response.priv;if(request.status>=200&&request.status<300){response.features=this.parseFeatures(request);response.code=OpenLayers.Protocol.Response.SUCCESS;}else{response.code=OpenLayers.Protocol.Response.FAILURE;}
59822 options.callback.call(options.scope,response);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
59823 if(!doc||doc.length<=0){return null;}
59824 return(this.readFormat!==null)?this.readFormat.read(doc):this.format.read(doc);},commit:function(features,options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options);var response=new OpenLayers.Protocol.Response({requestType:"commit",reqFeatures:features});response.priv=OpenLayers.Request.POST({url:options.url,data:this.format.write(features,options),callback:this.createCallback(this.handleCommit,response,options)});return response;},handleCommit:function(response,options){if(options.callback){var request=response.priv;var data=request.responseXML;if(!data||!data.documentElement){data=request.responseText;}
59825 var obj=this.format.read(data)||{};response.insertIds=obj.insertIds||[];response.code=(obj.success)?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE;options.callback.call(options.scope,response);}},filterDelete:function(filter,options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options);var response=new OpenLayers.Protocol.Response({requestType:"commit"});var root=this.format.createElementNSPlus("wfs:Transaction",{attributes:{service:"WFS",version:this.version}});var deleteNode=this.format.createElementNSPlus("wfs:Delete",{attributes:{typeName:(options.featureNS?this.featurePrefix+":":"")+
59826 options.featureType}});if(options.featureNS){deleteNode.setAttribute("xmlns:"+this.featurePrefix,options.featureNS);}
59827 var filterNode=this.format.writeNode("ogc:Filter",filter);deleteNode.appendChild(filterNode);root.appendChild(deleteNode);var data=OpenLayers.Format.XML.prototype.write.apply(this.format,[root]);return OpenLayers.Request.POST({url:this.url,callback:options.callback||function(){},data:data});},abort:function(response){if(response){response.priv.abort();}},CLASS_NAME:"OpenLayers.Protocol.WFS.v1"});OpenLayers.Renderer.SVG=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"http://www.w3.org/2000/svg",xlinkns:"http://www.w3.org/1999/xlink",MAX_PIXEL:15000,translationParameters:null,symbolMetrics:null,isGecko:null,supportUse:null,initialize:function(containerID){if(!this.supported()){return;}
59828 OpenLayers.Renderer.Elements.prototype.initialize.apply(this,arguments);this.translationParameters={x:0,y:0};this.supportUse=(navigator.userAgent.toLowerCase().indexOf("applewebkit/5")==-1);this.isGecko=(navigator.userAgent.toLowerCase().indexOf("gecko/")!=-1);this.symbolMetrics={};},destroy:function(){OpenLayers.Renderer.Elements.prototype.destroy.apply(this,arguments);},supported:function(){var svgFeature="http://www.w3.org/TR/SVG11/feature#";return(document.implementation&&(document.implementation.hasFeature("org.w3c.svg","1.0")||document.implementation.hasFeature(svgFeature+"SVG","1.1")||document.implementation.hasFeature(svgFeature+"BasicStructure","1.1")));},inValidRange:function(x,y,xyOnly){var left=x+(xyOnly?0:this.translationParameters.x);var top=y+(xyOnly?0:this.translationParameters.y);return(left>=-this.MAX_PIXEL&&left<=this.MAX_PIXEL&&top>=-this.MAX_PIXEL&&top<=this.MAX_PIXEL);},setExtent:function(extent,resolutionChanged){OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments);var resolution=this.getResolution();var left=-extent.left/resolution;var top=extent.top/resolution;if(resolutionChanged){this.left=left;this.top=top;var extentString="0 0 "+this.size.w+" "+this.size.h;this.rendererRoot.setAttributeNS(null,"viewBox",extentString);this.translate(0,0);return true;}else{var inRange=this.translate(left-this.left,top-this.top);if(!inRange){this.setExtent(extent,true);}
59829 return inRange;}},translate:function(x,y){if(!this.inValidRange(x,y,true)){return false;}else{var transformString="";if(x||y){transformString="translate("+x+","+y+")";}
59830 this.root.setAttributeNS(null,"transform",transformString);this.translationParameters={x:x,y:y};return true;}},setSize:function(size){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);this.rendererRoot.setAttributeNS(null,"width",this.size.w);this.rendererRoot.setAttributeNS(null,"height",this.size.h);},getNodeType:function(geometry,style){var nodeType=null;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.externalGraphic){nodeType="image";}else if(this.isComplexSymbol(style.graphicName)){nodeType=this.supportUse===false?"svg":"use";}else{nodeType="circle";}
59831 break;case"OpenLayers.Geometry.Rectangle":nodeType="rect";break;case"OpenLayers.Geometry.LineString":nodeType="polyline";break;case"OpenLayers.Geometry.LinearRing":nodeType="polygon";break;case"OpenLayers.Geometry.Polygon":case"OpenLayers.Geometry.Curve":case"OpenLayers.Geometry.Surface":nodeType="path";break;default:break;}
59832 return nodeType;},setStyle:function(node,style,options){style=style||node._style;options=options||node._options;var r=parseFloat(node.getAttributeNS(null,"r"));var widthFactor=1;var pos;if(node._geometryClass=="OpenLayers.Geometry.Point"&&r){node.style.visibility="";if(style.graphic===false){node.style.visibility="hidden";}else if(style.externalGraphic){pos=this.getPosition(node);if(style.graphicTitle){node.setAttributeNS(null,"title",style.graphicTitle);}
59833 if(style.graphicWidth&&style.graphicHeight){node.setAttributeNS(null,"preserveAspectRatio","none");}
59834 var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);var opacity=style.graphicOpacity||style.fillOpacity;node.setAttributeNS(null,"x",(pos.x+xOffset).toFixed());node.setAttributeNS(null,"y",(pos.y+yOffset).toFixed());node.setAttributeNS(null,"width",width);node.setAttributeNS(null,"height",height);node.setAttributeNS(this.xlinkns,"href",style.externalGraphic);node.setAttributeNS(null,"style","opacity: "+opacity);}else if(this.isComplexSymbol(style.graphicName)){var offset=style.pointRadius*3;var size=offset*2;var id=this.importSymbol(style.graphicName);pos=this.getPosition(node);widthFactor=this.symbolMetrics[id][0]*3/size;var parent=node.parentNode;var nextSibling=node.nextSibling;if(parent){parent.removeChild(node);}
59835 if(this.supportUse===false){var src=document.getElementById(id);node.firstChild&&node.removeChild(node.firstChild);node.appendChild(src.firstChild.cloneNode(true));node.setAttributeNS(null,"viewBox",src.getAttributeNS(null,"viewBox"));}else{node.setAttributeNS(this.xlinkns,"href","#"+id);}
59836 node.setAttributeNS(null,"width",size);node.setAttributeNS(null,"height",size);node.setAttributeNS(null,"x",pos.x-offset);node.setAttributeNS(null,"y",pos.y-offset);if(nextSibling){parent.insertBefore(node,nextSibling);}else if(parent){parent.appendChild(node);}}else{node.setAttributeNS(null,"r",style.pointRadius);}
59837 var rotation=style.rotation;if((rotation!==undefined||node._rotation!==undefined)&&pos){node._rotation=rotation;rotation|=0;if(node.nodeName!=="svg"){node.setAttributeNS(null,"transform","rotate("+rotation+" "+pos.x+" "+
59838 pos.y+")");}else{var metrics=this.symbolMetrics[id];node.firstChild.setAttributeNS(null,"transform","rotate("+style.rotation+" "+metrics[1]+" "+metrics[2]+")");}}}
59839 if(options.isFilled){node.setAttributeNS(null,"fill",style.fillColor);node.setAttributeNS(null,"fill-opacity",style.fillOpacity);}else{node.setAttributeNS(null,"fill","none");}
59840 if(options.isStroked){node.setAttributeNS(null,"stroke",style.strokeColor);node.setAttributeNS(null,"stroke-opacity",style.strokeOpacity);node.setAttributeNS(null,"stroke-width",style.strokeWidth*widthFactor);node.setAttributeNS(null,"stroke-linecap",style.strokeLinecap||"round");node.setAttributeNS(null,"stroke-linejoin","round");style.strokeDashstyle&&node.setAttributeNS(null,"stroke-dasharray",this.dashStyle(style,widthFactor));}else{node.setAttributeNS(null,"stroke","none");}
59841 if(style.pointerEvents){node.setAttributeNS(null,"pointer-events",style.pointerEvents);}
59842 if(style.cursor!=null){node.setAttributeNS(null,"cursor",style.cursor);}
59843 return node;},dashStyle:function(style,widthFactor){var w=style.strokeWidth*widthFactor;var str=style.strokeDashstyle;switch(str){case'solid':return'none';case'dot':return[1,4*w].join();case'dash':return[4*w,4*w].join();case'dashdot':return[4*w,4*w,1,4*w].join();case'longdash':return[8*w,4*w].join();case'longdashdot':return[8*w,4*w,1,4*w].join();default:return OpenLayers.String.trim(str).replace(/\s+/g,",");}},createNode:function(type,id){var node=document.createElementNS(this.xmlns,type);if(id){node.setAttributeNS(null,"id",id);}
59844 return node;},nodeTypeCompare:function(node,type){return(type==node.nodeName);},createRenderRoot:function(){return this.nodeFactory(this.container.id+"_svgRoot","svg");},createRoot:function(suffix){return this.nodeFactory(this.container.id+suffix,"g");},createDefs:function(){var defs=this.nodeFactory(this.container.id+"_defs","defs");this.rendererRoot.appendChild(defs);return defs;},drawPoint:function(node,geometry){return this.drawCircle(node,geometry,1);},drawCircle:function(node,geometry,radius){var resolution=this.getResolution();var x=(geometry.x/resolution+this.left);var y=(this.top-geometry.y/resolution);if(this.inValidRange(x,y)){node.setAttributeNS(null,"cx",x);node.setAttributeNS(null,"cy",y);node.setAttributeNS(null,"r",radius);return node;}else{return false;}},drawLineString:function(node,geometry){var componentsResult=this.getComponentsString(geometry.components);if(componentsResult.path){node.setAttributeNS(null,"points",componentsResult.path);return(componentsResult.complete?node:null);}else{return false;}},drawLinearRing:function(node,geometry){var componentsResult=this.getComponentsString(geometry.components);if(componentsResult.path){node.setAttributeNS(null,"points",componentsResult.path);return(componentsResult.complete?node:null);}else{return false;}},drawPolygon:function(node,geometry){var d="";var draw=true;var complete=true;var linearRingResult,path;for(var j=0,len=geometry.components.length;j<len;j++){d+=" M";linearRingResult=this.getComponentsString(geometry.components[j].components," ");path=linearRingResult.path;if(path){d+=" "+path;complete=linearRingResult.complete&&complete;}else{draw=false;}}
59845 d+=" z";if(draw){node.setAttributeNS(null,"d",d);node.setAttributeNS(null,"fill-rule","evenodd");return complete?node:null;}else{return false;}},drawRectangle:function(node,geometry){var resolution=this.getResolution();var x=(geometry.x/resolution+this.left);var y=(this.top-geometry.y/resolution);if(this.inValidRange(x,y)){node.setAttributeNS(null,"x",x);node.setAttributeNS(null,"y",y);node.setAttributeNS(null,"width",geometry.width/resolution);node.setAttributeNS(null,"height",geometry.height/resolution);return node;}else{return false;}},drawSurface:function(node,geometry){var d=null;var draw=true;for(var i=0,len=geometry.components.length;i<len;i++){if((i%3)==0&&(i/3)==0){var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
59846 d="M "+component;}else if((i%3)==1){var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
59847 d+=" C "+component;}else{var component=this.getShortString(geometry.components[i]);if(!component){draw=false;}
59848 d+=" "+component;}}
59849 d+=" Z";if(draw){node.setAttributeNS(null,"d",d);return node;}else{return false;}},drawText:function(featureId,style,location){var resolution=this.getResolution();var x=(location.x/resolution+this.left);var y=(location.y/resolution-this.top);var label=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX,"text");var tspan=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX+"_tspan","tspan");label.setAttributeNS(null,"x",x);label.setAttributeNS(null,"y",-y);if(style.fontColor){label.setAttributeNS(null,"fill",style.fontColor);}
59850 if(style.fontOpacity){label.setAttributeNS(null,"opacity",style.fontOpacity);}
59851 if(style.fontFamily){label.setAttributeNS(null,"font-family",style.fontFamily);}
59852 if(style.fontSize){label.setAttributeNS(null,"font-size",style.fontSize);}
59853 if(style.fontWeight){label.setAttributeNS(null,"font-weight",style.fontWeight);}
59854 if(style.labelSelect===true){label.setAttributeNS(null,"pointer-events","visible");label._featureId=featureId;tspan._featureId=featureId;tspan._geometry=location;tspan._geometryClass=location.CLASS_NAME;}else{label.setAttributeNS(null,"pointer-events","none");}
59855 var align=style.labelAlign||"cm";label.setAttributeNS(null,"text-anchor",OpenLayers.Renderer.SVG.LABEL_ALIGN[align[0]]||"middle");if(this.isGecko){label.setAttributeNS(null,"dominant-baseline",OpenLayers.Renderer.SVG.LABEL_ALIGN[align[1]]||"central");}else{tspan.setAttributeNS(null,"baseline-shift",OpenLayers.Renderer.SVG.LABEL_VSHIFT[align[1]]||"-35%");}
59856 tspan.textContent=style.label;if(!label.parentNode){label.appendChild(tspan);this.textRoot.appendChild(label);}},getComponentsString:function(components,separator){var renderCmp=[];var complete=true;var len=components.length;var strings=[];var str,component;for(var i=0;i<len;i++){component=components[i];renderCmp.push(component);str=this.getShortString(component);if(str){strings.push(str);}else{if(i>0){if(this.getShortString(components[i-1])){strings.push(this.clipLine(components[i],components[i-1]));}}
59857 if(i<len-1){if(this.getShortString(components[i+1])){strings.push(this.clipLine(components[i],components[i+1]));}}
59858 complete=false;}}
59859 return{path:strings.join(separator||","),complete:complete};},clipLine:function(badComponent,goodComponent){if(goodComponent.equals(badComponent)){return"";}
59860 var resolution=this.getResolution();var maxX=this.MAX_PIXEL-this.translationParameters.x;var maxY=this.MAX_PIXEL-this.translationParameters.y;var x1=goodComponent.x/resolution+this.left;var y1=this.top-goodComponent.y/resolution;var x2=badComponent.x/resolution+this.left;var y2=this.top-badComponent.y/resolution;var k;if(x2<-maxX||x2>maxX){k=(y2-y1)/(x2-x1);x2=x2<0?-maxX:maxX;y2=y1+(x2-x1)*k;}
59861 if(y2<-maxY||y2>maxY){k=(x2-x1)/(y2-y1);y2=y2<0?-maxY:maxY;x2=x1+(y2-y1)*k;}
59862 return x2+","+y2;},getShortString:function(point){var resolution=this.getResolution();var x=(point.x/resolution+this.left);var y=(this.top-point.y/resolution);if(this.inValidRange(x,y)){return x+","+y;}else{return false;}},getPosition:function(node){return({x:parseFloat(node.getAttributeNS(null,"cx")),y:parseFloat(node.getAttributeNS(null,"cy"))});},importSymbol:function(graphicName){if(!this.defs){this.defs=this.createDefs();}
59863 var id=this.container.id+"-"+graphicName;if(document.getElementById(id)!=null){return id;}
59864 var symbol=OpenLayers.Renderer.symbol[graphicName];if(!symbol){throw new Error(graphicName+' is not a valid symbol name');}
59865 var symbolNode=this.nodeFactory(id,"symbol");var node=this.nodeFactory(null,"polygon");symbolNode.appendChild(node);var symbolExtent=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0);var points=[];var x,y;for(var i=0;i<symbol.length;i=i+2){x=symbol[i];y=symbol[i+1];symbolExtent.left=Math.min(symbolExtent.left,x);symbolExtent.bottom=Math.min(symbolExtent.bottom,y);symbolExtent.right=Math.max(symbolExtent.right,x);symbolExtent.top=Math.max(symbolExtent.top,y);points.push(x,",",y);}
59866 node.setAttributeNS(null,"points",points.join(" "));var width=symbolExtent.getWidth();var height=symbolExtent.getHeight();var viewBox=[symbolExtent.left-width,symbolExtent.bottom-height,width*3,height*3];symbolNode.setAttributeNS(null,"viewBox",viewBox.join(" "));this.symbolMetrics[id]=[Math.max(width,height),symbolExtent.getCenterLonLat().lon,symbolExtent.getCenterLonLat().lat];this.defs.appendChild(symbolNode);return symbolNode.id;},getFeatureIdFromEvent:function(evt){var featureId=OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent.apply(this,arguments);if(this.supportUse===false&&!featureId){var target=evt.target;featureId=target.parentNode&&target!=this.rendererRoot&&target.parentNode._featureId;}
59867 return featureId;},CLASS_NAME:"OpenLayers.Renderer.SVG"});OpenLayers.Renderer.SVG.LABEL_ALIGN={"l":"start","r":"end","b":"bottom","t":"hanging"};OpenLayers.Renderer.SVG.LABEL_VSHIFT={"t":"-70%","b":"0"};OpenLayers.Renderer.VML=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"urn:schemas-microsoft-com:vml",symbolCache:{},offset:null,initialize:function(containerID){if(!this.supported()){return;}
59868 if(!document.namespaces.olv){document.namespaces.add("olv",this.xmlns);var style=document.createStyleSheet();var shapes=['shape','rect','oval','fill','stroke','imagedata','group','textbox'];for(var i=0,len=shapes.length;i<len;i++){style.addRule('olv\\:'+shapes[i],"behavior: url(#default#VML); "+"position: absolute; display: inline-block;");}}
59869 OpenLayers.Renderer.Elements.prototype.initialize.apply(this,arguments);},destroy:function(){OpenLayers.Renderer.Elements.prototype.destroy.apply(this,arguments);},supported:function(){return!!(document.namespaces);},setExtent:function(extent,resolutionChanged){OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments);var resolution=this.getResolution();var left=(extent.left/resolution)|0;var top=(extent.top/resolution-this.size.h)|0;if(resolutionChanged||!this.offset){this.offset={x:left,y:top};left=0;top=0;}else{left=left-this.offset.x;top=top-this.offset.y;}
59870 var org=left+" "+top;this.root.coordorigin=org;var roots=[this.root,this.vectorRoot,this.textRoot];var root;for(var i=0,len=roots.length;i<len;++i){root=roots[i];var size=this.size.w+" "+this.size.h;root.coordsize=size;}
59871 this.root.style.flip="y";return true;},setSize:function(size){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);var roots=[this.rendererRoot,this.root,this.vectorRoot,this.textRoot];var w=this.size.w+"px";var h=this.size.h+"px";var root;for(var i=0,len=roots.length;i<len;++i){root=roots[i];root.style.width=w;root.style.height=h;}},getNodeType:function(geometry,style){var nodeType=null;switch(geometry.CLASS_NAME){case"OpenLayers.Geometry.Point":if(style.externalGraphic){nodeType="olv:rect";}else if(this.isComplexSymbol(style.graphicName)){nodeType="olv:shape";}else{nodeType="olv:oval";}
59872 break;case"OpenLayers.Geometry.Rectangle":nodeType="olv:rect";break;case"OpenLayers.Geometry.LineString":case"OpenLayers.Geometry.LinearRing":case"OpenLayers.Geometry.Polygon":case"OpenLayers.Geometry.Curve":case"OpenLayers.Geometry.Surface":nodeType="olv:shape";break;default:break;}
59873 return nodeType;},setStyle:function(node,style,options,geometry){style=style||node._style;options=options||node._options;var fillColor=style.fillColor;if(node._geometryClass==="OpenLayers.Geometry.Point"){if(style.externalGraphic){if(style.graphicTitle){node.title=style.graphicTitle;}
59874 var width=style.graphicWidth||style.graphicHeight;var height=style.graphicHeight||style.graphicWidth;width=width?width:style.pointRadius*2;height=height?height:style.pointRadius*2;var resolution=this.getResolution();var xOffset=(style.graphicXOffset!=undefined)?style.graphicXOffset:-(0.5*width);var yOffset=(style.graphicYOffset!=undefined)?style.graphicYOffset:-(0.5*height);node.style.left=(((geometry.x/resolution-this.offset.x)+xOffset)|0)+"px";node.style.top=(((geometry.y/resolution-this.offset.y)-(yOffset+height))|0)+"px";node.style.width=width+"px";node.style.height=height+"px";node.style.flip="y";fillColor="none";options.isStroked=false;}else if(this.isComplexSymbol(style.graphicName)){var cache=this.importSymbol(style.graphicName);node.path=cache.path;node.coordorigin=cache.left+","+cache.bottom;var size=cache.size;node.coordsize=size+","+size;this.drawCircle(node,geometry,style.pointRadius);node.style.flip="y";}else{this.drawCircle(node,geometry,style.pointRadius);}}
59875 if(options.isFilled){node.fillcolor=fillColor;}else{node.filled="false";}
59876 var fills=node.getElementsByTagName("fill");var fill=(fills.length==0)?null:fills[0];if(!options.isFilled){if(fill){node.removeChild(fill);}}else{if(!fill){fill=this.createNode('olv:fill',node.id+"_fill");}
59877 fill.opacity=style.fillOpacity;if(node._geometryClass==="OpenLayers.Geometry.Point"&&style.externalGraphic){if(style.graphicOpacity){fill.opacity=style.graphicOpacity;}
59878 fill.src=style.externalGraphic;fill.type="frame";if(!(style.graphicWidth&&style.graphicHeight)){fill.aspect="atmost";}}
59879 if(fill.parentNode!=node){node.appendChild(fill);}}
59880 var rotation=style.rotation;if((rotation!==undefined||node._rotation!==undefined)){node._rotation=rotation;if(style.externalGraphic){this.graphicRotate(node,xOffset,yOffset,style);fill.opacity=0;}else if(node._geometryClass==="OpenLayers.Geometry.Point"){node.style.rotation=rotation||0;}}
59881 var strokes=node.getElementsByTagName("stroke");var stroke=(strokes.length==0)?null:strokes[0];if(!options.isStroked){node.stroked=false;if(stroke){stroke.on=false;}}else{if(!stroke){stroke=this.createNode('olv:stroke',node.id+"_stroke");node.appendChild(stroke);}
59882 stroke.on=true;stroke.color=style.strokeColor;stroke.weight=style.strokeWidth+"px";stroke.opacity=style.strokeOpacity;stroke.endcap=style.strokeLinecap=='butt'?'flat':(style.strokeLinecap||'round');if(style.strokeDashstyle){stroke.dashstyle=this.dashStyle(style);}}
59883 if(style.cursor!="inherit"&&style.cursor!=null){node.style.cursor=style.cursor;}
59884 return node;},graphicRotate:function(node,xOffset,yOffset,style){var style=style||node._style;var rotation=style.rotation||0;var aspectRatio,size;if(!(style.graphicWidth&&style.graphicHeight)){var img=new Image();img.onreadystatechange=OpenLayers.Function.bind(function(){if(img.readyState=="complete"||img.readyState=="interactive"){aspectRatio=img.width/img.height;size=Math.max(style.pointRadius*2,style.graphicWidth||0,style.graphicHeight||0);xOffset=xOffset*aspectRatio;style.graphicWidth=size*aspectRatio;style.graphicHeight=size;this.graphicRotate(node,xOffset,yOffset,style);}},this);img.src=style.externalGraphic;return;}else{size=Math.max(style.graphicWidth,style.graphicHeight);aspectRatio=style.graphicWidth/style.graphicHeight;}
59885 var width=Math.round(style.graphicWidth||size*aspectRatio);var height=Math.round(style.graphicHeight||size);node.style.width=width+"px";node.style.height=height+"px";var image=document.getElementById(node.id+"_image");if(!image){image=this.createNode("olv:imagedata",node.id+"_image");node.appendChild(image);}
59886 image.style.width=width+"px";image.style.height=height+"px";image.src=style.externalGraphic;image.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader("+"src='', sizingMethod='scale')";var rot=rotation*Math.PI/180;var sintheta=Math.sin(rot);var costheta=Math.cos(rot);var filter="progid:DXImageTransform.Microsoft.Matrix(M11="+costheta+",M12="+(-sintheta)+",M21="+sintheta+",M22="+costheta+",SizingMethod='auto expand')\n";var opacity=style.graphicOpacity||style.fillOpacity;if(opacity&&opacity!=1){filter+="progid:DXImageTransform.Microsoft.BasicImage(opacity="+
59887 opacity+")\n";}
59888 node.style.filter=filter;var centerPoint=new OpenLayers.Geometry.Point(-xOffset,-yOffset);var imgBox=new OpenLayers.Bounds(0,0,width,height).toGeometry();imgBox.rotate(style.rotation,centerPoint);var imgBounds=imgBox.getBounds();node.style.left=Math.round(parseInt(node.style.left)+imgBounds.left)+"px";node.style.top=Math.round(parseInt(node.style.top)-imgBounds.bottom)+"px";},postDraw:function(node){node.style.visibility="visible";var fillColor=node._style.fillColor;var strokeColor=node._style.strokeColor;if(fillColor=="none"&&node.fillcolor!=fillColor){node.fillcolor=fillColor;}
59889 if(strokeColor=="none"&&node.strokecolor!=strokeColor){node.strokecolor=strokeColor;}},setNodeDimension:function(node,geometry){var bbox=geometry.getBounds();if(bbox){var resolution=this.getResolution();var scaledBox=new OpenLayers.Bounds((bbox.left/resolution-this.offset.x)|0,(bbox.bottom/resolution-this.offset.y)|0,(bbox.right/resolution-this.offset.x)|0,(bbox.top/resolution-this.offset.y)|0);node.style.left=scaledBox.left+"px";node.style.top=scaledBox.top+"px";node.style.width=scaledBox.getWidth()+"px";node.style.height=scaledBox.getHeight()+"px";node.coordorigin=scaledBox.left+" "+scaledBox.top;node.coordsize=scaledBox.getWidth()+" "+scaledBox.getHeight();}},dashStyle:function(style){var dash=style.strokeDashstyle;switch(dash){case'solid':case'dot':case'dash':case'dashdot':case'longdash':case'longdashdot':return dash;default:var parts=dash.split(/[ ,]/);if(parts.length==2){if(1*parts[0]>=2*parts[1]){return"longdash";}
59890 return(parts[0]==1||parts[1]==1)?"dot":"dash";}else if(parts.length==4){return(1*parts[0]>=2*parts[1])?"longdashdot":"dashdot";}
59891 return"solid";}},createNode:function(type,id){var node=document.createElement(type);if(id){node.id=id;}
59892 node.unselectable='on';node.onselectstart=OpenLayers.Function.False;return node;},nodeTypeCompare:function(node,type){var subType=type;var splitIndex=subType.indexOf(":");if(splitIndex!=-1){subType=subType.substr(splitIndex+1);}
59893 var nodeName=node.nodeName;splitIndex=nodeName.indexOf(":");if(splitIndex!=-1){nodeName=nodeName.substr(splitIndex+1);}
59894 return(subType==nodeName);},createRenderRoot:function(){return this.nodeFactory(this.container.id+"_vmlRoot","div");},createRoot:function(suffix){return this.nodeFactory(this.container.id+suffix,"olv:group");},drawPoint:function(node,geometry){return this.drawCircle(node,geometry,1);},drawCircle:function(node,geometry,radius){if(!isNaN(geometry.x)&&!isNaN(geometry.y)){var resolution=this.getResolution();node.style.left=(((geometry.x/resolution-this.offset.x)|0)-radius)+"px";node.style.top=(((geometry.y/resolution-this.offset.y)|0)-radius)+"px";var diameter=radius*2;node.style.width=diameter+"px";node.style.height=diameter+"px";return node;}
59895 return false;},drawLineString:function(node,geometry){return this.drawLine(node,geometry,false);},drawLinearRing:function(node,geometry){return this.drawLine(node,geometry,true);},drawLine:function(node,geometry,closeLine){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var numComponents=geometry.components.length;var parts=new Array(numComponents);var comp,x,y;for(var i=0;i<numComponents;i++){comp=geometry.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;parts[i]=" "+x+","+y+" l ";}
59896 var end=(closeLine)?" x e":" e";node.path="m"+parts.join("")+end;return node;},drawPolygon:function(node,geometry){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var path=[];var linearRing,i,j,len,ilen,comp,x,y;for(j=0,len=geometry.components.length;j<len;j++){linearRing=geometry.components[j];path.push("m");for(i=0,ilen=linearRing.components.length;i<ilen;i++){comp=linearRing.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;path.push(" "+x+","+y);if(i==0){path.push(" l");}}
59897 path.push(" x ");}
59898 path.push("e");node.path=path.join("");return node;},drawRectangle:function(node,geometry){var resolution=this.getResolution();node.style.left=((geometry.x/resolution-this.offset.x)|0)+"px";node.style.top=((geometry.y/resolution-this.offset.y)|0)+"px";node.style.width=((geometry.width/resolution)|0)+"px";node.style.height=((geometry.height/resolution)|0)+"px";return node;},drawText:function(featureId,style,location){var label=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX,"olv:rect");var textbox=this.nodeFactory(featureId+this.LABEL_ID_SUFFIX+"_textbox","olv:textbox");var resolution=this.getResolution();label.style.left=((location.x/resolution-this.offset.x)|0)+"px";label.style.top=((location.y/resolution-this.offset.y)|0)+"px";label.style.flip="y";textbox.innerText=style.label;if(style.fontColor){textbox.style.color=style.fontColor;}
59899 if(style.fontOpacity){textbox.style.filter='alpha(opacity='+(style.fontOpacity*100)+')';}
59900 if(style.fontFamily){textbox.style.fontFamily=style.fontFamily;}
59901 if(style.fontSize){textbox.style.fontSize=style.fontSize;}
59902 if(style.fontWeight){textbox.style.fontWeight=style.fontWeight;}
59903 if(style.labelSelect===true){label._featureId=featureId;textbox._featureId=featureId;textbox._geometry=location;textbox._geometryClass=location.CLASS_NAME;}
59904 textbox.style.whiteSpace="nowrap";textbox.inset="1px,0px,0px,0px";if(!label.parentNode){label.appendChild(textbox);this.textRoot.appendChild(label);}
59905 var align=style.labelAlign||"cm";if(align.length==1){align+="m";}
59906 var xshift=textbox.clientWidth*(OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(0,1)]);var yshift=textbox.clientHeight*(OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(1,1)]);label.style.left=parseInt(label.style.left)-xshift-1+"px";label.style.top=parseInt(label.style.top)+yshift+"px";},drawSurface:function(node,geometry){this.setNodeDimension(node,geometry);var resolution=this.getResolution();var path=[];var comp,x,y;for(var i=0,len=geometry.components.length;i<len;i++){comp=geometry.components[i];x=(comp.x/resolution-this.offset.x)|0;y=(comp.y/resolution-this.offset.y)|0;if((i%3)==0&&(i/3)==0){path.push("m");}else if((i%3)==1){path.push(" c");}
59907 path.push(" "+x+","+y);}
59908 path.push(" x e");node.path=path.join("");return node;},moveRoot:function(renderer){var layer=this.map.getLayer(renderer.container.id);if(layer instanceof OpenLayers.Layer.Vector.RootContainer){layer=this.map.getLayer(this.container.id);}
59909 layer&&layer.renderer.clear();OpenLayers.Renderer.Elements.prototype.moveRoot.apply(this,arguments);layer&&layer.redraw();},importSymbol:function(graphicName){var id=this.container.id+"-"+graphicName;var cache=this.symbolCache[id];if(cache){return cache;}
59910 var symbol=OpenLayers.Renderer.symbol[graphicName];if(!symbol){throw new Error(graphicName+' is not a valid symbol name');}
59911 var symbolExtent=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0);var pathitems=["m"];for(var i=0;i<symbol.length;i=i+2){var x=symbol[i];var y=symbol[i+1];symbolExtent.left=Math.min(symbolExtent.left,x);symbolExtent.bottom=Math.min(symbolExtent.bottom,y);symbolExtent.right=Math.max(symbolExtent.right,x);symbolExtent.top=Math.max(symbolExtent.top,y);pathitems.push(x);pathitems.push(y);if(i==0){pathitems.push("l");}}
59912 pathitems.push("x e");var path=pathitems.join(" ");var diff=(symbolExtent.getWidth()-symbolExtent.getHeight())/2;if(diff>0){symbolExtent.bottom=symbolExtent.bottom-diff;symbolExtent.top=symbolExtent.top+diff;}else{symbolExtent.left=symbolExtent.left+diff;symbolExtent.right=symbolExtent.right-diff;}
59913 cache={path:path,size:symbolExtent.getWidth(),left:symbolExtent.left,bottom:symbolExtent.bottom};this.symbolCache[id]=cache;return cache;},CLASS_NAME:"OpenLayers.Renderer.VML"});OpenLayers.Renderer.VML.LABEL_SHIFT={"l":0,"c":.5,"r":1,"t":0,"m":.5,"b":1};OpenLayers.Tile=OpenLayers.Class({EVENT_TYPES:["loadstart","loadend","reload","unload"],events:null,id:null,layer:null,url:null,bounds:null,size:null,position:null,isLoading:false,initialize:function(layer,position,bounds,url,size){this.layer=layer;this.position=position.clone();this.bounds=bounds.clone();this.url=url;this.size=size.clone();this.id=OpenLayers.Util.createUniqueID("Tile_");this.events=new OpenLayers.Events(this,null,this.EVENT_TYPES);},unload:function(){if(this.isLoading){this.isLoading=false;this.events.triggerEvent("unload");}},destroy:function(){this.layer=null;this.bounds=null;this.size=null;this.position=null;this.events.destroy();this.events=null;},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile(this.layer,this.position,this.bounds,this.url,this.size);}
59914 OpenLayers.Util.applyDefaults(obj,this);return obj;},draw:function(){var maxExtent=this.layer.maxExtent;var withinMaxExtent=(maxExtent&&this.bounds.intersectsBounds(maxExtent,false));this.shouldDraw=(withinMaxExtent||this.layer.displayOutsideMaxExtent);this.clear();return this.shouldDraw;},moveTo:function(bounds,position,redraw){if(redraw==null){redraw=true;}
59915 this.bounds=bounds.clone();this.position=position.clone();if(redraw){this.draw();}},clear:function(){},getBoundsFromBaseLayer:function(position){var msg=OpenLayers.i18n('reprojectDeprecated',{'layerName':this.layer.name});OpenLayers.Console.warn(msg);var topLeft=this.layer.map.getLonLatFromLayerPx(position);var bottomRightPx=position.clone();bottomRightPx.x+=this.size.w;bottomRightPx.y+=this.size.h;var bottomRight=this.layer.map.getLonLatFromLayerPx(bottomRightPx);if(topLeft.lon>bottomRight.lon){if(topLeft.lon<0){topLeft.lon=-180-(topLeft.lon+180);}else{bottomRight.lon=180+bottomRight.lon+180;}}
59916 var bounds=new OpenLayers.Bounds(topLeft.lon,bottomRight.lat,bottomRight.lon,topLeft.lat);return bounds;},showTile:function(){if(this.shouldDraw){this.show();}},show:function(){},hide:function(){},CLASS_NAME:"OpenLayers.Tile"});OpenLayers.Control.MouseToolbar=OpenLayers.Class(OpenLayers.Control.MouseDefaults,{mode:null,buttons:null,direction:"vertical",buttonClicked:null,initialize:function(position,direction){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.position=new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,OpenLayers.Control.MouseToolbar.Y);if(position){this.position=position;}
59917 if(direction){this.direction=direction;}
59918 this.measureDivs=[];},destroy:function(){for(var btnId in this.buttons){var btn=this.buttons[btnId];btn.map=null;btn.events.destroy();}
59919 OpenLayers.Control.MouseDefaults.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);OpenLayers.Control.MouseDefaults.prototype.draw.apply(this,arguments);this.buttons={};var sz=new OpenLayers.Size(28,28);var centered=new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,0);this._addButton("zoombox","drag-rectangle-off.png","drag-rectangle-on.png",centered,sz,"Shift->Drag to zoom to area");centered=centered.add((this.direction=="vertical"?0:sz.w),(this.direction=="vertical"?sz.h:0));this._addButton("pan","panning-hand-off.png","panning-hand-on.png",centered,sz,"Drag the map to pan.");centered=centered.add((this.direction=="vertical"?0:sz.w),(this.direction=="vertical"?sz.h:0));this.switchModeTo("pan");return this.div;},_addButton:function(id,img,activeImg,xy,sz,title){var imgLocation=OpenLayers.Util.getImagesLocation()+img;var activeImgLocation=OpenLayers.Util.getImagesLocation()+activeImg;var btn=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MouseToolbar_"+id,xy,sz,imgLocation,"absolute");this.div.appendChild(btn);btn.imgLocation=imgLocation;btn.activeImgLocation=activeImgLocation;btn.events=new OpenLayers.Events(this,btn,null,true);btn.events.on({"mousedown":this.buttonDown,"mouseup":this.buttonUp,"dblclick":OpenLayers.Event.stop,scope:this});btn.action=id;btn.title=title;btn.alt=title;btn.map=this.map;this.buttons[id]=btn;return btn;},buttonDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59920 this.buttonClicked=evt.element.action;OpenLayers.Event.stop(evt);},buttonUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59921 if(this.buttonClicked!=null){if(this.buttonClicked==evt.element.action){this.switchModeTo(evt.element.action);}
59922 OpenLayers.Event.stop(evt);this.buttonClicked=null;}},defaultDblClick:function(evt){this.switchModeTo("pan");this.performedDrag=false;var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);OpenLayers.Event.stop(evt);return false;},defaultMouseDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59923 this.mouseDragStart=evt.xy.clone();this.performedDrag=false;this.startViaKeyboard=false;if(evt.shiftKey&&this.mode!="zoombox"){this.switchModeTo("zoombox");this.startViaKeyboard=true;}else if(evt.altKey&&this.mode!="measure"){this.switchModeTo("measure");}else if(!this.mode){this.switchModeTo("pan");}
59924 switch(this.mode){case"zoombox":this.map.div.style.cursor="crosshair";this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.mouseDragStart,null,null,"absolute","2px solid red");this.zoomBox.style.backgroundColor="white";this.zoomBox.style.filter="alpha(opacity=50)";this.zoomBox.style.opacity="0.50";this.zoomBox.style.fontSize="1px";this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);this.performedDrag=true;break;case"measure":var distance="";if(this.measureStart){var measureEnd=this.map.getLonLatFromViewPortPx(this.mouseDragStart);distance=OpenLayers.Util.distVincenty(this.measureStart,measureEnd);distance=Math.round(distance*100)/100;distance=distance+"km";this.measureStartBox=this.measureBox;}
59925 this.measureStart=this.map.getLonLatFromViewPortPx(this.mouseDragStart);;this.measureBox=OpenLayers.Util.createDiv(null,this.mouseDragStart.add(-2-parseInt(this.map.layerContainerDiv.style.left),-2-parseInt(this.map.layerContainerDiv.style.top)),null,null,"absolute");this.measureBox.style.width="4px";this.measureBox.style.height="4px";this.measureBox.style.fontSize="1px";this.measureBox.style.backgroundColor="red";this.measureBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBox);if(distance){this.measureBoxDistance=OpenLayers.Util.createDiv(null,this.mouseDragStart.add(-2-parseInt(this.map.layerContainerDiv.style.left),2-parseInt(this.map.layerContainerDiv.style.top)),null,null,"absolute");this.measureBoxDistance.innerHTML=distance;this.measureBoxDistance.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBoxDistance);this.measureDivs.push(this.measureBoxDistance);}
59926 this.measureBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.layerContainerDiv.appendChild(this.measureBox);this.measureDivs.push(this.measureBox);break;default:this.map.div.style.cursor="move";break;}
59927 document.onselectstart=OpenLayers.Function.False;OpenLayers.Event.stop(evt);},switchModeTo:function(mode){if(mode!=this.mode){if(this.mode&&this.buttons[this.mode]){OpenLayers.Util.modifyAlphaImageDiv(this.buttons[this.mode],null,null,null,this.buttons[this.mode].imgLocation);}
59928 if(this.mode=="measure"&&mode!="measure"){for(var i=0,len=this.measureDivs.length;i<len;i++){if(this.measureDivs[i]){this.map.layerContainerDiv.removeChild(this.measureDivs[i]);}}
59929 this.measureDivs=[];this.measureStart=null;}
59930 this.mode=mode;if(this.buttons[mode]){OpenLayers.Util.modifyAlphaImageDiv(this.buttons[mode],null,null,null,this.buttons[mode].activeImgLocation);}
59931 switch(this.mode){case"zoombox":this.map.div.style.cursor="crosshair";break;default:this.map.div.style.cursor="";break;}}},leaveMode:function(){this.switchModeTo("pan");},defaultMouseMove:function(evt){if(this.mouseDragStart!=null){switch(this.mode){case"zoombox":var deltaX=Math.abs(this.mouseDragStart.x-evt.xy.x);var deltaY=Math.abs(this.mouseDragStart.y-evt.xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";if(evt.xy.x<this.mouseDragStart.x){this.zoomBox.style.left=evt.xy.x+"px";}
59932 if(evt.xy.y<this.mouseDragStart.y){this.zoomBox.style.top=evt.xy.y+"px";}
59933 break;default:var deltaX=this.mouseDragStart.x-evt.xy.x;var deltaY=this.mouseDragStart.y-evt.xy.y;var size=this.map.getSize();var newXY=new OpenLayers.Pixel(size.w/2+deltaX,size.h/2+deltaY);var newCenter=this.map.getLonLatFromViewPortPx(newXY);this.map.setCenter(newCenter,null,true);this.mouseDragStart=evt.xy.clone();}
59934 this.performedDrag=true;}},defaultMouseUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59935 switch(this.mode){case"zoombox":this.zoomBoxEnd(evt);if(this.startViaKeyboard){this.leaveMode();}
59936 break;case"pan":if(this.performedDrag){this.map.setCenter(this.map.center);}}
59937 document.onselectstart=null;this.mouseDragStart=null;this.map.div.style.cursor="default";},defaultMouseOut:function(evt){if(this.mouseDragStart!=null&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.zoomBox){this.removeZoomBox();if(this.startViaKeyboard){this.leaveMode();}}
59938 this.mouseDragStart=null;this.map.div.style.cursor="default";}},defaultClick:function(evt){if(this.performedDrag){this.performedDrag=false;return false;}},CLASS_NAME:"OpenLayers.Control.MouseToolbar"});OpenLayers.Control.MouseToolbar.X=6;OpenLayers.Control.MouseToolbar.Y=300;OpenLayers.Control.NavigationHistory=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOGGLE,previous:null,previousOptions:null,next:null,nextOptions:null,limit:50,autoActivate:true,clearOnDeactivate:false,registry:null,nextStack:null,previousStack:null,listeners:null,restoring:false,initialize:function(options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.registry=OpenLayers.Util.extend({"moveend":this.getState},this.registry);var previousOptions={trigger:OpenLayers.Function.bind(this.previousTrigger,this),displayClass:this.displayClass+" "+this.displayClass+"Previous"};OpenLayers.Util.extend(previousOptions,this.previousOptions);this.previous=new OpenLayers.Control.Button(previousOptions);var nextOptions={trigger:OpenLayers.Function.bind(this.nextTrigger,this),displayClass:this.displayClass+" "+this.displayClass+"Next"};OpenLayers.Util.extend(nextOptions,this.nextOptions);this.next=new OpenLayers.Control.Button(nextOptions);this.clear();},onPreviousChange:function(state,length){if(state&&!this.previous.active){this.previous.activate();}else if(!state&&this.previous.active){this.previous.deactivate();}},onNextChange:function(state,length){if(state&&!this.next.active){this.next.activate();}else if(!state&&this.next.active){this.next.deactivate();}},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this);this.previous.destroy();this.next.destroy();this.deactivate();for(var prop in this){this[prop]=null;}},setMap:function(map){this.map=map;this.next.setMap(map);this.previous.setMap(map);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.next.draw();this.previous.draw();},previousTrigger:function(){var current=this.previousStack.shift();var state=this.previousStack.shift();if(state!=undefined){this.nextStack.unshift(current);this.previousStack.unshift(state);this.restoring=true;this.restore(state);this.restoring=false;this.onNextChange(this.nextStack[0],this.nextStack.length);this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}else{this.previousStack.unshift(current);}
59939 return state;},nextTrigger:function(){var state=this.nextStack.shift();if(state!=undefined){this.previousStack.unshift(state);this.restoring=true;this.restore(state);this.restoring=false;this.onNextChange(this.nextStack[0],this.nextStack.length);this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}
59940 return state;},clear:function(){this.previousStack=[];this.previous.deactivate();this.nextStack=[];this.next.deactivate();},getState:function(){return{center:this.map.getCenter(),resolution:this.map.getResolution(),projection:this.map.getProjectionObject(),units:this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units};},restore:function(state){var center,zoom;if(this.map.getProjectionObject()==state.projection){zoom=this.map.getZoomForResolution(state.resolution);center=state.center;}else{center=state.center.clone();center.transform(state.projection,this.map.getProjectionObject());var sourceUnits=state.units;var targetUnits=this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units;var resolutionFactor=sourceUnits&&targetUnits?OpenLayers.INCHES_PER_UNIT[sourceUnits]/OpenLayers.INCHES_PER_UNIT[targetUnits]:1;zoom=this.map.getZoomForResolution(resolutionFactor*state.resolution);}
59941 this.map.setCenter(center,zoom);},setListeners:function(){this.listeners={};for(var type in this.registry){this.listeners[type]=OpenLayers.Function.bind(function(){if(!this.restoring){var state=this.registry[type].apply(this,arguments);this.previousStack.unshift(state);if(this.previousStack.length>1){this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);}
59942 if(this.previousStack.length>(this.limit+1)){this.previousStack.pop();}
59943 if(this.nextStack.length>0){this.nextStack=[];this.onNextChange(null,0);}}
59944 return true;},this);}},activate:function(){var activated=false;if(this.map){if(OpenLayers.Control.prototype.activate.apply(this)){if(this.listeners==null){this.setListeners();}
59945 for(var type in this.listeners){this.map.events.register(type,this,this.listeners[type]);}
59946 activated=true;if(this.previousStack.length==0){this.initStack();}}}
59947 return activated;},initStack:function(){if(this.map.getCenter()){this.listeners.moveend();}},deactivate:function(){var deactivated=false;if(this.map){if(OpenLayers.Control.prototype.deactivate.apply(this)){for(var type in this.listeners){this.map.events.unregister(type,this,this.listeners[type]);}
59948 if(this.clearOnDeactivate){this.clear();}
59949 deactivated=true;}}
59950 return deactivated;},CLASS_NAME:"OpenLayers.Control.NavigationHistory"});OpenLayers.Control.PanPanel=OpenLayers.Class(OpenLayers.Control.Panel,{slideFactor:50,initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Pan(OpenLayers.Control.Pan.NORTH,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.SOUTH,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.EAST,{slideFactor:this.slideFactor}),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.WEST,{slideFactor:this.slideFactor})]);},CLASS_NAME:"OpenLayers.Control.PanPanel"});OpenLayers.Control.PanZoomBar=OpenLayers.Class(OpenLayers.Control.PanZoom,{zoomStopWidth:18,zoomStopHeight:11,slider:null,sliderEvents:null,zoombarDiv:null,divEvents:null,zoomWorldIcon:false,forceFixedZoomLevel:false,mouseDragStart:null,zoomStart:null,initialize:function(){OpenLayers.Control.PanZoom.prototype.initialize.apply(this,arguments);},destroy:function(){this._removeZoomBar();this.map.events.un({"changebaselayer":this.redraw,scope:this});OpenLayers.Control.PanZoom.prototype.destroy.apply(this,arguments);delete this.mouseDragStart;delete this.zoomStart;},setMap:function(map){OpenLayers.Control.PanZoom.prototype.setMap.apply(this,arguments);this.map.events.register("changebaselayer",this,this.redraw);},redraw:function(){if(this.div!=null){this.removeButtons();this._removeZoomBar();}
59951 this.draw();},draw:function(px){OpenLayers.Control.prototype.draw.apply(this,arguments);px=this.position.clone();this.buttons=[];var sz=new OpenLayers.Size(18,18);var centered=new OpenLayers.Pixel(px.x+sz.w/2,px.y);var wposition=sz.w;if(this.zoomWorldIcon){centered=new OpenLayers.Pixel(px.x+sz.w,px.y);}
59952 this._addButton("panup","north-mini.png",centered,sz);px.y=centered.y+sz.h;this._addButton("panleft","west-mini.png",px,sz);if(this.zoomWorldIcon){this._addButton("zoomworld","zoom-world-mini.png",px.add(sz.w,0),sz);wposition*=2;}
59953 this._addButton("panright","east-mini.png",px.add(wposition,0),sz);this._addButton("pandown","south-mini.png",centered.add(0,sz.h*2),sz);this._addButton("zoomin","zoom-plus-mini.png",centered.add(0,sz.h*3+5),sz);centered=this._addZoomBar(centered.add(0,sz.h*4+5));this._addButton("zoomout","zoom-minus-mini.png",centered,sz);return this.div;},_addZoomBar:function(centered){var imgLocation=OpenLayers.Util.getImagesLocation();var id=this.id+"_"+this.map.id;var zoomsToEnd=this.map.getNumZoomLevels()-1-this.map.getZoom();var slider=OpenLayers.Util.createAlphaImageDiv(id,centered.add(-1,zoomsToEnd*this.zoomStopHeight),new OpenLayers.Size(20,9),imgLocation+"slider.png","absolute");this.slider=slider;this.sliderEvents=new OpenLayers.Events(this,slider,null,true,{includeXY:true});this.sliderEvents.on({"mousedown":this.zoomBarDown,"mousemove":this.zoomBarDrag,"mouseup":this.zoomBarUp,"dblclick":this.doubleClick,"click":this.doubleClick});var sz=new OpenLayers.Size();sz.h=this.zoomStopHeight*this.map.getNumZoomLevels();sz.w=this.zoomStopWidth;var div=null;if(OpenLayers.Util.alphaHack()){var id=this.id+"_"+this.map.id;div=OpenLayers.Util.createAlphaImageDiv(id,centered,new OpenLayers.Size(sz.w,this.zoomStopHeight),imgLocation+"zoombar.png","absolute",null,"crop");div.style.height=sz.h+"px";}else{div=OpenLayers.Util.createDiv('OpenLayers_Control_PanZoomBar_Zoombar'+this.map.id,centered,sz,imgLocation+"zoombar.png");}
59954 this.zoombarDiv=div;this.divEvents=new OpenLayers.Events(this,div,null,true,{includeXY:true});this.divEvents.on({"mousedown":this.divClick,"mousemove":this.passEventToSlider,"dblclick":this.doubleClick,"click":this.doubleClick});this.div.appendChild(div);this.startTop=parseInt(div.style.top);this.div.appendChild(slider);this.map.events.register("zoomend",this,this.moveZoomBar);centered=centered.add(0,this.zoomStopHeight*this.map.getNumZoomLevels());return centered;},_removeZoomBar:function(){this.sliderEvents.un({"mousedown":this.zoomBarDown,"mousemove":this.zoomBarDrag,"mouseup":this.zoomBarUp,"dblclick":this.doubleClick,"click":this.doubleClick});this.sliderEvents.destroy();this.divEvents.un({"mousedown":this.divClick,"mousemove":this.passEventToSlider,"dblclick":this.doubleClick,"click":this.doubleClick});this.divEvents.destroy();this.div.removeChild(this.zoombarDiv);this.zoombarDiv=null;this.div.removeChild(this.slider);this.slider=null;this.map.events.unregister("zoomend",this,this.moveZoomBar);},passEventToSlider:function(evt){this.sliderEvents.handleBrowserEvent(evt);},divClick:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59955 var y=evt.xy.y;var top=OpenLayers.Util.pagePosition(evt.object)[1];var levels=(y-top)/this.zoomStopHeight;if(this.forceFixedZoomLevel||!this.map.fractionalZoom){levels=Math.floor(levels);}
59956 var zoom=(this.map.getNumZoomLevels()-1)-levels;zoom=Math.min(Math.max(zoom,0),this.map.getNumZoomLevels()-1);this.map.zoomTo(zoom);OpenLayers.Event.stop(evt);},zoomBarDown:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59957 this.map.events.on({"mousemove":this.passEventToSlider,"mouseup":this.passEventToSlider,scope:this});this.mouseDragStart=evt.xy.clone();this.zoomStart=evt.xy.clone();this.div.style.cursor="move";this.zoombarDiv.offsets=null;OpenLayers.Event.stop(evt);},zoomBarDrag:function(evt){if(this.mouseDragStart!=null){var deltaY=this.mouseDragStart.y-evt.xy.y;var offsets=OpenLayers.Util.pagePosition(this.zoombarDiv);if((evt.clientY-offsets[1])>0&&(evt.clientY-offsets[1])<parseInt(this.zoombarDiv.style.height)-2){var newTop=parseInt(this.slider.style.top)-deltaY;this.slider.style.top=newTop+"px";this.mouseDragStart=evt.xy.clone();}
59958 OpenLayers.Event.stop(evt);}},zoomBarUp:function(evt){if(!OpenLayers.Event.isLeftClick(evt)){return;}
59959 if(this.mouseDragStart){this.div.style.cursor="";this.map.events.un({"mouseup":this.passEventToSlider,"mousemove":this.passEventToSlider,scope:this});var deltaY=this.zoomStart.y-evt.xy.y;var zoomLevel=this.map.zoom;if(!this.forceFixedZoomLevel&&this.map.fractionalZoom){zoomLevel+=deltaY/this.zoomStopHeight;zoomLevel=Math.min(Math.max(zoomLevel,0),this.map.getNumZoomLevels()-1);}else{zoomLevel+=Math.round(deltaY/this.zoomStopHeight);}
59960 this.map.zoomTo(zoomLevel);this.mouseDragStart=null;this.zoomStart=null;OpenLayers.Event.stop(evt);}},moveZoomBar:function(){var newTop=((this.map.getNumZoomLevels()-1)-this.map.getZoom())*this.zoomStopHeight+this.startTop+1;this.slider.style.top=newTop+"px";},CLASS_NAME:"OpenLayers.Control.PanZoomBar"});OpenLayers.Control.Permalink=OpenLayers.Class(OpenLayers.Control,{argParserClass:OpenLayers.Control.ArgParser,element:null,base:'',displayProjection:null,initialize:function(element,base,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.element=OpenLayers.Util.getElement(element);this.base=base||document.location.href;},destroy:function(){if(this.element.parentNode==this.div){this.div.removeChild(this.element);}
59961 this.element=null;this.map.events.unregister('moveend',this,this.updateLink);OpenLayers.Control.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var i=0,len=this.map.controls.length;i<len;i++){var control=this.map.controls[i];if(control.CLASS_NAME==this.argParserClass.CLASS_NAME){if(control.displayProjection!=this.displayProjection){this.displayProjection=control.displayProjection;}
59962 break;}}
59963 if(i==this.map.controls.length){this.map.addControl(new this.argParserClass({'displayProjection':this.displayProjection}));}},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.element){this.div.className=this.displayClass;this.element=document.createElement("a");this.element.innerHTML=OpenLayers.i18n("permalink");this.element.href="";this.div.appendChild(this.element);}
59964 this.map.events.on({'moveend':this.updateLink,'changelayer':this.updateLink,'changebaselayer':this.updateLink,scope:this});this.updateLink();return this.div;},updateLink:function(){var href=this.base;if(href.indexOf('?')!=-1){href=href.substring(0,href.indexOf('?'));}
59965 href+='?'+OpenLayers.Util.getParameterString(this.createParams());this.element.href=href;},createParams:function(center,zoom,layers){center=center||this.map.getCenter();var params=OpenLayers.Util.getParameters(this.base);if(center){params.zoom=zoom||this.map.getZoom();var lat=center.lat;var lon=center.lon;if(this.displayProjection){var mapPosition=OpenLayers.Projection.transform({x:lon,y:lat},this.map.getProjectionObject(),this.displayProjection);lon=mapPosition.x;lat=mapPosition.y;}
59966 params.lat=Math.round(lat*100000)/100000;params.lon=Math.round(lon*100000)/100000;layers=layers||this.map.layers;params.layers='';for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];if(layer.isBaseLayer){params.layers+=(layer==this.map.baseLayer)?"B":"0";}else{params.layers+=(layer.getVisibility())?"T":"F";}}}
59967 return params;},CLASS_NAME:"OpenLayers.Control.Permalink"});OpenLayers.Control.ZoomPanel=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.ZoomIn(),new OpenLayers.Control.ZoomToMaxExtent(),new OpenLayers.Control.ZoomOut()]);},CLASS_NAME:"OpenLayers.Control.ZoomPanel"});OpenLayers.Format.CSWGetDomain=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.CSWGetDomain.DEFAULTS);var cls=OpenLayers.Format.CSWGetDomain["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported CSWGetDomain version: "+options.version;}
59968 return new cls(options);};OpenLayers.Format.CSWGetDomain.DEFAULTS={"version":"2.0.2"};OpenLayers.Format.CSWGetRecords=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.CSWGetRecords.DEFAULTS);var cls=OpenLayers.Format.CSWGetRecords["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported CSWGetRecords version: "+options.version;}
59969 return new cls(options);};OpenLayers.Format.CSWGetRecords.DEFAULTS={"version":"2.0.2"};OpenLayers.Format.JSON=OpenLayers.Class(OpenLayers.Format,{indent:"    ",space:" ",newline:"\n",level:0,pretty:false,initialize:function(options){OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(json,filter){try{if(/^[\],:{}\s]*$/.test(json.replace(/\\["\\\/bfnrtu]/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){var object=eval('('+json+')');if(typeof filter==='function'){function walk(k,v){if(v&&typeof v==='object'){for(var i in v){if(v.hasOwnProperty(i)){v[i]=walk(i,v[i]);}}}
59970 return filter(k,v);}
59971 object=walk('',object);}
59972 if(this.keepData){this.data=object;}
59973 return object;}}catch(e){}
59974 return null;},write:function(value,pretty){this.pretty=!!pretty;var json=null;var type=typeof value;if(this.serialize[type]){try{json=this.serialize[type].apply(this,[value]);}catch(err){OpenLayers.Console.error("Trouble serializing: "+err);}}
59975 return json;},writeIndent:function(){var pieces=[];if(this.pretty){for(var i=0;i<this.level;++i){pieces.push(this.indent);}}
59976 return pieces.join('');},writeNewline:function(){return(this.pretty)?this.newline:'';},writeSpace:function(){return(this.pretty)?this.space:'';},serialize:{'object':function(object){if(object==null){return"null";}
59977 if(object.constructor==Date){return this.serialize.date.apply(this,[object]);}
59978 if(object.constructor==Array){return this.serialize.array.apply(this,[object]);}
59979 var pieces=['{'];this.level+=1;var key,keyJSON,valueJSON;var addComma=false;for(key in object){if(object.hasOwnProperty(key)){keyJSON=OpenLayers.Format.JSON.prototype.write.apply(this,[key,this.pretty]);valueJSON=OpenLayers.Format.JSON.prototype.write.apply(this,[object[key],this.pretty]);if(keyJSON!=null&&valueJSON!=null){if(addComma){pieces.push(',');}
59980 pieces.push(this.writeNewline(),this.writeIndent(),keyJSON,':',this.writeSpace(),valueJSON);addComma=true;}}}
59981 this.level-=1;pieces.push(this.writeNewline(),this.writeIndent(),'}');return pieces.join('');},'array':function(array){var json;var pieces=['['];this.level+=1;for(var i=0,len=array.length;i<len;++i){json=OpenLayers.Format.JSON.prototype.write.apply(this,[array[i],this.pretty]);if(json!=null){if(i>0){pieces.push(',');}
59982 pieces.push(this.writeNewline(),this.writeIndent(),json);}}
59983 this.level-=1;pieces.push(this.writeNewline(),this.writeIndent(),']');return pieces.join('');},'string':function(string){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};if(/["\\\x00-\x1f]/.test(string)){return'"'+string.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c;}
59984 c=b.charCodeAt();return'\\u00'+
59985 Math.floor(c/16).toString(16)+
59986 (c%16).toString(16);})+'"';}
59987 return'"'+string+'"';},'number':function(number){return isFinite(number)?String(number):"null";},'boolean':function(bool){return String(bool);},'date':function(date){function format(number){return(number<10)?'0'+number:number;}
59988 return'"'+date.getFullYear()+'-'+
59989 format(date.getMonth()+1)+'-'+
59990 format(date.getDate())+'T'+
59991 format(date.getHours())+':'+
59992 format(date.getMinutes())+':'+
59993 format(date.getSeconds())+'"';}},CLASS_NAME:"OpenLayers.Format.JSON"});OpenLayers.Format.WFST=function(options){options=OpenLayers.Util.applyDefaults(options,OpenLayers.Format.WFST.DEFAULTS);var cls=OpenLayers.Format.WFST["v"+options.version.replace(/\./g,"_")];if(!cls){throw"Unsupported WFST version: "+options.version;}
59994 return new cls(options);};OpenLayers.Format.WFST.DEFAULTS={"version":"1.0.0"};OpenLayers.Format.XML=OpenLayers.Class(OpenLayers.Format,{namespaces:null,namespaceAlias:null,defaultPrefix:null,readers:{},writers:{},xmldom:null,initialize:function(options){if(window.ActiveXObject){this.xmldom=new ActiveXObject("Microsoft.XMLDOM");}
59995 OpenLayers.Format.prototype.initialize.apply(this,[options]);this.namespaces=OpenLayers.Util.extend({},this.namespaces);this.namespaceAlias={};for(var alias in this.namespaces){this.namespaceAlias[this.namespaces[alias]]=alias;}},destroy:function(){this.xmldom=null;OpenLayers.Format.prototype.destroy.apply(this,arguments);},setNamespace:function(alias,uri){this.namespaces[alias]=uri;this.namespaceAlias[uri]=alias;},read:function(text){var index=text.indexOf('<');if(index>0){text=text.substring(index);}
59996 var node=OpenLayers.Util.Try(OpenLayers.Function.bind((function(){var xmldom;if(window.ActiveXObject&&!this.xmldom){xmldom=new ActiveXObject("Microsoft.XMLDOM");}else{xmldom=this.xmldom;}
59997 xmldom.loadXML(text);return xmldom;}),this),function(){return new DOMParser().parseFromString(text,'text/xml');},function(){var req=new XMLHttpRequest();req.open("GET","data:"+"text/xml"+";charset=utf-8,"+encodeURIComponent(text),false);if(req.overrideMimeType){req.overrideMimeType("text/xml");}
59998 req.send(null);return req.responseXML;});if(this.keepData){this.data=node;}
59999 return node;},write:function(node){var data;if(this.xmldom){data=node.xml;}else{var serializer=new XMLSerializer();if(node.nodeType==1){var doc=document.implementation.createDocument("","",null);if(doc.importNode){node=doc.importNode(node,true);}
60000 doc.appendChild(node);data=serializer.serializeToString(doc);}else{data=serializer.serializeToString(node);}}
60001 return data;},createElementNS:function(uri,name){var element;if(this.xmldom){if(typeof uri=="string"){element=this.xmldom.createNode(1,name,uri);}else{element=this.xmldom.createNode(1,name,"");}}else{element=document.createElementNS(uri,name);}
60002 return element;},createTextNode:function(text){var node;if(typeof text!=="string"){text=String(text);}
60003 if(this.xmldom){node=this.xmldom.createTextNode(text);}else{node=document.createTextNode(text);}
60004 return node;},getElementsByTagNameNS:function(node,uri,name){var elements=[];if(node.getElementsByTagNameNS){elements=node.getElementsByTagNameNS(uri,name);}else{var allNodes=node.getElementsByTagName("*");var potentialNode,fullName;for(var i=0,len=allNodes.length;i<len;++i){potentialNode=allNodes[i];fullName=(potentialNode.prefix)?(potentialNode.prefix+":"+name):name;if((name=="*")||(fullName==potentialNode.nodeName)){if((uri=="*")||(uri==potentialNode.namespaceURI)){elements.push(potentialNode);}}}}
60005 return elements;},getAttributeNodeNS:function(node,uri,name){var attributeNode=null;if(node.getAttributeNodeNS){attributeNode=node.getAttributeNodeNS(uri,name);}else{var attributes=node.attributes;var potentialNode,fullName;for(var i=0,len=attributes.length;i<len;++i){potentialNode=attributes[i];if(potentialNode.namespaceURI==uri){fullName=(potentialNode.prefix)?(potentialNode.prefix+":"+name):name;if(fullName==potentialNode.nodeName){attributeNode=potentialNode;break;}}}}
60006 return attributeNode;},getAttributeNS:function(node,uri,name){var attributeValue="";if(node.getAttributeNS){attributeValue=node.getAttributeNS(uri,name)||"";}else{var attributeNode=this.getAttributeNodeNS(node,uri,name);if(attributeNode){attributeValue=attributeNode.nodeValue;}}
60007 return attributeValue;},getChildValue:function(node,def){var value=def||"";if(node){for(var child=node.firstChild;child;child=child.nextSibling){switch(child.nodeType){case 3:case 4:value+=child.nodeValue;}}}
60008 return value;},concatChildValues:function(node,def){var value="";var child=node.firstChild;var childValue;while(child){childValue=child.nodeValue;if(childValue){value+=childValue;}
60009 child=child.nextSibling;}
60010 if(value==""&&def!=undefined){value=def;}
60011 return value;},isSimpleContent:function(node){var simple=true;for(var child=node.firstChild;child;child=child.nextSibling){if(child.nodeType===1){simple=false;break;}}
60012 return simple;},contentType:function(node){var simple=false,complex=false;var type=OpenLayers.Format.XML.CONTENT_TYPE.EMPTY;for(var child=node.firstChild;child;child=child.nextSibling){switch(child.nodeType){case 1:complex=true;break;case 8:break;default:simple=true;}
60013 if(complex&&simple){break;}}
60014 if(complex&&simple){type=OpenLayers.Format.XML.CONTENT_TYPE.MIXED;}else if(complex){return OpenLayers.Format.XML.CONTENT_TYPE.COMPLEX;}else if(simple){return OpenLayers.Format.XML.CONTENT_TYPE.SIMPLE;}
60015 return type;},hasAttributeNS:function(node,uri,name){var found=false;if(node.hasAttributeNS){found=node.hasAttributeNS(uri,name);}else{found=!!this.getAttributeNodeNS(node,uri,name);}
60016 return found;},setAttributeNS:function(node,uri,name,value){if(node.setAttributeNS){node.setAttributeNS(uri,name,value);}else{if(this.xmldom){if(uri){var attribute=node.ownerDocument.createNode(2,name,uri);attribute.nodeValue=value;node.setAttributeNode(attribute);}else{node.setAttribute(name,value);}}else{throw"setAttributeNS not implemented";}}},createElementNSPlus:function(name,options){options=options||{};var uri=options.uri||this.namespaces[options.prefix];if(!uri){var loc=name.indexOf(":");uri=this.namespaces[name.substring(0,loc)];}
60017 if(!uri){uri=this.namespaces[this.defaultPrefix];}
60018 var node=this.createElementNS(uri,name);if(options.attributes){this.setAttributes(node,options.attributes);}
60019 var value=options.value;if(value!=null){node.appendChild(this.createTextNode(value));}
60020 return node;},setAttributes:function(node,obj){var value,uri;for(var name in obj){if(obj[name]!=null&&obj[name].toString){value=obj[name].toString();uri=this.namespaces[name.substring(0,name.indexOf(":"))]||null;this.setAttributeNS(node,uri,name,value);}}},readNode:function(node,obj){if(!obj){obj={};}
60021 var group=this.readers[node.namespaceURI?this.namespaceAlias[node.namespaceURI]:this.defaultPrefix];if(group){var local=node.localName||node.nodeName.split(":").pop();var reader=group[local]||group["*"];if(reader){reader.apply(this,[node,obj]);}}
60022 return obj;},readChildNodes:function(node,obj){if(!obj){obj={};}
60023 var children=node.childNodes;var child;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){this.readNode(child,obj);}}
60024 return obj;},writeNode:function(name,obj,parent){var prefix,local;var split=name.indexOf(":");if(split>0){prefix=name.substring(0,split);local=name.substring(split+1);}else{if(parent){prefix=this.namespaceAlias[parent.namespaceURI];}else{prefix=this.defaultPrefix;}
60025 local=name;}
60026 var child=this.writers[prefix][local].apply(this,[obj]);if(parent){parent.appendChild(child);}
60027 return child;},getChildEl:function(node,name,uri){return node&&this.getThisOrNextEl(node.firstChild,name,uri);},getNextEl:function(node,name,uri){return node&&this.getThisOrNextEl(node.nextSibling,name,uri);},getThisOrNextEl:function(node,name,uri){outer:for(var sibling=node;sibling;sibling=sibling.nextSibling){switch(sibling.nodeType){case 1:if((!name||name===(sibling.localName||sibling.nodeName.split(":").pop()))&&(!uri||uri===sibling.namespaceURI)){break outer;}
60028 sibling=null;break outer;case 3:if(/^\s*$/.test(sibling.nodeValue)){break;}
60029 case 4:case 6:case 12:case 10:case 11:sibling=null;break outer;}}
60030 return sibling||null;},lookupNamespaceURI:function(node,prefix){var uri=null;if(node){if(node.lookupNamespaceURI){uri=node.lookupNamespaceURI(prefix);}else{outer:switch(node.nodeType){case 1:if(node.namespaceURI!==null&&node.prefix===prefix){uri=node.namespaceURI;break outer;}
60031 var len=node.attributes.length;if(len){var attr;for(var i=0;i<len;++i){attr=node.attributes[i];if(attr.prefix==="xmlns"&&attr.name==="xmlns:"+prefix){uri=attr.value||null;break outer;}else if(attr.name==="xmlns"&&prefix===null){uri=attr.value||null;break outer;}}}
60032 uri=this.lookupNamespaceURI(node.parentNode,prefix);break outer;case 2:uri=this.lookupNamespaceURI(node.ownerElement,prefix);break outer;case 9:uri=this.lookupNamespaceURI(node.documentElement,prefix);break outer;case 6:case 12:case 10:case 11:break outer;default:uri=this.lookupNamespaceURI(node.parentNode,prefix);break outer;}}}
60033 return uri;},CLASS_NAME:"OpenLayers.Format.XML"});OpenLayers.Format.XML.CONTENT_TYPE={EMPTY:0,SIMPLE:1,COMPLEX:2,MIXED:3};OpenLayers.Format.XML.lookupNamespaceURI=OpenLayers.Function.bind(OpenLayers.Format.XML.prototype.lookupNamespaceURI,OpenLayers.Format.XML.prototype);OpenLayers.Handler=OpenLayers.Class({id:null,control:null,map:null,keyMask:null,active:false,evt:null,initialize:function(control,callbacks,options){OpenLayers.Util.extend(this,options);this.control=control;this.callbacks=callbacks;var map=this.map||control.map;if(map){this.setMap(map);}
60034 this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},setMap:function(map){this.map=map;},checkModifiers:function(evt){if(this.keyMask==null){return true;}
60035 var keyModifiers=(evt.shiftKey?OpenLayers.Handler.MOD_SHIFT:0)|(evt.ctrlKey?OpenLayers.Handler.MOD_CTRL:0)|(evt.altKey?OpenLayers.Handler.MOD_ALT:0);return(keyModifiers==this.keyMask);},activate:function(){if(this.active){return false;}
60036 var events=OpenLayers.Events.prototype.BROWSER_EVENTS;for(var i=0,len=events.length;i<len;i++){if(this[events[i]]){this.register(events[i],this[events[i]]);}}
60037 this.active=true;return true;},deactivate:function(){if(!this.active){return false;}
60038 var events=OpenLayers.Events.prototype.BROWSER_EVENTS;for(var i=0,len=events.length;i<len;i++){if(this[events[i]]){this.unregister(events[i],this[events[i]]);}}
60039 this.active=false;return true;},callback:function(name,args){if(name&&this.callbacks[name]){this.callbacks[name].apply(this.control,args);}},register:function(name,method){this.map.events.registerPriority(name,this,method);this.map.events.registerPriority(name,this,this.setEvent);},unregister:function(name,method){this.map.events.unregister(name,this,method);this.map.events.unregister(name,this,this.setEvent);},setEvent:function(evt){this.evt=evt;return true;},destroy:function(){this.deactivate();this.control=this.map=null;},CLASS_NAME:"OpenLayers.Handler"});OpenLayers.Handler.MOD_NONE=0;OpenLayers.Handler.MOD_SHIFT=1;OpenLayers.Handler.MOD_CTRL=2;OpenLayers.Handler.MOD_ALT=4;OpenLayers.Map=OpenLayers.Class({Z_INDEX_BASE:{BaseLayer:100,Overlay:325,Feature:725,Popup:750,Control:1000},EVENT_TYPES:["preaddlayer","addlayer","removelayer","changelayer","movestart","move","moveend","zoomend","popupopen","popupclose","addmarker","removemarker","clearmarkers","mouseover","mouseout","mousemove","dragstart","drag","dragend","changebaselayer"],id:null,fractionalZoom:false,events:null,allOverlays:false,div:null,dragging:false,size:null,viewPortDiv:null,layerContainerOrigin:null,layerContainerDiv:null,layers:null,controls:null,popups:null,baseLayer:null,center:null,resolution:null,zoom:0,panRatio:1.5,viewRequestID:0,tileSize:null,projection:"EPSG:4326",units:'degrees',resolutions:null,maxResolution:1.40625,minResolution:null,maxScale:null,minScale:null,maxExtent:null,minExtent:null,restrictedExtent:null,numZoomLevels:16,theme:null,displayProjection:null,fallThrough:true,panTween:null,eventListeners:null,panMethod:OpenLayers.Easing.Expo.easeOut,panDuration:50,paddingForPopups:null,initialize:function(div,options){if(arguments.length===1&&typeof div==="object"){options=div;div=options&&options.div;}
60040 this.tileSize=new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH,OpenLayers.Map.TILE_HEIGHT);this.maxExtent=new OpenLayers.Bounds(-180,-90,180,90);this.paddingForPopups=new OpenLayers.Bounds(15,15,15,15);this.theme=OpenLayers._getScriptLocation()?OpenLayers._getScriptLocation()+'theme/default/style.css':null;OpenLayers.Util.extend(this,options);this.layers=[];this.id=OpenLayers.Util.createUniqueID("OpenLayers.Map_");this.div=OpenLayers.Util.getElement(div);if(!this.div){this.div=document.createElement("div");this.div.style.height="1px";this.div.style.width="1px";}
60041 OpenLayers.Element.addClass(this.div,'olMap');var id=this.id+"_OpenLayers_ViewPort";this.viewPortDiv=OpenLayers.Util.createDiv(id,null,null,null,"relative",null,"hidden");this.viewPortDiv.style.width="100%";this.viewPortDiv.style.height="100%";this.viewPortDiv.className="olMapViewport";this.div.appendChild(this.viewPortDiv);id=this.id+"_OpenLayers_Container";this.layerContainerDiv=OpenLayers.Util.createDiv(id);this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE['Popup']-1;this.viewPortDiv.appendChild(this.layerContainerDiv);this.events=new OpenLayers.Events(this,this.div,this.EVENT_TYPES,this.fallThrough,{includeXY:true});this.updateSize();if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}
60042 this.events.register("movestart",this,this.updateSize);if(OpenLayers.String.contains(navigator.appName,"Microsoft")){this.events.register("resize",this,this.updateSize);}else{this.updateSizeDestroy=OpenLayers.Function.bind(this.updateSize,this);OpenLayers.Event.observe(window,'resize',this.updateSizeDestroy);}
60043 if(this.theme){var addNode=true;var nodes=document.getElementsByTagName('link');for(var i=0,len=nodes.length;i<len;++i){if(OpenLayers.Util.isEquivalentUrl(nodes.item(i).href,this.theme)){addNode=false;break;}}
60044 if(addNode){var cssNode=document.createElement('link');cssNode.setAttribute('rel','stylesheet');cssNode.setAttribute('type','text/css');cssNode.setAttribute('href',this.theme);document.getElementsByTagName('head')[0].appendChild(cssNode);}}
60045 if(this.controls==null){if(OpenLayers.Control!=null){this.controls=[new OpenLayers.Control.Navigation(),new OpenLayers.Control.PanZoom(),new OpenLayers.Control.ArgParser(),new OpenLayers.Control.Attribution()];}else{this.controls=[];}}
60046 for(var i=0,len=this.controls.length;i<len;i++){this.addControlToMap(this.controls[i]);}
60047 this.popups=[];this.unloadDestroy=OpenLayers.Function.bind(this.destroy,this);OpenLayers.Event.observe(window,'unload',this.unloadDestroy);if(options&&options.layers){this.addLayers(options.layers);if(options.center){this.setCenter(options.center,options.zoom);}}},render:function(div){this.div=OpenLayers.Util.getElement(div);OpenLayers.Element.addClass(this.div,'olMap');this.events.attachToElement(this.div);this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);this.div.appendChild(this.viewPortDiv);this.updateSize();},unloadDestroy:null,updateSizeDestroy:null,destroy:function(){if(!this.unloadDestroy){return false;}
60048 if(this.panTween){this.panTween.stop();this.panTween=null;}
60049 OpenLayers.Event.stopObserving(window,'unload',this.unloadDestroy);this.unloadDestroy=null;if(this.updateSizeDestroy){OpenLayers.Event.stopObserving(window,'resize',this.updateSizeDestroy);}else{this.events.unregister("resize",this,this.updateSize);}
60050 this.paddingForPopups=null;if(this.controls!=null){for(var i=this.controls.length-1;i>=0;--i){this.controls[i].destroy();}
60051 this.controls=null;}
60052 if(this.layers!=null){for(var i=this.layers.length-1;i>=0;--i){this.layers[i].destroy(false);}
60053 this.layers=null;}
60054 if(this.viewPortDiv){this.div.removeChild(this.viewPortDiv);}
60055 this.viewPortDiv=null;if(this.eventListeners){this.events.un(this.eventListeners);this.eventListeners=null;}
60056 this.events.destroy();this.events=null;},setOptions:function(options){OpenLayers.Util.extend(this,options);},getTileSize:function(){return this.tileSize;},getBy:function(array,property,match){var test=(typeof match.test=="function");var found=OpenLayers.Array.filter(this[array],function(item){return item[property]==match||(test&&match.test(item[property]));});return found;},getLayersBy:function(property,match){return this.getBy("layers",property,match);},getLayersByName:function(match){return this.getLayersBy("name",match);},getLayersByClass:function(match){return this.getLayersBy("CLASS_NAME",match);},getControlsBy:function(property,match){return this.getBy("controls",property,match);},getControlsByClass:function(match){return this.getControlsBy("CLASS_NAME",match);},getLayer:function(id){var foundLayer=null;for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer.id==id){foundLayer=layer;break;}}
60057 return foundLayer;},setLayerZIndex:function(layer,zIdx){layer.setZIndex(this.Z_INDEX_BASE[layer.isBaseLayer?'BaseLayer':'Overlay']
60058 +zIdx*5);},resetLayersZIndex:function(){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];this.setLayerZIndex(layer,i);}},addLayer:function(layer){for(var i=0,len=this.layers.length;i<len;i++){if(this.layers[i]==layer){var msg=OpenLayers.i18n('layerAlreadyAdded',{'layerName':layer.name});OpenLayers.Console.warn(msg);return false;}}
60059 if(this.allOverlays){layer.isBaseLayer=false;}
60060 if(this.events.triggerEvent("preaddlayer",{layer:layer})===false){return;}
60061 layer.div.className="olLayerDiv";layer.div.style.overflow="";this.setLayerZIndex(layer,this.layers.length);if(layer.isFixed){this.viewPortDiv.appendChild(layer.div);}else{this.layerContainerDiv.appendChild(layer.div);}
60062 this.layers.push(layer);layer.setMap(this);if(layer.isBaseLayer||(this.allOverlays&&!this.baseLayer)){if(this.baseLayer==null){this.setBaseLayer(layer);}else{layer.setVisibility(false);}}else{layer.redraw();}
60063 this.events.triggerEvent("addlayer",{layer:layer});layer.afterAdd();},addLayers:function(layers){for(var i=0,len=layers.length;i<len;i++){this.addLayer(layers[i]);}},removeLayer:function(layer,setNewBaseLayer){if(setNewBaseLayer==null){setNewBaseLayer=true;}
60064 if(layer.isFixed){this.viewPortDiv.removeChild(layer.div);}else{this.layerContainerDiv.removeChild(layer.div);}
60065 OpenLayers.Util.removeItem(this.layers,layer);layer.removeMap(this);layer.map=null;if(this.baseLayer==layer){this.baseLayer=null;if(setNewBaseLayer){for(var i=0,len=this.layers.length;i<len;i++){var iLayer=this.layers[i];if(iLayer.isBaseLayer||this.allOverlays){this.setBaseLayer(iLayer);break;}}}}
60066 this.resetLayersZIndex();this.events.triggerEvent("removelayer",{layer:layer});},getNumLayers:function(){return this.layers.length;},getLayerIndex:function(layer){return OpenLayers.Util.indexOf(this.layers,layer);},setLayerIndex:function(layer,idx){var base=this.getLayerIndex(layer);if(idx<0){idx=0;}else if(idx>this.layers.length){idx=this.layers.length;}
60067 if(base!=idx){this.layers.splice(base,1);this.layers.splice(idx,0,layer);for(var i=0,len=this.layers.length;i<len;i++){this.setLayerZIndex(this.layers[i],i);}
60068 this.events.triggerEvent("changelayer",{layer:layer,property:"order"});if(this.allOverlays){if(idx===0){this.setBaseLayer(layer);}else if(this.baseLayer!==this.layers[0]){this.setBaseLayer(this.layers[0]);}}}},raiseLayer:function(layer,delta){var idx=this.getLayerIndex(layer)+delta;this.setLayerIndex(layer,idx);},setBaseLayer:function(newBaseLayer){if(newBaseLayer!=this.baseLayer){if(OpenLayers.Util.indexOf(this.layers,newBaseLayer)!=-1){var center=this.getCenter();var newResolution=OpenLayers.Util.getResolutionFromScale(this.getScale(),newBaseLayer.units);if(this.baseLayer!=null&&!this.allOverlays){this.baseLayer.setVisibility(false);}
60069 this.baseLayer=newBaseLayer;this.viewRequestID++;if(!this.allOverlays||this.baseLayer.visibility){this.baseLayer.setVisibility(true);}
60070 if(center!=null){var newZoom=this.getZoomForResolution(newResolution||this.resolution,true);this.setCenter(center,newZoom,false,true);}
60071 this.events.triggerEvent("changebaselayer",{layer:this.baseLayer});}}},addControl:function(control,px){this.controls.push(control);this.addControlToMap(control,px);},addControls:function(controls,pixels){var pxs=(arguments.length===1)?[]:pixels;for(var i=0,len=controls.length;i<len;i++){var ctrl=controls[i];var px=(pxs[i])?pxs[i]:null;this.addControl(ctrl,px);}},addControlToMap:function(control,px){control.outsideViewport=(control.div!=null);if(this.displayProjection&&!control.displayProjection){control.displayProjection=this.displayProjection;}
60072 control.setMap(this);var div=control.draw(px);if(div){if(!control.outsideViewport){div.style.zIndex=this.Z_INDEX_BASE['Control']+
60073 this.controls.length;this.viewPortDiv.appendChild(div);}}
60074 if(control.autoActivate){control.activate();}},getControl:function(id){var returnControl=null;for(var i=0,len=this.controls.length;i<len;i++){var control=this.controls[i];if(control.id==id){returnControl=control;break;}}
60075 return returnControl;},removeControl:function(control){if((control)&&(control==this.getControl(control.id))){if(control.div&&(control.div.parentNode==this.viewPortDiv)){this.viewPortDiv.removeChild(control.div);}
60076 OpenLayers.Util.removeItem(this.controls,control);}},addPopup:function(popup,exclusive){if(exclusive){for(var i=this.popups.length-1;i>=0;--i){this.removePopup(this.popups[i]);}}
60077 popup.map=this;this.popups.push(popup);var popupDiv=popup.draw();if(popupDiv){popupDiv.style.zIndex=this.Z_INDEX_BASE['Popup']+
60078 this.popups.length;this.layerContainerDiv.appendChild(popupDiv);}},removePopup:function(popup){OpenLayers.Util.removeItem(this.popups,popup);if(popup.div){try{this.layerContainerDiv.removeChild(popup.div);}
60079 catch(e){}}
60080 popup.map=null;},getSize:function(){var size=null;if(this.size!=null){size=this.size.clone();}
60081 return size;},updateSize:function(){var newSize=this.getCurrentSize();if(newSize&&!isNaN(newSize.h)&&!isNaN(newSize.w)){this.events.clearMouseCache();var oldSize=this.getSize();if(oldSize==null){this.size=oldSize=newSize;}
60082 if(!newSize.equals(oldSize)){this.size=newSize;for(var i=0,len=this.layers.length;i<len;i++){this.layers[i].onMapResize();}
60083 var center=this.getCenter();if(this.baseLayer!=null&&center!=null){var zoom=this.getZoom();this.zoom=null;this.setCenter(center,zoom);}}}},getCurrentSize:function(){var size=new OpenLayers.Size(this.div.clientWidth,this.div.clientHeight);if(size.w==0&&size.h==0||isNaN(size.w)&&isNaN(size.h)){size.w=this.div.offsetWidth;size.h=this.div.offsetHeight;}
60084 if(size.w==0&&size.h==0||isNaN(size.w)&&isNaN(size.h)){size.w=parseInt(this.div.style.width);size.h=parseInt(this.div.style.height);}
60085 return size;},calculateBounds:function(center,resolution){var extent=null;if(center==null){center=this.getCenter();}
60086 if(resolution==null){resolution=this.getResolution();}
60087 if((center!=null)&&(resolution!=null)){var size=this.getSize();var w_deg=size.w*resolution;var h_deg=size.h*resolution;extent=new OpenLayers.Bounds(center.lon-w_deg/2,center.lat-h_deg/2,center.lon+w_deg/2,center.lat+h_deg/2);}
60088 return extent;},getCenter:function(){var center=null;if(this.center){center=this.center.clone();}
60089 return center;},getZoom:function(){return this.zoom;},pan:function(dx,dy,options){options=OpenLayers.Util.applyDefaults(options,{animate:true,dragging:false});var centerPx=this.getViewPortPxFromLonLat(this.getCenter());var newCenterPx=centerPx.add(dx,dy);if(!options.dragging||!newCenterPx.equals(centerPx)){var newCenterLonLat=this.getLonLatFromViewPortPx(newCenterPx);if(options.animate){this.panTo(newCenterLonLat);}else{this.setCenter(newCenterLonLat,null,options.dragging);}}},panTo:function(lonlat){if(this.panMethod&&this.getExtent().scale(this.panRatio).containsLonLat(lonlat)){if(!this.panTween){this.panTween=new OpenLayers.Tween(this.panMethod);}
60090 var center=this.getCenter();if(lonlat.lon==center.lon&&lonlat.lat==center.lat){return;}
60091 var from={lon:center.lon,lat:center.lat};var to={lon:lonlat.lon,lat:lonlat.lat};this.panTween.start(from,to,this.panDuration,{callbacks:{start:OpenLayers.Function.bind(function(lonlat){this.events.triggerEvent("movestart");},this),eachStep:OpenLayers.Function.bind(function(lonlat){lonlat=new OpenLayers.LonLat(lonlat.lon,lonlat.lat);this.moveTo(lonlat,this.zoom,{'dragging':true,'noEvent':true});},this),done:OpenLayers.Function.bind(function(lonlat){lonlat=new OpenLayers.LonLat(lonlat.lon,lonlat.lat);this.moveTo(lonlat,this.zoom,{'noEvent':true});this.events.triggerEvent("moveend");},this)}});}else{this.setCenter(lonlat);}},setCenter:function(lonlat,zoom,dragging,forceZoomChange){this.moveTo(lonlat,zoom,{'dragging':dragging,'forceZoomChange':forceZoomChange,'caller':'setCenter'});},moveTo:function(lonlat,zoom,options){if(!options){options={};}
60092 if(zoom!=null){zoom=parseFloat(zoom);if(!this.fractionalZoom){zoom=Math.round(zoom);}}
60093 var dragging=options.dragging;var forceZoomChange=options.forceZoomChange;var noEvent=options.noEvent;if(this.panTween&&options.caller=="setCenter"){this.panTween.stop();}
60094 if(!this.center&&!this.isValidLonLat(lonlat)){lonlat=this.maxExtent.getCenterLonLat();}
60095 if(this.restrictedExtent!=null){if(lonlat==null){lonlat=this.getCenter();}
60096 if(zoom==null){zoom=this.getZoom();}
60097 var resolution=this.getResolutionForZoom(zoom);var extent=this.calculateBounds(lonlat,resolution);if(!this.restrictedExtent.containsBounds(extent)){var maxCenter=this.restrictedExtent.getCenterLonLat();if(extent.getWidth()>this.restrictedExtent.getWidth()){lonlat=new OpenLayers.LonLat(maxCenter.lon,lonlat.lat);}else if(extent.left<this.restrictedExtent.left){lonlat=lonlat.add(this.restrictedExtent.left-
60098 extent.left,0);}else if(extent.right>this.restrictedExtent.right){lonlat=lonlat.add(this.restrictedExtent.right-
60099 extent.right,0);}
60100 if(extent.getHeight()>this.restrictedExtent.getHeight()){lonlat=new OpenLayers.LonLat(lonlat.lon,maxCenter.lat);}else if(extent.bottom<this.restrictedExtent.bottom){lonlat=lonlat.add(0,this.restrictedExtent.bottom-
60101 extent.bottom);}
60102 else if(extent.top>this.restrictedExtent.top){lonlat=lonlat.add(0,this.restrictedExtent.top-
60103 extent.top);}}}
60104 var zoomChanged=forceZoomChange||((this.isValidZoomLevel(zoom))&&(zoom!=this.getZoom()));var centerChanged=(this.isValidLonLat(lonlat))&&(!lonlat.equals(this.center));if(zoomChanged||centerChanged||!dragging){if(!this.dragging&&!noEvent){this.events.triggerEvent("movestart");}
60105 if(centerChanged){if((!zoomChanged)&&(this.center)){this.centerLayerContainer(lonlat);}
60106 this.center=lonlat.clone();}
60107 if((zoomChanged)||(this.layerContainerOrigin==null)){this.layerContainerOrigin=this.center.clone();this.layerContainerDiv.style.left="0px";this.layerContainerDiv.style.top="0px";}
60108 if(zoomChanged){this.zoom=zoom;this.resolution=this.getResolutionForZoom(zoom);this.viewRequestID++;}
60109 var bounds=this.getExtent();if(this.baseLayer.visibility){this.baseLayer.moveTo(bounds,zoomChanged,dragging);if(dragging){this.baseLayer.events.triggerEvent("move");}else{this.baseLayer.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});}}
60110 bounds=this.baseLayer.getExtent();for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer!==this.baseLayer&&!layer.isBaseLayer){var inRange=layer.calculateInRange();if(layer.inRange!=inRange){layer.inRange=inRange;if(!inRange){layer.display(false);}
60111 this.events.triggerEvent("changelayer",{layer:layer,property:"visibility"});}
60112 if(inRange&&layer.visibility){layer.moveTo(bounds,zoomChanged,dragging);if(dragging){layer.events.triggerEvent("move");}else{layer.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});}}}}
60113 if(zoomChanged){for(var i=0,len=this.popups.length;i<len;i++){this.popups[i].updatePosition();}}
60114 this.events.triggerEvent("move");if(zoomChanged){this.events.triggerEvent("zoomend");}}
60115 if(!dragging&&!noEvent){this.events.triggerEvent("moveend");}
60116 this.dragging=!!dragging;},centerLayerContainer:function(lonlat){var originPx=this.getViewPortPxFromLonLat(this.layerContainerOrigin);var newPx=this.getViewPortPxFromLonLat(lonlat);if((originPx!=null)&&(newPx!=null)){this.layerContainerDiv.style.left=Math.round(originPx.x-newPx.x)+"px";this.layerContainerDiv.style.top=Math.round(originPx.y-newPx.y)+"px";}},isValidZoomLevel:function(zoomLevel){return((zoomLevel!=null)&&(zoomLevel>=0)&&(zoomLevel<this.getNumZoomLevels()));},isValidLonLat:function(lonlat){var valid=false;if(lonlat!=null){var maxExtent=this.getMaxExtent();valid=maxExtent.containsLonLat(lonlat);}
60117 return valid;},getProjection:function(){var projection=this.getProjectionObject();return projection?projection.getCode():null;},getProjectionObject:function(){var projection=null;if(this.baseLayer!=null){projection=this.baseLayer.projection;}
60118 return projection;},getMaxResolution:function(){var maxResolution=null;if(this.baseLayer!=null){maxResolution=this.baseLayer.maxResolution;}
60119 return maxResolution;},getMaxExtent:function(options){var maxExtent=null;if(options&&options.restricted&&this.restrictedExtent){maxExtent=this.restrictedExtent;}else if(this.baseLayer!=null){maxExtent=this.baseLayer.maxExtent;}
60120 return maxExtent;},getNumZoomLevels:function(){var numZoomLevels=null;if(this.baseLayer!=null){numZoomLevels=this.baseLayer.numZoomLevels;}
60121 return numZoomLevels;},getExtent:function(){var extent=null;if(this.baseLayer!=null){extent=this.baseLayer.getExtent();}
60122 return extent;},getResolution:function(){var resolution=null;if(this.baseLayer!=null){resolution=this.baseLayer.getResolution();}else if(this.allOverlays===true&&this.layers.length>0){resolution=this.layers[0].getResolution();}
60123 return resolution;},getUnits:function(){var units=null;if(this.baseLayer!=null){units=this.baseLayer.units;}
60124 return units;},getScale:function(){var scale=null;if(this.baseLayer!=null){var res=this.getResolution();var units=this.baseLayer.units;scale=OpenLayers.Util.getScaleFromResolution(res,units);}
60125 return scale;},getZoomForExtent:function(bounds,closest){var zoom=null;if(this.baseLayer!=null){zoom=this.baseLayer.getZoomForExtent(bounds,closest);}
60126 return zoom;},getResolutionForZoom:function(zoom){var resolution=null;if(this.baseLayer){resolution=this.baseLayer.getResolutionForZoom(zoom);}
60127 return resolution;},getZoomForResolution:function(resolution,closest){var zoom=null;if(this.baseLayer!=null){zoom=this.baseLayer.getZoomForResolution(resolution,closest);}
60128 return zoom;},zoomTo:function(zoom){if(this.isValidZoomLevel(zoom)){this.setCenter(null,zoom);}},zoomIn:function(){this.zoomTo(this.getZoom()+1);},zoomOut:function(){this.zoomTo(this.getZoom()-1);},zoomToExtent:function(bounds,closest){var center=bounds.getCenterLonLat();if(this.baseLayer.wrapDateLine){var maxExtent=this.getMaxExtent();bounds=bounds.clone();while(bounds.right<bounds.left){bounds.right+=maxExtent.getWidth();}
60129 center=bounds.getCenterLonLat().wrapDateLine(maxExtent);}
60130 this.setCenter(center,this.getZoomForExtent(bounds,closest));},zoomToMaxExtent:function(options){var restricted=(options)?options.restricted:true;var maxExtent=this.getMaxExtent({'restricted':restricted});this.zoomToExtent(maxExtent);},zoomToScale:function(scale,closest){var res=OpenLayers.Util.getResolutionFromScale(scale,this.baseLayer.units);var size=this.getSize();var w_deg=size.w*res;var h_deg=size.h*res;var center=this.getCenter();var extent=new OpenLayers.Bounds(center.lon-w_deg/2,center.lat-h_deg/2,center.lon+w_deg/2,center.lat+h_deg/2);this.zoomToExtent(extent,closest);},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if(this.baseLayer!=null){lonlat=this.baseLayer.getLonLatFromViewPortPx(viewPortPx);}
60131 return lonlat;},getViewPortPxFromLonLat:function(lonlat){var px=null;if(this.baseLayer!=null){px=this.baseLayer.getViewPortPxFromLonLat(lonlat);}
60132 return px;},getLonLatFromPixel:function(px){return this.getLonLatFromViewPortPx(px);},getPixelFromLonLat:function(lonlat){var px=this.getViewPortPxFromLonLat(lonlat);px.x=Math.round(px.x);px.y=Math.round(px.y);return px;},getGeodesicPixelSize:function(px){var lonlat=px?this.getLonLatFromPixel(px):(this.getCenter()||new OpenLayers.LonLat(0,0));var res=this.getResolution();var left=lonlat.add(-res/2,0);var right=lonlat.add(res/2,0);var bottom=lonlat.add(0,-res/2);var top=lonlat.add(0,res/2);var dest=new OpenLayers.Projection("EPSG:4326");var source=this.getProjectionObject()||dest;if(!source.equals(dest)){left.transform(source,dest);right.transform(source,dest);bottom.transform(source,dest);top.transform(source,dest);}
60133 return new OpenLayers.Size(OpenLayers.Util.distVincenty(left,right),OpenLayers.Util.distVincenty(bottom,top));},getViewPortPxFromLayerPx:function(layerPx){var viewPortPx=null;if(layerPx!=null){var dX=parseInt(this.layerContainerDiv.style.left);var dY=parseInt(this.layerContainerDiv.style.top);viewPortPx=layerPx.add(dX,dY);}
60134 return viewPortPx;},getLayerPxFromViewPortPx:function(viewPortPx){var layerPx=null;if(viewPortPx!=null){var dX=-parseInt(this.layerContainerDiv.style.left);var dY=-parseInt(this.layerContainerDiv.style.top);layerPx=viewPortPx.add(dX,dY);if(isNaN(layerPx.x)||isNaN(layerPx.y)){layerPx=null;}}
60135 return layerPx;},getLonLatFromLayerPx:function(px){px=this.getViewPortPxFromLayerPx(px);return this.getLonLatFromViewPortPx(px);},getLayerPxFromLonLat:function(lonlat){var px=this.getPixelFromLonLat(lonlat);return this.getLayerPxFromViewPortPx(px);},CLASS_NAME:"OpenLayers.Map"});OpenLayers.Map.TILE_WIDTH=256;OpenLayers.Map.TILE_HEIGHT=256;OpenLayers.Marker=OpenLayers.Class({icon:null,lonlat:null,events:null,map:null,initialize:function(lonlat,icon){this.lonlat=lonlat;var newIcon=(icon)?icon:OpenLayers.Marker.defaultIcon();if(this.icon==null){this.icon=newIcon;}else{this.icon.url=newIcon.url;this.icon.size=newIcon.size;this.icon.offset=newIcon.offset;this.icon.calculateOffset=newIcon.calculateOffset;}
60136 this.events=new OpenLayers.Events(this,this.icon.imageDiv,null);},destroy:function(){this.erase();this.map=null;this.events.destroy();this.events=null;if(this.icon!=null){this.icon.destroy();this.icon=null;}},draw:function(px){return this.icon.draw(px);},erase:function(){if(this.icon!=null){this.icon.erase();}},moveTo:function(px){if((px!=null)&&(this.icon!=null)){this.icon.moveTo(px);}
60137 this.lonlat=this.map.getLonLatFromLayerPx(px);},isDrawn:function(){var isDrawn=(this.icon&&this.icon.isDrawn());return isDrawn;},onScreen:function(){var onScreen=false;if(this.map){var screenBounds=this.map.getExtent();onScreen=screenBounds.containsLonLat(this.lonlat);}
60138 return onScreen;},inflate:function(inflate){if(this.icon){var newSize=new OpenLayers.Size(this.icon.size.w*inflate,this.icon.size.h*inflate);this.icon.setSize(newSize);}},setOpacity:function(opacity){this.icon.setOpacity(opacity);},setUrl:function(url){this.icon.setUrl(url);},display:function(display){this.icon.display(display);},CLASS_NAME:"OpenLayers.Marker"});OpenLayers.Marker.defaultIcon=function(){var url=OpenLayers.Util.getImagesLocation()+"marker.png";var size=new OpenLayers.Size(21,25);var calculateOffset=function(size){return new OpenLayers.Pixel(-(size.w/2),-size.h);};return new OpenLayers.Icon(url,size,null,calculateOffset);};OpenLayers.Popup.FramedCloud=OpenLayers.Class(OpenLayers.Popup.Framed,{contentDisplayClass:"olFramedCloudPopupContent",autoSize:true,panMapIfOutOfView:true,imageSize:new OpenLayers.Size(1276,736),isAlphaImage:false,fixedRelativePosition:false,positionBlocks:{"tl":{'offset':new OpenLayers.Pixel(44,0),'padding':new OpenLayers.Bounds(8,40,8,9),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,51,22,0),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,50,0,0),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',19),anchor:new OpenLayers.Bounds(0,32,22,null),position:new OpenLayers.Pixel(0,-631)},{size:new OpenLayers.Size(22,18),anchor:new OpenLayers.Bounds(null,32,0,null),position:new OpenLayers.Pixel(-1238,-632)},{size:new OpenLayers.Size(81,35),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(0,-688)}]},"tr":{'offset':new OpenLayers.Pixel(-45,0),'padding':new OpenLayers.Bounds(8,40,8,9),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,51,22,0),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,50,0,0),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',19),anchor:new OpenLayers.Bounds(0,32,22,null),position:new OpenLayers.Pixel(0,-631)},{size:new OpenLayers.Size(22,19),anchor:new OpenLayers.Bounds(null,32,0,null),position:new OpenLayers.Pixel(-1238,-631)},{size:new OpenLayers.Size(81,35),anchor:new OpenLayers.Bounds(0,0,null,null),position:new OpenLayers.Pixel(-215,-687)}]},"bl":{'offset':new OpenLayers.Pixel(45,0),'padding':new OpenLayers.Bounds(8,9,8,40),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,21,22,32),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,21,0,32),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',21),anchor:new OpenLayers.Bounds(0,0,22,null),position:new OpenLayers.Pixel(0,-629)},{size:new OpenLayers.Size(22,21),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(-1238,-629)},{size:new OpenLayers.Size(81,33),anchor:new OpenLayers.Bounds(null,null,0,0),position:new OpenLayers.Pixel(-101,-674)}]},"br":{'offset':new OpenLayers.Pixel(-44,0),'padding':new OpenLayers.Bounds(8,9,8,40),'blocks':[{size:new OpenLayers.Size('auto','auto'),anchor:new OpenLayers.Bounds(0,21,22,32),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,'auto'),anchor:new OpenLayers.Bounds(null,21,0,32),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size('auto',21),anchor:new OpenLayers.Bounds(0,0,22,null),position:new OpenLayers.Pixel(0,-629)},{size:new OpenLayers.Size(22,21),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(-1238,-629)},{size:new OpenLayers.Size(81,33),anchor:new OpenLayers.Bounds(0,null,null,0),position:new OpenLayers.Pixel(-311,-674)}]}},minSize:new OpenLayers.Size(105,10),maxSize:new OpenLayers.Size(1200,660),initialize:function(id,lonlat,contentSize,contentHTML,anchor,closeBox,closeBoxCallback){this.imageSrc=OpenLayers.Util.getImagesLocation()+'cloud-popup-relative.png';OpenLayers.Popup.Framed.prototype.initialize.apply(this,arguments);this.contentDiv.className=this.contentDisplayClass;},destroy:function(){OpenLayers.Popup.Framed.prototype.destroy.apply(this,arguments);},CLASS_NAME:"OpenLayers.Popup.FramedCloud"});OpenLayers.Request={DEFAULT_CONFIG:{method:"GET",url:window.location.href,async:true,user:undefined,password:undefined,params:null,proxy:OpenLayers.ProxyHost,headers:{},data:null,callback:function(){},success:null,failure:null,scope:null},events:new OpenLayers.Events(this,null,["complete","success","failure"]),issue:function(config){var defaultConfig=OpenLayers.Util.extend(this.DEFAULT_CONFIG,{proxy:OpenLayers.ProxyHost});config=OpenLayers.Util.applyDefaults(config,defaultConfig);var request=new OpenLayers.Request.XMLHttpRequest();var url=config.url;if(config.params){var paramString=OpenLayers.Util.getParameterString(config.params);if(paramString.length>0){var separator=(url.indexOf('?')>-1)?'&':'?';url+=separator+paramString;}}
60139 if(config.proxy&&(url.indexOf("http")==0)){if(typeof config.proxy=="function"){url=config.proxy(url);}else{url=config.proxy+encodeURIComponent(url);}}
60140 request.open(config.method,url,config.async,config.user,config.password);for(var header in config.headers){request.setRequestHeader(header,config.headers[header]);}
60141 var events=this.events;var self=this;request.onreadystatechange=function(){if(request.readyState==OpenLayers.Request.XMLHttpRequest.DONE){var proceed=events.triggerEvent("complete",{request:request,config:config,requestUrl:url});if(proceed!==false){self.runCallbacks({request:request,config:config,requestUrl:url});}}};if(config.async===false){request.send(config.data);}else{window.setTimeout(function(){if(request._aborted!==true){request.send(config.data);}},0);}
60142 return request;},runCallbacks:function(options){var request=options.request;var config=options.config;var complete=(config.scope)?OpenLayers.Function.bind(config.callback,config.scope):config.callback;var success;if(config.success){success=(config.scope)?OpenLayers.Function.bind(config.success,config.scope):config.success;}
60143 var failure;if(config.failure){failure=(config.scope)?OpenLayers.Function.bind(config.failure,config.scope):config.failure;}
60144 complete(request);if(!request.status||(request.status>=200&&request.status<300)){this.events.triggerEvent("success",options);if(success){success(request);}}
60145 if(request.status&&(request.status<200||request.status>=300)){this.events.triggerEvent("failure",options);if(failure){failure(request);}}},GET:function(config){config=OpenLayers.Util.extend(config,{method:"GET"});return OpenLayers.Request.issue(config);},POST:function(config){config=OpenLayers.Util.extend(config,{method:"POST"});config.headers=config.headers?config.headers:{};if(!("CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(config.headers))){config.headers["Content-Type"]="application/xml";}
60146 return OpenLayers.Request.issue(config);},PUT:function(config){config=OpenLayers.Util.extend(config,{method:"PUT"});config.headers=config.headers?config.headers:{};if(!("CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(config.headers))){config.headers["Content-Type"]="application/xml";}
60147 return OpenLayers.Request.issue(config);},DELETE:function(config){config=OpenLayers.Util.extend(config,{method:"DELETE"});return OpenLayers.Request.issue(config);},HEAD:function(config){config=OpenLayers.Util.extend(config,{method:"HEAD"});return OpenLayers.Request.issue(config);},OPTIONS:function(config){config=OpenLayers.Util.extend(config,{method:"OPTIONS"});return OpenLayers.Request.issue(config);}};OpenLayers.Tile.Image=OpenLayers.Class(OpenLayers.Tile,{url:null,imgDiv:null,frame:null,layerAlphaHack:null,isBackBuffer:false,lastRatio:1,isFirstDraw:true,backBufferTile:null,initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.prototype.initialize.apply(this,arguments);this.url=url;this.frame=document.createElement('div');this.frame.style.overflow='hidden';this.frame.style.position='absolute';this.layerAlphaHack=this.layer.alpha&&OpenLayers.Util.alphaHack();},destroy:function(){if(this.imgDiv!=null){if(this.layerAlphaHack){OpenLayers.Event.stopObservingElement(this.imgDiv.childNodes[0]);}
60148 OpenLayers.Event.stopObservingElement(this.imgDiv);if(this.imgDiv.parentNode==this.frame){this.frame.removeChild(this.imgDiv);this.imgDiv.map=null;}
60149 this.imgDiv.urls=null;this.imgDiv.src=OpenLayers.Util.getImagesLocation()+"blank.gif";}
60150 this.imgDiv=null;if((this.frame!=null)&&(this.frame.parentNode==this.layer.div)){this.layer.div.removeChild(this.frame);}
60151 this.frame=null;if(this.backBufferTile){this.backBufferTile.destroy();this.backBufferTile=null;}
60152 this.layer.events.unregister("loadend",this,this.resetBackBuffer);OpenLayers.Tile.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile.Image(this.layer,this.position,this.bounds,this.url,this.size);}
60153 obj=OpenLayers.Tile.prototype.clone.apply(this,[obj]);obj.imgDiv=null;return obj;},draw:function(){if(this.layer!=this.layer.map.baseLayer&&this.layer.reproject){this.bounds=this.getBoundsFromBaseLayer(this.position);}
60154 var drawTile=OpenLayers.Tile.prototype.draw.apply(this,arguments);if((OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,this.layer.transitionEffect)!=-1)||this.layer.singleTile){if(drawTile){if(!this.backBufferTile){this.backBufferTile=this.clone();this.backBufferTile.hide();this.backBufferTile.isBackBuffer=true;this.events.register('loadend',this,this.resetBackBuffer);this.layer.events.register("loadend",this,this.resetBackBuffer);}
60155 this.startTransition();}else{if(this.backBufferTile){this.backBufferTile.clear();}}}else{if(drawTile&&this.isFirstDraw){this.events.register('loadend',this,this.showTile);this.isFirstDraw=false;}}
60156 if(!drawTile){return false;}
60157 if(this.isLoading){this.events.triggerEvent("reload");}else{this.isLoading=true;this.events.triggerEvent("loadstart");}
60158 return this.renderTile();},resetBackBuffer:function(){this.showTile();if(this.backBufferTile&&(this.isFirstDraw||!this.layer.numLoadingTiles)){this.isFirstDraw=false;var maxExtent=this.layer.maxExtent;var withinMaxExtent=(maxExtent&&this.bounds.intersectsBounds(maxExtent,false));if(withinMaxExtent){this.backBufferTile.position=this.position;this.backBufferTile.bounds=this.bounds;this.backBufferTile.size=this.size;this.backBufferTile.imageSize=this.layer.getImageSize(this.bounds)||this.size;this.backBufferTile.imageOffset=this.layer.imageOffset;this.backBufferTile.resolution=this.layer.getResolution();this.backBufferTile.renderTile();}
60159 this.backBufferTile.hide();}},renderTile:function(){if(this.imgDiv==null){this.initImgDiv();}
60160 this.imgDiv.viewRequestID=this.layer.map.viewRequestID;if(this.layer.async){this.layer.getURLasync(this.bounds,this,"url",this.positionImage);}else{if(this.layer.url instanceof Array){this.imgDiv.urls=this.layer.url.slice();}
60161 this.url=this.layer.getURL(this.bounds);this.positionImage();}
60162 return true;},positionImage:function(){if(this.layer===null){return;}
60163 OpenLayers.Util.modifyDOMElement(this.frame,null,this.position,this.size);var imageSize=this.layer.getImageSize(this.bounds);if(this.layerAlphaHack){OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv,null,null,imageSize,this.url);}else{OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,imageSize);this.imgDiv.src=this.url;}},clear:function(){if(this.imgDiv){this.hide();if(OpenLayers.Tile.Image.useBlankTile){this.imgDiv.src=OpenLayers.Util.getImagesLocation()+"blank.gif";}}},initImgDiv:function(){var offset=this.layer.imageOffset;var size=this.layer.getImageSize(this.bounds);if(this.layerAlphaHack){this.imgDiv=OpenLayers.Util.createAlphaImageDiv(null,offset,size,null,"relative",null,null,null,true);}else{this.imgDiv=OpenLayers.Util.createImage(null,offset,size,null,"relative",null,null,true);}
60164 this.imgDiv.className='olTileImage';this.frame.style.zIndex=this.isBackBuffer?0:1;this.frame.appendChild(this.imgDiv);this.layer.div.appendChild(this.frame);if(this.layer.opacity!=null){OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,null,null,null,null,this.layer.opacity);}
60165 this.imgDiv.map=this.layer.map;var onload=function(){if(this.isLoading){this.isLoading=false;this.events.triggerEvent("loadend");}};if(this.layerAlphaHack){OpenLayers.Event.observe(this.imgDiv.childNodes[0],'load',OpenLayers.Function.bind(onload,this));}else{OpenLayers.Event.observe(this.imgDiv,'load',OpenLayers.Function.bind(onload,this));}
60166 var onerror=function(){if(this.imgDiv._attempts>OpenLayers.IMAGE_RELOAD_ATTEMPTS){onload.call(this);}};OpenLayers.Event.observe(this.imgDiv,"error",OpenLayers.Function.bind(onerror,this));},checkImgURL:function(){if(this.layer){var loaded=this.layerAlphaHack?this.imgDiv.firstChild.src:this.imgDiv.src;if(!OpenLayers.Util.isEquivalentUrl(loaded,this.url)){this.hide();}}},startTransition:function(){if(!this.backBufferTile||!this.backBufferTile.imgDiv){return;}
60167 var ratio=1;if(this.backBufferTile.resolution){ratio=this.backBufferTile.resolution/this.layer.getResolution();}
60168 if(ratio!=this.lastRatio){if(this.layer.transitionEffect=='resize'){var upperLeft=new OpenLayers.LonLat(this.backBufferTile.bounds.left,this.backBufferTile.bounds.top);var size=new OpenLayers.Size(this.backBufferTile.size.w*ratio,this.backBufferTile.size.h*ratio);var px=this.layer.map.getLayerPxFromLonLat(upperLeft);OpenLayers.Util.modifyDOMElement(this.backBufferTile.frame,null,px,size);var imageSize=this.backBufferTile.imageSize;imageSize=new OpenLayers.Size(imageSize.w*ratio,imageSize.h*ratio);var imageOffset=this.backBufferTile.imageOffset;if(imageOffset){imageOffset=new OpenLayers.Pixel(imageOffset.x*ratio,imageOffset.y*ratio);}
60169 OpenLayers.Util.modifyDOMElement(this.backBufferTile.imgDiv,null,imageOffset,imageSize);this.backBufferTile.show();}}else{if(this.layer.singleTile){this.backBufferTile.show();}else{this.backBufferTile.hide();}}
60170 this.lastRatio=ratio;},show:function(){this.frame.style.display='';if(OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,this.layer.transitionEffect)!=-1){if(navigator.userAgent.toLowerCase().indexOf("gecko")!=-1){this.frame.scrollLeft=this.frame.scrollLeft;}}},hide:function(){this.frame.style.display='none';},CLASS_NAME:"OpenLayers.Tile.Image"});OpenLayers.Tile.Image.useBlankTile=(OpenLayers.Util.getBrowserName()=="safari"||OpenLayers.Util.getBrowserName()=="opera");OpenLayers.Control.OverviewMap=OpenLayers.Class(OpenLayers.Control,{element:null,ovmap:null,size:new OpenLayers.Size(180,90),layers:null,minRectSize:15,minRectDisplayClass:"RectReplacement",minRatio:8,maxRatio:32,mapOptions:null,autoPan:false,handlers:null,resolutionFactor:1,maximized:false,initialize:function(options){this.layers=[];this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,[options]);},destroy:function(){if(!this.mapDiv){return;}
60171 if(this.handlers.click){this.handlers.click.destroy();}
60172 if(this.handlers.drag){this.handlers.drag.destroy();}
60173 this.mapDiv.removeChild(this.extentRectangle);this.extentRectangle=null;if(this.rectEvents){this.rectEvents.destroy();this.rectEvents=null;}
60174 if(this.ovmap){this.ovmap.destroy();this.ovmap=null;}
60175 this.element.removeChild(this.mapDiv);this.mapDiv=null;this.div.removeChild(this.element);this.element=null;if(this.maximizeDiv){OpenLayers.Event.stopObservingElement(this.maximizeDiv);this.div.removeChild(this.maximizeDiv);this.maximizeDiv=null;}
60176 if(this.minimizeDiv){OpenLayers.Event.stopObservingElement(this.minimizeDiv);this.div.removeChild(this.minimizeDiv);this.minimizeDiv=null;}
60177 this.map.events.un({"moveend":this.update,"changebaselayer":this.baseLayerDraw,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!(this.layers.length>0)){if(this.map.baseLayer){var layer=this.map.baseLayer.clone();this.layers=[layer];}else{this.map.events.register("changebaselayer",this,this.baseLayerDraw);return this.div;}}
60178 this.element=document.createElement('div');this.element.className=this.displayClass+'Element';this.element.style.display='none';this.mapDiv=document.createElement('div');this.mapDiv.style.width=this.size.w+'px';this.mapDiv.style.height=this.size.h+'px';this.mapDiv.style.position='relative';this.mapDiv.style.overflow='hidden';this.mapDiv.id=OpenLayers.Util.createUniqueID('overviewMap');this.extentRectangle=document.createElement('div');this.extentRectangle.style.position='absolute';this.extentRectangle.style.zIndex=1000;this.extentRectangle.className=this.displayClass+'ExtentRectangle';this.mapDiv.appendChild(this.extentRectangle);this.element.appendChild(this.mapDiv);this.div.appendChild(this.element);if(!this.outsideViewport){this.div.className+=" "+this.displayClass+'Container';var imgLocation=OpenLayers.Util.getImagesLocation();var img=imgLocation+'layer-switcher-maximize.png';this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv(this.displayClass+'MaximizeButton',null,new OpenLayers.Size(18,18),img,'absolute');this.maximizeDiv.style.display='none';this.maximizeDiv.className=this.displayClass+'MaximizeButton';OpenLayers.Event.observe(this.maximizeDiv,'click',OpenLayers.Function.bindAsEventListener(this.maximizeControl,this));this.div.appendChild(this.maximizeDiv);var img=imgLocation+'layer-switcher-minimize.png';this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv('OpenLayers_Control_minimizeDiv',null,new OpenLayers.Size(18,18),img,'absolute');this.minimizeDiv.style.display='none';this.minimizeDiv.className=this.displayClass+'MinimizeButton';OpenLayers.Event.observe(this.minimizeDiv,'click',OpenLayers.Function.bindAsEventListener(this.minimizeControl,this));this.div.appendChild(this.minimizeDiv);var eventsToStop=['dblclick','mousedown'];for(var i=0,len=eventsToStop.length;i<len;i++){OpenLayers.Event.observe(this.maximizeDiv,eventsToStop[i],OpenLayers.Event.stop);OpenLayers.Event.observe(this.minimizeDiv,eventsToStop[i],OpenLayers.Event.stop);}
60179 this.minimizeControl();}else{this.element.style.display='';}
60180 if(this.map.getExtent()){this.update();}
60181 this.map.events.register('moveend',this,this.update);if(this.maximized){this.maximizeControl();}
60182 return this.div;},baseLayerDraw:function(){this.draw();this.map.events.unregister("changebaselayer",this,this.baseLayerDraw);},rectDrag:function(px){var deltaX=this.handlers.drag.last.x-px.x;var deltaY=this.handlers.drag.last.y-px.y;if(deltaX!=0||deltaY!=0){var rectTop=this.rectPxBounds.top;var rectLeft=this.rectPxBounds.left;var rectHeight=Math.abs(this.rectPxBounds.getHeight());var rectWidth=this.rectPxBounds.getWidth();var newTop=Math.max(0,(rectTop-deltaY));newTop=Math.min(newTop,this.ovmap.size.h-this.hComp-rectHeight);var newLeft=Math.max(0,(rectLeft-deltaX));newLeft=Math.min(newLeft,this.ovmap.size.w-this.wComp-rectWidth);this.setRectPxBounds(new OpenLayers.Bounds(newLeft,newTop+rectHeight,newLeft+rectWidth,newTop));}},mapDivClick:function(evt){var pxCenter=this.rectPxBounds.getCenterPixel();var deltaX=evt.xy.x-pxCenter.x;var deltaY=evt.xy.y-pxCenter.y;var top=this.rectPxBounds.top;var left=this.rectPxBounds.left;var height=Math.abs(this.rectPxBounds.getHeight());var width=this.rectPxBounds.getWidth();var newTop=Math.max(0,(top+deltaY));newTop=Math.min(newTop,this.ovmap.size.h-height);var newLeft=Math.max(0,(left+deltaX));newLeft=Math.min(newLeft,this.ovmap.size.w-width);this.setRectPxBounds(new OpenLayers.Bounds(newLeft,newTop+height,newLeft+width,newTop));this.updateMapToRect();},maximizeControl:function(e){this.element.style.display='';this.showToggle(false);if(e!=null){OpenLayers.Event.stop(e);}},minimizeControl:function(e){this.element.style.display='none';this.showToggle(true);if(e!=null){OpenLayers.Event.stop(e);}},showToggle:function(minimize){this.maximizeDiv.style.display=minimize?'':'none';this.minimizeDiv.style.display=minimize?'none':'';},update:function(){if(this.ovmap==null){this.createMap();}
60183 if(this.autoPan||!this.isSuitableOverview()){this.updateOverview();}
60184 this.updateRectToMap();},isSuitableOverview:function(){var mapExtent=this.map.getExtent();var maxExtent=this.map.maxExtent;var testExtent=new OpenLayers.Bounds(Math.max(mapExtent.left,maxExtent.left),Math.max(mapExtent.bottom,maxExtent.bottom),Math.min(mapExtent.right,maxExtent.right),Math.min(mapExtent.top,maxExtent.top));if(this.ovmap.getProjection()!=this.map.getProjection()){testExtent=testExtent.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}
60185 var resRatio=this.ovmap.getResolution()/this.map.getResolution();return((resRatio>this.minRatio)&&(resRatio<=this.maxRatio)&&(this.ovmap.getExtent().containsBounds(testExtent)));},updateOverview:function(){var mapRes=this.map.getResolution();var targetRes=this.ovmap.getResolution();var resRatio=targetRes/mapRes;if(resRatio>this.maxRatio){targetRes=this.minRatio*mapRes;}else if(resRatio<=this.minRatio){targetRes=this.maxRatio*mapRes;}
60186 var center;if(this.ovmap.getProjection()!=this.map.getProjection()){center=this.map.center.clone();center.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}else{center=this.map.center;}
60187 this.ovmap.setCenter(center,this.ovmap.getZoomForResolution(targetRes*this.resolutionFactor));this.updateRectToMap();},createMap:function(){var options=OpenLayers.Util.extend({controls:[],maxResolution:'auto',fallThrough:false},this.mapOptions);this.ovmap=new OpenLayers.Map(this.mapDiv,options);OpenLayers.Event.stopObserving(window,'unload',this.ovmap.unloadDestroy);this.ovmap.addLayers(this.layers);this.ovmap.zoomToMaxExtent();this.wComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-left-width'))+
60188 parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-right-width'));this.wComp=(this.wComp)?this.wComp:2;this.hComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-top-width'))+
60189 parseInt(OpenLayers.Element.getStyle(this.extentRectangle,'border-bottom-width'));this.hComp=(this.hComp)?this.hComp:2;this.handlers.drag=new OpenLayers.Handler.Drag(this,{move:this.rectDrag,done:this.updateMapToRect},{map:this.ovmap});this.handlers.click=new OpenLayers.Handler.Click(this,{"click":this.mapDivClick},{"single":true,"double":false,"stopSingle":true,"stopDouble":true,"pixelTolerance":1,map:this.ovmap});this.handlers.click.activate();this.rectEvents=new OpenLayers.Events(this,this.extentRectangle,null,true);this.rectEvents.register("mouseover",this,function(e){if(!this.handlers.drag.active&&!this.map.dragging){this.handlers.drag.activate();}});this.rectEvents.register("mouseout",this,function(e){if(!this.handlers.drag.dragging){this.handlers.drag.deactivate();}});if(this.ovmap.getProjection()!=this.map.getProjection()){var sourceUnits=this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units;var targetUnits=this.ovmap.getProjectionObject().getUnits()||this.ovmap.units||this.ovmap.baseLayer.units;this.resolutionFactor=sourceUnits&&targetUnits?OpenLayers.INCHES_PER_UNIT[sourceUnits]/OpenLayers.INCHES_PER_UNIT[targetUnits]:1;}},updateRectToMap:function(){var bounds;if(this.ovmap.getProjection()!=this.map.getProjection()){bounds=this.map.getExtent().transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject());}else{bounds=this.map.getExtent();}
60190 var pxBounds=this.getRectBoundsFromMapBounds(bounds);if(pxBounds){this.setRectPxBounds(pxBounds);}},updateMapToRect:function(){var lonLatBounds=this.getMapBoundsFromRectBounds(this.rectPxBounds);if(this.ovmap.getProjection()!=this.map.getProjection()){lonLatBounds=lonLatBounds.transform(this.ovmap.getProjectionObject(),this.map.getProjectionObject());}
60191 this.map.panTo(lonLatBounds.getCenterLonLat());},setRectPxBounds:function(pxBounds){var top=Math.max(pxBounds.top,0);var left=Math.max(pxBounds.left,0);var bottom=Math.min(pxBounds.top+Math.abs(pxBounds.getHeight()),this.ovmap.size.h-this.hComp);var right=Math.min(pxBounds.left+pxBounds.getWidth(),this.ovmap.size.w-this.wComp);var width=Math.max(right-left,0);var height=Math.max(bottom-top,0);if(width<this.minRectSize||height<this.minRectSize){this.extentRectangle.className=this.displayClass+
60192 this.minRectDisplayClass;var rLeft=left+(width/2)-(this.minRectSize/2);var rTop=top+(height/2)-(this.minRectSize/2);this.extentRectangle.style.top=Math.round(rTop)+'px';this.extentRectangle.style.left=Math.round(rLeft)+'px';this.extentRectangle.style.height=this.minRectSize+'px';this.extentRectangle.style.width=this.minRectSize+'px';}else{this.extentRectangle.className=this.displayClass+'ExtentRectangle';this.extentRectangle.style.top=Math.round(top)+'px';this.extentRectangle.style.left=Math.round(left)+'px';this.extentRectangle.style.height=Math.round(height)+'px';this.extentRectangle.style.width=Math.round(width)+'px';}
60193 this.rectPxBounds=new OpenLayers.Bounds(Math.round(left),Math.round(bottom),Math.round(right),Math.round(top));},getRectBoundsFromMapBounds:function(lonLatBounds){var leftBottomLonLat=new OpenLayers.LonLat(lonLatBounds.left,lonLatBounds.bottom);var rightTopLonLat=new OpenLayers.LonLat(lonLatBounds.right,lonLatBounds.top);var leftBottomPx=this.getOverviewPxFromLonLat(leftBottomLonLat);var rightTopPx=this.getOverviewPxFromLonLat(rightTopLonLat);var bounds=null;if(leftBottomPx&&rightTopPx){bounds=new OpenLayers.Bounds(leftBottomPx.x,leftBottomPx.y,rightTopPx.x,rightTopPx.y);}
60194 return bounds;},getMapBoundsFromRectBounds:function(pxBounds){var leftBottomPx=new OpenLayers.Pixel(pxBounds.left,pxBounds.bottom);var rightTopPx=new OpenLayers.Pixel(pxBounds.right,pxBounds.top);var leftBottomLonLat=this.getLonLatFromOverviewPx(leftBottomPx);var rightTopLonLat=this.getLonLatFromOverviewPx(rightTopPx);return new OpenLayers.Bounds(leftBottomLonLat.lon,leftBottomLonLat.lat,rightTopLonLat.lon,rightTopLonLat.lat);},getLonLatFromOverviewPx:function(overviewMapPx){var size=this.ovmap.size;var res=this.ovmap.getResolution();var center=this.ovmap.getExtent().getCenterLonLat();var delta_x=overviewMapPx.x-(size.w/2);var delta_y=overviewMapPx.y-(size.h/2);return new OpenLayers.LonLat(center.lon+delta_x*res,center.lat-delta_y*res);},getOverviewPxFromLonLat:function(lonlat){var res=this.ovmap.getResolution();var extent=this.ovmap.getExtent();var px=null;if(extent){px=new OpenLayers.Pixel(Math.round(1/res*(lonlat.lon-extent.left)),Math.round(1/res*(extent.top-lonlat.lat)));}
60195 return px;},CLASS_NAME:'OpenLayers.Control.OverviewMap'});OpenLayers.Feature=OpenLayers.Class({layer:null,id:null,lonlat:null,data:null,marker:null,popupClass:OpenLayers.Popup.AnchoredBubble,popup:null,initialize:function(layer,lonlat,data){this.layer=layer;this.lonlat=lonlat;this.data=(data!=null)?data:{};this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){if((this.layer!=null)&&(this.layer.map!=null)){if(this.popup!=null){this.layer.map.removePopup(this.popup);}}
60196 if(this.layer!=null&&this.marker!=null){this.layer.removeMarker(this.marker);}
60197 this.layer=null;this.id=null;this.lonlat=null;this.data=null;if(this.marker!=null){this.destroyMarker(this.marker);this.marker=null;}
60198 if(this.popup!=null){this.destroyPopup(this.popup);this.popup=null;}},onScreen:function(){var onScreen=false;if((this.layer!=null)&&(this.layer.map!=null)){var screenBounds=this.layer.map.getExtent();onScreen=screenBounds.containsLonLat(this.lonlat);}
60199 return onScreen;},createMarker:function(){if(this.lonlat!=null){this.marker=new OpenLayers.Marker(this.lonlat,this.data.icon);}
60200 return this.marker;},destroyMarker:function(){this.marker.destroy();},createPopup:function(closeBox){if(this.lonlat!=null){var id=this.id+"_popup";var anchor=(this.marker)?this.marker.icon:null;if(!this.popup){this.popup=new this.popupClass(id,this.lonlat,this.data.popupSize,this.data.popupContentHTML,anchor,closeBox);}
60201 if(this.data.overflow!=null){this.popup.contentDiv.style.overflow=this.data.overflow;}
60202 this.popup.feature=this;}
60203 return this.popup;},destroyPopup:function(){if(this.popup){this.popup.feature=null;this.popup.destroy();this.popup=null;}},CLASS_NAME:"OpenLayers.Feature"});OpenLayers.Format.CSWGetDomain.v2_0_2=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",csw:"http://www.opengis.net/cat/csw/2.0.2"},defaultPrefix:"csw",version:"2.0.2",schemaLocation:"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",PropertyName:null,ParameterName:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60204 if(data&&data.nodeType==9){data=data.documentElement;}
60205 var obj={};this.readNode(data,obj);return obj;},readers:{"csw":{"GetDomainResponse":function(node,obj){this.readChildNodes(node,obj);},"DomainValues":function(node,obj){if(!(obj.DomainValues instanceof Array)){obj.DomainValues=[];}
60206 var attrs=node.attributes;var domainValue={};for(var i=0,len=attrs.length;i<len;++i){domainValue[attrs[i].name]=attrs[i].nodeValue;}
60207 this.readChildNodes(node,domainValue);obj.DomainValues.push(domainValue);},"PropertyName":function(node,obj){obj.PropertyName=this.getChildValue(node);},"ParameterName":function(node,obj){obj.ParameterName=this.getChildValue(node);},"ListOfValues":function(node,obj){if(!(obj.ListOfValues instanceof Array)){obj.ListOfValues=[];}
60208 this.readChildNodes(node,obj.ListOfValues);},"Value":function(node,obj){var attrs=node.attributes;var value={}
60209 for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
60210 value.value=this.getChildValue(node);obj.push({Value:value});},"ConceptualScheme":function(node,obj){obj.ConceptualScheme={};this.readChildNodes(node,obj.ConceptualScheme);},"Name":function(node,obj){obj.Name=this.getChildValue(node);},"Document":function(node,obj){obj.Document=this.getChildValue(node);},"Authority":function(node,obj){obj.Authority=this.getChildValue(node);},"RangeOfValues":function(node,obj){obj.RangeOfValues={};this.readChildNodes(node,obj.RangeOfValues);},"MinValue":function(node,obj){var attrs=node.attributes;var value={}
60211 for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
60212 value.value=this.getChildValue(node);obj.MinValue=value;},"MaxValue":function(node,obj){var attrs=node.attributes;var value={}
60213 for(var i=0,len=attrs.length;i<len;++i){value[attrs[i].name]=attrs[i].nodeValue;}
60214 value.value=this.getChildValue(node);obj.MaxValue=value;}}},write:function(options){var node=this.writeNode("csw:GetDomain",options);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"csw":{"GetDomain":function(options){var node=this.createElementNSPlus("csw:GetDomain",{attributes:{service:"CSW",version:this.version}});if(options.PropertyName||this.PropertyName){this.writeNode("csw:PropertyName",options.PropertyName||this.PropertyName,node);}else if(options.ParameterName||this.ParameterName){this.writeNode("csw:ParameterName",options.ParameterName||this.ParameterName,node);}
60215 this.readChildNodes(node,options);return node;},"PropertyName":function(value){var node=this.createElementNSPlus("csw:PropertyName",{value:value});return node;},"ParameterName":function(value){var node=this.createElementNSPlus("csw:ParameterName",{value:value});return node;}}},CLASS_NAME:"OpenLayers.Format.CSWGetDomain.v2_0_2"});OpenLayers.Format.Context=OpenLayers.Class({version:null,layerOptions:null,layerParams:null,parser:null,initialize:function(options){OpenLayers.Util.extend(this,options);this.options=options;},read:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60216 var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");}
60217 var parser=this.getParser(version);var context=parser.read(data,options);var map;if(options&&options.map){this.context=context;if(options.map instanceof OpenLayers.Map){map=this.mergeContextToMap(context,options.map);}else{var mapOptions=options.map;if(OpenLayers.Util.isElement(mapOptions)||typeof mapOptions=="string"){mapOptions={div:mapOptions};}
60218 map=this.contextToMap(context,mapOptions);}}else{map=context;}
60219 return map;},getLayerFromContext:function(layerContext){var i,len;var options={queryable:layerContext.queryable,visibility:layerContext.visibility,maxExtent:layerContext.maxExtent,metadata:OpenLayers.Util.applyDefaults(layerContext.metadata,{styles:layerContext.styles}),numZoomLevels:layerContext.numZoomLevels,units:layerContext.units,isBaseLayer:layerContext.isBaseLayer,opacity:layerContext.opacity,displayInLayerSwitcher:layerContext.displayInLayerSwitcher,singleTile:layerContext.singleTile,tileSize:(layerContext.tileSize)?new OpenLayers.Size(layerContext.tileSize.width,layerContext.tileSize.height):undefined,minScale:layerContext.minScale||layerContext.maxScaleDenominator,maxScale:layerContext.maxScale||layerContext.minScaleDenominator};if(this.layerOptions){OpenLayers.Util.applyDefaults(options,this.layerOptions);}
60220 var params={layers:layerContext.name,transparent:layerContext.transparent,version:layerContext.version};if(layerContext.formats&&layerContext.formats.length>0){params.format=layerContext.formats[0].value;for(i=0,len=layerContext.formats.length;i<len;i++){var format=layerContext.formats[i];if(format.current==true){params.format=format.value;break;}}}
60221 if(layerContext.styles&&layerContext.styles.length>0){for(i=0,len=layerContext.styles.length;i<len;i++){var style=layerContext.styles[i];if(style.current==true){if(style.href){params.sld=style.href;}else if(style.body){params.sld_body=style.body;}else{params.styles=style.name;}
60222 break;}}}
60223 if(this.layerParams){OpenLayers.Util.applyDefaults(params,this.layerParams);}
60224 var layer=null;var service=layerContext.service;if(service==OpenLayers.Format.Context.serviceTypes.WFS){options.strategies=[new OpenLayers.Strategy.BBOX()];options.protocol=new OpenLayers.Protocol.WFS({url:layerContext.url,featurePrefix:layerContext.name.split(":")[0],featureType:layerContext.name.split(":").pop()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(service==OpenLayers.Format.Context.serviceTypes.KML){options.strategies=[new OpenLayers.Strategy.Fixed()];options.protocol=new OpenLayers.Protocol.HTTP({url:layerContext.url,format:new OpenLayers.Format.KML()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(service==OpenLayers.Format.Context.serviceTypes.GML){options.strategies=[new OpenLayers.Strategy.Fixed()];options.protocol=new OpenLayers.Protocol.HTTP({url:layerContext.url,format:new OpenLayers.Format.GML()});layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);}else if(layerContext.features){layer=new OpenLayers.Layer.Vector(layerContext.title||layerContext.name,options);layer.addFeatures(layerContext.features);}else if(layerContext.categoryLayer!==true){layer=new OpenLayers.Layer.WMS(layerContext.title||layerContext.name,layerContext.url,params,options);}
60225 return layer;},getLayersFromContext:function(layersContext){var layers=[];for(var i=0,len=layersContext.length;i<len;i++){var layer=this.getLayerFromContext(layersContext[i]);if(layer!==null){layers.push(layer);}}
60226 return layers;},contextToMap:function(context,options){options=OpenLayers.Util.applyDefaults({maxExtent:context.maxExtent,projection:context.projection},options);var map=new OpenLayers.Map(options);map.addLayers(this.getLayersFromContext(context.layersContext));map.setCenter(context.bounds.getCenterLonLat(),map.getZoomForExtent(context.bounds,true));return map;},mergeContextToMap:function(context,map){map.addLayers(this.getLayersFromContext(context.layersContext));return map;},write:function(obj,options){obj=this.toContext(obj);var version=options&&options.version;var parser=this.getParser(version);var context=parser.write(obj,options);return context;},CLASS_NAME:"OpenLayers.Format.Context"});OpenLayers.Format.Context.serviceTypes={"WMS":"urn:ogc:serviceType:WMS","WFS":"urn:ogc:serviceType:WFS","WCS":"urn:ogc:serviceType:WCS","GML":"urn:ogc:serviceType:GML","SLD":"urn:ogc:serviceType:SLD","FES":"urn:ogc:serviceType:FES","KML":"urn:ogc:serviceType:KML"};if(!OpenLayers.Format.OWSCommon){OpenLayers.Format.OWSCommon={};}
60227 OpenLayers.Format.OWSCommon.v1=OpenLayers.Class(OpenLayers.Format.XML,{regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},readers:{"ows":{"ServiceIdentification":function(node,obj){obj.serviceIdentification={};this.readChildNodes(node,obj.serviceIdentification);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,serviceIdentification){serviceIdentification["abstract"]=this.getChildValue(node);},"Keywords":function(node,serviceIdentification){serviceIdentification.keywords={};this.readChildNodes(node,serviceIdentification.keywords);},"Keyword":function(node,keywords){keywords[this.getChildValue(node)]=true;},"ServiceType":function(node,serviceIdentification){serviceIdentification.serviceType={codeSpace:node.getAttribute('codeSpace'),value:this.getChildValue(node)};},"ServiceTypeVersion":function(node,serviceIdentification){serviceIdentification.serviceTypeVersion=this.getChildValue(node);},"Fees":function(node,serviceIdentification){serviceIdentification.fees=this.getChildValue(node);},"AccessConstraints":function(node,serviceIdentification){serviceIdentification.accessConstraints=this.getChildValue(node);},"ServiceProvider":function(node,obj){obj.serviceProvider={};this.readChildNodes(node,obj.serviceProvider);},"ProviderName":function(node,serviceProvider){serviceProvider.providerName=this.getChildValue(node);},"ProviderSite":function(node,serviceProvider){serviceProvider.providerSite=this.getAttributeNS(node,this.namespaces.xlink,"href");},"ServiceContact":function(node,serviceProvider){serviceProvider.serviceContact={};this.readChildNodes(node,serviceProvider.serviceContact);},"IndividualName":function(node,serviceContact){serviceContact.individualName=this.getChildValue(node);},"PositionName":function(node,serviceContact){serviceContact.positionName=this.getChildValue(node);},"ContactInfo":function(node,serviceContact){serviceContact.contactInfo={};this.readChildNodes(node,serviceContact.contactInfo);},"Phone":function(node,contactInfo){contactInfo.phone={};this.readChildNodes(node,contactInfo.phone);},"Voice":function(node,phone){phone.voice=this.getChildValue(node);},"Address":function(node,contactInfo){contactInfo.address={};this.readChildNodes(node,contactInfo.address);},"DeliveryPoint":function(node,address){address.deliveryPoint=this.getChildValue(node);},"City":function(node,address){address.city=this.getChildValue(node);},"AdministrativeArea":function(node,address){address.administrativeArea=this.getChildValue(node);},"PostalCode":function(node,address){address.postalCode=this.getChildValue(node);},"Country":function(node,address){address.country=this.getChildValue(node);},"ElectronicMailAddress":function(node,address){address.electronicMailAddress=this.getChildValue(node);},"Role":function(node,serviceContact){serviceContact.role=this.getChildValue(node);},"OperationsMetadata":function(node,obj){obj.operationsMetadata={};this.readChildNodes(node,obj.operationsMetadata);},"Operation":function(node,operationsMetadata){var name=node.getAttribute("name");operationsMetadata[name]={};this.readChildNodes(node,operationsMetadata[name]);},"DCP":function(node,operation){operation.dcp={};this.readChildNodes(node,operation.dcp);},"HTTP":function(node,dcp){dcp.http={};this.readChildNodes(node,dcp.http);},"Get":function(node,http){http.get=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Post":function(node,http){http.post=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Parameter":function(node,operation){if(!operation.parameters){operation.parameters={};}
60228 var name=node.getAttribute("name");operation.parameters[name]={};this.readChildNodes(node,operation.parameters[name]);},"Value":function(node,allowedValues){allowedValues[this.getChildValue(node)]=true;},"OutputFormat":function(node,obj){obj.formats.push({value:this.getChildValue(node)});this.readChildNodes(node,obj);},"WGS84BoundingBox":function(node,obj){var boundingBox={};boundingBox.crs=node.getAttribute("crs");if(obj.BoundingBox){obj.BoundingBox.push(boundingBox);}else{obj.projection=boundingBox.crs;boundingBox=obj;}
60229 this.readChildNodes(node,boundingBox);},"BoundingBox":function(node,obj){this.readers['ows']['WGS84BoundingBox'].apply(this,[node,obj]);},"LowerCorner":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);obj.left=pointList[0];obj.bottom=pointList[1];},"UpperCorner":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);obj.right=pointList[0];obj.top=pointList[1];obj.bounds=new OpenLayers.Bounds(obj.left,obj.bottom,obj.right,obj.top);delete obj.left;delete obj.bottom;delete obj.right;delete obj.top;}}},writers:{"ows":{"BoundingBox":function(options){var node=this.createElementNSPlus("ows:BoundingBox",{attributes:{crs:options.projection}});this.writeNode("ows:LowerCorner",options,node);this.writeNode("ows:UpperCorner",options,node);return node;},"LowerCorner":function(options){var node=this.createElementNSPlus("ows:LowerCorner",{value:options.bounds.left+" "+options.bounds.bottom});return node;},"UpperCorner":function(options){var node=this.createElementNSPlus("ows:UpperCorner",{value:options.bounds.right+" "+options.bounds.top});return node;},"Title":function(title){var node=this.createElementNSPlus("ows:Title",{value:title});return node;},"OutputFormat":function(format){var node=this.createElementNSPlus("ows:OutputFormat",{value:format});return node;}}},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1"});OpenLayers.Format.SOSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60230 var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.SOSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a SOS capabilities parser for version "+version;}
60231 var parser=new constr(this.options);}
60232 var capabilities=parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.SOSCapabilities"});OpenLayers.Format.WFSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.0",version:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60233 var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
60234 var constr=OpenLayers.Format.WFSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a WFS capabilities parser for version "+version;}
60235 var parser=new constr(this.options);var capabilities=parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.WFSCapabilities"});OpenLayers.Format.WFSDescribeFeatureType=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xsd:"http://www.w3.org/2001/XMLSchema"},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},readers:{"xsd":{"schema":function(node,obj){var complexTypes=[];var customTypes={};var schema={complexTypes:complexTypes,customTypes:customTypes};this.readChildNodes(node,schema);var attributes=node.attributes;var attr,name;for(var i=0,len=attributes.length;i<len;++i){attr=attributes[i];name=attr.name;if(name.indexOf("xmlns")==0){this.setNamespace(name.split(":")[1]||"",attr.value);}else{obj[name]=attr.value;}}
60236 obj.featureTypes=complexTypes;obj.targetPrefix=this.namespaceAlias[obj.targetNamespace];var complexType,customType;for(var i=0,len=complexTypes.length;i<len;++i){complexType=complexTypes[i];customType=customTypes[complexType.typeName];if(customTypes[complexType.typeName]){complexType.typeName=customType.name;}}},"complexType":function(node,obj){var complexType={"typeName":node.getAttribute("name")};this.readChildNodes(node,complexType);obj.complexTypes.push(complexType);},"complexContent":function(node,obj){this.readChildNodes(node,obj);},"extension":function(node,obj){this.readChildNodes(node,obj);},"sequence":function(node,obj){var sequence={elements:[]};this.readChildNodes(node,sequence);obj.properties=sequence.elements;},"element":function(node,obj){if(obj.elements){var element={};var attributes=node.attributes;var attr;for(var i=0,len=attributes.length;i<len;++i){attr=attributes[i];element[attr.name]=attr.value;}
60237 var type=element.type;if(!type){type={};this.readChildNodes(node,type);element.restriction=type;element.type=type.base;}
60238 var fullType=type.base||type;element.localType=fullType.split(":").pop();obj.elements.push(element);}
60239 if(obj.complexTypes){var type=node.getAttribute("type");var localType=type.split(":").pop();obj.customTypes[localType]={"name":node.getAttribute("name"),"type":type};}},"simpleType":function(node,obj){this.readChildNodes(node,obj);},"restriction":function(node,obj){obj.base=node.getAttribute("base");this.readRestriction(node,obj);}}},readRestriction:function(node,obj){var children=node.childNodes;var child,nodeName,value;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){nodeName=child.nodeName.split(":").pop();value=child.getAttribute("value");if(!obj[nodeName]){obj[nodeName]=value;}else{if(typeof obj[nodeName]=="string"){obj[nodeName]=[obj[nodeName]];}
60240 obj[nodeName].push(value);}}}},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60241 if(data&&data.nodeType==9){data=data.documentElement;}
60242 var schema={};this.readNode(data,schema);return schema;},CLASS_NAME:"OpenLayers.Format.WFSDescribeFeatureType"});OpenLayers.Format.WFST.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",wfs:"http://www.opengis.net/wfs",gml:"http://www.opengis.net/gml",ogc:"http://www.opengis.net/ogc"},defaultPrefix:"wfs",version:null,schemaLocations:null,srsName:null,extractAttributes:true,xy:true,stateName:null,initialize:function(options){this.stateName={};this.stateName[OpenLayers.State.INSERT]="wfs:Insert";this.stateName[OpenLayers.State.UPDATE]="wfs:Update";this.stateName[OpenLayers.State.DELETE]="wfs:Delete";OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},getSrsName:function(feature,options){var srsName=options&&options.srsName;if(!srsName){if(feature&&feature.layer){srsName=feature.layer.projection.getCode();}else{srsName=this.srsName;}}
60243 return srsName;},read:function(data,options){options=options||{};OpenLayers.Util.applyDefaults(options,{output:"features"});if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60244 if(data&&data.nodeType==9){data=data.documentElement;}
60245 var obj={};if(data){this.readNode(data,obj);}
60246 if(obj.features&&options.output==="features"){obj=obj.features;}
60247 return obj;},readers:{"wfs":{"FeatureCollection":function(node,obj){obj.features=[];this.readChildNodes(node,obj);}}},write:function(features){var node=this.writeNode("wfs:Transaction",features);var value=this.schemaLocationAttr();if(value){this.setAttributeNS(node,this.namespaces["xsi"],"xsi:schemaLocation",value)}
60248 return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"wfs":{"GetFeature":function(options){var node=this.createElementNSPlus("wfs:GetFeature",{attributes:{service:"WFS",version:this.version,outputFormat:options&&options.outputFormat,maxFeatures:options&&options.maxFeatures,"xsi:schemaLocation":this.schemaLocationAttr(options)}});if(typeof this.featureType=="string"){this.writeNode("Query",options,node);}else{for(var i=0,len=this.featureType.length;i<len;i++){options.featureType=this.featureType[i];this.writeNode("Query",options,node);}}
60249 return node;},"Transaction":function(features){var node=this.createElementNSPlus("wfs:Transaction",{attributes:{service:"WFS",version:this.version}});if(features){var name,feature;for(var i=0,len=features.length;i<len;++i){feature=features[i];name=this.stateName[feature.state];if(name){this.writeNode(name,feature,node);}}}
60250 return node;},"Insert":function(feature){var node=this.createElementNSPlus("wfs:Insert");this.srsName=this.getSrsName(feature);this.writeNode("feature:_typeName",feature,node);return node;},"Update":function(feature){var node=this.createElementNSPlus("wfs:Update",{attributes:{typeName:(this.featureNS?this.featurePrefix+":":"")+
60251 this.featureType}});if(this.featureNS){node.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);}
60252 if(this.geometryName!==null){this.writeNode("Property",{name:this.geometryName,value:feature},node);}
60253 for(var key in feature.attributes){if(feature.attributes[key]!==undefined){this.writeNode("Property",{name:key,value:feature.attributes[key]},node);}}
60254 this.writeNode("ogc:Filter",new OpenLayers.Filter.FeatureId({fids:[feature.fid]}),node);return node;},"Property":function(obj){var node=this.createElementNSPlus("wfs:Property");this.writeNode("Name",obj.name,node);if(obj.value!==null){this.writeNode("Value",obj.value,node);}
60255 return node;},"Name":function(name){return this.createElementNSPlus("wfs:Name",{value:name});},"Value":function(obj){var node;if(obj instanceof OpenLayers.Feature.Vector){node=this.createElementNSPlus("wfs:Value");this.srsName=this.getSrsName(obj);var geom=this.writeNode("feature:_geometry",obj.geometry).firstChild;node.appendChild(geom);}else{node=this.createElementNSPlus("wfs:Value",{value:obj});}
60256 return node;},"Delete":function(feature){var node=this.createElementNSPlus("wfs:Delete",{attributes:{typeName:(this.featureNS?this.featurePrefix+":":"")+
60257 this.featureType}});if(this.featureNS){node.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);}
60258 this.writeNode("ogc:Filter",new OpenLayers.Filter.FeatureId({fids:[feature.fid]}),node);return node;}}},schemaLocationAttr:function(options){options=OpenLayers.Util.extend({featurePrefix:this.featurePrefix,schema:this.schema},options);var schemaLocations=OpenLayers.Util.extend({},this.schemaLocations);if(options.schema){schemaLocations[options.featurePrefix]=options.schema;}
60259 var parts=[];var uri;for(var key in schemaLocations){uri=this.namespaces[key];if(uri){parts.push(uri+" "+schemaLocations[key]);}}
60260 var value=parts.join(" ")||undefined;return value;},setFilterProperty:function(filter){if(filter.filters){for(var i=0,len=filter.filters.length;i<len;++i){this.setFilterProperty(filter.filters[i]);}}else{if(filter instanceof OpenLayers.Filter.Spatial){filter.property=this.geometryName;}}},CLASS_NAME:"OpenLayers.Format.WFST.v1"});OpenLayers.Format.WMSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.1",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60261 var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.WMSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw"Can't find a WMS capabilities parser for version "+version;}
60262 this.parser=new constr(this.options);}
60263 var capabilities=this.parser.read(data);capabilities.version=version;return capabilities;},CLASS_NAME:"OpenLayers.Format.WMSCapabilities"});OpenLayers.Format.WMSDescribeLayer=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.1.1",version:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60264 var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
60265 if(version=="1.1.1"||version=="1.1.0"){version="1.1";}
60266 var constructor=OpenLayers.Format.WMSDescribeLayer["v"+version.replace(/\./g,"_")];if(!constructor){throw"Can't find a WMS DescribeLayer parser for version "+
60267 version;}
60268 var parser=new constructor(this.options);var describelayer=parser.read(data);describelayer.version=version;return describelayer;},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer"});OpenLayers.Format.WMSGetFeatureInfo=OpenLayers.Class(OpenLayers.Format.XML,{layerIdentifier:'_layer',featureIdentifier:'_feature',regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},gmlFormat:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,arguments);OpenLayers.Util.extend(this,options);this.options=options;},read:function(data){var result;if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60269 var root=data.documentElement;if(root){var scope=this;var read=this["read_"+root.nodeName];if(read){result=read.call(this,root);}else{result=new OpenLayers.Format.GML((this.options?this.options:{})).read(data);}}else{result=data;}
60270 return result;},read_msGMLOutput:function(data){var response=[];var layerNodes=this.getSiblingNodesByTagCriteria(data,this.layerIdentifier);if(layerNodes){for(var i=0,len=layerNodes.length;i<len;++i){var node=layerNodes[i];var layerName=node.nodeName;if(node.prefix){layerName=layerName.split(':')[1];}
60271 var layerName=layerName.replace(this.layerIdentifier,'');var featureNodes=this.getSiblingNodesByTagCriteria(node,this.featureIdentifier);if(featureNodes){for(var j=0;j<featureNodes.length;j++){var featureNode=featureNodes[j];var geomInfo=this.parseGeometry(featureNode);var attributes=this.parseAttributes(featureNode);var feature=new OpenLayers.Feature.Vector(geomInfo.geometry,attributes,null);feature.bounds=geomInfo.bounds;feature.type=layerName;response.push(feature);}}}}
60272 return response;},read_FeatureInfoResponse:function(data){var response=[];var featureNodes=this.getElementsByTagNameNS(data,'*','FIELDS');for(var i=0,len=featureNodes.length;i<len;i++){var featureNode=featureNodes[i];var geom=null;var attributes={};for(var j=0,jlen=featureNode.attributes.length;j<jlen;j++){var attribute=featureNode.attributes[j];attributes[attribute.nodeName]=attribute.nodeValue;}
60273 response.push(new OpenLayers.Feature.Vector(geom,attributes,null));}
60274 return response;},getSiblingNodesByTagCriteria:function(node,criteria){var nodes=[];var children,tagName,n,matchNodes,child;if(node&&node.hasChildNodes()){children=node.childNodes;n=children.length;for(var k=0;k<n;k++){child=children[k];while(child&&child.nodeType!=1){child=child.nextSibling;k++;}
60275 tagName=(child?child.nodeName:'');if(tagName.length>0&&tagName.indexOf(criteria)>-1){nodes.push(child);}else{matchNodes=this.getSiblingNodesByTagCriteria(child,criteria);if(matchNodes.length>0){(nodes.length==0)?nodes=matchNodes:nodes.push(matchNodes);}}}}
60276 return nodes;},parseAttributes:function(node){var attributes={};if(node.nodeType==1){var children=node.childNodes;var n=children.length;for(var i=0;i<n;++i){var child=children[i];if(child.nodeType==1){var grandchildren=child.childNodes;if(grandchildren.length==1){var grandchild=grandchildren[0];if(grandchild.nodeType==3||grandchild.nodeType==4){var name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var value=grandchild.nodeValue.replace(this.regExes.trimSpace,"");attributes[name]=value;}}}}}
60277 return attributes;},parseGeometry:function(node){if(!this.gmlFormat){this.gmlFormat=new OpenLayers.Format.GML();}
60278 var feature=this.gmlFormat.parseFeature(node);var geometry,bounds=null;if(feature){geometry=feature.geometry&&feature.geometry.clone();bounds=feature.bounds&&feature.bounds.clone();feature.destroy();}
60279 return{geometry:geometry,bounds:bounds};},CLASS_NAME:"OpenLayers.Format.WMSGetFeatureInfo"});OpenLayers.Format.WMTSCapabilities=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,yx:{"urn:ogc:def:crs:EPSG::4326":true},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60280 var root=data.documentElement;var version=this.version||root.getAttribute("version")||this.defaultVersion;if(!this.parser||this.parser.version!==version){var constr=OpenLayers.Format.WMTSCapabilities["v"+version.replace(/\./g,"_")];if(!constr){throw new Error("Can't find a WMTS capabilities parser for version "+version);}
60281 this.parser=new constr(this.options);}
60282 return this.parser.read(data);},createLayer:function(capabilities,config){var layer;var required={layer:true,matrixSet:true};for(var prop in required){if(!(prop in config)){throw new Error("Missing property '"+prop+"' in layer configuration.");}}
60283 var contents=capabilities.contents;var matrixSet=contents.tileMatrixSets[config.matrixSet];var layers=contents.layers;var layerDef;for(var i=0,ii=contents.layers.length;i<ii;++i){if(contents.layers[i].identifier===config.layer){layerDef=contents.layers[i];break;}}
60284 if(layerDef&&matrixSet){var style;for(var i=0,ii=layerDef.styles.length;i<ii;++i){style=layerDef.styles[i];if(style.isDefault){break;}}
60285 layer=new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults(config,{url:capabilities.operationsMetadata.GetTile.dcp.http.get,name:layerDef.title,style:style,matrixIds:matrixSet.matrixIds}));}
60286 return layer;},CLASS_NAME:"OpenLayers.Format.WMTSCapabilities"});OpenLayers.Handler.Click=OpenLayers.Class(OpenLayers.Handler,{delay:300,single:true,'double':false,pixelTolerance:0,stopSingle:false,stopDouble:false,timerId:null,down:null,rightclickTimerId:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);if(this.pixelTolerance!=null){this.mousedown=function(evt){this.down=evt.xy;return true;};}},mousedown:null,mouseup:function(evt){var propagate=true;if(this.checkModifiers(evt)&&this.control.handleRightClicks&&OpenLayers.Event.isRightClick(evt)){propagate=this.rightclick(evt);}
60287 return propagate;},rightclick:function(evt){if(this.passesTolerance(evt)){if(this.rightclickTimerId!=null){this.clearTimer();this.callback('dblrightclick',[evt]);return!this.stopDouble;}else{var clickEvent=this['double']?OpenLayers.Util.extend({},evt):this.callback('rightclick',[evt]);var delayedRightCall=OpenLayers.Function.bind(this.delayedRightCall,this,clickEvent);this.rightclickTimerId=window.setTimeout(delayedRightCall,this.delay);}}
60288 return!this.stopSingle;},delayedRightCall:function(evt){this.rightclickTimerId=null;if(evt){this.callback('rightclick',[evt]);}
60289 return!this.stopSingle;},dblclick:function(evt){if(this.passesTolerance(evt)){if(this["double"]){this.callback('dblclick',[evt]);}
60290 this.clearTimer();}
60291 return!this.stopDouble;},click:function(evt){if(this.passesTolerance(evt)){if(this.timerId!=null){this.clearTimer();}else{var clickEvent=this.single?OpenLayers.Util.extend({},evt):null;this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,this,clickEvent),this.delay);}}
60292 return!this.stopSingle;},passesTolerance:function(evt){var passes=true;if(this.pixelTolerance!=null&&this.down){var dpx=Math.sqrt(Math.pow(this.down.x-evt.xy.x,2)+
60293 Math.pow(this.down.y-evt.xy.y,2));if(dpx>this.pixelTolerance){passes=false;}}
60294 return passes;},clearTimer:function(){if(this.timerId!=null){window.clearTimeout(this.timerId);this.timerId=null;}
60295 if(this.rightclickTimerId!=null){window.clearTimeout(this.rightclickTimerId);this.rightclickTimerId=null;}},delayedCall:function(evt){this.timerId=null;if(evt){this.callback('click',[evt]);}},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.clearTimer();this.down=null;deactivated=true;}
60296 return deactivated;},CLASS_NAME:"OpenLayers.Handler.Click"});OpenLayers.Handler.Drag=OpenLayers.Class(OpenLayers.Handler,{started:false,stopDown:true,dragging:false,last:null,start:null,oldOnselectstart:null,interval:0,timeoutId:null,documentDrag:false,documentEvents:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);},down:function(evt){},move:function(evt){},up:function(evt){},out:function(evt){},mousedown:function(evt){var propagate=true;this.dragging=false;if(this.checkModifiers(evt)&&OpenLayers.Event.isLeftClick(evt)){this.started=true;this.start=evt.xy;this.last=evt.xy;OpenLayers.Element.addClass(this.map.viewPortDiv,"olDragDown");this.down(evt);this.callback("down",[evt.xy]);OpenLayers.Event.stop(evt);if(!this.oldOnselectstart){this.oldOnselectstart=(document.onselectstart)?document.onselectstart:OpenLayers.Function.True;}
60297 document.onselectstart=OpenLayers.Function.False;propagate=!this.stopDown;}else{this.started=false;this.start=null;this.last=null;}
60298 return propagate;},mousemove:function(evt){if(this.started&&!this.timeoutId&&(evt.xy.x!=this.last.x||evt.xy.y!=this.last.y)){if(this.documentDrag===true&&this.documentEvents){if(evt.element===document){this.adjustXY(evt);this.setEvent(evt);}else{this.destroyDocumentEvents();}}
60299 if(this.interval>0){this.timeoutId=setTimeout(OpenLayers.Function.bind(this.removeTimeout,this),this.interval);}
60300 this.dragging=true;this.move(evt);this.callback("move",[evt.xy]);if(!this.oldOnselectstart){this.oldOnselectstart=document.onselectstart;document.onselectstart=OpenLayers.Function.False;}
60301 this.last=this.evt.xy;}
60302 return true;},removeTimeout:function(){this.timeoutId=null;},mouseup:function(evt){if(this.started){if(this.documentDrag===true&&this.documentEvents){this.adjustXY(evt);this.destroyDocumentEvents();}
60303 var dragged=(this.start!=this.last);this.started=false;this.dragging=false;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.up(evt);this.callback("up",[evt.xy]);if(dragged){this.callback("done",[evt.xy]);}
60304 document.onselectstart=this.oldOnselectstart;}
60305 return true;},mouseout:function(evt){if(this.started&&OpenLayers.Util.mouseLeft(evt,this.map.div)){if(this.documentDrag===true){this.documentEvents=new OpenLayers.Events(this,document,null,null,{includeXY:true});this.documentEvents.on({mousemove:this.mousemove,mouseup:this.mouseup});OpenLayers.Element.addClass(document.body,"olDragDown");}else{var dragged=(this.start!=this.last);this.started=false;this.dragging=false;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.out(evt);this.callback("out",[]);if(dragged){this.callback("done",[evt.xy]);}
60306 if(document.onselectstart){document.onselectstart=this.oldOnselectstart;}}}
60307 return true;},click:function(evt){return(this.start==this.last);},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.dragging=false;activated=true;}
60308 return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.started=false;this.dragging=false;this.start=null;this.last=null;deactivated=true;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");}
60309 return deactivated;},adjustXY:function(evt){var pos=OpenLayers.Util.pagePosition(this.map.div);evt.xy.x-=pos[0];evt.xy.y-=pos[1];},destroyDocumentEvents:function(){OpenLayers.Element.removeClass(document.body,"olDragDown");this.documentEvents.destroy();this.documentEvents=null;},CLASS_NAME:"OpenLayers.Handler.Drag"});OpenLayers.Handler.Feature=OpenLayers.Class(OpenLayers.Handler,{EVENTMAP:{'click':{'in':'click','out':'clickout'},'mousemove':{'in':'over','out':'out'},'dblclick':{'in':'dblclick','out':null},'mousedown':{'in':null,'out':null},'mouseup':{'in':null,'out':null}},feature:null,lastFeature:null,down:null,up:null,clickTolerance:4,geometryTypes:null,stopClick:true,stopDown:true,stopUp:false,initialize:function(control,layer,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,[control,callbacks,options]);this.layer=layer;},mousedown:function(evt){this.down=evt.xy;return this.handle(evt)?!this.stopDown:true;},mouseup:function(evt){this.up=evt.xy;return this.handle(evt)?!this.stopUp:true;},click:function(evt){return this.handle(evt)?!this.stopClick:true;},mousemove:function(evt){if(!this.callbacks['over']&&!this.callbacks['out']){return true;}
60310 this.handle(evt);return true;},dblclick:function(evt){return!this.handle(evt);},geometryTypeMatches:function(feature){return this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)>-1;},handle:function(evt){if(this.feature&&!this.feature.layer){this.feature=null;}
60311 var type=evt.type;var handled=false;var previouslyIn=!!(this.feature);var click=(type=="click"||type=="dblclick");this.feature=this.layer.getFeatureFromEvent(evt);if(this.feature&&!this.feature.layer){this.feature=null;}
60312 if(this.lastFeature&&!this.lastFeature.layer){this.lastFeature=null;}
60313 if(this.feature){var inNew=(this.feature!=this.lastFeature);if(this.geometryTypeMatches(this.feature)){if(previouslyIn&&inNew){if(this.lastFeature){this.triggerCallback(type,'out',[this.lastFeature]);}
60314 this.triggerCallback(type,'in',[this.feature]);}else if(!previouslyIn||click){this.triggerCallback(type,'in',[this.feature]);}
60315 this.lastFeature=this.feature;handled=true;}else{if(this.lastFeature&&(previouslyIn&&inNew||click)){this.triggerCallback(type,'out',[this.lastFeature]);}
60316 this.feature=null;}}else{if(this.lastFeature&&(previouslyIn||click)){this.triggerCallback(type,'out',[this.lastFeature]);}}
60317 return handled;},triggerCallback:function(type,mode,args){var key=this.EVENTMAP[type][mode];if(key){if(type=='click'&&this.up&&this.down){var dpx=Math.sqrt(Math.pow(this.up.x-this.down.x,2)+
60318 Math.pow(this.up.y-this.down.y,2));if(dpx<=this.clickTolerance){this.callback(key,args);}}else{this.callback(key,args);}}},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.moveLayerToTop();this.map.events.on({"removelayer":this.handleMapEvents,"changelayer":this.handleMapEvents,scope:this});activated=true;}
60319 return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.moveLayerBack();this.feature=null;this.lastFeature=null;this.down=null;this.up=null;this.map.events.un({"removelayer":this.handleMapEvents,"changelayer":this.handleMapEvents,scope:this});deactivated=true;}
60320 return deactivated;},handleMapEvents:function(evt){if(!evt.property||evt.property=="order"){this.moveLayerToTop();}},moveLayerToTop:function(){var index=Math.max(this.map.Z_INDEX_BASE['Feature']-1,this.layer.getZIndex())+1;this.layer.setZIndex(index);},moveLayerBack:function(){var index=this.layer.getZIndex()-1;if(index>=this.map.Z_INDEX_BASE['Feature']){this.layer.setZIndex(index);}else{this.map.setLayerZIndex(this.layer,this.map.getLayerIndex(this.layer));}},CLASS_NAME:"OpenLayers.Handler.Feature"});OpenLayers.Handler.Hover=OpenLayers.Class(OpenLayers.Handler,{delay:500,pixelTolerance:null,stopMove:false,px:null,timerId:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);},mousemove:function(evt){if(this.passesTolerance(evt.xy)){this.clearTimer();this.callback('move',[evt]);this.px=evt.xy;evt=OpenLayers.Util.extend({},evt);this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,this,evt),this.delay);}
60321 return!this.stopMove;},mouseout:function(evt){if(OpenLayers.Util.mouseLeft(evt,this.map.div)){this.clearTimer();this.callback('move',[evt]);}
60322 return true;},passesTolerance:function(px){var passes=true;if(this.pixelTolerance&&this.px){var dpx=Math.sqrt(Math.pow(this.px.x-px.x,2)+
60323 Math.pow(this.px.y-px.y,2));if(dpx<this.pixelTolerance){passes=false;}}
60324 return passes;},clearTimer:function(){if(this.timerId!=null){window.clearTimeout(this.timerId);this.timerId=null;}},delayedCall:function(evt){this.callback('pause',[evt]);},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.clearTimer();deactivated=true;}
60325 return deactivated;},CLASS_NAME:"OpenLayers.Handler.Hover"});OpenLayers.Handler.Keyboard=OpenLayers.Class(OpenLayers.Handler,{KEY_EVENTS:["keydown","keyup"],eventListener:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.eventListener=OpenLayers.Function.bindAsEventListener(this.handleKeyEvent,this);},destroy:function(){this.deactivate();this.eventListener=null;OpenLayers.Handler.prototype.destroy.apply(this,arguments);},activate:function(){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){for(var i=0,len=this.KEY_EVENTS.length;i<len;i++){OpenLayers.Event.observe(document,this.KEY_EVENTS[i],this.eventListener);}
60326 return true;}else{return false;}},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){for(var i=0,len=this.KEY_EVENTS.length;i<len;i++){OpenLayers.Event.stopObserving(document,this.KEY_EVENTS[i],this.eventListener);}
60327 deactivated=true;}
60328 return deactivated;},handleKeyEvent:function(evt){if(this.checkModifiers(evt)){this.callback(evt.type,[evt]);}},CLASS_NAME:"OpenLayers.Handler.Keyboard"});OpenLayers.Handler.MouseWheel=OpenLayers.Class(OpenLayers.Handler,{wheelListener:null,mousePosition:null,interval:0,delta:0,cumulative:true,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.wheelListener=OpenLayers.Function.bindAsEventListener(this.onWheelEvent,this);},destroy:function(){OpenLayers.Handler.prototype.destroy.apply(this,arguments);this.wheelListener=null;},onWheelEvent:function(e){if(!this.map||!this.checkModifiers(e)){return;}
60329 var overScrollableDiv=false;var overLayerDiv=false;var overMapDiv=false;var elem=OpenLayers.Event.element(e);while((elem!=null)&&!overMapDiv&&!overScrollableDiv){if(!overScrollableDiv){try{if(elem.currentStyle){overflow=elem.currentStyle["overflow"];}else{var style=document.defaultView.getComputedStyle(elem,null);var overflow=style.getPropertyValue("overflow");}
60330 overScrollableDiv=(overflow&&(overflow=="auto")||(overflow=="scroll"));}catch(err){}}
60331 if(!overLayerDiv){for(var i=0,len=this.map.layers.length;i<len;i++){if(elem==this.map.layers[i].div||elem==this.map.layers[i].pane){overLayerDiv=true;break;}}}
60332 overMapDiv=(elem==this.map.div);elem=elem.parentNode;}
60333 if(!overScrollableDiv&&overMapDiv){if(overLayerDiv){var delta=0;if(!e){e=window.event;}
60334 if(e.wheelDelta){delta=e.wheelDelta/120;if(window.opera&&window.opera.version()<9.2){delta=-delta;}}else if(e.detail){delta=-e.detail/3;}
60335 this.delta=this.delta+delta;if(this.interval){window.clearTimeout(this._timeoutId);this._timeoutId=window.setTimeout(OpenLayers.Function.bind(function(){this.wheelZoom(e);},this),this.interval);}else{this.wheelZoom(e);}}
60336 OpenLayers.Event.stop(e);}},wheelZoom:function(e){var delta=this.delta;this.delta=0;if(delta){if(this.mousePosition){e.xy=this.mousePosition;}
60337 if(!e.xy){e.xy=this.map.getPixelFromLonLat(this.map.getCenter());}
60338 if(delta<0){this.callback("down",[e,this.cumulative?delta:-1]);}else{this.callback("up",[e,this.cumulative?delta:1]);}}},mousemove:function(evt){this.mousePosition=evt.xy;},activate:function(evt){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){var wheelListener=this.wheelListener;OpenLayers.Event.observe(window,"DOMMouseScroll",wheelListener);OpenLayers.Event.observe(window,"mousewheel",wheelListener);OpenLayers.Event.observe(document,"mousewheel",wheelListener);return true;}else{return false;}},deactivate:function(evt){if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){var wheelListener=this.wheelListener;OpenLayers.Event.stopObserving(window,"DOMMouseScroll",wheelListener);OpenLayers.Event.stopObserving(window,"mousewheel",wheelListener);OpenLayers.Event.stopObserving(document,"mousewheel",wheelListener);return true;}else{return false;}},CLASS_NAME:"OpenLayers.Handler.MouseWheel"});OpenLayers.Layer=OpenLayers.Class({id:null,name:null,div:null,opacity:null,alwaysInRange:null,EVENT_TYPES:["loadstart","loadend","loadcancel","visibilitychanged","move","moveend"],RESOLUTION_PROPERTIES:['scales','resolutions','maxScale','minScale','maxResolution','minResolution','numZoomLevels','maxZoomLevel'],events:null,map:null,isBaseLayer:false,alpha:false,displayInLayerSwitcher:true,visibility:true,attribution:null,inRange:false,imageSize:null,imageOffset:null,options:null,eventListeners:null,gutter:0,projection:null,units:null,scales:null,resolutions:null,maxExtent:null,minExtent:null,maxResolution:null,minResolution:null,numZoomLevels:null,minScale:null,maxScale:null,displayOutsideMaxExtent:false,wrapDateLine:false,transitionEffect:null,SUPPORTED_TRANSITIONS:['resize'],metadata:{},initialize:function(name,options){this.addOptions(options);this.name=name;if(this.id==null){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");this.div=OpenLayers.Util.createDiv(this.id);this.div.style.width="100%";this.div.style.height="100%";this.div.dir="ltr";this.events=new OpenLayers.Events(this,this.div,this.EVENT_TYPES);if(this.eventListeners instanceof Object){this.events.on(this.eventListeners);}}
60339 if(this.wrapDateLine){this.displayOutsideMaxExtent=true;}},destroy:function(setNewBaseLayer){if(setNewBaseLayer==null){setNewBaseLayer=true;}
60340 if(this.map!=null){this.map.removeLayer(this,setNewBaseLayer);}
60341 this.projection=null;this.map=null;this.name=null;this.div=null;this.options=null;if(this.events){if(this.eventListeners){this.events.un(this.eventListeners);}
60342 this.events.destroy();}
60343 this.eventListeners=null;this.events=null;},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer(this.name,this.getOptions());}
60344 OpenLayers.Util.applyDefaults(obj,this);obj.map=null;return obj;},getOptions:function(){var options={};for(var o in this.options){options[o]=this[o];}
60345 return options;},setName:function(newName){if(newName!=this.name){this.name=newName;if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"name"});}}},addOptions:function(newOptions){if(this.options==null){this.options={};}
60346 OpenLayers.Util.extend(this.options,newOptions);OpenLayers.Util.extend(this,newOptions);if(typeof this.projection=="string"){this.projection=new OpenLayers.Projection(this.projection);}
60347 if(this.projection&&this.projection.getUnits()){this.units=this.projection.getUnits();}
60348 if(this.map){var properties=this.RESOLUTION_PROPERTIES.concat(["projection","units","minExtent","maxExtent"]);for(var o in newOptions){if(newOptions.hasOwnProperty(o)&&OpenLayers.Util.indexOf(properties,o)>=0){this.initResolutions();break;}}}},onMapResize:function(){},redraw:function(){var redrawn=false;if(this.map){this.inRange=this.calculateInRange();var extent=this.getExtent();if(extent&&this.inRange&&this.visibility){var zoomChanged=true;this.moveTo(extent,zoomChanged,false);this.events.triggerEvent("moveend",{"zoomChanged":zoomChanged});redrawn=true;}}
60349 return redrawn;},moveTo:function(bounds,zoomChanged,dragging){var display=this.visibility;if(!this.isBaseLayer){display=display&&this.inRange;}
60350 this.display(display);},setMap:function(map){if(this.map==null){this.map=map;this.maxExtent=this.maxExtent||this.map.maxExtent;this.minExtent=this.minExtent||this.map.minExtent;this.projection=this.projection||this.map.projection;if(typeof this.projection=="string"){this.projection=new OpenLayers.Projection(this.projection);}
60351 this.units=this.projection.getUnits()||this.units||this.map.units;this.initResolutions();if(!this.isBaseLayer){this.inRange=this.calculateInRange();var show=((this.visibility)&&(this.inRange));this.div.style.display=show?"":"none";}
60352 this.setTileSize();}},afterAdd:function(){},removeMap:function(map){},getImageSize:function(bounds){return(this.imageSize||this.tileSize);},setTileSize:function(size){var tileSize=(size)?size:((this.tileSize)?this.tileSize:this.map.getTileSize());this.tileSize=tileSize;if(this.gutter){this.imageOffset=new OpenLayers.Pixel(-this.gutter,-this.gutter);this.imageSize=new OpenLayers.Size(tileSize.w+(2*this.gutter),tileSize.h+(2*this.gutter));}},getVisibility:function(){return this.visibility;},setVisibility:function(visibility){if(visibility!=this.visibility){this.visibility=visibility;this.display(visibility);this.redraw();if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"visibility"});}
60353 this.events.triggerEvent("visibilitychanged");}},display:function(display){if(display!=(this.div.style.display!="none")){this.div.style.display=(display&&this.calculateInRange())?"block":"none";}},calculateInRange:function(){var inRange=false;if(this.alwaysInRange){inRange=true;}else{if(this.map){var resolution=this.map.getResolution();inRange=((resolution>=this.minResolution)&&(resolution<=this.maxResolution));}}
60354 return inRange;},setIsBaseLayer:function(isBaseLayer){if(isBaseLayer!=this.isBaseLayer){this.isBaseLayer=isBaseLayer;if(this.map!=null){this.map.events.triggerEvent("changebaselayer",{layer:this});}}},initResolutions:function(){var i,len;var props={},alwaysInRange=true;for(i=0,len=this.RESOLUTION_PROPERTIES.length;i<len;i++){var p=this.RESOLUTION_PROPERTIES[i];props[p]=this.options[p];if(alwaysInRange&&this.options[p]){alwaysInRange=false;}}
60355 if(this.alwaysInRange==null){this.alwaysInRange=alwaysInRange;}
60356 if(props.resolutions==null){props.resolutions=this.resolutionsFromScales(props.scales);}
60357 if(props.resolutions==null){props.resolutions=this.calculateResolutions(props);}
60358 if(props.resolutions==null){for(i=0,len=this.RESOLUTION_PROPERTIES.length;i<len;i++){var p=this.RESOLUTION_PROPERTIES[i];props[p]=this.options[p]!=null?this.options[p]:this.map[p];}
60359 if(props.resolutions==null){props.resolutions=this.resolutionsFromScales(props.scales);}
60360 if(props.resolutions==null){props.resolutions=this.calculateResolutions(props);}}
60361 var maxResolution;if(this.options.maxResolution&&this.options.maxResolution!=="auto"){maxResolution=this.options.maxResolution;}
60362 if(this.options.minScale){maxResolution=OpenLayers.Util.getResolutionFromScale(this.options.minScale,this.units);}
60363 var minResolution;if(this.options.minResolution&&this.options.minResolution!=="auto"){minResolution=this.options.minResolution;}
60364 if(this.options.maxScale){minResolution=OpenLayers.Util.getResolutionFromScale(this.options.maxScale,this.units);}
60365 if(props.resolutions){props.resolutions.sort(function(a,b){return(b-a);});if(!maxResolution){maxResolution=props.resolutions[0];}
60366 if(!minResolution){var lastIdx=props.resolutions.length-1;minResolution=props.resolutions[lastIdx];}}
60367 this.resolutions=props.resolutions;if(this.resolutions){len=this.resolutions.length;this.scales=new Array(len);for(i=0;i<len;i++){this.scales[i]=OpenLayers.Util.getScaleFromResolution(this.resolutions[i],this.units);}
60368 this.numZoomLevels=len;}
60369 this.minResolution=minResolution;if(minResolution){this.maxScale=OpenLayers.Util.getScaleFromResolution(minResolution,this.units);}
60370 this.maxResolution=maxResolution;if(maxResolution){this.minScale=OpenLayers.Util.getScaleFromResolution(maxResolution,this.units);}},resolutionsFromScales:function(scales){if(scales==null){return;}
60371 var resolutions,i,len;len=scales.length;resolutions=new Array(len);for(i=0;i<len;i++){resolutions[i]=OpenLayers.Util.getResolutionFromScale(scales[i],this.units);}
60372 return resolutions;},calculateResolutions:function(props){var maxResolution=props.maxResolution;if(props.minScale!=null){maxResolution=OpenLayers.Util.getResolutionFromScale(props.minScale,this.units);}else if(maxResolution=="auto"&&this.maxExtent!=null){var viewSize=this.map.getSize();var wRes=this.maxExtent.getWidth()/viewSize.w;var hRes=this.maxExtent.getHeight()/viewSize.h;maxResolution=Math.max(wRes,hRes);}
60373 var minResolution=props.minResolution;if(props.maxScale!=null){minResolution=OpenLayers.Util.getResolutionFromScale(props.maxScale,this.units);}else if(props.minResolution=="auto"&&this.minExtent!=null){var viewSize=this.map.getSize();var wRes=this.minExtent.getWidth()/viewSize.w;var hRes=this.minExtent.getHeight()/viewSize.h;minResolution=Math.max(wRes,hRes);}
60374 var maxZoomLevel=props.maxZoomLevel;var numZoomLevels=props.numZoomLevels;if(typeof minResolution==="number"&&typeof maxResolution==="number"&&numZoomLevels===undefined){var ratio=maxResolution/minResolution;numZoomLevels=Math.floor(Math.log(ratio)/Math.log(2))+1;}else if(numZoomLevels===undefined&&maxZoomLevel!=null){numZoomLevels=maxZoomLevel+1;}
60375 if(typeof numZoomLevels!=="number"||numZoomLevels<=0||(typeof maxResolution!=="number"&&typeof minResolution!=="number")){return;}
60376 var resolutions=new Array(numZoomLevels);var base=2;if(typeof minResolution=="number"&&typeof maxResolution=="number"){base=Math.pow((maxResolution/minResolution),(1/(numZoomLevels-1)));}
60377 var i;if(typeof maxResolution==="number"){for(i=0;i<numZoomLevels;i++){resolutions[i]=maxResolution/Math.pow(base,i);}}else{for(i=0;i<numZoomLevels;i++){resolutions[numZoomLevels-1-i]=minResolution*Math.pow(base,i);}}
60378 return resolutions;},getResolution:function(){var zoom=this.map.getZoom();return this.getResolutionForZoom(zoom);},getExtent:function(){return this.map.calculateBounds();},getZoomForExtent:function(extent,closest){var viewSize=this.map.getSize();var idealResolution=Math.max(extent.getWidth()/viewSize.w,extent.getHeight()/viewSize.h);return this.getZoomForResolution(idealResolution,closest);},getDataExtent:function(){},getResolutionForZoom:function(zoom){zoom=Math.max(0,Math.min(zoom,this.resolutions.length-1));var resolution;if(this.map.fractionalZoom){var low=Math.floor(zoom);var high=Math.ceil(zoom);resolution=this.resolutions[low]-
60379 ((zoom-low)*(this.resolutions[low]-this.resolutions[high]));}else{resolution=this.resolutions[Math.round(zoom)];}
60380 return resolution;},getZoomForResolution:function(resolution,closest){var zoom;if(this.map.fractionalZoom){var lowZoom=0;var highZoom=this.resolutions.length-1;var highRes=this.resolutions[lowZoom];var lowRes=this.resolutions[highZoom];var res;for(var i=0,len=this.resolutions.length;i<len;++i){res=this.resolutions[i];if(res>=resolution){highRes=res;lowZoom=i;}
60381 if(res<=resolution){lowRes=res;highZoom=i;break;}}
60382 var dRes=highRes-lowRes;if(dRes>0){zoom=lowZoom+((highRes-resolution)/dRes);}else{zoom=lowZoom;}}else{var diff;var minDiff=Number.POSITIVE_INFINITY;for(var i=0,len=this.resolutions.length;i<len;i++){if(closest){diff=Math.abs(this.resolutions[i]-resolution);if(diff>minDiff){break;}
60383 minDiff=diff;}else{if(this.resolutions[i]<resolution){break;}}}
60384 zoom=Math.max(0,i-1);}
60385 return zoom;},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if(viewPortPx!=null){var size=this.map.getSize();var center=this.map.getCenter();if(center){var res=this.map.getResolution();var delta_x=viewPortPx.x-(size.w/2);var delta_y=viewPortPx.y-(size.h/2);lonlat=new OpenLayers.LonLat(center.lon+delta_x*res,center.lat-delta_y*res);if(this.wrapDateLine){lonlat=lonlat.wrapDateLine(this.maxExtent);}}}
60386 return lonlat;},getViewPortPxFromLonLat:function(lonlat){var px=null;if(lonlat!=null){var resolution=this.map.getResolution();var extent=this.map.getExtent();px=new OpenLayers.Pixel((1/resolution*(lonlat.lon-extent.left)),(1/resolution*(extent.top-lonlat.lat)));}
60387 return px;},setOpacity:function(opacity){if(opacity!=this.opacity){this.opacity=opacity;for(var i=0,len=this.div.childNodes.length;i<len;++i){var element=this.div.childNodes[i].firstChild;OpenLayers.Util.modifyDOMElement(element,null,null,null,null,null,null,opacity);}
60388 if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"opacity"});}}},getZIndex:function(){return this.div.style.zIndex;},setZIndex:function(zIndex){this.div.style.zIndex=zIndex;},adjustBounds:function(bounds){if(this.gutter){var mapGutter=this.gutter*this.map.getResolution();bounds=new OpenLayers.Bounds(bounds.left-mapGutter,bounds.bottom-mapGutter,bounds.right+mapGutter,bounds.top+mapGutter);}
60389 if(this.wrapDateLine){var wrappingOptions={'rightTolerance':this.getResolution()};bounds=bounds.wrapDateLine(this.maxExtent,wrappingOptions);}
60390 return bounds;},CLASS_NAME:"OpenLayers.Layer"});OpenLayers.Marker.Box=OpenLayers.Class(OpenLayers.Marker,{bounds:null,div:null,initialize:function(bounds,borderColor,borderWidth){this.bounds=bounds;this.div=OpenLayers.Util.createDiv();this.div.style.overflow='hidden';this.events=new OpenLayers.Events(this,this.div,null);this.setBorder(borderColor,borderWidth);},destroy:function(){this.bounds=null;this.div=null;OpenLayers.Marker.prototype.destroy.apply(this,arguments);},setBorder:function(color,width){if(!color){color="red";}
60391 if(!width){width=2;}
60392 this.div.style.border=width+"px solid "+color;},draw:function(px,sz){OpenLayers.Util.modifyDOMElement(this.div,null,px,sz);return this.div;},onScreen:function(){var onScreen=false;if(this.map){var screenBounds=this.map.getExtent();onScreen=screenBounds.containsBounds(this.bounds,true,true);}
60393 return onScreen;},display:function(display){this.div.style.display=(display)?"":"none";},CLASS_NAME:"OpenLayers.Marker.Box"});(function(){var oXMLHttpRequest=window.XMLHttpRequest;var bGecko=!!window.controllers,bIE=window.document.all&&!window.opera,bIE7=bIE&&window.navigator.userAgent.match(/MSIE ([\.0-9]+)/)&&RegExp.$1==7;function cXMLHttpRequest(){this._object=oXMLHttpRequest&&!bIE7?new oXMLHttpRequest:new window.ActiveXObject("Microsoft.XMLHTTP");this._listeners=[];};if(bGecko&&oXMLHttpRequest.wrapped)
60394 cXMLHttpRequest.wrapped=oXMLHttpRequest.wrapped;cXMLHttpRequest.UNSENT=0;cXMLHttpRequest.OPENED=1;cXMLHttpRequest.HEADERS_RECEIVED=2;cXMLHttpRequest.LOADING=3;cXMLHttpRequest.DONE=4;cXMLHttpRequest.prototype.readyState=cXMLHttpRequest.UNSENT;cXMLHttpRequest.prototype.responseText='';cXMLHttpRequest.prototype.responseXML=null;cXMLHttpRequest.prototype.status=0;cXMLHttpRequest.prototype.statusText='';cXMLHttpRequest.prototype.onreadystatechange=null;cXMLHttpRequest.onreadystatechange=null;cXMLHttpRequest.onopen=null;cXMLHttpRequest.onsend=null;cXMLHttpRequest.onabort=null;cXMLHttpRequest.prototype.open=function(sMethod,sUrl,bAsync,sUser,sPassword){delete this._headers;if(arguments.length<3)
60395 bAsync=true;this._async=bAsync;var oRequest=this,nState=this.readyState,fOnUnload;if(bIE&&bAsync){fOnUnload=function(){if(nState!=cXMLHttpRequest.DONE){fCleanTransport(oRequest);oRequest.abort();}};window.attachEvent("onunload",fOnUnload);}
60396 if(cXMLHttpRequest.onopen)
60397 cXMLHttpRequest.onopen.apply(this,arguments);if(arguments.length>4)
60398 this._object.open(sMethod,sUrl,bAsync,sUser,sPassword);else
60399 if(arguments.length>3)
60400 this._object.open(sMethod,sUrl,bAsync,sUser);else
60401 this._object.open(sMethod,sUrl,bAsync);if(!bGecko&&!bIE){this.readyState=cXMLHttpRequest.OPENED;fReadyStateChange(this);}
60402 this._object.onreadystatechange=function(){if(bGecko&&!bAsync)
60403 return;oRequest.readyState=oRequest._object.readyState;fSynchronizeValues(oRequest);if(oRequest._aborted){oRequest.readyState=cXMLHttpRequest.UNSENT;return;}
60404 if(oRequest.readyState==cXMLHttpRequest.DONE){fCleanTransport(oRequest);if(bIE&&bAsync)
60405 window.detachEvent("onunload",fOnUnload);}
60406 if(nState!=oRequest.readyState)
60407 fReadyStateChange(oRequest);nState=oRequest.readyState;}};cXMLHttpRequest.prototype.send=function(vData){if(cXMLHttpRequest.onsend)
60408 cXMLHttpRequest.onsend.apply(this,arguments);if(vData&&vData.nodeType){vData=window.XMLSerializer?new window.XMLSerializer().serializeToString(vData):vData.xml;if(!this._headers["Content-Type"])
60409 this._object.setRequestHeader("Content-Type","application/xml");}
60410 this._object.send(vData);if(bGecko&&!this._async){this.readyState=cXMLHttpRequest.OPENED;fSynchronizeValues(this);while(this.readyState<cXMLHttpRequest.DONE){this.readyState++;fReadyStateChange(this);if(this._aborted)
60411 return;}}};cXMLHttpRequest.prototype.abort=function(){if(cXMLHttpRequest.onabort)
60412 cXMLHttpRequest.onabort.apply(this,arguments);if(this.readyState>cXMLHttpRequest.UNSENT)
60413 this._aborted=true;this._object.abort();fCleanTransport(this);};cXMLHttpRequest.prototype.getAllResponseHeaders=function(){return this._object.getAllResponseHeaders();};cXMLHttpRequest.prototype.getResponseHeader=function(sName){return this._object.getResponseHeader(sName);};cXMLHttpRequest.prototype.setRequestHeader=function(sName,sValue){if(!this._headers)
60414 this._headers={};this._headers[sName]=sValue;return this._object.setRequestHeader(sName,sValue);};cXMLHttpRequest.prototype.addEventListener=function(sName,fHandler,bUseCapture){for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
60415 if(oListener[0]==sName&&oListener[1]==fHandler&&oListener[2]==bUseCapture)
60416 return;this._listeners.push([sName,fHandler,bUseCapture]);};cXMLHttpRequest.prototype.removeEventListener=function(sName,fHandler,bUseCapture){for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
60417 if(oListener[0]==sName&&oListener[1]==fHandler&&oListener[2]==bUseCapture)
60418 break;if(oListener)
60419 this._listeners.splice(nIndex,1);};cXMLHttpRequest.prototype.dispatchEvent=function(oEvent){var oEventPseudo={'type':oEvent.type,'target':this,'currentTarget':this,'eventPhase':2,'bubbles':oEvent.bubbles,'cancelable':oEvent.cancelable,'timeStamp':oEvent.timeStamp,'stopPropagation':function(){},'preventDefault':function(){},'initEvent':function(){}};if(oEventPseudo.type=="readystatechange"&&this.onreadystatechange)
60420 (this.onreadystatechange.handleEvent||this.onreadystatechange).apply(this,[oEventPseudo]);for(var nIndex=0,oListener;oListener=this._listeners[nIndex];nIndex++)
60421 if(oListener[0]==oEventPseudo.type&&!oListener[2])
60422 (oListener[1].handleEvent||oListener[1]).apply(this,[oEventPseudo]);};cXMLHttpRequest.prototype.toString=function(){return'['+"object"+' '+"XMLHttpRequest"+']';};cXMLHttpRequest.toString=function(){return'['+"XMLHttpRequest"+']';};function fReadyStateChange(oRequest){if(cXMLHttpRequest.onreadystatechange)
60423 cXMLHttpRequest.onreadystatechange.apply(oRequest);oRequest.dispatchEvent({'type':"readystatechange",'bubbles':false,'cancelable':false,'timeStamp':new Date+0});};function fGetDocument(oRequest){var oDocument=oRequest.responseXML,sResponse=oRequest.responseText;if(bIE&&sResponse&&oDocument&&!oDocument.documentElement&&oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)){oDocument=new window.ActiveXObject("Microsoft.XMLDOM");oDocument.async=false;oDocument.validateOnParse=false;oDocument.loadXML(sResponse);}
60424 if(oDocument)
60425 if((bIE&&oDocument.parseError!=0)||!oDocument.documentElement||(oDocument.documentElement&&oDocument.documentElement.tagName=="parsererror"))
60426 return null;return oDocument;};function fSynchronizeValues(oRequest){try{oRequest.responseText=oRequest._object.responseText;}catch(e){}
60427 try{oRequest.responseXML=fGetDocument(oRequest._object);}catch(e){}
60428 try{oRequest.status=oRequest._object.status;}catch(e){}
60429 try{oRequest.statusText=oRequest._object.statusText;}catch(e){}};function fCleanTransport(oRequest){oRequest._object.onreadystatechange=new window.Function;};if(!window.Function.prototype.apply){window.Function.prototype.apply=function(oRequest,oArguments){if(!oArguments)
60430 oArguments=[];oRequest.__func=this;oRequest.__func(oArguments[0],oArguments[1],oArguments[2],oArguments[3],oArguments[4]);delete oRequest.__func;};};OpenLayers.Request.XMLHttpRequest=cXMLHttpRequest;})();OpenLayers.Tile.Image.IFrame=OpenLayers.Class(OpenLayers.Tile.Image,{initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.Image.prototype.initialize.apply(this,arguments);this.layerAlphaHack=false;},destroy:function(){if(this.imgDiv!=null){OpenLayers.Event.stopObservingElement(this.imgDiv.firstChild);}
60431 OpenLayers.Tile.Image.prototype.destroy.apply(this,arguments);},clear:function(){if(this.imgDiv){var iFrame=this.imgDiv.firstChild;OpenLayers.Event.stopObservingElement(iFrame);this.imgDiv.removeChild(iFrame);}},clone:function(obj){if(obj==null){obj=new OpenLayers.Tile.Image.IFrame(this.layer,this.position,this.bounds,this.url,this.size);}
60432 obj=OpenLayers.Tile.Image.prototype.clone.apply(this,[obj]);return obj;},renderTile:function(){if(OpenLayers.Tile.Image.prototype.renderTile.apply(this,arguments)){var form=this.createRequestForm();this.imgDiv.appendChild(form);form.submit();this.imgDiv.removeChild(form);}},initImgDiv:function(){this.imgDiv=this.createImgDiv();OpenLayers.Util.modifyDOMElement(this.imgDiv,this.id,null,this.layer.getImageSize(),"relative");this.imgDiv.className='olTileImage';this.frame.appendChild(this.imgDiv);this.layer.div.appendChild(this.frame);if(this.layer.opacity!=null){OpenLayers.Util.modifyDOMElement(this.imgDiv,null,null,null,null,null,null,this.layer.opacity);}
60433 this.imgDiv.map=this.layer.map;},createImgDiv:function(){var eventPane=document.createElement("div");if(OpenLayers.Util.getBrowserName()=="msie"){eventPane.style.backgroundColor='#FFFFFF';eventPane.style.filter='chroma(color=#FFFFFF)';}
60434 OpenLayers.Util.modifyDOMElement(eventPane,null,new OpenLayers.Pixel(0,0),this.layer.getImageSize(),"absolute");var imgDiv=document.createElement("div");imgDiv.appendChild(eventPane);return imgDiv;},createIFrame:function(){var id=this.id+'_iFrame';var iframe;if(OpenLayers.Util.getBrowserName()=="msie"){iframe=document.createElement('<iframe name="'+id+'">');iframe.style.backgroundColor='#FFFFFF';iframe.style.filter='chroma(color=#FFFFFF)';}
60435 else{iframe=document.createElement('iframe');iframe.style.backgroundColor='transparent';iframe.name=id;}
60436 iframe.id=id;iframe.scrolling='no';iframe.marginWidth='0px';iframe.marginHeight='0px';iframe.frameBorder='0';OpenLayers.Util.modifyDOMElement(iframe,id,new OpenLayers.Pixel(0,0),this.layer.getImageSize(),"absolute");var onload=function(){this.show();if(this.isLoading){this.isLoading=false;this.events.triggerEvent("loadend");}};OpenLayers.Event.observe(iframe,'load',OpenLayers.Function.bind(onload,this));return iframe;},createRequestForm:function(){var form=document.createElement('form');form.method='POST';var cacheId=this.layer.params["_OLSALT"];cacheId=(cacheId?cacheId+"_":"")+this.bounds.toBBOX();form.action=OpenLayers.Util.urlAppend(this.layer.url,cacheId);this.imgDiv.insertBefore(this.createIFrame(),this.imgDiv.firstChild);form.target=this.id+'_iFrame';var imageSize=this.layer.getImageSize();var params=OpenLayers.Util.extend({"BBOX":this.encodeBBOX?this.bounds.toBBOX():this.bounds.toArray(),"WIDTH":imageSize.w,"HEIGHT":imageSize.h},this.layer.params);for(var par in params){var field=document.createElement('input');field.type='hidden';field.name=par;field.value=params[par];form.appendChild(field);}
60437 return form;},CLASS_NAME:"OpenLayers.Tile.Image.IFrame"});OpenLayers.ProxyHost="";OpenLayers.nullHandler=function(request){OpenLayers.Console.userError(OpenLayers.i18n("unhandledRequest",{'statusText':request.statusText}));};OpenLayers.loadURL=function(uri,params,caller,onComplete,onFailure){if(typeof params=='string'){params=OpenLayers.Util.getParameters(params);}
60438 var success=(onComplete)?onComplete:OpenLayers.nullHandler;var failure=(onFailure)?onFailure:OpenLayers.nullHandler;return OpenLayers.Request.GET({url:uri,params:params,success:success,failure:failure,scope:caller});};OpenLayers.parseXMLString=function(text){var index=text.indexOf('<');if(index>0){text=text.substring(index);}
60439 var ajaxResponse=OpenLayers.Util.Try(function(){var xmldom=new ActiveXObject('Microsoft.XMLDOM');xmldom.loadXML(text);return xmldom;},function(){return new DOMParser().parseFromString(text,'text/xml');},function(){var req=new XMLHttpRequest();req.open("GET","data:"+"text/xml"+";charset=utf-8,"+encodeURIComponent(text),false);if(req.overrideMimeType){req.overrideMimeType("text/xml");}
60440 req.send(null);return req.responseXML;});return ajaxResponse;};OpenLayers.Ajax={emptyFunction:function(){},getTransport:function(){return OpenLayers.Util.Try(function(){return new XMLHttpRequest();},function(){return new ActiveXObject('Msxml2.XMLHTTP');},function(){return new ActiveXObject('Microsoft.XMLHTTP');})||false;},activeRequestCount:0};OpenLayers.Ajax.Responders={responders:[],register:function(responderToAdd){for(var i=0;i<this.responders.length;i++){if(responderToAdd==this.responders[i]){return;}}
60441 this.responders.push(responderToAdd);},unregister:function(responderToRemove){OpenLayers.Util.removeItem(this.reponders,responderToRemove);},dispatch:function(callback,request,transport){var responder;for(var i=0;i<this.responders.length;i++){responder=this.responders[i];if(responder[callback]&&typeof responder[callback]=='function'){try{responder[callback].apply(responder,[request,transport]);}catch(e){}}}}};OpenLayers.Ajax.Responders.register({onCreate:function(){OpenLayers.Ajax.activeRequestCount++;},onComplete:function(){OpenLayers.Ajax.activeRequestCount--;}});OpenLayers.Ajax.Base=OpenLayers.Class({initialize:function(options){this.options={method:'post',asynchronous:true,contentType:'application/xml',parameters:''};OpenLayers.Util.extend(this.options,options||{});this.options.method=this.options.method.toLowerCase();if(typeof this.options.parameters=='string'){this.options.parameters=OpenLayers.Util.getParameters(this.options.parameters);}}});OpenLayers.Ajax.Request=OpenLayers.Class(OpenLayers.Ajax.Base,{_complete:false,initialize:function(url,options){OpenLayers.Ajax.Base.prototype.initialize.apply(this,[options]);if(OpenLayers.ProxyHost&&OpenLayers.String.startsWith(url,"http")){url=OpenLayers.ProxyHost+encodeURIComponent(url);}
60442 this.transport=OpenLayers.Ajax.getTransport();this.request(url);},request:function(url){this.url=url;this.method=this.options.method;var params=OpenLayers.Util.extend({},this.options.parameters);if(this.method!='get'&&this.method!='post'){params['_method']=this.method;this.method='post';}
60443 this.parameters=params;if(params=OpenLayers.Util.getParameterString(params)){if(this.method=='get'){this.url+=((this.url.indexOf('?')>-1)?'&':'?')+params;}else if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)){params+='&_=';}}
60444 try{var response=new OpenLayers.Ajax.Response(this);if(this.options.onCreate){this.options.onCreate(response);}
60445 OpenLayers.Ajax.Responders.dispatch('onCreate',this,response);this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);if(this.options.asynchronous){window.setTimeout(OpenLayers.Function.bind(this.respondToReadyState,this,1),10);}
60446 this.transport.onreadystatechange=OpenLayers.Function.bind(this.onStateChange,this);this.setRequestHeaders();this.body=this.method=='post'?(this.options.postBody||params):null;this.transport.send(this.body);if(!this.options.asynchronous&&this.transport.overrideMimeType){this.onStateChange();}}catch(e){this.dispatchException(e);}},onStateChange:function(){var readyState=this.transport.readyState;if(readyState>1&&!((readyState==4)&&this._complete)){this.respondToReadyState(this.transport.readyState);}},setRequestHeaders:function(){var headers={'X-Requested-With':'XMLHttpRequest','Accept':'text/javascript, text/html, application/xml, text/xml, */*','OpenLayers':true};if(this.method=='post'){headers['Content-type']=this.options.contentType+
60447 (this.options.encoding?'; charset='+this.options.encoding:'');if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005){headers['Connection']='close';}}
60448 if(typeof this.options.requestHeaders=='object'){var extras=this.options.requestHeaders;if(typeof extras.push=='function'){for(var i=0,length=extras.length;i<length;i+=2){headers[extras[i]]=extras[i+1];}}else{for(var i in extras){headers[i]=extras[i];}}}
60449 for(var name in headers){this.transport.setRequestHeader(name,headers[name]);}},success:function(){var status=this.getStatus();return!status||(status>=200&&status<300);},getStatus:function(){try{return this.transport.status||0;}catch(e){return 0;}},respondToReadyState:function(readyState){var state=OpenLayers.Ajax.Request.Events[readyState];var response=new OpenLayers.Ajax.Response(this);if(state=='Complete'){try{this._complete=true;(this.options['on'+response.status]||this.options['on'+(this.success()?'Success':'Failure')]||OpenLayers.Ajax.emptyFunction)(response);}catch(e){this.dispatchException(e);}
60450 var contentType=response.getHeader('Content-type');}
60451 try{(this.options['on'+state]||OpenLayers.Ajax.emptyFunction)(response);OpenLayers.Ajax.Responders.dispatch('on'+state,this,response);}catch(e){this.dispatchException(e);}
60452 if(state=='Complete'){this.transport.onreadystatechange=OpenLayers.Ajax.emptyFunction;}},getHeader:function(name){try{return this.transport.getResponseHeader(name);}catch(e){return null;}},dispatchException:function(exception){var handler=this.options.onException;if(handler){handler(this,exception);OpenLayers.Ajax.Responders.dispatch('onException',this,exception);}else{var listener=false;var responders=OpenLayers.Ajax.Responders.responders;for(var i=0;i<responders.length;i++){if(responders[i].onException){listener=true;break;}}
60453 if(listener){OpenLayers.Ajax.Responders.dispatch('onException',this,exception);}else{throw exception;}}}});OpenLayers.Ajax.Request.Events=['Uninitialized','Loading','Loaded','Interactive','Complete'];OpenLayers.Ajax.Response=OpenLayers.Class({status:0,statusText:'',initialize:function(request){this.request=request;var transport=this.transport=request.transport,readyState=this.readyState=transport.readyState;if((readyState>2&&!(!!(window.attachEvent&&!window.opera)))||readyState==4){this.status=this.getStatus();this.statusText=this.getStatusText();this.responseText=transport.responseText==null?'':String(transport.responseText);}
60454 if(readyState==4){var xml=transport.responseXML;this.responseXML=xml===undefined?null:xml;}},getStatus:OpenLayers.Ajax.Request.prototype.getStatus,getStatusText:function(){try{return this.transport.statusText||'';}catch(e){return'';}},getHeader:OpenLayers.Ajax.Request.prototype.getHeader,getResponseHeader:function(name){return this.transport.getResponseHeader(name);}});OpenLayers.Ajax.getElementsByTagNameNS=function(parentnode,nsuri,nsprefix,tagname){var elem=null;if(parentnode.getElementsByTagNameNS){elem=parentnode.getElementsByTagNameNS(nsuri,tagname);}else{elem=parentnode.getElementsByTagName(nsprefix+':'+tagname);}
60455 return elem;};OpenLayers.Ajax.serializeXMLToString=function(xmldom){var serializer=new XMLSerializer();var data=serializer.serializeToString(xmldom);return data;};OpenLayers.Control.DragFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,onStart:function(feature,pixel){},onDrag:function(feature,pixel){},onComplete:function(feature,pixel){},documentDrag:false,layer:null,feature:null,dragCallbacks:{},featureCallbacks:{},lastPixel:null,initialize:function(layer,options){OpenLayers.Control.prototype.initialize.apply(this,[options]);this.layer=layer;this.handlers={drag:new OpenLayers.Handler.Drag(this,OpenLayers.Util.extend({down:this.downFeature,move:this.moveFeature,up:this.upFeature,out:this.cancel,done:this.doneDragging},this.dragCallbacks),{documentDrag:this.documentDrag}),feature:new OpenLayers.Handler.Feature(this,this.layer,OpenLayers.Util.extend({over:this.overFeature,out:this.outFeature},this.featureCallbacks),{geometryTypes:this.geometryTypes})};},destroy:function(){this.layer=null;OpenLayers.Control.prototype.destroy.apply(this,[]);},activate:function(){return(this.handlers.feature.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments));},deactivate:function(){this.handlers.drag.deactivate();this.handlers.feature.deactivate();this.feature=null;this.dragging=false;this.lastPixel=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass+"Over");return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},overFeature:function(feature){if(!this.handlers.drag.dragging){this.feature=feature;this.handlers.drag.activate();this.over=true;OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass+"Over");}else{if(this.feature.id==feature.id){this.over=true;}else{this.over=false;}}},downFeature:function(pixel){this.lastPixel=pixel;this.onStart(this.feature,pixel);},moveFeature:function(pixel){var res=this.map.getResolution();this.feature.geometry.move(res*(pixel.x-this.lastPixel.x),res*(this.lastPixel.y-pixel.y));this.layer.drawFeature(this.feature);this.lastPixel=pixel;this.onDrag(this.feature,pixel);},upFeature:function(pixel){if(!this.over){this.handlers.drag.deactivate();}},doneDragging:function(pixel){this.onComplete(this.feature,pixel);},outFeature:function(feature){if(!this.handlers.drag.dragging){this.over=false;this.handlers.drag.deactivate();OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass+"Over");this.feature=null;}else{if(this.feature.id==feature.id){this.over=false;}}},cancel:function(){this.handlers.drag.deactivate();this.over=false;},setMap:function(map){this.handlers.drag.setMap(map);this.handlers.feature.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.DragFeature"});OpenLayers.Control.DragPan=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,panned:false,interval:25,documentDrag:false,draw:function(){this.handler=new OpenLayers.Handler.Drag(this,{"move":this.panMap,"done":this.panMapDone},{interval:this.interval,documentDrag:this.documentDrag});},panMap:function(xy){this.panned=true;this.map.pan(this.handler.last.x-xy.x,this.handler.last.y-xy.y,{dragging:this.handler.dragging,animate:false});},panMapDone:function(xy){if(this.panned){this.panMap(xy);this.panned=false;}},CLASS_NAME:"OpenLayers.Control.DragPan"});OpenLayers.Control.KeyboardDefaults=OpenLayers.Class(OpenLayers.Control,{autoActivate:true,slideFactor:75,initialize:function(){OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){if(this.handler){this.handler.destroy();}
60456 this.handler=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},draw:function(){this.handler=new OpenLayers.Handler.Keyboard(this,{"keydown":this.defaultKeyPress});},defaultKeyPress:function(evt){switch(evt.keyCode){case OpenLayers.Event.KEY_LEFT:this.map.pan(-this.slideFactor,0);break;case OpenLayers.Event.KEY_RIGHT:this.map.pan(this.slideFactor,0);break;case OpenLayers.Event.KEY_UP:this.map.pan(0,-this.slideFactor);break;case OpenLayers.Event.KEY_DOWN:this.map.pan(0,this.slideFactor);break;case 33:var size=this.map.getSize();this.map.pan(0,-0.75*size.h);break;case 34:var size=this.map.getSize();this.map.pan(0,0.75*size.h);break;case 35:var size=this.map.getSize();this.map.pan(0.75*size.w,0);break;case 36:var size=this.map.getSize();this.map.pan(-0.75*size.w,0);break;case 43:case 61:case 187:case 107:this.map.zoomIn();break;case 45:case 109:case 189:case 95:this.map.zoomOut();break;}},CLASS_NAME:"OpenLayers.Control.KeyboardDefaults"});OpenLayers.Control.WMSGetFeatureInfo=OpenLayers.Class(OpenLayers.Control,{hover:false,drillDown:false,maxFeatures:10,clickCallback:"click",layers:null,queryVisible:false,url:null,layerUrls:null,infoFormat:'text/html',vendorParams:{},format:null,formatOptions:null,handlerOptions:null,handler:null,hoverRequest:null,EVENT_TYPES:["beforegetfeatureinfo","nogetfeatureinfo","getfeatureinfo"],initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.WMSGetFeatureInfo.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options=options||{};options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!this.format){this.format=new OpenLayers.Format.WMSGetFeatureInfo(options.formatOptions);}
60457 if(this.drillDown===true){this.hover=false;}
60458 if(this.hover){this.handler=new OpenLayers.Handler.Hover(this,{'move':this.cancelHover,'pause':this.getInfoForHover},OpenLayers.Util.extend(this.handlerOptions.hover||{},{'delay':250}));}else{var callbacks={};callbacks[this.clickCallback]=this.getInfoForClick;this.handler=new OpenLayers.Handler.Click(this,callbacks,this.handlerOptions.click||{});}},activate:function(){if(!this.active){this.handler.activate();}
60459 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},getInfoForClick:function(evt){this.events.triggerEvent("beforegetfeatureinfo",{xy:evt.xy});OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");this.request(evt.xy,{});},getInfoForHover:function(evt){this.events.triggerEvent("beforegetfeatureinfo",{xy:evt.xy});this.request(evt.xy,{hover:true});},cancelHover:function(){if(this.hoverRequest){this.hoverRequest.abort();this.hoverRequest=null;}},findLayers:function(){var candidates=this.layers||this.map.layers;var layers=[];var layer,url;for(var i=0,len=candidates.length;i<len;++i){layer=candidates[i];if(layer instanceof OpenLayers.Layer.WMS&&(!this.queryVisible||layer.getVisibility())){url=layer.url instanceof Array?layer.url[0]:layer.url;if(this.drillDown===false&&!this.url){this.url=url;}
60460 if(this.drillDown===true||this.urlMatches(url)){layers.push(layer);}}}
60461 return layers;},urlMatches:function(url){var matches=OpenLayers.Util.isEquivalentUrl(this.url,url);if(!matches&&this.layerUrls){for(var i=0,len=this.layerUrls.length;i<len;++i){if(OpenLayers.Util.isEquivalentUrl(this.layerUrls[i],url)){matches=true;break;}}}
60462 return matches;},buildWMSOptions:function(url,layers,clickPosition,format){var layerNames=[],styleNames=[];for(var i=0,len=layers.length;i<len;i++){layerNames=layerNames.concat(layers[i].params.LAYERS);styleNames=styleNames.concat(this.getStyleNames(layers[i]));}
60463 var params=OpenLayers.Util.extend({service:"WMS",version:layers[0].params.VERSION,request:"GetFeatureInfo",layers:layerNames,query_layers:layerNames,styles:styleNames,bbox:this.map.getExtent().toBBOX(null,layers[0].reverseAxisOrder()),feature_count:this.maxFeatures,height:this.map.getSize().h,width:this.map.getSize().w,format:format,info_format:this.infoFormat},(parseFloat(layers[0].params.VERSION)>=1.3)?{crs:this.map.getProjection(),i:clickPosition.x,j:clickPosition.y}:{srs:this.map.getProjection(),x:clickPosition.x,y:clickPosition.y});OpenLayers.Util.applyDefaults(params,this.vendorParams);return{url:url,params:OpenLayers.Util.upperCaseObject(params),callback:function(request){this.handleResponse(clickPosition,request);},scope:this};},getStyleNames:function(layer){var styleNames;if(layer.params.STYLES){styleNames=layer.params.STYLES;}else{if(layer.params.LAYERS instanceof Array){styleNames=new Array(layer.params.LAYERS.length);}else{styleNames=layer.params.LAYERS.replace(/[^,]/g,"");}}
60464 return styleNames;},request:function(clickPosition,options){var layers=this.findLayers();if(layers.length==0){this.events.triggerEvent("nogetfeatureinfo");OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");return;}
60465 options=options||{};if(this.drillDown===false){var wmsOptions=this.buildWMSOptions(this.url,layers,clickPosition,layers[0].params.FORMAT);var request=OpenLayers.Request.GET(wmsOptions);if(options.hover===true){this.hoverRequest=request;}}else{this._requestCount=0;this._numRequests=0;this.features=[];var services={},url;for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];var service,found=false;url=layer.url instanceof Array?layer.url[0]:layer.url;if(url in services){services[url].push(layer);}else{this._numRequests++;services[url]=[layer];}}
60466 var layers;for(var url in services){layers=services[url];var wmsOptions=this.buildWMSOptions(url,layers,clickPosition,layers[0].params.FORMAT);OpenLayers.Request.GET(wmsOptions);}}},triggerGetFeatureInfo:function(request,xy,features){this.events.triggerEvent("getfeatureinfo",{text:request.responseText,features:features,request:request,xy:xy});OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");},handleResponse:function(xy,request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
60467 var features=this.format.read(doc);if(this.drillDown===false){this.triggerGetFeatureInfo(request,xy,features);}else{this._requestCount++;this._features=(this._features||[]).concat(features);if(this._requestCount===this._numRequests){this.triggerGetFeatureInfo(request,xy,this._features.concat());delete this._features;delete this._requestCount;delete this._numRequests;}}},CLASS_NAME:"OpenLayers.Control.WMSGetFeatureInfo"});OpenLayers.Control.WMTSGetFeatureInfo=OpenLayers.Class(OpenLayers.Control,{hover:false,requestEncoding:"KVP",drillDown:false,maxFeatures:10,clickCallback:"click",layers:null,queryVisible:true,infoFormat:'text/html',vendorParams:{},format:null,formatOptions:null,handlerOptions:null,handler:null,hoverRequest:null,EVENT_TYPES:["beforegetfeatureinfo","getfeatureinfo","exception"],pending:0,initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.WMTSGetFeatureInfo.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options=options||{};options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!this.format){this.format=new OpenLayers.Format.WMSGetFeatureInfo(options.formatOptions);}
60468 if(this.drillDown===true){this.hover=false;}
60469 if(this.hover){this.handler=new OpenLayers.Handler.Hover(this,{move:this.cancelHover,pause:this.getInfoForHover},OpenLayers.Util.extend(this.handlerOptions.hover||{},{delay:250}));}else{var callbacks={};callbacks[this.clickCallback]=this.getInfoForClick;this.handler=new OpenLayers.Handler.Click(this,callbacks,this.handlerOptions.click||{});}},activate:function(){if(!this.active){this.handler.activate();}
60470 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},getInfoForClick:function(evt){this.request(evt.xy,{});},getInfoForHover:function(evt){this.request(evt.xy,{hover:true});},cancelHover:function(){if(this.hoverRequest){--this.pending;if(this.pending<=0){OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");this.pending=0;}
60471 this.hoverRequest.abort();this.hoverRequest=null;}},findLayers:function(){var candidates=this.layers||this.map.layers;var layers=[];var layer;for(var i=candidates.length-1;i>=0;--i){layer=candidates[i];if(layer instanceof OpenLayers.Layer.WMTS&&layer.requestEncoding===this.requestEncoding&&(!this.queryVisible||layer.getVisibility())){layers.push(layer);if(!this.drillDown||this.hover){break;}}}
60472 return layers;},buildRequestOptions:function(layer,xy){var loc=this.map.getLonLatFromPixel(xy);var getTileUrl=layer.getURL(new OpenLayers.Bounds(loc.lon,loc.lat,loc.lon,loc.lat));var params=OpenLayers.Util.getParameters(getTileUrl);var tileInfo=layer.getTileInfo(loc);OpenLayers.Util.extend(params,{service:"WMTS",version:layer.version,request:"GetFeatureInfo",infoFormat:this.infoFormat,i:tileInfo.i,j:tileInfo.j});OpenLayers.Util.applyDefaults(params,this.vendorParams);return{url:layer.url instanceof Array?layer.url[0]:layer.url,params:OpenLayers.Util.upperCaseObject(params),callback:function(request){this.handleResponse(xy,request,layer);},scope:this};},request:function(xy,options){options=options||{};var layers=this.findLayers();if(layers.length>0){var issue,layer;for(var i=0,len=layers.length;i<len;i++){layer=layers[i];issue=this.events.triggerEvent("beforegetfeatureinfo",{xy:xy,layer:layer});if(issue!==false){++this.pending;var requestOptions=this.buildRequestOptions(layer,xy);var request=OpenLayers.Request.GET(requestOptions);if(options.hover===true){this.hoverRequest=request;}}}
60473 if(this.pending>0){OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");}}},handleResponse:function(xy,request,layer){--this.pending;if(this.pending<=0){OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");this.pending=0;}
60474 if(request.status&&(request.status<200||request.status>=300)){this.events.triggerEvent("exception",{xy:xy,request:request,layer:layer});}else{var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
60475 var features,except;try{features=this.format.read(doc);}catch(error){except=true;this.events.triggerEvent("exception",{xy:xy,request:request,error:error,layer:layer});}
60476 if(!except){this.events.triggerEvent("getfeatureinfo",{text:request.responseText,features:features,request:request,xy:xy,layer:layer});}}},setMap:function(map){this.handler.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.WMTSGetFeatureInfo"});OpenLayers.State={UNKNOWN:'Unknown',INSERT:'Insert',UPDATE:'Update',DELETE:'Delete'};OpenLayers.Feature.Vector=OpenLayers.Class(OpenLayers.Feature,{fid:null,geometry:null,attributes:null,bounds:null,state:null,style:null,url:null,renderIntent:"default",initialize:function(geometry,attributes,style){OpenLayers.Feature.prototype.initialize.apply(this,[null,null,attributes]);this.lonlat=null;this.geometry=geometry?geometry:null;this.state=null;this.attributes={};if(attributes){this.attributes=OpenLayers.Util.extend(this.attributes,attributes);}
60477 this.style=style?style:null;},destroy:function(){if(this.layer){this.layer.removeFeatures(this);this.layer=null;}
60478 this.geometry=null;OpenLayers.Feature.prototype.destroy.apply(this,arguments);},clone:function(){return new OpenLayers.Feature.Vector(this.geometry?this.geometry.clone():null,this.attributes,this.style);},onScreen:function(boundsOnly){var onScreen=false;if(this.layer&&this.layer.map){var screenBounds=this.layer.map.getExtent();if(boundsOnly){var featureBounds=this.geometry.getBounds();onScreen=screenBounds.intersectsBounds(featureBounds);}else{var screenPoly=screenBounds.toGeometry();onScreen=screenPoly.intersects(this.geometry);}}
60479 return onScreen;},getVisibility:function(){return!(this.style&&this.style.display=='none'||!this.layer||this.layer&&this.layer.styleMap&&this.layer.styleMap.createSymbolizer(this,this.renderIntent).display=='none'||this.layer&&!this.layer.getVisibility());},createMarker:function(){return null;},destroyMarker:function(){},createPopup:function(){return null;},atPoint:function(lonlat,toleranceLon,toleranceLat){var atPoint=false;if(this.geometry){atPoint=this.geometry.atPoint(lonlat,toleranceLon,toleranceLat);}
60480 return atPoint;},destroyPopup:function(){},move:function(location){if(!this.layer||!this.geometry.move){return;}
60481 var pixel;if(location.CLASS_NAME=="OpenLayers.LonLat"){pixel=this.layer.getViewPortPxFromLonLat(location);}else{pixel=location;}
60482 var lastPixel=this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());var res=this.layer.map.getResolution();this.geometry.move(res*(pixel.x-lastPixel.x),res*(lastPixel.y-pixel.y));this.layer.drawFeature(this);return lastPixel;},toState:function(state){if(state==OpenLayers.State.UPDATE){switch(this.state){case OpenLayers.State.UNKNOWN:case OpenLayers.State.DELETE:this.state=state;break;case OpenLayers.State.UPDATE:case OpenLayers.State.INSERT:break;}}else if(state==OpenLayers.State.INSERT){switch(this.state){case OpenLayers.State.UNKNOWN:break;default:this.state=state;break;}}else if(state==OpenLayers.State.DELETE){switch(this.state){case OpenLayers.State.INSERT:break;case OpenLayers.State.DELETE:break;case OpenLayers.State.UNKNOWN:case OpenLayers.State.UPDATE:this.state=state;break;}}else if(state==OpenLayers.State.UNKNOWN){this.state=state;}},CLASS_NAME:"OpenLayers.Feature.Vector"});OpenLayers.Feature.Vector.style={'default':{fillColor:"#ee9900",fillOpacity:0.4,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"#ee9900",strokeOpacity:1,strokeWidth:1,strokeLinecap:"round",strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"inherit"},'select':{fillColor:"blue",fillOpacity:0.4,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"blue",strokeOpacity:1,strokeWidth:2,strokeLinecap:"round",strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"pointer"},'temporary':{fillColor:"#66cccc",fillOpacity:0.2,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"#66cccc",strokeOpacity:1,strokeLinecap:"round",strokeWidth:2,strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"inherit"},'delete':{display:"none"}};OpenLayers.Feature.WFS=OpenLayers.Class(OpenLayers.Feature,{initialize:function(layer,xmlNode){var newArguments=arguments;var data=this.processXMLNode(xmlNode);newArguments=new Array(layer,data.lonlat,data);OpenLayers.Feature.prototype.initialize.apply(this,newArguments);this.createMarker();this.layer.addMarker(this.marker);},destroy:function(){if(this.marker!=null){this.layer.removeMarker(this.marker);}
60483 OpenLayers.Feature.prototype.destroy.apply(this,arguments);},processXMLNode:function(xmlNode){var point=OpenLayers.Ajax.getElementsByTagNameNS(xmlNode,"http://www.opengis.net/gml","gml","Point");var text=OpenLayers.Util.getXmlNodeValue(OpenLayers.Ajax.getElementsByTagNameNS(point[0],"http://www.opengis.net/gml","gml","coordinates")[0]);var floats=text.split(",");return{lonlat:new OpenLayers.LonLat(parseFloat(floats[0]),parseFloat(floats[1])),id:null};},CLASS_NAME:"OpenLayers.Feature.WFS"});OpenLayers.Format.OWSCommon.v1_0_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1,{namespaces:{ows:"http://www.opengis.net/ows/1.0",xlink:"http://www.w3.org/1999/xlink"},readers:{"ows":OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"]},writers:{"ows":OpenLayers.Format.OWSCommon.v1.prototype.writers["ows"]},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1_1_0"});OpenLayers.Format.OWSCommon.v1_1_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1,{namespaces:{ows:"http://www.opengis.net/ows/1.1",xlink:"http://www.w3.org/1999/xlink"},readers:{"ows":OpenLayers.Util.applyDefaults({"AllowedValues":function(node,parameter){parameter.allowedValues={};this.readChildNodes(node,parameter.allowedValues);},"AnyValue":function(node,parameter){parameter.anyValue=true;},"Range":function(node,allowedValues){allowedValues.range={};this.readChildNodes(node,allowedValues.range);},"MinimumValue":function(node,range){range.minValue=this.getChildValue(node);},"MaximumValue":function(node,range){range.maxValue=this.getChildValue(node);},"Identifier":function(node,obj){obj.identifier=this.getChildValue(node);},"SupportedCRS":function(node,obj){obj.supportedCRS=this.getChildValue(node);}},OpenLayers.Format.OWSCommon.v1.prototype.readers["ows"])},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1_1_0"});OpenLayers.Format.OWSContext=OpenLayers.Class(OpenLayers.Format.Context,{defaultVersion:"0.3.1",getParser:function(version){var v=version||this.version||this.defaultVersion;if(v==="0.3.0"){v=this.defaultVersion;}
60484 if(!this.parser||this.parser.VERSION!=v){var format=OpenLayers.Format.OWSContext["v"+v.replace(/\./g,"_")];if(!format){throw"Can't find a OWSContext parser for version "+v;}
60485 this.parser=new format(this.options);}
60486 return this.parser;},toContext:function(obj){var context={};if(obj.CLASS_NAME=="OpenLayers.Map"){context.bounds=obj.getExtent();context.maxExtent=obj.maxExtent;context.projection=obj.projection;context.size=obj.getSize();context.layers=obj.layers;}
60487 return context;},CLASS_NAME:"OpenLayers.Format.OWSContext"});OpenLayers.Format.WFSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.WFSCapabilities,{initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60488 var capabilities={};var root=data.documentElement;this.runChildNodes(capabilities,root);return capabilities;},runChildNodes:function(obj,node){var children=node.childNodes;var childNode,processor;for(var i=0;i<children.length;++i){childNode=children[i];if(childNode.nodeType==1){processor=this["read_cap_"+childNode.nodeName];if(processor){processor.apply(this,[obj,childNode]);}}}},read_cap_FeatureTypeList:function(request,node){var featureTypeList={featureTypes:[]};this.runChildNodes(featureTypeList,node);request.featureTypeList=featureTypeList;},read_cap_FeatureType:function(featureTypeList,node,parentLayer){var featureType={};this.runChildNodes(featureType,node);featureTypeList.featureTypes.push(featureType);},read_cap_Name:function(obj,node){var name=this.getChildValue(node);if(name){var parts=name.split(":");obj.name=parts.pop();if(parts.length>0){obj.featureNS=this.lookupNamespaceURI(node,parts[0]);}}},read_cap_Title:function(obj,node){var title=this.getChildValue(node);if(title){obj.title=title;}},read_cap_Abstract:function(obj,node){var abst=this.getChildValue(node);if(abst){obj["abstract"]=abst;}},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1"});OpenLayers.Format.WMC=OpenLayers.Class(OpenLayers.Format.Context,{defaultVersion:"1.1.0",getParser:function(version){var v=version||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=v){var format=OpenLayers.Format.WMC["v"+v.replace(/\./g,"_")];if(!format){throw"Can't find a WMC parser for version "+v;}
60489 this.parser=new format(this.options);}
60490 return this.parser;},layerToContext:function(layer){var parser=this.getParser();var layerContext={queryable:layer.queryable,visibility:layer.visibility,name:layer.params["LAYERS"],title:layer.name,metadataURL:layer.metadataURL,version:layer.params["VERSION"],url:layer.url,maxExtent:layer.maxExtent,transparent:layer.params["TRANSPARENT"],numZoomLevels:layer.numZoomLevels,units:layer.units,isBaseLayer:layer.isBaseLayer,opacity:layer.opacity,displayInLayerSwitcher:layer.displayInLayerSwitcher,singleTile:layer.singleTile,tileSize:(layer.singleTile||!layer.tileSize)?undefined:{width:layer.tileSize.w,height:layer.tileSize.h},minScale:(layer.options.resolutions||layer.options.scales||layer.options.maxResolution||layer.options.minScale)?layer.minScale:undefined,maxScale:(layer.options.resolutions||layer.options.scales||layer.options.minResolution||layer.options.maxScale)?layer.maxScale:undefined,formats:[{value:layer.params["FORMAT"],current:true}],styles:[{href:layer.params["SLD"],body:layer.params["SLD_BODY"],name:layer.params["STYLES"]||parser.defaultStyleName,title:parser.defaultStyleTitle,current:true}]};return layerContext;},toContext:function(obj){var context={};var layers=obj.layers;if(obj.CLASS_NAME=="OpenLayers.Map"){context.bounds=obj.getExtent();context.maxExtent=obj.maxExtent;context.projection=obj.projection;context.size=obj.getSize();}
60491 else{OpenLayers.Util.applyDefaults(context,obj);if(context.layers!=undefined){delete(context.layers);}}
60492 if(context.layersContext==undefined){context.layersContext=[];}
60493 if(layers!=undefined&&layers instanceof Array){for(var i=0,len=layers.length;i<len;i++){var layer=layers[i];if(layer instanceof OpenLayers.Layer.WMS){context.layersContext.push(this.layerToContext(layer));}}}
60494 return context;},CLASS_NAME:"OpenLayers.Format.WMC"});OpenLayers.Format.WMSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{wms:"http://www.opengis.net/wms",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"wms",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60495 if(data&&data.nodeType==9){data=data.documentElement;}
60496 var capabilities={};this.readNode(data,capabilities);this.postProcessLayers(capabilities);return capabilities;},postProcessLayers:function(capabilities){if(capabilities.capability){capabilities.capability.layers=[];var layers=capabilities.capability.nestedLayers;for(var i=0,len=layers.length;i<len;++i){var layer=layers[i];this.processLayer(capabilities.capability,layer);}}},processLayer:function(capability,layer,parentLayer){if(layer.formats===undefined){layer.formats=capability.request.getmap.formats;}
60497 if(parentLayer){layer.styles=layer.styles.concat(parentLayer.styles);var attributes=["queryable","cascaded","fixedWidth","fixedHeight","opaque","noSubsets","llbbox","minScale","maxScale","attribution"];var complexAttr=["srs","bbox","dimensions","authorityURLs"];var key;for(var j=0;j<attributes.length;j++){key=attributes[j];if(key in parentLayer){if(layer[key]==null){layer[key]=parentLayer[key];}
60498 if(layer[key]==null){var intAttr=["cascaded","fixedWidth","fixedHeight"];var boolAttr=["queryable","opaque","noSubsets"];if(OpenLayers.Util.indexOf(intAttr,key)!=-1){layer[key]=0;}
60499 if(OpenLayers.Util.indexOf(boolAttr,key)!=-1){layer[key]=false;}}}}
60500 for(var j=0;j<complexAttr.length;j++){key=complexAttr[j];layer[key]=OpenLayers.Util.extend(layer[key],parentLayer[key]);}}
60501 for(var i=0,len=layer.nestedLayers.length;i<len;i++){var childLayer=layer.nestedLayers[i];this.processLayer(capability,childLayer,layer);}
60502 if(layer.name){capability.layers.push(layer);}},readers:{"wms":{"Service":function(node,obj){obj.service={};this.readChildNodes(node,obj.service);},"Name":function(node,obj){obj.name=this.getChildValue(node);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,obj){obj["abstract"]=this.getChildValue(node);},"BoundingBox":function(node,obj){var bbox={};bbox.bbox=[parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy"))];var res={x:parseFloat(node.getAttribute("resx")),y:parseFloat(node.getAttribute("resy"))};if(!(isNaN(res.x)&&isNaN(res.y))){bbox.res=res;}
60503 return bbox;},"OnlineResource":function(node,obj){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},"ContactInformation":function(node,obj){obj.contactInformation={};this.readChildNodes(node,obj.contactInformation);},"ContactPersonPrimary":function(node,obj){obj.personPrimary={};this.readChildNodes(node,obj.personPrimary);},"ContactPerson":function(node,obj){obj.person=this.getChildValue(node);},"ContactOrganization":function(node,obj){obj.organization=this.getChildValue(node);},"ContactPosition":function(node,obj){obj.position=this.getChildValue(node);},"ContactAddress":function(node,obj){obj.contactAddress={};this.readChildNodes(node,obj.contactAddress);},"AddressType":function(node,obj){obj.type=this.getChildValue(node);},"Address":function(node,obj){obj.address=this.getChildValue(node);},"City":function(node,obj){obj.city=this.getChildValue(node);},"StateOrProvince":function(node,obj){obj.stateOrProvince=this.getChildValue(node);},"PostCode":function(node,obj){obj.postcode=this.getChildValue(node);},"Country":function(node,obj){obj.country=this.getChildValue(node);},"ContactVoiceTelephone":function(node,obj){obj.phone=this.getChildValue(node);},"ContactFacsimileTelephone":function(node,obj){obj.fax=this.getChildValue(node);},"ContactElectronicMailAddress":function(node,obj){obj.email=this.getChildValue(node);},"Fees":function(node,obj){var fees=this.getChildValue(node);if(fees&&fees.toLowerCase()!="none"){obj.fees=fees;}},"AccessConstraints":function(node,obj){var constraints=this.getChildValue(node);if(constraints&&constraints.toLowerCase()!="none"){obj.accessConstraints=constraints;}},"Capability":function(node,obj){obj.capability={nestedLayers:[]};this.readChildNodes(node,obj.capability);},"Request":function(node,obj){obj.request={};this.readChildNodes(node,obj.request);},"GetCapabilities":function(node,obj){obj.getcapabilities={formats:[]};this.readChildNodes(node,obj.getcapabilities);},"Format":function(node,obj){if(obj.formats instanceof Array){obj.formats.push(this.getChildValue(node));}else{obj.format=this.getChildValue(node);}},"DCPType":function(node,obj){this.readChildNodes(node,obj);},"HTTP":function(node,obj){this.readChildNodes(node,obj);},"Get":function(node,obj){this.readChildNodes(node,obj);},"Post":function(node,obj){this.readChildNodes(node,obj);},"GetMap":function(node,obj){obj.getmap={formats:[]};this.readChildNodes(node,obj.getmap);},"GetFeatureInfo":function(node,obj){obj.getfeatureinfo={formats:[]};this.readChildNodes(node,obj.getfeatureinfo);},"Exception":function(node,obj){obj.exception={formats:[]};this.readChildNodes(node,obj.exception);},"Layer":function(node,obj){var attrNode=node.getAttributeNode("queryable");var queryable=(attrNode&&attrNode.specified)?node.getAttribute("queryable"):null;attrNode=node.getAttributeNode("cascaded");var cascaded=(attrNode&&attrNode.specified)?node.getAttribute("cascaded"):null;attrNode=node.getAttributeNode("opaque");var opaque=(attrNode&&attrNode.specified)?node.getAttribute('opaque'):null;var noSubsets=node.getAttribute('noSubsets');var fixedWidth=node.getAttribute('fixedWidth');var fixedHeight=node.getAttribute('fixedHeight');var layer={nestedLayers:[],styles:[],srs:{},metadataURLs:[],bbox:{},dimensions:{},authorityURLs:{},identifiers:{},keywords:[],queryable:(queryable&&queryable!=="")?(queryable==="1"||queryable==="true"):null,cascaded:(cascaded!==null)?parseInt(cascaded):null,opaque:opaque?(opaque==="1"||opaque==="true"):null,noSubsets:(noSubsets!==null)?(noSubsets==="1"||noSubsets==="true"):null,fixedWidth:(fixedWidth!=null)?parseInt(fixedWidth):null,fixedHeight:(fixedHeight!=null)?parseInt(fixedHeight):null};obj.nestedLayers.push(layer);this.readChildNodes(node,layer);if(layer.name){var parts=layer.name.split(":");if(parts.length>0){layer.prefix=parts[0];}}},"Attribution":function(node,obj){obj.attribution={};this.readChildNodes(node,obj.attribution);},"LogoURL":function(node,obj){obj.logo={width:node.getAttribute("width"),height:node.getAttribute("height")};this.readChildNodes(node,obj.logo);},"Style":function(node,obj){var style={};obj.styles.push(style);this.readChildNodes(node,style);},"LegendURL":function(node,obj){var legend={width:node.getAttribute("width"),height:node.getAttribute("height")};obj.legend=legend;this.readChildNodes(node,legend);},"MetadataURL":function(node,obj){var metadataURL={type:node.getAttribute("type")};obj.metadataURLs.push(metadataURL);this.readChildNodes(node,metadataURL);},"DataURL":function(node,obj){obj.dataURL={};this.readChildNodes(node,obj.dataURL);},"FeatureListURL":function(node,obj){obj.featureListURL={};this.readChildNodes(node,obj.featureListURL);},"AuthorityURL":function(node,obj){var name=node.getAttribute("name");var authority={};this.readChildNodes(node,authority);obj.authorityURLs[name]=authority.href;},"Identifier":function(node,obj){var authority=node.getAttribute("authority");obj.identifiers[authority]=this.getChildValue(node);},"KeywordList":function(node,obj){this.readChildNodes(node,obj);},"SRS":function(node,obj){obj.srs[this.getChildValue(node)]=true;}}},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1"});OpenLayers.Format.WMSDescribeLayer.v1_1=OpenLayers.Class(OpenLayers.Format.WMSDescribeLayer,{initialize:function(options){OpenLayers.Format.WMSDescribeLayer.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60504 var root=data.documentElement;var children=root.childNodes;var describelayer=[];var childNode,nodeName;for(var i=0;i<children.length;++i){childNode=children[i];nodeName=childNode.nodeName;if(nodeName=='LayerDescription'){var layerName=childNode.getAttribute('name');var owsType='';var owsURL='';var typeName='';if(childNode.getAttribute('owsType')){owsType=childNode.getAttribute('owsType');owsURL=childNode.getAttribute('owsURL');}else{if(childNode.getAttribute('wfs')!=''){owsType='WFS';owsURL=childNode.getAttribute('wfs');}else if(childNode.getAttribute('wcs')!=''){owsType='WCS';owsURL=childNode.getAttribute('wcs');}}
60505 var query=childNode.getElementsByTagName('Query');if(query.length>0){typeName=query[0].getAttribute('typeName');if(!typeName){typeName=query[0].getAttribute('typename');}}
60506 describelayer.push({layerName:layerName,owsType:owsType,owsURL:owsURL,typeName:typeName});}}
60507 return describelayer;},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer.v1_1"});OpenLayers.Handler.Box=OpenLayers.Class(OpenLayers.Handler,{dragHandler:null,boxDivClassName:'olHandlerBoxZoomBox',boxCharacteristics:null,initialize:function(control,callbacks,options){OpenLayers.Handler.prototype.initialize.apply(this,arguments);var callbacks={"down":this.startBox,"move":this.moveBox,"out":this.removeBox,"up":this.endBox};this.dragHandler=new OpenLayers.Handler.Drag(this,callbacks,{keyMask:this.keyMask});},destroy:function(){if(this.dragHandler){this.dragHandler.destroy();this.dragHandler=null;}
60508 OpenLayers.Handler.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Handler.prototype.setMap.apply(this,arguments);if(this.dragHandler){this.dragHandler.setMap(map);}},startBox:function(xy){this.zoomBox=OpenLayers.Util.createDiv('zoomBox',this.dragHandler.start);this.zoomBox.className=this.boxDivClassName;this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE["Popup"]-1;this.map.viewPortDiv.appendChild(this.zoomBox);OpenLayers.Element.addClass(this.map.viewPortDiv,"olDrawBox");},moveBox:function(xy){var startX=this.dragHandler.start.x;var startY=this.dragHandler.start.y;var deltaX=Math.abs(startX-xy.x);var deltaY=Math.abs(startY-xy.y);this.zoomBox.style.width=Math.max(1,deltaX)+"px";this.zoomBox.style.height=Math.max(1,deltaY)+"px";this.zoomBox.style.left=xy.x<startX?xy.x+"px":startX+"px";this.zoomBox.style.top=xy.y<startY?xy.y+"px":startY+"px";var box=this.getBoxCharacteristics();if(box.newBoxModel){if(xy.x>startX){this.zoomBox.style.width=Math.max(1,deltaX-box.xOffset)+"px";}
60509 if(xy.y>startY){this.zoomBox.style.height=Math.max(1,deltaY-box.yOffset)+"px";}}},endBox:function(end){var result;if(Math.abs(this.dragHandler.start.x-end.x)>5||Math.abs(this.dragHandler.start.y-end.y)>5){var start=this.dragHandler.start;var top=Math.min(start.y,end.y);var bottom=Math.max(start.y,end.y);var left=Math.min(start.x,end.x);var right=Math.max(start.x,end.x);result=new OpenLayers.Bounds(left,bottom,right,top);}else{result=this.dragHandler.start.clone();}
60510 this.removeBox();this.callback("done",[result]);},removeBox:function(){this.map.viewPortDiv.removeChild(this.zoomBox);this.zoomBox=null;this.boxCharacteristics=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDrawBox");},activate:function(){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){this.dragHandler.activate();return true;}else{return false;}},deactivate:function(){if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){this.dragHandler.deactivate();return true;}else{return false;}},getBoxCharacteristics:function(){if(!this.boxCharacteristics){var xOffset=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-left-width"))+parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-right-width"))+1;var yOffset=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-top-width"))+parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-bottom-width"))+1;var newBoxModel=OpenLayers.Util.getBrowserName()=="msie"?document.compatMode!="BackCompat":true;this.boxCharacteristics={xOffset:xOffset,yOffset:yOffset,newBoxModel:newBoxModel};}
60511 return this.boxCharacteristics;},CLASS_NAME:"OpenLayers.Handler.Box"});OpenLayers.Handler.RegularPolygon=OpenLayers.Class(OpenLayers.Handler.Drag,{sides:4,radius:null,snapAngle:null,snapToggle:'shiftKey',layerOptions:null,persist:false,irregular:false,angle:null,fixedRadius:false,feature:null,layer:null,origin:null,initialize:function(control,callbacks,options){if(!(options&&options.layerOptions&&options.layerOptions.styleMap)){this.style=OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'],{});}
60512 OpenLayers.Handler.prototype.initialize.apply(this,[control,callbacks,options]);this.options=(options)?options:{};},setOptions:function(newOptions){OpenLayers.Util.extend(this.options,newOptions);OpenLayers.Util.extend(this,newOptions);},activate:function(){var activated=false;if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){var options=OpenLayers.Util.extend({displayInLayerSwitcher:false,calculateInRange:OpenLayers.Function.True},this.layerOptions);this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,options);this.map.addLayer(this.layer);activated=true;}
60513 return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Handler.Drag.prototype.deactivate.apply(this,arguments)){if(this.dragging){this.cancel();}
60514 if(this.layer.map!=null){this.layer.destroy(false);if(this.feature){this.feature.destroy();}}
60515 this.layer=null;this.feature=null;deactivated=true;}
60516 return deactivated;},down:function(evt){this.fixedRadius=!!(this.radius);var maploc=this.map.getLonLatFromPixel(evt.xy);this.origin=new OpenLayers.Geometry.Point(maploc.lon,maploc.lat);if(!this.fixedRadius||this.irregular){this.radius=this.map.getResolution();}
60517 if(this.persist){this.clear();}
60518 this.feature=new OpenLayers.Feature.Vector();this.createGeometry();this.callback("create",[this.origin,this.feature]);this.layer.addFeatures([this.feature],{silent:true});this.layer.drawFeature(this.feature,this.style);},move:function(evt){var maploc=this.map.getLonLatFromPixel(evt.xy);var point=new OpenLayers.Geometry.Point(maploc.lon,maploc.lat);if(this.irregular){var ry=Math.sqrt(2)*Math.abs(point.y-this.origin.y)/2;this.radius=Math.max(this.map.getResolution()/2,ry);}else if(this.fixedRadius){this.origin=point;}else{this.calculateAngle(point,evt);this.radius=Math.max(this.map.getResolution()/2,point.distanceTo(this.origin));}
60519 this.modifyGeometry();if(this.irregular){var dx=point.x-this.origin.x;var dy=point.y-this.origin.y;var ratio;if(dy==0){ratio=dx/(this.radius*Math.sqrt(2));}else{ratio=dx/dy;}
60520 this.feature.geometry.resize(1,this.origin,ratio);this.feature.geometry.move(dx/2,dy/2);}
60521 this.layer.drawFeature(this.feature,this.style);},up:function(evt){this.finalize();if(this.start==this.last){this.callback("done",[evt.xy]);}},out:function(evt){this.finalize();},createGeometry:function(){this.angle=Math.PI*((1/this.sides)-(1/2));if(this.snapAngle){this.angle+=this.snapAngle*(Math.PI/180);}
60522 this.feature.geometry=OpenLayers.Geometry.Polygon.createRegularPolygon(this.origin,this.radius,this.sides,this.snapAngle);},modifyGeometry:function(){var angle,point;var ring=this.feature.geometry.components[0];if(ring.components.length!=(this.sides+1)){this.createGeometry();ring=this.feature.geometry.components[0];}
60523 for(var i=0;i<this.sides;++i){point=ring.components[i];angle=this.angle+(i*2*Math.PI/this.sides);point.x=this.origin.x+(this.radius*Math.cos(angle));point.y=this.origin.y+(this.radius*Math.sin(angle));point.clearBounds();}},calculateAngle:function(point,evt){var alpha=Math.atan2(point.y-this.origin.y,point.x-this.origin.x);if(this.snapAngle&&(this.snapToggle&&!evt[this.snapToggle])){var snapAngleRad=(Math.PI/180)*this.snapAngle;this.angle=Math.round(alpha/snapAngleRad)*snapAngleRad;}else{this.angle=alpha;}},cancel:function(){this.callback("cancel",null);this.finalize();},finalize:function(){this.origin=null;this.radius=this.options.radius;},clear:function(){if(this.layer){this.layer.renderer.clear();this.layer.destroyFeatures();}},callback:function(name,args){if(this.callbacks[name]){this.callbacks[name].apply(this.control,[this.feature.geometry.clone()]);}
60524 if(!this.persist&&(name=="done"||name=="cancel")){this.clear();}},CLASS_NAME:"OpenLayers.Handler.RegularPolygon"});OpenLayers.Layer.EventPane=OpenLayers.Class(OpenLayers.Layer,{smoothDragPan:true,isBaseLayer:true,isFixed:true,pane:null,mapObject:null,initialize:function(name,options){OpenLayers.Layer.prototype.initialize.apply(this,arguments);if(this.pane==null){this.pane=OpenLayers.Util.createDiv(this.div.id+"_EventPane");}},destroy:function(){this.mapObject=null;this.pane=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},setMap:function(map){OpenLayers.Layer.prototype.setMap.apply(this,arguments);this.pane.style.zIndex=parseInt(this.div.style.zIndex)+1;this.pane.style.display=this.div.style.display;this.pane.style.width="100%";this.pane.style.height="100%";if(OpenLayers.Util.getBrowserName()=="msie"){this.pane.style.background="url("+OpenLayers.Util.getImagesLocation()+"blank.gif)";}
60525 if(this.isFixed){this.map.viewPortDiv.appendChild(this.pane);}else{this.map.layerContainerDiv.appendChild(this.pane);}
60526 this.loadMapObject();if(this.mapObject==null){this.loadWarningMessage();}},removeMap:function(map){if(this.pane&&this.pane.parentNode){this.pane.parentNode.removeChild(this.pane);}
60527 OpenLayers.Layer.prototype.removeMap.apply(this,arguments);},loadWarningMessage:function(){this.div.style.backgroundColor="darkblue";var viewSize=this.map.getSize();var msgW=Math.min(viewSize.w,300);var msgH=Math.min(viewSize.h,200);var size=new OpenLayers.Size(msgW,msgH);var centerPx=new OpenLayers.Pixel(viewSize.w/2,viewSize.h/2);var topLeft=centerPx.add(-size.w/2,-size.h/2);var div=OpenLayers.Util.createDiv(this.name+"_warning",topLeft,size,null,null,null,"auto");div.style.padding="7px";div.style.backgroundColor="yellow";div.innerHTML=this.getWarningHTML();this.div.appendChild(div);},getWarningHTML:function(){return"";},display:function(display){OpenLayers.Layer.prototype.display.apply(this,arguments);this.pane.style.display=this.div.style.display;},setZIndex:function(zIndex){OpenLayers.Layer.prototype.setZIndex.apply(this,arguments);this.pane.style.zIndex=parseInt(this.div.style.zIndex)+1;},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);if(this.mapObject!=null){var newCenter=this.map.getCenter();var newZoom=this.map.getZoom();if(newCenter!=null){var moOldCenter=this.getMapObjectCenter();var oldCenter=this.getOLLonLatFromMapObjectLonLat(moOldCenter);var moOldZoom=this.getMapObjectZoom();var oldZoom=this.getOLZoomFromMapObjectZoom(moOldZoom);if(!(newCenter.equals(oldCenter))||!(newZoom==oldZoom)){if(dragging&&this.dragPanMapObject&&this.smoothDragPan){var oldPx=this.map.getViewPortPxFromLonLat(oldCenter);var newPx=this.map.getViewPortPxFromLonLat(newCenter);this.dragPanMapObject(newPx.x-oldPx.x,oldPx.y-newPx.y);}else{var center=this.getMapObjectLonLatFromOLLonLat(newCenter);var zoom=this.getMapObjectZoomFromOLZoom(newZoom);this.setMapObjectCenter(center,zoom,dragging);}}}}},getLonLatFromViewPortPx:function(viewPortPx){var lonlat=null;if((this.mapObject!=null)&&(this.getMapObjectCenter()!=null)){var moPixel=this.getMapObjectPixelFromOLPixel(viewPortPx);var moLonLat=this.getMapObjectLonLatFromMapObjectPixel(moPixel);lonlat=this.getOLLonLatFromMapObjectLonLat(moLonLat);}
60528 return lonlat;},getViewPortPxFromLonLat:function(lonlat){var viewPortPx=null;if((this.mapObject!=null)&&(this.getMapObjectCenter()!=null)){var moLonLat=this.getMapObjectLonLatFromOLLonLat(lonlat);var moPixel=this.getMapObjectPixelFromMapObjectLonLat(moLonLat);viewPortPx=this.getOLPixelFromMapObjectPixel(moPixel);}
60529 return viewPortPx;},getOLLonLatFromMapObjectLonLat:function(moLonLat){var olLonLat=null;if(moLonLat!=null){var lon=this.getLongitudeFromMapObjectLonLat(moLonLat);var lat=this.getLatitudeFromMapObjectLonLat(moLonLat);olLonLat=new OpenLayers.LonLat(lon,lat);}
60530 return olLonLat;},getMapObjectLonLatFromOLLonLat:function(olLonLat){var moLatLng=null;if(olLonLat!=null){moLatLng=this.getMapObjectLonLatFromLonLat(olLonLat.lon,olLonLat.lat);}
60531 return moLatLng;},getOLPixelFromMapObjectPixel:function(moPixel){var olPixel=null;if(moPixel!=null){var x=this.getXFromMapObjectPixel(moPixel);var y=this.getYFromMapObjectPixel(moPixel);olPixel=new OpenLayers.Pixel(x,y);}
60532 return olPixel;},getMapObjectPixelFromOLPixel:function(olPixel){var moPixel=null;if(olPixel!=null){moPixel=this.getMapObjectPixelFromXY(olPixel.x,olPixel.y);}
60533 return moPixel;},CLASS_NAME:"OpenLayers.Layer.EventPane"});OpenLayers.Layer.FixedZoomLevels=OpenLayers.Class({initialize:function(){},initResolutions:function(){var props=new Array('minZoomLevel','maxZoomLevel','numZoomLevels');for(var i=0,len=props.length;i<len;i++){var property=props[i];this[property]=(this.options[property]!=null)?this.options[property]:this.map[property];}
60534 if((this.minZoomLevel==null)||(this.minZoomLevel<this.MIN_ZOOM_LEVEL)){this.minZoomLevel=this.MIN_ZOOM_LEVEL;}
60535 var desiredZoomLevels;var limitZoomLevels=this.MAX_ZOOM_LEVEL-this.minZoomLevel+1;if(((this.options.numZoomLevels==null)&&(this.options.maxZoomLevel!=null))||((this.numZoomLevels==null)&&(this.maxZoomLevel!=null))){desiredZoomLevels=this.maxZoomLevel-this.minZoomLevel+1;}else{desiredZoomLevels=this.numZoomLevels;}
60536 if(desiredZoomLevels!=null){this.numZoomLevels=Math.min(desiredZoomLevels,limitZoomLevels);}else{this.numZoomLevels=limitZoomLevels;}
60537 this.maxZoomLevel=this.minZoomLevel+this.numZoomLevels-1;if(this.RESOLUTIONS!=null){var resolutionsIndex=0;this.resolutions=[];for(var i=this.minZoomLevel;i<=this.maxZoomLevel;i++){this.resolutions[resolutionsIndex++]=this.RESOLUTIONS[i];}
60538 this.maxResolution=this.resolutions[0];this.minResolution=this.resolutions[this.resolutions.length-1];}},getResolution:function(){if(this.resolutions!=null){return OpenLayers.Layer.prototype.getResolution.apply(this,arguments);}else{var resolution=null;var viewSize=this.map.getSize();var extent=this.getExtent();if((viewSize!=null)&&(extent!=null)){resolution=Math.max(extent.getWidth()/viewSize.w,extent.getHeight()/viewSize.h);}
60539 return resolution;}},getExtent:function(){var extent=null;var size=this.map.getSize();var tlPx=new OpenLayers.Pixel(0,0);var tlLL=this.getLonLatFromViewPortPx(tlPx);var brPx=new OpenLayers.Pixel(size.w,size.h);var brLL=this.getLonLatFromViewPortPx(brPx);if((tlLL!=null)&&(brLL!=null)){extent=new OpenLayers.Bounds(tlLL.lon,brLL.lat,brLL.lon,tlLL.lat);}
60540 return extent;},getZoomForResolution:function(resolution){if(this.resolutions!=null){return OpenLayers.Layer.prototype.getZoomForResolution.apply(this,arguments);}else{var extent=OpenLayers.Layer.prototype.getExtent.apply(this,[]);return this.getZoomForExtent(extent);}},getOLZoomFromMapObjectZoom:function(moZoom){var zoom=null;if(moZoom!=null){zoom=moZoom-this.minZoomLevel;}
60541 return zoom;},getMapObjectZoomFromOLZoom:function(olZoom){var zoom=null;if(olZoom!=null){zoom=olZoom+this.minZoomLevel;}
60542 return zoom;},CLASS_NAME:"OpenLayers.Layer.FixedZoomLevels"});OpenLayers.Layer.HTTPRequest=OpenLayers.Class(OpenLayers.Layer,{URL_HASH_FACTOR:(Math.sqrt(5)-1)/2,url:null,params:null,reproject:false,initialize:function(name,url,params,options){var newArguments=arguments;newArguments=[name,options];OpenLayers.Layer.prototype.initialize.apply(this,newArguments);this.url=url;this.params=OpenLayers.Util.extend({},params);},destroy:function(){this.url=null;this.params=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.HTTPRequest(this.name,this.url,this.params,this.getOptions());}
60543 obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);return obj;},setUrl:function(newUrl){this.url=newUrl;},mergeNewParams:function(newParams){this.params=OpenLayers.Util.extend(this.params,newParams);var ret=this.redraw();if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"params"});}
60544 return ret;},redraw:function(force){if(force){return this.mergeNewParams({"_olSalt":Math.random()});}else{return OpenLayers.Layer.prototype.redraw.apply(this,[]);}},selectUrl:function(paramString,urls){var product=1;for(var i=0,len=paramString.length;i<len;i++){product*=paramString.charCodeAt(i)*this.URL_HASH_FACTOR;product-=Math.floor(product);}
60545 return urls[Math.floor(product*urls.length)];},getFullRequestString:function(newParams,altUrl){var url=altUrl||this.url;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var paramsString=OpenLayers.Util.getParameterString(allParams);if(url instanceof Array){url=this.selectUrl(paramsString,url);}
60546 var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
60547 paramsString=OpenLayers.Util.getParameterString(allParams);return OpenLayers.Util.urlAppend(url,paramsString);},CLASS_NAME:"OpenLayers.Layer.HTTPRequest"});OpenLayers.Layer.Image=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:true,url:null,extent:null,size:null,tile:null,aspectRatio:null,initialize:function(name,url,extent,size,options){this.url=url;this.extent=extent;this.maxExtent=extent;this.size=size;OpenLayers.Layer.prototype.initialize.apply(this,[name,options]);this.aspectRatio=(this.extent.getHeight()/this.size.h)/(this.extent.getWidth()/this.size.w);},destroy:function(){if(this.tile){this.removeTileMonitoringHooks(this.tile);this.tile.destroy();this.tile=null;}
60548 OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Image(this.name,this.url,this.extent,this.size,this.getOptions());}
60549 obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);return obj;},setMap:function(map){if(this.options.maxResolution==null){this.options.maxResolution=this.aspectRatio*this.extent.getWidth()/this.size.w;}
60550 OpenLayers.Layer.prototype.setMap.apply(this,arguments);},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);var firstRendering=(this.tile==null);if(zoomChanged||firstRendering){this.setTileSize();var ul=new OpenLayers.LonLat(this.extent.left,this.extent.top);var ulPx=this.map.getLayerPxFromLonLat(ul);if(firstRendering){this.tile=new OpenLayers.Tile.Image(this,ulPx,this.extent,null,this.tileSize);this.addTileMonitoringHooks(this.tile);}else{this.tile.size=this.tileSize.clone();this.tile.position=ulPx.clone();}
60551 this.tile.draw();}},setTileSize:function(){var tileWidth=this.extent.getWidth()/this.map.getResolution();var tileHeight=this.extent.getHeight()/this.map.getResolution();this.tileSize=new OpenLayers.Size(tileWidth,tileHeight);},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){this.events.triggerEvent("loadstart");};tile.events.register("loadstart",this,tile.onLoadStart);tile.onLoadEnd=function(){this.events.triggerEvent("loadend");};tile.events.register("loadend",this,tile.onLoadEnd);tile.events.register("unload",this,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:this});},setUrl:function(newUrl){this.url=newUrl;this.tile.draw();},getURL:function(bounds){return this.url;},CLASS_NAME:"OpenLayers.Layer.Image"});OpenLayers.Layer.Markers=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:false,markers:null,drawn:false,initialize:function(name,options){OpenLayers.Layer.prototype.initialize.apply(this,arguments);this.markers=[];},destroy:function(){this.clearMarkers();this.markers=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},setOpacity:function(opacity){if(opacity!=this.opacity){this.opacity=opacity;for(var i=0,len=this.markers.length;i<len;i++){this.markers[i].setOpacity(this.opacity);}}},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);if(zoomChanged||!this.drawn){for(var i=0,len=this.markers.length;i<len;i++){this.drawMarker(this.markers[i]);}
60552 this.drawn=true;}},addMarker:function(marker){this.markers.push(marker);if(this.opacity!=null){marker.setOpacity(this.opacity);}
60553 if(this.map&&this.map.getExtent()){marker.map=this.map;this.drawMarker(marker);}},removeMarker:function(marker){if(this.markers&&this.markers.length){OpenLayers.Util.removeItem(this.markers,marker);marker.erase();}},clearMarkers:function(){if(this.markers!=null){while(this.markers.length>0){this.removeMarker(this.markers[0]);}}},drawMarker:function(marker){var px=this.map.getLayerPxFromLonLat(marker.lonlat);if(px==null){marker.display(false);}else{if(!marker.isDrawn()){var markerImg=marker.draw(px);this.div.appendChild(markerImg);}else if(marker.icon){marker.icon.moveTo(px);}}},getDataExtent:function(){var maxExtent=null;if(this.markers&&(this.markers.length>0)){var maxExtent=new OpenLayers.Bounds();for(var i=0,len=this.markers.length;i<len;i++){var marker=this.markers[i];maxExtent.extend(marker.lonlat);}}
60554 return maxExtent;},CLASS_NAME:"OpenLayers.Layer.Markers"});OpenLayers.Layer.SphericalMercator={getExtent:function(){var extent=null;if(this.sphericalMercator){extent=this.map.calculateBounds();}else{extent=OpenLayers.Layer.FixedZoomLevels.prototype.getExtent.apply(this);}
60555 return extent;},getLonLatFromViewPortPx:function(viewPortPx){return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this,arguments);},getViewPortPxFromLonLat:function(lonlat){return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this,arguments);},initMercatorParameters:function(){this.RESOLUTIONS=[];var maxResolution=156543.0339;for(var zoom=0;zoom<=this.MAX_ZOOM_LEVEL;++zoom){this.RESOLUTIONS[zoom]=maxResolution/Math.pow(2,zoom);}
60556 this.units="m";this.projection=this.projection||"EPSG:900913";},forwardMercator:function(lon,lat){var x=lon*20037508.34/180;var y=Math.log(Math.tan((90+lat)*Math.PI/360))/(Math.PI/180);y=y*20037508.34/180;return new OpenLayers.LonLat(x,y);},inverseMercator:function(x,y){var lon=(x/20037508.34)*180;var lat=(y/20037508.34)*180;lat=180/Math.PI*(2*Math.atan(Math.exp(lat*Math.PI/180))-Math.PI/2);return new OpenLayers.LonLat(lon,lat);},projectForward:function(point){var lonlat=OpenLayers.Layer.SphericalMercator.forwardMercator(point.x,point.y);point.x=lonlat.lon;point.y=lonlat.lat;return point;},projectInverse:function(point){var lonlat=OpenLayers.Layer.SphericalMercator.inverseMercator(point.x,point.y);point.x=lonlat.lon;point.y=lonlat.lat;return point;}};OpenLayers.Projection.addTransform("EPSG:4326","EPSG:900913",OpenLayers.Layer.SphericalMercator.projectForward);OpenLayers.Projection.addTransform("EPSG:900913","EPSG:4326",OpenLayers.Layer.SphericalMercator.projectInverse);OpenLayers.Tile.WFS=OpenLayers.Class(OpenLayers.Tile,{features:null,url:null,request:null,initialize:function(layer,position,bounds,url,size){OpenLayers.Tile.prototype.initialize.apply(this,arguments);this.url=url;this.features=[];},destroy:function(){OpenLayers.Tile.prototype.destroy.apply(this,arguments);this.destroyAllFeatures();this.features=null;this.url=null;if(this.request){this.request.abort();this.request=null;}},clear:function(){this.destroyAllFeatures();},draw:function(){if(OpenLayers.Tile.prototype.draw.apply(this,arguments)){if(this.isLoading){this.events.triggerEvent("reload");}else{this.isLoading=true;this.events.triggerEvent("loadstart");}
60557 this.loadFeaturesForRegion(this.requestSuccess);}},loadFeaturesForRegion:function(success,failure){if(this.request){this.request.abort();}
60558 this.request=OpenLayers.Request.GET({url:this.url,success:success,failure:failure,scope:this});},requestSuccess:function(request){if(this.features){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
60559 if(this.layer.vectorMode){this.layer.addFeatures(this.layer.formatObject.read(doc));}else{var xml=new OpenLayers.Format.XML();if(typeof doc=="string"){doc=xml.read(doc);}
60560 var resultFeatures=xml.getElementsByTagNameNS(doc,"http://www.opengis.net/gml","featureMember");this.addResults(resultFeatures);}}
60561 if(this.events){this.events.triggerEvent("loadend");}
60562 this.request=null;},addResults:function(results){for(var i=0;i<results.length;i++){var feature=new this.layer.featureClass(this.layer,results[i]);this.features.push(feature);}},destroyAllFeatures:function(){while(this.features.length>0){var feature=this.features.shift();feature.destroy();}},CLASS_NAME:"OpenLayers.Tile.WFS"});OpenLayers.Control.DrawFeature=OpenLayers.Class(OpenLayers.Control,{layer:null,callbacks:null,EVENT_TYPES:["featureadded"],multi:false,featureAdded:function(){},handlerOptions:null,initialize:function(layer,handler,options){this.EVENT_TYPES=OpenLayers.Control.DrawFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.drawFeature,modify:function(vertex,feature){this.layer.events.triggerEvent("sketchmodified",{vertex:vertex,feature:feature});},create:function(vertex,feature){this.layer.events.triggerEvent("sketchstarted",{vertex:vertex,feature:feature});}},this.callbacks);this.layer=layer;this.handlerOptions=this.handlerOptions||{};if(!("multi"in this.handlerOptions)){this.handlerOptions.multi=this.multi;}
60563 var sketchStyle=this.layer.styleMap&&this.layer.styleMap.styles.temporary;if(sketchStyle){this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{styleMap:new OpenLayers.StyleMap({"default":sketchStyle})});}
60564 this.handler=new handler(this,this.callbacks,this.handlerOptions);},drawFeature:function(geometry){var feature=new OpenLayers.Feature.Vector(geometry);var proceed=this.layer.events.triggerEvent("sketchcomplete",{feature:feature});if(proceed!==false){feature.state=OpenLayers.State.INSERT;this.layer.addFeatures([feature]);this.featureAdded(feature);this.events.triggerEvent("featureadded",{feature:feature});}},CLASS_NAME:"OpenLayers.Control.DrawFeature"});OpenLayers.Control.Measure=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:['measure','measurepartial'],handlerOptions:null,callbacks:null,displaySystem:'metric',geodesic:false,displaySystemUnits:{geographic:['dd'],english:['mi','ft','in'],metric:['km','m']},partialDelay:300,delayedTrigger:null,persist:false,initialize:function(handler,options){this.EVENT_TYPES=OpenLayers.Control.Measure.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.measureComplete,point:this.measurePartial},this.callbacks);this.handlerOptions=OpenLayers.Util.extend({persist:this.persist},this.handlerOptions);this.handler=new handler(this,this.callbacks,this.handlerOptions);},cancel:function(){this.handler.cancel();},updateHandler:function(handler,options){var active=this.active;if(active){this.deactivate();}
60565 this.handler=new handler(this,this.callbacks,options);if(active){this.activate();}},measureComplete:function(geometry){if(this.delayedTrigger){window.clearTimeout(this.delayedTrigger);}
60566 this.measure(geometry,"measure");},measurePartial:function(point,geometry){if(geometry.getLength()>0){geometry=geometry.clone();this.delayedTrigger=window.setTimeout(OpenLayers.Function.bind(function(){this.measure(geometry,"measurepartial");},this),this.partialDelay);}},measure:function(geometry,eventType){var stat,order;if(geometry.CLASS_NAME.indexOf('LineString')>-1){stat=this.getBestLength(geometry);order=1;}else{stat=this.getBestArea(geometry);order=2;}
60567 this.events.triggerEvent(eventType,{measure:stat[0],units:stat[1],order:order,geometry:geometry});},getBestArea:function(geometry){var units=this.displaySystemUnits[this.displaySystem];var unit,area;for(var i=0,len=units.length;i<len;++i){unit=units[i];area=this.getArea(geometry,unit);if(area>1){break;}}
60568 return[area,unit];},getArea:function(geometry,units){var area,geomUnits;if(this.geodesic){area=geometry.getGeodesicArea(this.map.getProjectionObject());geomUnits="m";}else{area=geometry.getArea();geomUnits=this.map.getUnits();}
60569 var inPerDisplayUnit=OpenLayers.INCHES_PER_UNIT[units];if(inPerDisplayUnit){var inPerMapUnit=OpenLayers.INCHES_PER_UNIT[geomUnits];area*=Math.pow((inPerMapUnit/inPerDisplayUnit),2);}
60570 return area;},getBestLength:function(geometry){var units=this.displaySystemUnits[this.displaySystem];var unit,length;for(var i=0,len=units.length;i<len;++i){unit=units[i];length=this.getLength(geometry,unit);if(length>1){break;}}
60571 return[length,unit];},getLength:function(geometry,units){var length,geomUnits;if(this.geodesic){length=geometry.getGeodesicLength(this.map.getProjectionObject());geomUnits="m";}else{length=geometry.getLength();geomUnits=this.map.getUnits();}
60572 var inPerDisplayUnit=OpenLayers.INCHES_PER_UNIT[units];if(inPerDisplayUnit){var inPerMapUnit=OpenLayers.INCHES_PER_UNIT[geomUnits];length*=(inPerMapUnit/inPerDisplayUnit);}
60573 return length;},CLASS_NAME:"OpenLayers.Control.Measure"});OpenLayers.Control.ZoomBox=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,out:false,alwaysZoom:false,draw:function(){this.handler=new OpenLayers.Handler.Box(this,{done:this.zoomBox},{keyMask:this.keyMask});},zoomBox:function(position){if(position instanceof OpenLayers.Bounds){var bounds;if(!this.out){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);}else{var pixWidth=Math.abs(position.right-position.left);var pixHeight=Math.abs(position.top-position.bottom);var zoomFactor=Math.min((this.map.size.h/pixHeight),(this.map.size.w/pixWidth));var extent=this.map.getExtent();var center=this.map.getLonLatFromPixel(position.getCenterPixel());var xmin=center.lon-(extent.getWidth()/2)*zoomFactor;var xmax=center.lon+(extent.getWidth()/2)*zoomFactor;var ymin=center.lat-(extent.getHeight()/2)*zoomFactor;var ymax=center.lat+(extent.getHeight()/2)*zoomFactor;bounds=new OpenLayers.Bounds(xmin,ymin,xmax,ymax);}
60574 var lastZoom=this.map.getZoom();this.map.zoomToExtent(bounds);if(lastZoom==this.map.getZoom()&&this.alwaysZoom==true){this.map.zoomTo(lastZoom+(this.out?-1:1));}}else{if(!this.out){this.map.setCenter(this.map.getLonLatFromPixel(position),this.map.getZoom()+1);}else{this.map.setCenter(this.map.getLonLatFromPixel(position),this.map.getZoom()-1);}}},CLASS_NAME:"OpenLayers.Control.ZoomBox"});OpenLayers.Format.WFSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.WFSCapabilities.v1,{initialize:function(options){OpenLayers.Format.WFSCapabilities.v1.prototype.initialize.apply(this,[options]);},read_cap_Service:function(capabilities,node){var service={};this.runChildNodes(service,node);capabilities.service=service;},read_cap_Fees:function(service,node){var fees=this.getChildValue(node);if(fees&&fees.toLowerCase()!="none"){service.fees=fees;}},read_cap_AccessConstraints:function(service,node){var constraints=this.getChildValue(node);if(constraints&&constraints.toLowerCase()!="none"){service.accessConstraints=constraints;}},read_cap_OnlineResource:function(service,node){var onlineResource=this.getChildValue(node);if(onlineResource&&onlineResource.toLowerCase()!="none"){service.onlineResource=onlineResource;}},read_cap_Keywords:function(service,node){var keywords=this.getChildValue(node);if(keywords&&keywords.toLowerCase()!="none"){service.keywords=keywords.split(', ');}},read_cap_Capability:function(capabilities,node){var capability={};this.runChildNodes(capability,node);capabilities.capability=capability;},read_cap_Request:function(obj,node){var request={};this.runChildNodes(request,node);obj.request=request;},read_cap_GetFeature:function(request,node){var getfeature={href:{},formats:[]};this.runChildNodes(getfeature,node);request.getfeature=getfeature;},read_cap_ResultFormat:function(obj,node){var children=node.childNodes;var childNode;for(var i=0;i<children.length;i++){childNode=children[i];if(childNode.nodeType==1){obj.formats.push(childNode.nodeName);}}},read_cap_DCPType:function(obj,node){this.runChildNodes(obj,node);},read_cap_HTTP:function(obj,node){this.runChildNodes(obj.href,node);},read_cap_Get:function(obj,node){obj.get=node.getAttribute("onlineResource");},read_cap_Post:function(obj,node){obj.post=node.getAttribute("onlineResource");},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1_0_0"});OpenLayers.Format.WFSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WFSCapabilities.v1,{initialize:function(options){OpenLayers.Format.WFSCapabilities.v1.prototype.initialize.apply(this,[options]);},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1_1_0"});OpenLayers.Format.WKT=OpenLayers.Class(OpenLayers.Format,{initialize:function(options){this.regExes={'typeStr':/^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,'spaces':/\s+/,'parenComma':/\)\s*,\s*\(/,'doubleParenComma':/\)\s*\)\s*,\s*\(\s*\(/,'trimParens':/^\s*\(?(.*?)\)?\s*$/};OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(wkt){var features,type,str;var matches=this.regExes.typeStr.exec(wkt);if(matches){type=matches[1].toLowerCase();str=matches[2];if(this.parse[type]){features=this.parse[type].apply(this,[str]);}
60575 if(this.internalProjection&&this.externalProjection){if(features&&features.CLASS_NAME=="OpenLayers.Feature.Vector"){features.geometry.transform(this.externalProjection,this.internalProjection);}else if(features&&type!="geometrycollection"&&typeof features=="object"){for(var i=0,len=features.length;i<len;i++){var component=features[i];component.geometry.transform(this.externalProjection,this.internalProjection);}}}}
60576 return features;},write:function(features){var collection,geometry,type,data,isCollection;if(features.constructor==Array){collection=features;isCollection=true;}else{collection=[features];isCollection=false;}
60577 var pieces=[];if(isCollection){pieces.push('GEOMETRYCOLLECTION(');}
60578 for(var i=0,len=collection.length;i<len;++i){if(isCollection&&i>0){pieces.push(',');}
60579 geometry=collection[i].geometry;type=geometry.CLASS_NAME.split('.')[2].toLowerCase();if(!this.extract[type]){return null;}
60580 if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
60581 data=this.extract[type].apply(this,[geometry]);pieces.push(type.toUpperCase()+'('+data+')');}
60582 if(isCollection){pieces.push(')');}
60583 return pieces.join('');},extract:{'point':function(point){return point.x+' '+point.y;},'multipoint':function(multipoint){var array=[];for(var i=0,len=multipoint.components.length;i<len;++i){array.push('('+
60584 this.extract.point.apply(this,[multipoint.components[i]])+')');}
60585 return array.join(',');},'linestring':function(linestring){var array=[];for(var i=0,len=linestring.components.length;i<len;++i){array.push(this.extract.point.apply(this,[linestring.components[i]]));}
60586 return array.join(',');},'multilinestring':function(multilinestring){var array=[];for(var i=0,len=multilinestring.components.length;i<len;++i){array.push('('+
60587 this.extract.linestring.apply(this,[multilinestring.components[i]])+')');}
60588 return array.join(',');},'polygon':function(polygon){var array=[];for(var i=0,len=polygon.components.length;i<len;++i){array.push('('+
60589 this.extract.linestring.apply(this,[polygon.components[i]])+')');}
60590 return array.join(',');},'multipolygon':function(multipolygon){var array=[];for(var i=0,len=multipolygon.components.length;i<len;++i){array.push('('+
60591 this.extract.polygon.apply(this,[multipolygon.components[i]])+')');}
60592 return array.join(',');}},parse:{'point':function(str){var coords=OpenLayers.String.trim(str).split(this.regExes.spaces);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(coords[0],coords[1]));},'multipoint':function(str){var point;var points=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=points.length;i<len;++i){point=points[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.point.apply(this,[point]).geometry);}
60593 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPoint(components));},'linestring':function(str){var points=OpenLayers.String.trim(str).split(',');var components=[];for(var i=0,len=points.length;i<len;++i){components.push(this.parse.point.apply(this,[points[i]]).geometry);}
60594 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(components));},'multilinestring':function(str){var line;var lines=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=lines.length;i<len;++i){line=lines[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.linestring.apply(this,[line]).geometry);}
60595 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiLineString(components));},'polygon':function(str){var ring,linestring,linearring;var rings=OpenLayers.String.trim(str).split(this.regExes.parenComma);var components=[];for(var i=0,len=rings.length;i<len;++i){ring=rings[i].replace(this.regExes.trimParens,'$1');linestring=this.parse.linestring.apply(this,[ring]).geometry;linearring=new OpenLayers.Geometry.LinearRing(linestring.components);components.push(linearring);}
60596 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon(components));},'multipolygon':function(str){var polygon;var polygons=OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);var components=[];for(var i=0,len=polygons.length;i<len;++i){polygon=polygons[i].replace(this.regExes.trimParens,'$1');components.push(this.parse.polygon.apply(this,[polygon]).geometry);}
60597 return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPolygon(components));},'geometrycollection':function(str){str=str.replace(/,\s*([A-Za-z])/g,'|$1');var wktArray=OpenLayers.String.trim(str).split('|');var components=[];for(var i=0,len=wktArray.length;i<len;++i){components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));}
60598 return components;}},CLASS_NAME:"OpenLayers.Format.WKT"});OpenLayers.Format.WMC.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ol:"http://openlayers.org/context",wmc:"http://www.opengis.net/context",sld:"http://www.opengis.net/sld",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"",getNamespacePrefix:function(uri){var prefix=null;if(uri==null){prefix=this.namespaces[this.defaultPrefix];}else{for(prefix in this.namespaces){if(this.namespaces[prefix]==uri){break;}}}
60599 return prefix;},defaultPrefix:"wmc",rootPrefix:null,defaultStyleName:"",defaultStyleTitle:"Default",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60600 var root=data.documentElement;this.rootPrefix=root.prefix;var context={version:root.getAttribute("version")};this.runChildNodes(context,root);return context;},runChildNodes:function(obj,node){var children=node.childNodes;var childNode,processor,prefix,local;for(var i=0,len=children.length;i<len;++i){childNode=children[i];if(childNode.nodeType==1){prefix=this.getNamespacePrefix(childNode.namespaceURI);local=childNode.nodeName.split(":").pop();processor=this["read_"+prefix+"_"+local];if(processor){processor.apply(this,[obj,childNode]);}}}},read_wmc_General:function(context,node){this.runChildNodes(context,node);},read_wmc_BoundingBox:function(context,node){context.projection=node.getAttribute("SRS");context.bounds=new OpenLayers.Bounds(parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy")));},read_wmc_LayerList:function(context,node){context.layersContext=[];this.runChildNodes(context,node);},read_wmc_Layer:function(context,node){var layerContext={visibility:(node.getAttribute("hidden")!="1"),queryable:(node.getAttribute("queryable")=="1"),formats:[],styles:[]};this.runChildNodes(layerContext,node);context.layersContext.push(layerContext);},read_wmc_Extension:function(obj,node){this.runChildNodes(obj,node);},read_ol_units:function(layerContext,node){layerContext.units=this.getChildValue(node);},read_ol_maxExtent:function(obj,node){var bounds=new OpenLayers.Bounds(node.getAttribute("minx"),node.getAttribute("miny"),node.getAttribute("maxx"),node.getAttribute("maxy"));obj.maxExtent=bounds;},read_ol_transparent:function(layerContext,node){layerContext.transparent=this.getChildValue(node);},read_ol_numZoomLevels:function(layerContext,node){layerContext.numZoomLevels=parseInt(this.getChildValue(node));},read_ol_opacity:function(layerContext,node){layerContext.opacity=parseFloat(this.getChildValue(node));},read_ol_singleTile:function(layerContext,node){layerContext.singleTile=(this.getChildValue(node)=="true");},read_ol_tileSize:function(layerContext,node){var obj={"width":node.getAttribute("width"),"height":node.getAttribute("height")};layerContext.tileSize=obj;},read_ol_isBaseLayer:function(layerContext,node){layerContext.isBaseLayer=(this.getChildValue(node)=="true");},read_ol_displayInLayerSwitcher:function(layerContext,node){layerContext.displayInLayerSwitcher=(this.getChildValue(node)=="true");},read_wmc_Server:function(layerContext,node){layerContext.version=node.getAttribute("version");var server={};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(server,links[0]);}
60601 layerContext.url=server.href;},read_wmc_FormatList:function(layerContext,node){this.runChildNodes(layerContext,node);},read_wmc_Format:function(layerContext,node){var format={value:this.getChildValue(node)};if(node.getAttribute("current")=="1"){format.current=true;}
60602 layerContext.formats.push(format);},read_wmc_StyleList:function(layerContext,node){this.runChildNodes(layerContext,node);},read_wmc_Style:function(layerContext,node){var style={};this.runChildNodes(style,node);if(node.getAttribute("current")=="1"){style.current=true;}
60603 layerContext.styles.push(style);},read_wmc_SLD:function(style,node){this.runChildNodes(style,node);},read_sld_StyledLayerDescriptor:function(sld,node){var xml=OpenLayers.Format.XML.prototype.write.apply(this,[node]);sld.body=xml;},read_wmc_OnlineResource:function(obj,node){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},read_wmc_Name:function(obj,node){var name=this.getChildValue(node);if(name){obj.name=name;}},read_wmc_Title:function(obj,node){var title=this.getChildValue(node);if(title){obj.title=title;}},read_wmc_MetadataURL:function(layerContext,node){var metadataURL={};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(metadataURL,links[0]);}
60604 layerContext.metadataURL=metadataURL.href;},read_wmc_Abstract:function(obj,node){var abst=this.getChildValue(node);if(abst){obj["abstract"]=abst;}},read_wmc_LegendURL:function(style,node){var legend={width:node.getAttribute('width'),height:node.getAttribute('height')};var links=node.getElementsByTagName("OnlineResource");if(links.length>0){this.read_wmc_OnlineResource(legend,links[0]);}
60605 style.legend=legend;},write:function(context,options){var root=this.createElementDefaultNS("ViewContext");this.setAttributes(root,{version:this.VERSION,id:(options&&typeof options.id=="string")?options.id:OpenLayers.Util.createUniqueID("OpenLayers_Context_")});this.setAttributeNS(root,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);root.appendChild(this.write_wmc_General(context));root.appendChild(this.write_wmc_LayerList(context));return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},createElementDefaultNS:function(name,childValue,attributes){var node=this.createElementNS(this.namespaces[this.defaultPrefix],name);if(childValue){node.appendChild(this.createTextNode(childValue));}
60606 if(attributes){this.setAttributes(node,attributes);}
60607 return node;},setAttributes:function(node,obj){var value;for(var name in obj){value=obj[name].toString();if(value.match(/[A-Z]/)){this.setAttributeNS(node,null,name,value);}else{node.setAttribute(name,value);}}},write_wmc_General:function(context){var node=this.createElementDefaultNS("General");if(context.size){node.appendChild(this.createElementDefaultNS("Window",null,{width:context.size.w,height:context.size.h}));}
60608 var bounds=context.bounds;node.appendChild(this.createElementDefaultNS("BoundingBox",null,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18),SRS:context.projection}));node.appendChild(this.createElementDefaultNS("Title",context.title));node.appendChild(this.write_ol_MapExtension(context));return node;},write_ol_MapExtension:function(context){var node=this.createElementDefaultNS("Extension");var bounds=context.maxExtent;if(bounds){var maxExtent=this.createElementNS(this.namespaces.ol,"ol:maxExtent");this.setAttributes(maxExtent,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18)});node.appendChild(maxExtent);}
60609 return node;},write_wmc_LayerList:function(context){var list=this.createElementDefaultNS("LayerList");for(var i=0,len=context.layersContext.length;i<len;++i){list.appendChild(this.write_wmc_Layer(context.layersContext[i]));}
60610 return list;},write_wmc_Layer:function(context){var node=this.createElementDefaultNS("Layer",null,{queryable:context.queryable?"1":"0",hidden:context.visibility?"0":"1"});node.appendChild(this.write_wmc_Server(context));node.appendChild(this.createElementDefaultNS("Name",context.name));node.appendChild(this.createElementDefaultNS("Title",context.title));if(context.metadataURL){node.appendChild(this.write_wmc_MetadataURL(context.metadataURL));}
60611 return node;},write_wmc_LayerExtension:function(context){var node=this.createElementDefaultNS("Extension");var bounds=context.maxExtent;var maxExtent=this.createElementNS(this.namespaces.ol,"ol:maxExtent");this.setAttributes(maxExtent,{minx:bounds.left.toPrecision(18),miny:bounds.bottom.toPrecision(18),maxx:bounds.right.toPrecision(18),maxy:bounds.top.toPrecision(18)});node.appendChild(maxExtent);if(context.tileSize&&!context.singleTile){var size=this.createElementNS(this.namespaces.ol,"ol:tileSize");this.setAttributes(size,context.tileSize);node.appendChild(size);}
60612 var properties=["transparent","numZoomLevels","units","isBaseLayer","opacity","displayInLayerSwitcher","singleTile"];var child;for(var i=0,len=properties.length;i<len;++i){child=this.createOLPropertyNode(context,properties[i]);if(child){node.appendChild(child);}}
60613 return node;},createOLPropertyNode:function(obj,prop){var node=null;if(obj[prop]!=null){node=this.createElementNS(this.namespaces.ol,"ol:"+prop);node.appendChild(this.createTextNode(obj[prop].toString()));}
60614 return node;},write_wmc_Server:function(context){var node=this.createElementDefaultNS("Server");this.setAttributes(node,{service:"OGC:WMS",version:context.version});node.appendChild(this.write_wmc_OnlineResource(context.url));return node;},write_wmc_MetadataURL:function(metadataURL){var node=this.createElementDefaultNS("MetadataURL");node.appendChild(this.write_wmc_OnlineResource(metadataURL));return node;},write_wmc_FormatList:function(context){var node=this.createElementDefaultNS("FormatList");for(var i=0,len=context.formats.length;i<len;i++){var format=context.formats[i];node.appendChild(this.createElementDefaultNS("Format",format.value,(format.current&&format.current==true)?{current:"1"}:null));}
60615 return node;},write_wmc_StyleList:function(layer){var node=this.createElementDefaultNS("StyleList");var styles=layer.styles;if(styles&&styles instanceof Array){var sld;for(var i=0,len=styles.length;i<len;i++){var s=styles[i];var style=this.createElementDefaultNS("Style",null,(s.current&&s.current==true)?{current:"1"}:null);if(s.href){sld=this.createElementDefaultNS("SLD");var link=this.write_wmc_OnlineResource(s.href);sld.appendChild(link);sld.appendChild(this.createElementDefaultNS("Name",s.name));if(s.title){sld.appendChild(this.createElementDefaultNS("Title",s.title));}
60616 style.appendChild(sld);}else if(s.body){sld=this.createElementDefaultNS("SLD");var doc=OpenLayers.Format.XML.prototype.read.apply(this,[s.body]);var imported=doc.documentElement;if(sld.ownerDocument&&sld.ownerDocument.importNode){imported=sld.ownerDocument.importNode(imported,true);}
60617 sld.appendChild(imported);sld.appendChild(this.createElementDefaultNS("Name",s.name));if(s.title){sld.appendChild(this.createElementDefaultNS("Title",s.title));}
60618 style.appendChild(sld);}else{style.appendChild(this.createElementDefaultNS("Name",s.name));style.appendChild(this.createElementDefaultNS("Title",s.title));if(s['abstract']){style.appendChild(this.createElementDefaultNS("Abstract",s['abstract']));}}
60619 node.appendChild(style);}}
60620 return node;},write_wmc_OnlineResource:function(href){var node=this.createElementDefaultNS("OnlineResource");this.setAttributeNS(node,this.namespaces.xlink,"xlink:type","simple");this.setAttributeNS(node,this.namespaces.xlink,"xlink:href",href);return node;},CLASS_NAME:"OpenLayers.Format.WMC.v1"});OpenLayers.Format.WMSCapabilities.v1_1=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1,{readers:{"wms":OpenLayers.Util.applyDefaults({"WMT_MS_Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Keyword":function(node,obj){if(obj.keywords){obj.keywords.push(this.getChildValue(node));}},"DescribeLayer":function(node,obj){obj.describelayer={formats:[]};this.readChildNodes(node,obj.describelayer);},"GetLegendGraphic":function(node,obj){obj.getlegendgraphic={formats:[]};this.readChildNodes(node,obj.getlegendgraphic);},"GetStyles":function(node,obj){obj.getstyles={formats:[]};this.readChildNodes(node,obj.getstyles);},"PutStyles":function(node,obj){obj.putstyles={formats:[]};this.readChildNodes(node,obj.putstyles);},"UserDefinedSymbolization":function(node,obj){var userSymbols={supportSLD:parseInt(node.getAttribute("SupportSLD"))==1,userLayer:parseInt(node.getAttribute("UserLayer"))==1,userStyle:parseInt(node.getAttribute("UserStyle"))==1,remoteWFS:parseInt(node.getAttribute("RemoteWFS"))==1};obj.userSymbols=userSymbols;},"LatLonBoundingBox":function(node,obj){obj.llbbox=[parseFloat(node.getAttribute("minx")),parseFloat(node.getAttribute("miny")),parseFloat(node.getAttribute("maxx")),parseFloat(node.getAttribute("maxy"))];},"BoundingBox":function(node,obj){var bbox=OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"].BoundingBox.apply(this,[node,obj]);bbox.srs=node.getAttribute("SRS");obj.bbox[bbox.srs]=bbox;},"ScaleHint":function(node,obj){var min=node.getAttribute("min");var max=node.getAttribute("max");var rad2=Math.pow(2,0.5);var ipm=OpenLayers.INCHES_PER_UNIT["m"];obj.maxScale=parseFloat(((min/rad2)*ipm*OpenLayers.DOTS_PER_INCH).toPrecision(13));obj.minScale=parseFloat(((max/rad2)*ipm*OpenLayers.DOTS_PER_INCH).toPrecision(13));},"Dimension":function(node,obj){var name=node.getAttribute("name").toLowerCase();var dim={name:name,units:node.getAttribute("units"),unitsymbol:node.getAttribute("unitSymbol")};obj.dimensions[dim.name]=dim;},"Extent":function(node,obj){var name=node.getAttribute("name").toLowerCase();if(name in obj["dimensions"]){var extent=obj.dimensions[name];extent.nearestVal=node.getAttribute("nearestValue")==="1";extent.multipleVal=node.getAttribute("multipleValues")==="1";extent.current=node.getAttribute("current")==="1";extent["default"]=node.getAttribute("default")||"";var values=this.getChildValue(node);extent.values=values.split(",");}}},OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1"});OpenLayers.Format.WMSCapabilities.v1_3=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1,{readers:{"wms":OpenLayers.Util.applyDefaults({"WMS_Capabilities":function(node,obj){this.readChildNodes(node,obj);},"LayerLimit":function(node,obj){obj.layerLimit=parseInt(this.getChildValue(node));},"MaxWidth":function(node,obj){obj.maxWidth=parseInt(this.getChildValue(node));},"MaxHeight":function(node,obj){obj.maxHeight=parseInt(this.getChildValue(node));},"BoundingBox":function(node,obj){var bbox=OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"].BoundingBox.apply(this,[node,obj]);bbox.srs=node.getAttribute("CRS");obj.bbox[bbox.srs]=bbox;},"CRS":function(node,obj){this.readers.wms.SRS.apply(this,[node,obj]);},"EX_GeographicBoundingBox":function(node,obj){obj.llbbox=[];this.readChildNodes(node,obj.llbbox);},"westBoundLongitude":function(node,obj){obj[0]=this.getChildValue(node);},"eastBoundLongitude":function(node,obj){obj[2]=this.getChildValue(node);},"southBoundLatitude":function(node,obj){obj[1]=this.getChildValue(node);},"northBoundLatitude":function(node,obj){obj[3]=this.getChildValue(node);},"MinScaleDenominator":function(node,obj){obj.maxScale=parseFloat(this.getChildValue(node)).toPrecision(16);},"MaxScaleDenominator":function(node,obj){obj.minScale=parseFloat(this.getChildValue(node)).toPrecision(16);},"Dimension":function(node,obj){var name=node.getAttribute("name").toLowerCase();var dim={name:name,units:node.getAttribute("units"),unitsymbol:node.getAttribute("unitSymbol"),nearestVal:node.getAttribute("nearestValue")==="1",multipleVal:node.getAttribute("multipleValues")==="1","default":node.getAttribute("default")||"",current:node.getAttribute("current")==="1",values:this.getChildValue(node).split(",")};obj.dimensions[dim.name]=dim;},"Keyword":function(node,obj){var keyword={value:this.getChildValue(node),vocabulary:node.getAttribute("vocabulary")};if(obj.keywords){obj.keywords.push(keyword);}}},OpenLayers.Format.WMSCapabilities.v1.prototype.readers["wms"]),"sld":{"UserDefinedSymbolization":function(node,obj){this.readers.wms.UserDefinedSymbolization.apply(this,[node,obj]);obj.userSymbols.inlineFeature=parseInt(node.getAttribute("InlineFeature"))==1;obj.userSymbols.remoteWCS=parseInt(node.getAttribute("RemoteWCS"))==1;},"DescribeLayer":function(node,obj){this.readers.wms.DescribeLayer.apply(this,[node,obj]);},"GetLegendGraphic":function(node,obj){this.readers.wms.GetLegendGraphic.apply(this,[node,obj]);}}},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_3"});OpenLayers.Format.WMTSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1_1_0,{version:"1.0.0",namespaces:{ows:"http://www.opengis.net/ows/1.1",wmts:"http://www.opengis.net/wmts/1.0",xlink:"http://www.w3.org/1999/xlink"},yx:null,defaultPrefix:"wmts",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;var yx=OpenLayers.Util.extend({},OpenLayers.Format.WMTSCapabilities.prototype.yx);this.yx=OpenLayers.Util.extend(yx,this.yx);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60621 if(data&&data.nodeType==9){data=data.documentElement;}
60622 var capabilities={};this.readNode(data,capabilities);capabilities.version=this.version;return capabilities;},readers:{"wmts":{"Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Contents":function(node,obj){obj.contents={};obj.contents.layers=[];obj.contents.tileMatrixSets={};this.readChildNodes(node,obj.contents);},"Layer":function(node,obj){var layer={styles:[],formats:[],tileMatrixSetLinks:[]};layer.layers=[];this.readChildNodes(node,layer);obj.layers.push(layer);},"Style":function(node,obj){var style={};style.isDefault=(node.getAttribute("isDefault")==="true");this.readChildNodes(node,style);obj.styles.push(style);},"Format":function(node,obj){obj.formats.push(this.getChildValue(node));},"TileMatrixSetLink":function(node,obj){var tileMatrixSetLink={};this.readChildNodes(node,tileMatrixSetLink);obj.tileMatrixSetLinks.push(tileMatrixSetLink);},"TileMatrixSet":function(node,obj){if(obj.layers){var tileMatrixSet={matrixIds:[]};this.readChildNodes(node,tileMatrixSet);obj.tileMatrixSets[tileMatrixSet.identifier]=tileMatrixSet;}else{obj.tileMatrixSet=this.getChildValue(node);}},"TileMatrix":function(node,obj){var tileMatrix={supportedCRS:obj.supportedCRS};this.readChildNodes(node,tileMatrix);obj.matrixIds.push(tileMatrix);},"ScaleDenominator":function(node,obj){obj.scaleDenominator=parseFloat(this.getChildValue(node));},"TopLeftCorner":function(node,obj){var topLeftCorner=this.getChildValue(node);var coords=topLeftCorner.split(" ");var yx;if(obj.supportedCRS){var crs=obj.supportedCRS.replace(/urn:ogc:def:crs:(\w+):.+:(\w+)$/,"urn:ogc:def:crs:$1::$2");yx=!!this.yx[crs];}
60623 if(yx){obj.topLeftCorner=new OpenLayers.LonLat(coords[1],coords[0]);}else{obj.topLeftCorner=new OpenLayers.LonLat(coords[0],coords[1]);}},"TileWidth":function(node,obj){obj.tileWidth=parseInt(this.getChildValue(node));},"TileHeight":function(node,obj){obj.tileHeight=parseInt(this.getChildValue(node));},"MatrixWidth":function(node,obj){obj.matrixWidth=parseInt(this.getChildValue(node));},"MatrixHeight":function(node,obj){obj.matrixHeight=parseInt(this.getChildValue(node));},"WSDL":function(node,obj){obj.wsdl={};obj.wsdl.href=node.getAttribute("xlink:href");},"ServiceMetadataURL":function(node,obj){obj.serviceMetadataUrl={};obj.serviceMetadataUrl.href=node.getAttribute("xlink:href");}},"ows":OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers["ows"]},CLASS_NAME:"OpenLayers.Format.WMTSCapabilities.v1_0_0"});OpenLayers.Layer.Boxes=OpenLayers.Class(OpenLayers.Layer.Markers,{initialize:function(name,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,arguments);},drawMarker:function(marker){var bounds=marker.bounds;var topleft=this.map.getLayerPxFromLonLat(new OpenLayers.LonLat(bounds.left,bounds.top));var botright=this.map.getLayerPxFromLonLat(new OpenLayers.LonLat(bounds.right,bounds.bottom));if(botright==null||topleft==null){marker.display(false);}else{var sz=new OpenLayers.Size(Math.max(1,botright.x-topleft.x),Math.max(1,botright.y-topleft.y));var markerDiv=marker.draw(topleft,sz);if(!marker.drawn){this.div.appendChild(markerDiv);marker.drawn=true;}}},removeMarker:function(marker){OpenLayers.Util.removeItem(this.markers,marker);if((marker.div!=null)&&(marker.div.parentNode==this.div)){this.div.removeChild(marker.div);}},CLASS_NAME:"OpenLayers.Layer.Boxes"});OpenLayers.Layer.GeoRSS=OpenLayers.Class(OpenLayers.Layer.Markers,{location:null,features:null,formatOptions:null,selectedFeature:null,icon:null,popupSize:null,useFeedTitle:true,initialize:function(name,location,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,[name,options]);this.location=location;this.features=[];},destroy:function(){OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);this.clearFeatures();this.features=null;},loadRSS:function(){if(!this.loaded){this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.location,success:this.parseData,scope:this});this.loaded=true;}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadRSS();}},parseData:function(ajaxRequest){var doc=ajaxRequest.responseXML;if(!doc||!doc.documentElement){doc=OpenLayers.Format.XML.prototype.read(ajaxRequest.responseText);}
60624 if(this.useFeedTitle){var name=null;try{name=doc.getElementsByTagNameNS('*','title')[0].firstChild.nodeValue;}
60625 catch(e){name=doc.getElementsByTagName('title')[0].firstChild.nodeValue;}
60626 if(name){this.setName(name);}}
60627 var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
60628 var format=new OpenLayers.Format.GeoRSS(options);var features=format.read(doc);for(var i=0,len=features.length;i<len;i++){var data={};var feature=features[i];if(!feature.geometry){continue;}
60629 var title=feature.attributes.title?feature.attributes.title:"Untitled";var description=feature.attributes.description?feature.attributes.description:"No description.";var link=feature.attributes.link?feature.attributes.link:"";var location=feature.geometry.getBounds().getCenterLonLat();data.icon=this.icon==null?OpenLayers.Marker.defaultIcon():this.icon.clone();data.popupSize=this.popupSize?this.popupSize.clone():new OpenLayers.Size(250,120);if(title||description){data.title=title;data.description=description;var contentHTML='<div class="olLayerGeoRSSClose">[x]</div>';contentHTML+='<div class="olLayerGeoRSSTitle">';if(link){contentHTML+='<a class="link" href="'+link+'" target="_blank">';}
60630 contentHTML+=title;if(link){contentHTML+='</a>';}
60631 contentHTML+='</div>';contentHTML+='<div style="" class="olLayerGeoRSSDescription">';contentHTML+=description;contentHTML+='</div>';data['popupContentHTML']=contentHTML;}
60632 var feature=new OpenLayers.Feature(this,location,data);this.features.push(feature);var marker=feature.createMarker();marker.events.register('click',feature,this.markerClick);this.addMarker(marker);}
60633 this.events.triggerEvent("loadend");},markerClick:function(evt){var sameMarkerClicked=(this==this.layer.selectedFeature);this.layer.selectedFeature=(!sameMarkerClicked)?this:null;for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}
60634 if(!sameMarkerClicked){var popup=this.createPopup();OpenLayers.Event.observe(popup.div,"click",OpenLayers.Function.bind(function(){for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}},this));this.layer.map.addPopup(popup);}
60635 OpenLayers.Event.stop(evt);},clearFeatures:function(){if(this.features!=null){while(this.features.length>0){var feature=this.features[0];OpenLayers.Util.removeItem(this.features,feature);feature.destroy();}}},CLASS_NAME:"OpenLayers.Layer.GeoRSS"});OpenLayers.Layer.Google=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:0,MAX_ZOOM_LEVEL:21,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031,0.00000536441802978515,0.00000268220901489257,0.0000013411045074462891,0.00000067055225372314453],type:null,wrapDateLine:true,sphericalMercator:false,version:null,initialize:function(name,options){options=options||{};if(!options.version){options.version=typeof GMap2==="function"?"2":"3";}
60636 var mixin=OpenLayers.Layer.Google["v"+
60637 options.version.replace(/\./g,"_")];if(mixin){OpenLayers.Util.applyDefaults(options,mixin);}else{throw"Unsupported Google Maps API version: "+options.version;}
60638 OpenLayers.Util.applyDefaults(options,mixin.DEFAULTS);if(options.maxExtent){options.maxExtent=options.maxExtent.clone();}
60639 OpenLayers.Layer.EventPane.prototype.initialize.apply(this,[name,options]);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,[name,options]);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},clone:function(){return new OpenLayers.Layer.Google(this.name,this.getOptions());},setVisibility:function(visible){var opacity=this.opacity==null?1:this.opacity;OpenLayers.Layer.EventPane.prototype.setVisibility.apply(this,arguments);this.setOpacity(opacity);},display:function(visible){if(!this._dragging){this.setGMapVisibility(visible);}
60640 OpenLayers.Layer.EventPane.prototype.display.apply(this,arguments);},moveTo:function(bounds,zoomChanged,dragging){this._dragging=dragging;OpenLayers.Layer.EventPane.prototype.moveTo.apply(this,arguments);delete this._dragging;},setOpacity:function(opacity){if(opacity!==this.opacity){if(this.map!=null){this.map.events.triggerEvent("changelayer",{layer:this,property:"opacity"});}
60641 this.opacity=opacity;}
60642 if(this.getVisibility()){var container=this.getMapContainer();OpenLayers.Util.modifyDOMElement(container,null,null,null,null,null,null,opacity);}},destroy:function(){if(this.map){this.setGMapVisibility(false);var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache&&cache.count<=1){this.removeGMapElements();}}
60643 OpenLayers.Layer.EventPane.prototype.destroy.apply(this,arguments);},removeGMapElements:function(){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var container=this.mapObject&&this.getMapContainer();if(container&&container.parentNode){container.parentNode.removeChild(container);}
60644 var termsOfUse=cache.termsOfUse;if(termsOfUse&&termsOfUse.parentNode){termsOfUse.parentNode.removeChild(termsOfUse);}
60645 var poweredBy=cache.poweredBy;if(poweredBy&&poweredBy.parentNode){poweredBy.parentNode.removeChild(poweredBy);}}},removeMap:function(map){if(this.visibility&&this.mapObject){this.setGMapVisibility(false);}
60646 var cache=OpenLayers.Layer.Google.cache[map.id];if(cache){if(cache.count<=1){this.removeGMapElements();delete OpenLayers.Layer.Google.cache[map.id];}else{--cache.count;}}
60647 delete this.termsOfUse;delete this.poweredBy;delete this.mapObject;delete this.dragObject;OpenLayers.Layer.EventPane.prototype.removeMap.apply(this,arguments);},getOLBoundsFromMapObjectBounds:function(moBounds){var olBounds=null;if(moBounds!=null){var sw=moBounds.getSouthWest();var ne=moBounds.getNorthEast();if(this.sphericalMercator){sw=this.forwardMercator(sw.lng(),sw.lat());ne=this.forwardMercator(ne.lng(),ne.lat());}else{sw=new OpenLayers.LonLat(sw.lng(),sw.lat());ne=new OpenLayers.LonLat(ne.lng(),ne.lat());}
60648 olBounds=new OpenLayers.Bounds(sw.lon,sw.lat,ne.lon,ne.lat);}
60649 return olBounds;},getWarningHTML:function(){return OpenLayers.i18n("googleWarning");},getMapObjectCenter:function(){return this.mapObject.getCenter();},getMapObjectZoom:function(){return this.mapObject.getZoom();},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lng(),moLonLat.lat()).lon:moLonLat.lng();},getLatitudeFromMapObjectLonLat:function(moLonLat){var lat=this.sphericalMercator?this.forwardMercator(moLonLat.lng(),moLonLat.lat()).lat:moLonLat.lat();return lat;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},CLASS_NAME:"OpenLayers.Layer.Google"});OpenLayers.Layer.Google.cache={};OpenLayers.Layer.Google.v2={termsOfUse:null,poweredBy:null,dragObject:null,loadMapObject:function(){if(!this.type){this.type=G_NORMAL_MAP;}
60650 var mapObject,termsOfUse,poweredBy;var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){mapObject=cache.mapObject;termsOfUse=cache.termsOfUse;poweredBy=cache.poweredBy;++cache.count;}else{var container=this.map.viewPortDiv;var div=document.createElement("div");div.id=this.map.id+"_GMap2Container";div.style.position="absolute";div.style.width="100%";div.style.height="100%";container.appendChild(div);try{mapObject=new GMap2(div);termsOfUse=div.lastChild;container.appendChild(termsOfUse);termsOfUse.style.zIndex="1100";termsOfUse.style.right="";termsOfUse.style.bottom="";termsOfUse.className="olLayerGoogleCopyright";poweredBy=div.lastChild;container.appendChild(poweredBy);poweredBy.style.zIndex="1100";poweredBy.style.right="";poweredBy.style.bottom="";poweredBy.className="olLayerGooglePoweredBy gmnoprint";}catch(e){throw(e);}
60651 OpenLayers.Layer.Google.cache[this.map.id]={mapObject:mapObject,termsOfUse:termsOfUse,poweredBy:poweredBy,count:1};}
60652 this.mapObject=mapObject;this.termsOfUse=termsOfUse;this.poweredBy=poweredBy;if(OpenLayers.Util.indexOf(this.mapObject.getMapTypes(),this.type)===-1){this.mapObject.addMapType(this.type);}
60653 if(typeof mapObject.getDragObject=="function"){this.dragObject=mapObject.getDragObject();}else{this.dragPanMapObject=null;}
60654 if(this.isBaseLayer===false){this.setGMapVisibility(this.div.style.display!=="none");}},onMapResize:function(){if(this.visibility&&this.mapObject.isLoaded()){this.mapObject.checkResize();}else{if(!this._resized){var layer=this;var handle=GEvent.addListener(this.mapObject,"load",function(){GEvent.removeListener(handle);delete layer._resized;layer.mapObject.checkResize();layer.moveTo(layer.map.getCenter(),layer.map.getZoom());});}
60655 this._resized=true;}},setGMapVisibility:function(visible){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var container=this.mapObject.getContainer();if(visible===true){this.mapObject.setMapType(this.type);container.style.display="";this.termsOfUse.style.left="";this.termsOfUse.style.display="";this.poweredBy.style.display="";cache.displayed=this.id;}else{if(cache.displayed===this.id){delete cache.displayed;}
60656 if(!cache.displayed){container.style.display="none";this.termsOfUse.style.display="none";this.termsOfUse.style.left="-9999px";this.poweredBy.style.display="none";}}}},getMapContainer:function(){return this.mapObject.getContainer();},getMapObjectBoundsFromOLBounds:function(olBounds){var moBounds=null;if(olBounds!=null){var sw=this.sphericalMercator?this.inverseMercator(olBounds.bottom,olBounds.left):new OpenLayers.LonLat(olBounds.bottom,olBounds.left);var ne=this.sphericalMercator?this.inverseMercator(olBounds.top,olBounds.right):new OpenLayers.LonLat(olBounds.top,olBounds.right);moBounds=new GLatLngBounds(new GLatLng(sw.lat,sw.lon),new GLatLng(ne.lat,ne.lon));}
60657 return moBounds;},setMapObjectCenter:function(center,zoom){this.mapObject.setCenter(center,zoom);},dragPanMapObject:function(dX,dY){this.dragObject.moveBy(new GSize(-dX,dY));},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return this.mapObject.fromContainerPixelToLatLng(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.fromLatLngToContainerPixel(moLonLat);},getMapObjectZoomFromMapObjectBounds:function(moBounds){return this.mapObject.getBoundsZoomLevel(moBounds);},getMapObjectLonLatFromLonLat:function(lon,lat){var gLatLng;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);gLatLng=new GLatLng(lonlat.lat,lonlat.lon);}else{gLatLng=new GLatLng(lat,lon);}
60658 return gLatLng;},getMapObjectPixelFromXY:function(x,y){return new GPoint(x,y);}};OpenLayers.Layer.Grid=OpenLayers.Class(OpenLayers.Layer.HTTPRequest,{tileSize:null,grid:null,singleTile:false,ratio:1.5,buffer:2,numLoadingTiles:0,initialize:function(name,url,params,options){OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,arguments);this.events.addEventType("tileloaded");this.grid=[];},destroy:function(){this.clearGrid();this.grid=null;this.tileSize=null;OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this,arguments);},clearGrid:function(){if(this.grid){for(var iRow=0,len=this.grid.length;iRow<len;iRow++){var row=this.grid[iRow];for(var iCol=0,clen=row.length;iCol<clen;iCol++){var tile=row[iCol];this.removeTileMonitoringHooks(tile);tile.destroy();}}
60659 this.grid=[];}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Grid(this.name,this.url,this.params,this.getOptions());}
60660 obj=OpenLayers.Layer.HTTPRequest.prototype.clone.apply(this,[obj]);if(this.tileSize!=null){obj.tileSize=this.tileSize.clone();}
60661 obj.grid=[];return obj;},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this,arguments);bounds=bounds||this.map.getExtent();if(bounds!=null){var forceReTile=!this.grid.length||zoomChanged;var tilesBounds=this.getTilesBounds();if(this.singleTile){if(forceReTile||(!dragging&&!tilesBounds.containsBounds(bounds))){this.initSingleTile(bounds);}}else{if(forceReTile||!tilesBounds.containsBounds(bounds,true)){this.initGriddedTiles(bounds);}else{this.moveGriddedTiles(bounds);}}}},setTileSize:function(size){if(this.singleTile){size=this.map.getSize();size.h=parseInt(size.h*this.ratio);size.w=parseInt(size.w*this.ratio);}
60662 OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this,[size]);},getGridBounds:function(){var msg="The getGridBounds() function is deprecated. It will be "+"removed in 3.0. Please use getTilesBounds() instead.";OpenLayers.Console.warn(msg);return this.getTilesBounds();},getTilesBounds:function(){var bounds=null;if(this.grid.length){var bottom=this.grid.length-1;var bottomLeftTile=this.grid[bottom][0];var right=this.grid[0].length-1;var topRightTile=this.grid[0][right];bounds=new OpenLayers.Bounds(bottomLeftTile.bounds.left,bottomLeftTile.bounds.bottom,topRightTile.bounds.right,topRightTile.bounds.top);}
60663 return bounds;},initSingleTile:function(bounds){var center=bounds.getCenterLonLat();var tileWidth=bounds.getWidth()*this.ratio;var tileHeight=bounds.getHeight()*this.ratio;var tileBounds=new OpenLayers.Bounds(center.lon-(tileWidth/2),center.lat-(tileHeight/2),center.lon+(tileWidth/2),center.lat+(tileHeight/2));var ul=new OpenLayers.LonLat(tileBounds.left,tileBounds.top);var px=this.map.getLayerPxFromLonLat(ul);if(!this.grid.length){this.grid[0]=[];}
60664 var tile=this.grid[0][0];if(!tile){tile=this.addTile(tileBounds,px);this.addTileMonitoringHooks(tile);tile.draw();this.grid[0][0]=tile;}else{tile.moveTo(tileBounds,px);}
60665 this.removeExcessTiles(1,1);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=bounds.top-(extent.bottom+tilelat);var tilerow=Math.ceil(offsetlat/tilelat)+this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=-tilerowremain*this.tileSize.h;var tileoffsetlat=extent.bottom+tilerow*tilelat;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},initGriddedTiles:function(bounds){var viewSize=this.map.getSize();var minRows=Math.ceil(viewSize.h/this.tileSize.h)+
60666 Math.max(1,2*this.buffer);var minCols=Math.ceil(viewSize.w/this.tileSize.w)+
60667 Math.max(1,2*this.buffer);var extent=this.getMaxExtent();var resolution=this.map.getResolution();var tileLayout=this.calculateGridLayout(bounds,extent,resolution);var tileoffsetx=Math.round(tileLayout.tileoffsetx);var tileoffsety=Math.round(tileLayout.tileoffsety);var tileoffsetlon=tileLayout.tileoffsetlon;var tileoffsetlat=tileLayout.tileoffsetlat;var tilelon=tileLayout.tilelon;var tilelat=tileLayout.tilelat;this.origin=new OpenLayers.Pixel(tileoffsetx,tileoffsety);var startX=tileoffsetx;var startLon=tileoffsetlon;var rowidx=0;var layerContainerDivLeft=parseInt(this.map.layerContainerDiv.style.left);var layerContainerDivTop=parseInt(this.map.layerContainerDiv.style.top);do{var row=this.grid[rowidx++];if(!row){row=[];this.grid.push(row);}
60668 tileoffsetlon=startLon;tileoffsetx=startX;var colidx=0;do{var tileBounds=new OpenLayers.Bounds(tileoffsetlon,tileoffsetlat,tileoffsetlon+tilelon,tileoffsetlat+tilelat);var x=tileoffsetx;x-=layerContainerDivLeft;var y=tileoffsety;y-=layerContainerDivTop;var px=new OpenLayers.Pixel(x,y);var tile=row[colidx++];if(!tile){tile=this.addTile(tileBounds,px);this.addTileMonitoringHooks(tile);row.push(tile);}else{tile.moveTo(tileBounds,px,false);}
60669 tileoffsetlon+=tilelon;tileoffsetx+=this.tileSize.w;}while((tileoffsetlon<=bounds.right+tilelon*this.buffer)||colidx<minCols);tileoffsetlat-=tilelat;tileoffsety+=this.tileSize.h;}while((tileoffsetlat>=bounds.bottom-tilelat*this.buffer)||rowidx<minRows);this.removeExcessTiles(rowidx,colidx);this.spiralTileLoad();},getMaxExtent:function(){return this.maxExtent;},spiralTileLoad:function(){var tileQueue=[];var directions=["right","down","left","up"];var iRow=0;var iCell=-1;var direction=OpenLayers.Util.indexOf(directions,"right");var directionsTried=0;while(directionsTried<directions.length){var testRow=iRow;var testCell=iCell;switch(directions[direction]){case"right":testCell++;break;case"down":testRow++;break;case"left":testCell--;break;case"up":testRow--;break;}
60670 var tile=null;if((testRow<this.grid.length)&&(testRow>=0)&&(testCell<this.grid[0].length)&&(testCell>=0)){tile=this.grid[testRow][testCell];}
60671 if((tile!=null)&&(!tile.queued)){tileQueue.unshift(tile);tile.queued=true;directionsTried=0;iRow=testRow;iCell=testCell;}else{direction=(direction+1)%4;directionsTried++;}}
60672 for(var i=0,len=tileQueue.length;i<len;i++){var tile=tileQueue[i];tile.draw();tile.queued=false;}},addTile:function(bounds,position){},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){if(this.numLoadingTiles==0){this.events.triggerEvent("loadstart");}
60673 this.numLoadingTiles++;};tile.events.register("loadstart",this,tile.onLoadStart);tile.onLoadEnd=function(){this.numLoadingTiles--;this.events.triggerEvent("tileloaded");if(this.numLoadingTiles==0){this.events.triggerEvent("loadend");}};tile.events.register("loadend",this,tile.onLoadEnd);tile.events.register("unload",this,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:this});},moveGriddedTiles:function(bounds){var buffer=this.buffer||1;while(true){var tlLayer=this.grid[0][0].position;var tlViewPort=this.map.getViewPortPxFromLayerPx(tlLayer);if(tlViewPort.x>-this.tileSize.w*(buffer-1)){this.shiftColumn(true);}else if(tlViewPort.x<-this.tileSize.w*buffer){this.shiftColumn(false);}else if(tlViewPort.y>-this.tileSize.h*(buffer-1)){this.shiftRow(true);}else if(tlViewPort.y<-this.tileSize.h*buffer){this.shiftRow(false);}else{break;}};},shiftRow:function(prepend){var modelRowIndex=(prepend)?0:(this.grid.length-1);var grid=this.grid;var modelRow=grid[modelRowIndex];var resolution=this.map.getResolution();var deltaY=(prepend)?-this.tileSize.h:this.tileSize.h;var deltaLat=resolution*-deltaY;var row=(prepend)?grid.pop():grid.shift();for(var i=0,len=modelRow.length;i<len;i++){var modelTile=modelRow[i];var bounds=modelTile.bounds.clone();var position=modelTile.position.clone();bounds.bottom=bounds.bottom+deltaLat;bounds.top=bounds.top+deltaLat;position.y=position.y+deltaY;row[i].moveTo(bounds,position);}
60674 if(prepend){grid.unshift(row);}else{grid.push(row);}},shiftColumn:function(prepend){var deltaX=(prepend)?-this.tileSize.w:this.tileSize.w;var resolution=this.map.getResolution();var deltaLon=resolution*deltaX;for(var i=0,len=this.grid.length;i<len;i++){var row=this.grid[i];var modelTileIndex=(prepend)?0:(row.length-1);var modelTile=row[modelTileIndex];var bounds=modelTile.bounds.clone();var position=modelTile.position.clone();bounds.left=bounds.left+deltaLon;bounds.right=bounds.right+deltaLon;position.x=position.x+deltaX;var tile=prepend?this.grid[i].pop():this.grid[i].shift();tile.moveTo(bounds,position);if(prepend){row.unshift(tile);}else{row.push(tile);}}},removeExcessTiles:function(rows,columns){while(this.grid.length>rows){var row=this.grid.pop();for(var i=0,l=row.length;i<l;i++){var tile=row[i];this.removeTileMonitoringHooks(tile);tile.destroy();}}
60675 while(this.grid[0].length>columns){for(var i=0,l=this.grid.length;i<l;i++){var row=this.grid[i];var tile=row.pop();this.removeTileMonitoringHooks(tile);tile.destroy();}}},onMapResize:function(){if(this.singleTile){this.clearGrid();this.setTileSize();}},getTileBounds:function(viewPortPx){var maxExtent=this.maxExtent;var resolution=this.getResolution();var tileMapWidth=resolution*this.tileSize.w;var tileMapHeight=resolution*this.tileSize.h;var mapPoint=this.getLonLatFromViewPortPx(viewPortPx);var tileLeft=maxExtent.left+(tileMapWidth*Math.floor((mapPoint.lon-
60676 maxExtent.left)/tileMapWidth));var tileBottom=maxExtent.bottom+(tileMapHeight*Math.floor((mapPoint.lat-
60677 maxExtent.bottom)/tileMapHeight));return new OpenLayers.Bounds(tileLeft,tileBottom,tileLeft+tileMapWidth,tileBottom+tileMapHeight);},CLASS_NAME:"OpenLayers.Layer.Grid"});OpenLayers.Layer.MultiMap=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:1,MAX_ZOOM_LEVEL:17,RESOLUTIONS:[9,1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125],type:null,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();this.RESOLUTIONS.unshift(10);}},loadMapObject:function(){try{this.mapObject=new MultimapViewer(this.div);}catch(e){}},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':"MM",'layerLib':"MultiMap"});},setMapObjectCenter:function(center,zoom){this.mapObject.goToPosition(center,zoom);},getMapObjectCenter:function(){return this.mapObject.getCurrentPosition();},getMapObjectZoom:function(){return this.mapObject.getZoomFactor();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){moPixel.x=moPixel.x-(this.map.getSize().w/2);moPixel.y=moPixel.y-(this.map.getSize().h/2);return this.mapObject.getMapPositionAt(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.geoPosToContainerPixels(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lon,moLonLat.lat).lon:moLonLat.lon;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.lon,moLonLat.lat).lat:moLonLat.lat;},getMapObjectLonLatFromLonLat:function(lon,lat){var mmLatLon;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);mmLatLon=new MMLatLon(lonlat.lat,lonlat.lon);}else{mmLatLon=new MMLatLon(lat,lon);}
60678 return mmLatLon;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return new MMPoint(x,y);},CLASS_NAME:"OpenLayers.Layer.MultiMap"});OpenLayers.Layer.VirtualEarth=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:1,MAX_ZOOM_LEVEL:19,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031,0.00000536441802978515],type:null,wrapDateLine:true,sphericalMercator:false,animationEnabled:true,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},loadMapObject:function(){var veDiv=OpenLayers.Util.createDiv(this.name);var sz=this.map.getSize();veDiv.style.width=sz.w+"px";veDiv.style.height=sz.h+"px";this.div.appendChild(veDiv);try{this.mapObject=new VEMap(this.name);}catch(e){}
60679 if(this.mapObject!=null){try{this.mapObject.LoadMap(null,null,this.type,true);this.mapObject.AttachEvent("onmousedown",OpenLayers.Function.True);}catch(e){}
60680 this.mapObject.HideDashboard();if(typeof this.mapObject.SetAnimationEnabled=="function"){this.mapObject.SetAnimationEnabled(this.animationEnabled);}}
60681 if(!this.mapObject||!this.mapObject.vemapcontrol||!this.mapObject.vemapcontrol.PanMap||(typeof this.mapObject.vemapcontrol.PanMap!="function")){this.dragPanMapObject=null;}},onMapResize:function(){this.mapObject.Resize(this.map.size.w,this.map.size.h);},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':'VE','layerLib':'VirtualEarth'});},setMapObjectCenter:function(center,zoom){this.mapObject.SetCenterAndZoom(center,zoom);},getMapObjectCenter:function(){return this.mapObject.GetCenter();},dragPanMapObject:function(dX,dY){this.mapObject.vemapcontrol.PanMap(dX,-dY);},getMapObjectZoom:function(){return this.mapObject.GetZoomLevel();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return(typeof VEPixel!='undefined')?this.mapObject.PixelToLatLong(moPixel):this.mapObject.PixelToLatLong(moPixel.x,moPixel.y);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.LatLongToPixel(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Longitude,moLonLat.Latitude).lon:moLonLat.Longitude;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Longitude,moLonLat.Latitude).lat:moLonLat.Latitude;},getMapObjectLonLatFromLonLat:function(lon,lat){var veLatLong;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);veLatLong=new VELatLong(lonlat.lat,lonlat.lon);}else{veLatLong=new VELatLong(lat,lon);}
60682 return veLatLong;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return(typeof VEPixel!='undefined')?new VEPixel(x,y):new Msn.VE.Pixel(x,y);},CLASS_NAME:"OpenLayers.Layer.VirtualEarth"});OpenLayers.Layer.Yahoo=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:0,MAX_ZOOM_LEVEL:17,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,0.0006866455078125,0.00034332275390625,0.000171661376953125,0.0000858306884765625,0.00004291534423828125,0.00002145767211914062,0.00001072883605957031],type:null,wrapDateLine:true,sphericalMercator:false,initialize:function(name,options){OpenLayers.Layer.EventPane.prototype.initialize.apply(this,arguments);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,arguments);if(this.sphericalMercator){OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator);this.initMercatorParameters();}},loadMapObject:function(){try{var size=this.getMapObjectSizeFromOLSize(this.map.getSize());this.mapObject=new YMap(this.div,this.type,size);this.mapObject.disableKeyControls();this.mapObject.disableDragMap();if(!this.mapObject.moveByXY||(typeof this.mapObject.moveByXY!="function")){this.dragPanMapObject=null;}}catch(e){}},onMapResize:function(){try{var size=this.getMapObjectSizeFromOLSize(this.map.getSize());this.mapObject.resizeTo(size);}catch(e){}},setMap:function(map){OpenLayers.Layer.EventPane.prototype.setMap.apply(this,arguments);this.map.events.register("moveend",this,this.fixYahooEventPane);},fixYahooEventPane:function(){var yahooEventPane=OpenLayers.Util.getElement("ygddfdiv");if(yahooEventPane!=null){if(yahooEventPane.parentNode!=null){yahooEventPane.parentNode.removeChild(yahooEventPane);}
60683 this.map.events.unregister("moveend",this,this.fixYahooEventPane);}},getWarningHTML:function(){return OpenLayers.i18n("getLayerWarning",{'layerType':'Yahoo','layerLib':'Yahoo'});},getOLZoomFromMapObjectZoom:function(moZoom){var zoom=null;if(moZoom!=null){zoom=OpenLayers.Layer.FixedZoomLevels.prototype.getOLZoomFromMapObjectZoom.apply(this,[moZoom]);zoom=18-zoom;}
60684 return zoom;},getMapObjectZoomFromOLZoom:function(olZoom){var zoom=null;if(olZoom!=null){zoom=OpenLayers.Layer.FixedZoomLevels.prototype.getMapObjectZoomFromOLZoom.apply(this,[olZoom]);zoom=18-zoom;}
60685 return zoom;},setMapObjectCenter:function(center,zoom){this.mapObject.drawZoomAndCenter(center,zoom);},getMapObjectCenter:function(){return this.mapObject.getCenterLatLon();},dragPanMapObject:function(dX,dY){this.mapObject.moveByXY({'x':-dX,'y':dY});},getMapObjectZoom:function(){return this.mapObject.getZoomLevel();},getMapObjectLonLatFromMapObjectPixel:function(moPixel){return this.mapObject.convertXYLatLon(moPixel);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){return this.mapObject.convertLatLonXY(moLonLat);},getLongitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Lon,moLonLat.Lat).lon:moLonLat.Lon;},getLatitudeFromMapObjectLonLat:function(moLonLat){return this.sphericalMercator?this.forwardMercator(moLonLat.Lon,moLonLat.Lat).lat:moLonLat.Lat;},getMapObjectLonLatFromLonLat:function(lon,lat){var yLatLong;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);yLatLong=new YGeoPoint(lonlat.lat,lonlat.lon);}else{yLatLong=new YGeoPoint(lat,lon);}
60686 return yLatLong;},getXFromMapObjectPixel:function(moPixel){return moPixel.x;},getYFromMapObjectPixel:function(moPixel){return moPixel.y;},getMapObjectPixelFromXY:function(x,y){return new YCoordPoint(x,y);},getMapObjectSizeFromOLSize:function(olSize){return new YSize(olSize.w,olSize.h);},CLASS_NAME:"OpenLayers.Layer.Yahoo"});OpenLayers.Style=OpenLayers.Class({id:null,name:null,title:null,description:null,layerName:null,isDefault:false,rules:null,context:null,defaultStyle:null,defaultsPerSymbolizer:false,propertyStyles:null,initialize:function(style,options){OpenLayers.Util.extend(this,options);this.rules=[];if(options&&options.rules){this.addRules(options.rules);}
60687 this.setDefaultStyle(style||OpenLayers.Feature.Vector.style["default"]);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i=0,len=this.rules.length;i<len;i++){this.rules[i].destroy();this.rules[i]=null;}
60688 this.rules=null;this.defaultStyle=null;},createSymbolizer:function(feature){var style=this.defaultsPerSymbolizer?{}:this.createLiterals(OpenLayers.Util.extend({},this.defaultStyle),feature);var rules=this.rules;var rule,context;var elseRules=[];var appliedRules=false;for(var i=0,len=rules.length;i<len;i++){rule=rules[i];var applies=rule.evaluate(feature);if(applies){if(rule instanceof OpenLayers.Rule&&rule.elseFilter){elseRules.push(rule);}else{appliedRules=true;this.applySymbolizer(rule,style,feature);}}}
60689 if(appliedRules==false&&elseRules.length>0){appliedRules=true;for(var i=0,len=elseRules.length;i<len;i++){this.applySymbolizer(elseRules[i],style,feature);}}
60690 if(rules.length>0&&appliedRules==false){style.display="none";}
60691 return style;},applySymbolizer:function(rule,style,feature){var symbolizerPrefix=feature.geometry?this.getSymbolizerPrefix(feature.geometry):OpenLayers.Style.SYMBOLIZER_PREFIXES[0];var symbolizer=rule.symbolizer[symbolizerPrefix]||rule.symbolizer;if(this.defaultsPerSymbolizer===true){var defaults=this.defaultStyle;OpenLayers.Util.applyDefaults(symbolizer,{pointRadius:defaults.pointRadius});if(symbolizer.stroke===true||symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{strokeWidth:defaults.strokeWidth,strokeColor:defaults.strokeColor,strokeOpacity:defaults.strokeOpacity,strokeDashstyle:defaults.strokeDashstyle,strokeLinecap:defaults.strokeLinecap});}
60692 if(symbolizer.fill===true||symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{fillColor:defaults.fillColor,fillOpacity:defaults.fillOpacity});}
60693 if(symbolizer.graphic===true){OpenLayers.Util.applyDefaults(symbolizer,{pointRadius:this.defaultStyle.pointRadius,externalGraphic:this.defaultStyle.externalGraphic,graphicName:this.defaultStyle.graphicName,graphicOpacity:this.defaultStyle.graphicOpacity,graphicWidth:this.defaultStyle.graphicWidth,graphicHeight:this.defaultStyle.graphicHeight,graphicXOffset:this.defaultStyle.graphicXOffset,graphicYOffset:this.defaultStyle.graphicYOffset});}}
60694 return this.createLiterals(OpenLayers.Util.extend(style,symbolizer),feature);},createLiterals:function(style,feature){var context=OpenLayers.Util.extend({},feature.attributes||feature.data);OpenLayers.Util.extend(context,this.context);for(var i in this.propertyStyles){style[i]=OpenLayers.Style.createLiteral(style[i],context,feature,i);}
60695 return style;},findPropertyStyles:function(){var propertyStyles={};var style=this.defaultStyle;this.addPropertyStyles(propertyStyles,style);var rules=this.rules;var symbolizer,value;for(var i=0,len=rules.length;i<len;i++){symbolizer=rules[i].symbolizer;for(var key in symbolizer){value=symbolizer[key];if(typeof value=="object"){this.addPropertyStyles(propertyStyles,value);}else{this.addPropertyStyles(propertyStyles,symbolizer);break;}}}
60696 return propertyStyles;},addPropertyStyles:function(propertyStyles,symbolizer){var property;for(var key in symbolizer){property=symbolizer[key];if(typeof property=="string"&&property.match(/\$\{\w+\}/)){propertyStyles[key]=true;}}
60697 return propertyStyles;},addRules:function(rules){Array.prototype.push.apply(this.rules,rules);this.propertyStyles=this.findPropertyStyles();},setDefaultStyle:function(style){this.defaultStyle=style;this.propertyStyles=this.findPropertyStyles();},getSymbolizerPrefix:function(geometry){var prefixes=OpenLayers.Style.SYMBOLIZER_PREFIXES;for(var i=0,len=prefixes.length;i<len;i++){if(geometry.CLASS_NAME.indexOf(prefixes[i])!=-1){return prefixes[i];}}},clone:function(){var options=OpenLayers.Util.extend({},this);if(this.rules){options.rules=[];for(var i=0,len=this.rules.length;i<len;++i){options.rules.push(this.rules[i].clone());}}
60698 options.context=this.context&&OpenLayers.Util.extend({},this.context);var defaultStyle=OpenLayers.Util.extend({},this.defaultStyle);return new OpenLayers.Style(defaultStyle,options);},CLASS_NAME:"OpenLayers.Style"});OpenLayers.Style.createLiteral=function(value,context,feature,property){if(typeof value=="string"&&value.indexOf("${")!=-1){value=OpenLayers.String.format(value,context,[feature,property]);value=(isNaN(value)||!value)?value:parseFloat(value);}
60699 return value;};OpenLayers.Style.SYMBOLIZER_PREFIXES=['Point','Line','Polygon','Text','Raster'];OpenLayers.Control.Navigation=OpenLayers.Class(OpenLayers.Control,{dragPan:null,dragPanOptions:null,documentDrag:false,zoomBox:null,zoomBoxEnabled:true,zoomWheelEnabled:true,mouseWheelOptions:null,handleRightClicks:false,zoomBoxKeyMask:OpenLayers.Handler.MOD_SHIFT,autoActivate:true,initialize:function(options){this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,arguments);},destroy:function(){this.deactivate();if(this.dragPan){this.dragPan.destroy();}
60700 this.dragPan=null;if(this.zoomBox){this.zoomBox.destroy();}
60701 this.zoomBox=null;OpenLayers.Control.prototype.destroy.apply(this,arguments);},activate:function(){this.dragPan.activate();if(this.zoomWheelEnabled){this.handlers.wheel.activate();}
60702 this.handlers.click.activate();if(this.zoomBoxEnabled){this.zoomBox.activate();}
60703 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){this.zoomBox.deactivate();this.dragPan.deactivate();this.handlers.click.deactivate();this.handlers.wheel.deactivate();return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},draw:function(){if(this.handleRightClicks){this.map.viewPortDiv.oncontextmenu=OpenLayers.Function.False;}
60704 var clickCallbacks={'dblclick':this.defaultDblClick,'dblrightclick':this.defaultDblRightClick};var clickOptions={'double':true,'stopDouble':true};this.handlers.click=new OpenLayers.Handler.Click(this,clickCallbacks,clickOptions);this.dragPan=new OpenLayers.Control.DragPan(OpenLayers.Util.extend({map:this.map,documentDrag:this.documentDrag},this.dragPanOptions));this.zoomBox=new OpenLayers.Control.ZoomBox({map:this.map,keyMask:this.zoomBoxKeyMask});this.dragPan.draw();this.zoomBox.draw();this.handlers.wheel=new OpenLayers.Handler.MouseWheel(this,{"up":this.wheelUp,"down":this.wheelDown},this.mouseWheelOptions);},defaultDblClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom+1);},defaultDblRightClick:function(evt){var newCenter=this.map.getLonLatFromViewPortPx(evt.xy);this.map.setCenter(newCenter,this.map.zoom-1);},wheelChange:function(evt,deltaZ){var currentZoom=this.map.getZoom();var newZoom=this.map.getZoom()+Math.round(deltaZ);newZoom=Math.max(newZoom,0);newZoom=Math.min(newZoom,this.map.getNumZoomLevels());if(newZoom===currentZoom){return;}
60705 var size=this.map.getSize();var deltaX=size.w/2-evt.xy.x;var deltaY=evt.xy.y-size.h/2;var newRes=this.map.baseLayer.getResolutionForZoom(newZoom);var zoomPoint=this.map.getLonLatFromPixel(evt.xy);var newCenter=new OpenLayers.LonLat(zoomPoint.lon+deltaX*newRes,zoomPoint.lat+deltaY*newRes);this.map.setCenter(newCenter,newZoom);},wheelUp:function(evt,delta){this.wheelChange(evt,delta||1);},wheelDown:function(evt,delta){this.wheelChange(evt,delta||-1);},disableZoomBox:function(){this.zoomBoxEnabled=false;this.zoomBox.deactivate();},enableZoomBox:function(){this.zoomBoxEnabled=true;if(this.active){this.zoomBox.activate();}},disableZoomWheel:function(){this.zoomWheelEnabled=false;this.handlers.wheel.deactivate();},enableZoomWheel:function(){this.zoomWheelEnabled=true;if(this.active){this.handlers.wheel.activate();}},CLASS_NAME:"OpenLayers.Control.Navigation"});OpenLayers.Filter=OpenLayers.Class({initialize:function(options){OpenLayers.Util.extend(this,options);},destroy:function(){},evaluate:function(context){return true;},clone:function(){return null;},CLASS_NAME:"OpenLayers.Filter"});OpenLayers.Format.WMC.v1_0_0=OpenLayers.Class(OpenLayers.Format.WMC.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/context http://schemas.opengis.net/context/1.0.0/context.xsd",initialize:function(options){OpenLayers.Format.WMC.v1.prototype.initialize.apply(this,[options]);},write_wmc_Layer:function(context){var node=OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(this,[context]);node.appendChild(this.write_wmc_FormatList(context));node.appendChild(this.write_wmc_StyleList(context));node.appendChild(this.write_wmc_LayerExtension(context));},CLASS_NAME:"OpenLayers.Format.WMC.v1_0_0"});OpenLayers.Format.WMC.v1_1_0=OpenLayers.Class(OpenLayers.Format.WMC.v1,{VERSION:"1.1.0",schemaLocation:"http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd",initialize:function(options){OpenLayers.Format.WMC.v1.prototype.initialize.apply(this,[options]);},read_sld_MinScaleDenominator:function(layerContext,node){var minScaleDenominator=parseFloat(this.getChildValue(node));if(minScaleDenominator>0){layerContext.maxScale=minScaleDenominator;}},read_sld_MaxScaleDenominator:function(layerContext,node){layerContext.minScale=parseFloat(this.getChildValue(node));},write_wmc_Layer:function(context){var node=OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(this,[context]);if(context.maxScale){var minSD=this.createElementNS(this.namespaces.sld,"sld:MinScaleDenominator");minSD.appendChild(this.createTextNode(context.maxScale.toPrecision(16)));node.appendChild(minSD);}
60706 if(context.minScale){var maxSD=this.createElementNS(this.namespaces.sld,"sld:MaxScaleDenominator");maxSD.appendChild(this.createTextNode(context.minScale.toPrecision(16)));node.appendChild(maxSD);}
60707 node.appendChild(this.write_wmc_FormatList(context));node.appendChild(this.write_wmc_StyleList(context));node.appendChild(this.write_wmc_LayerExtension(context));return node;},CLASS_NAME:"OpenLayers.Format.WMC.v1_1_0"});OpenLayers.Format.WMSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1,{version:"1.1.0",initialize:function(options){OpenLayers.Format.WMSCapabilities.v1_1.prototype.initialize.apply(this,[options]);},readers:{"wms":OpenLayers.Util.applyDefaults({"SRS":function(node,obj){var srs=this.getChildValue(node);var values=srs.split(/ +/);for(var i=0,len=values.length;i<len;i++){obj.srs[values[i]]=true;}}},OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_0"});OpenLayers.Format.WMSCapabilities.v1_1_1=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1,{version:"1.1.1",initialize:function(options){OpenLayers.Format.WMSCapabilities.v1_1.prototype.initialize.apply(this,[options]);},readers:{"wms":OpenLayers.Util.applyDefaults({"SRS":function(node,obj){obj.srs[this.getChildValue(node)]=true;}},OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers["wms"])},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_1"});OpenLayers.Format.WMSCapabilities.v1_3_0=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_3,{version:"1.3.0",CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_3_0"});OpenLayers.Geometry=OpenLayers.Class({id:null,parent:null,bounds:null,initialize:function(){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){this.id=null;this.bounds=null;},clone:function(){return new OpenLayers.Geometry();},setBounds:function(bounds){if(bounds){this.bounds=bounds.clone();}},clearBounds:function(){this.bounds=null;if(this.parent){this.parent.clearBounds();}},extendBounds:function(newBounds){var bounds=this.getBounds();if(!bounds){this.setBounds(newBounds);}else{this.bounds.extend(newBounds);}},getBounds:function(){if(this.bounds==null){this.calculateBounds();}
60708 return this.bounds;},calculateBounds:function(){},distanceTo:function(geometry,options){},getVertices:function(nodes){},atPoint:function(lonlat,toleranceLon,toleranceLat){var atPoint=false;var bounds=this.getBounds();if((bounds!=null)&&(lonlat!=null)){var dX=(toleranceLon!=null)?toleranceLon:0;var dY=(toleranceLat!=null)?toleranceLat:0;var toleranceBounds=new OpenLayers.Bounds(this.bounds.left-dX,this.bounds.bottom-dY,this.bounds.right+dX,this.bounds.top+dY);atPoint=toleranceBounds.containsLonLat(lonlat);}
60709 return atPoint;},getLength:function(){return 0.0;},getArea:function(){return 0.0;},getCentroid:function(){return null;},toString:function(){return OpenLayers.Format.WKT.prototype.write(new OpenLayers.Feature.Vector(this));},CLASS_NAME:"OpenLayers.Geometry"});OpenLayers.Geometry.fromWKT=function(wkt){var format=arguments.callee.format;if(!format){format=new OpenLayers.Format.WKT();arguments.callee.format=format;}
60710 var geom;var result=format.read(wkt);if(result instanceof OpenLayers.Feature.Vector){geom=result.geometry;}else if(result instanceof Array){var len=result.length;var components=new Array(len);for(var i=0;i<len;++i){components[i]=result[i].geometry;}
60711 geom=new OpenLayers.Geometry.Collection(components);}
60712 return geom;};OpenLayers.Geometry.segmentsIntersect=function(seg1,seg2,options){var point=options&&options.point;var tolerance=options&&options.tolerance;var intersection=false;var x11_21=seg1.x1-seg2.x1;var y11_21=seg1.y1-seg2.y1;var x12_11=seg1.x2-seg1.x1;var y12_11=seg1.y2-seg1.y1;var y22_21=seg2.y2-seg2.y1;var x22_21=seg2.x2-seg2.x1;var d=(y22_21*x12_11)-(x22_21*y12_11);var n1=(x22_21*y11_21)-(y22_21*x11_21);var n2=(x12_11*y11_21)-(y12_11*x11_21);if(d==0){if(n1==0&&n2==0){intersection=true;}}else{var along1=n1/d;var along2=n2/d;if(along1>=0&&along1<=1&&along2>=0&&along2<=1){if(!point){intersection=true;}else{var x=seg1.x1+(along1*x12_11);var y=seg1.y1+(along1*y12_11);intersection=new OpenLayers.Geometry.Point(x,y);}}}
60713 if(tolerance){var dist;if(intersection){if(point){var segs=[seg1,seg2];var seg,x,y;outer:for(var i=0;i<2;++i){seg=segs[i];for(var j=1;j<3;++j){x=seg["x"+j];y=seg["y"+j];dist=Math.sqrt(Math.pow(x-intersection.x,2)+
60714 Math.pow(y-intersection.y,2));if(dist<tolerance){intersection.x=x;intersection.y=y;break outer;}}}}}else{var segs=[seg1,seg2];var source,target,x,y,p,result;outer:for(var i=0;i<2;++i){source=segs[i];target=segs[(i+1)%2];for(var j=1;j<3;++j){p={x:source["x"+j],y:source["y"+j]};result=OpenLayers.Geometry.distanceToSegment(p,target);if(result.distance<tolerance){if(point){intersection=new OpenLayers.Geometry.Point(p.x,p.y);}else{intersection=true;}
60715 break outer;}}}}}
60716 return intersection;};OpenLayers.Geometry.distanceToSegment=function(point,segment){var x0=point.x;var y0=point.y;var x1=segment.x1;var y1=segment.y1;var x2=segment.x2;var y2=segment.y2;var dx=x2-x1;var dy=y2-y1;var along=((dx*(x0-x1))+(dy*(y0-y1)))/(Math.pow(dx,2)+Math.pow(dy,2));var x,y;if(along<=0.0){x=x1;y=y1;}else if(along>=1.0){x=x2;y=y2;}else{x=x1+along*dx;y=y1+along*dy;}
60717 return{distance:Math.sqrt(Math.pow(x-x0,2)+Math.pow(y-y0,2)),x:x,y:y};};OpenLayers.Layer.ArcGIS93Rest=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{format:"png"},isBaseLayer:true,initialize:function(name,url,params,options){var newArguments=[];params=OpenLayers.Util.upperCaseObject(params);newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);OpenLayers.Util.applyDefaults(this.params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));if(this.params.TRANSPARENT&&this.params.TRANSPARENT.toString().toLowerCase()=="true"){if((options==null)||(!options.isBaseLayer)){this.isBaseLayer=false;}
60718 if(this.params.FORMAT=="jpg"){this.params.FORMAT=OpenLayers.Util.alphaHack()?"gif":"png";}}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.ArcGIS93Rest(this.name,this.url,this.params,this.getOptions());}
60719 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var projWords=this.projection.getCode().split(":");var srid=projWords[projWords.length-1];var imageSize=this.getImageSize();var newParams={'BBOX':bounds.toBBOX(),'SIZE':imageSize.w+","+imageSize.h,'F':"image",'BBOXSR':srid,'IMAGESR':srid};if(this.layerDefs){var layerDefStrList=[];var layerID;for(layerID in this.layerDefs){if(this.layerDefs.hasOwnProperty(layerID)){if(this.layerDefs[layerID]){layerDefStrList.push(layerID);layerDefStrList.push(":");layerDefStrList.push(this.layerDefs[layerID]);layerDefStrList.push(";");}}}
60720 if(layerDefStrList.length>0){newParams['LAYERDEFS']=layerDefStrList.join("");}}
60721 var requestString=this.getFullRequestString(newParams);return requestString;},setLayerFilter:function(id,queryDef){if(!this.layerDefs){this.layerDefs={};}
60722 if(queryDef){this.layerDefs[id]=queryDef;}else{delete this.layerDefs[id];}},clearLayerFilter:function(id){if(id){delete this.layerDefs[id];}else{delete this.layerDefs;}},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,newArguments);},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.ArcGIS93Rest"});OpenLayers.Layer.Google.v3={DEFAULTS:{maxExtent:new OpenLayers.Bounds(-128*156543.0339,-128*156543.0339,128*156543.0339,128*156543.0339),sphericalMercator:true,maxResolution:156543.0339,units:"m",projection:"EPSG:900913"},loadMapObject:function(){if(!this.type){this.type=google.maps.MapTypeId.ROADMAP;}
60723 var mapObject;var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){mapObject=cache.mapObject;++cache.count;}else{var container=this.map.viewPortDiv;var div=document.createElement("div");div.id=this.map.id+"_GMapContainer";div.style.position="absolute";div.style.width="100%";div.style.height="100%";container.appendChild(div);var center=this.map.getCenter();mapObject=new google.maps.Map(div,{center:center?new google.maps.LatLng(center.lat,center.lon):new google.maps.LatLng(0,0),zoom:this.map.getZoom()||0,mapTypeId:this.type,disableDefaultUI:true,keyboardShortcuts:false,draggable:false,disableDoubleClickZoom:true,scrollwheel:false});cache={mapObject:mapObject,count:1};OpenLayers.Layer.Google.cache[this.map.id]=cache;this.repositionListener=google.maps.event.addListenerOnce(mapObject,"center_changed",OpenLayers.Function.bind(this.repositionMapElements,this));}
60724 this.mapObject=mapObject;this.setGMapVisibility(this.visibility);},repositionMapElements:function(){google.maps.event.trigger(this.mapObject,"resize");var div=this.mapObject.getDiv().firstChild;if(!div||div.childNodes.length<3){this.repositionTimer=window.setTimeout(OpenLayers.Function.bind(this.repositionMapElements,this),250);return false;}
60725 var cache=OpenLayers.Layer.Google.cache[this.map.id];var container=this.map.viewPortDiv;var termsOfUse=div.lastChild;container.appendChild(termsOfUse);termsOfUse.style.zIndex="1100";termsOfUse.style.bottom="";termsOfUse.className="olLayerGoogleCopyright olLayerGoogleV3";termsOfUse.style.display="";cache.termsOfUse=termsOfUse;var poweredBy=div.lastChild;container.appendChild(poweredBy);poweredBy.style.zIndex="1100";poweredBy.style.bottom="";poweredBy.className="olLayerGooglePoweredBy olLayerGoogleV3 gmnoprint";poweredBy.style.display="";cache.poweredBy=poweredBy;this.setGMapVisibility(this.visibility);},onMapResize:function(){if(this.visibility){google.maps.event.trigger(this.mapObject,"resize");}else{if(!this._resized){var layer=this;google.maps.event.addListenerOnce(this.mapObject,"tilesloaded",function(){delete layer._resized;google.maps.event.trigger(layer.mapObject,"resize");layer.moveTo(layer.map.getCenter(),layer.map.getZoom());});}
60726 this._resized=true;}},setGMapVisibility:function(visible){var cache=OpenLayers.Layer.Google.cache[this.map.id];if(cache){var type=this.type;var layers=this.map.layers;var layer;for(var i=layers.length-1;i>=0;--i){layer=layers[i];if(layer instanceof OpenLayers.Layer.Google&&layer.visibility===true&&layer.inRange===true){type=layer.type;visible=true;break;}}
60727 var container=this.mapObject.getDiv();if(visible===true){this.mapObject.setMapTypeId(type);container.style.left="";if(cache.termsOfUse&&cache.termsOfUse.style){cache.termsOfUse.style.left="";cache.termsOfUse.style.display="";cache.poweredBy.style.display="";}
60728 cache.displayed=this.id;}else{delete cache.displayed;container.style.left="-9999px";if(cache.termsOfUse&&cache.termsOfUse.style){cache.termsOfUse.style.display="none";cache.termsOfUse.style.left="-9999px";cache.poweredBy.style.display="none";}}}},getMapContainer:function(){return this.mapObject.getDiv();},getMapObjectBoundsFromOLBounds:function(olBounds){var moBounds=null;if(olBounds!=null){var sw=this.sphericalMercator?this.inverseMercator(olBounds.bottom,olBounds.left):new OpenLayers.LonLat(olBounds.bottom,olBounds.left);var ne=this.sphericalMercator?this.inverseMercator(olBounds.top,olBounds.right):new OpenLayers.LonLat(olBounds.top,olBounds.right);moBounds=new google.maps.LatLngBounds(new google.maps.LatLng(sw.lat,sw.lon),new google.maps.LatLng(ne.lat,ne.lon));}
60729 return moBounds;},getMapObjectLonLatFromMapObjectPixel:function(moPixel){var size=this.map.getSize();var lon=this.getLongitudeFromMapObjectLonLat(this.mapObject.center);var lat=this.getLatitudeFromMapObjectLonLat(this.mapObject.center);var res=this.map.getResolution();var delta_x=moPixel.x-(size.w/2);var delta_y=moPixel.y-(size.h/2);var lonlat=new OpenLayers.LonLat(lon+delta_x*res,lat-delta_y*res);if(this.wrapDateLine){lonlat=lonlat.wrapDateLine(this.maxExtent);}
60730 return this.getMapObjectLonLatFromLonLat(lonlat.lon,lonlat.lat);},getMapObjectPixelFromMapObjectLonLat:function(moLonLat){var lon=this.getLongitudeFromMapObjectLonLat(moLonLat);var lat=this.getLatitudeFromMapObjectLonLat(moLonLat);var res=this.map.getResolution();var extent=this.map.getExtent();var px=new OpenLayers.Pixel((1/res*(lon-extent.left)),(1/res*(extent.top-lat)));return this.getMapObjectPixelFromXY(px.x,px.y);},setMapObjectCenter:function(center,zoom){this.mapObject.setOptions({center:center,zoom:zoom});},getMapObjectZoomFromMapObjectBounds:function(moBounds){return this.mapObject.getBoundsZoomLevel(moBounds);},getMapObjectLonLatFromLonLat:function(lon,lat){var gLatLng;if(this.sphericalMercator){var lonlat=this.inverseMercator(lon,lat);gLatLng=new google.maps.LatLng(lonlat.lat,lonlat.lon);}else{gLatLng=new google.maps.LatLng(lat,lon);}
60731 return gLatLng;},getMapObjectPixelFromXY:function(x,y){return new google.maps.Point(x,y);},destroy:function(){if(this.repositionListener){google.maps.event.removeListener(this.repositionListener);}
60732 if(this.repositionTimer){window.clearTimeout(this.repositionTimer);}
60733 OpenLayers.Layer.Google.prototype.destroy.apply(this,arguments);}};OpenLayers.Layer.KaMap=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,units:null,resolution:OpenLayers.DOTS_PER_INCH,DEFAULT_PARAMS:{i:'jpeg',map:''},initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var mapRes=this.map.getResolution();var scale=Math.round((this.map.getScale()*10000))/10000;var pX=Math.round(bounds.left/mapRes);var pY=-Math.round(bounds.top/mapRes);return this.getFullRequestString({t:pY,l:pX,s:scale});},addTile:function(bounds,position){var url=this.getURL(bounds);return new OpenLayers.Tile.Image(this,position,bounds,url,this.tileSize);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=tilecol*tilelon;var offsetlat=bounds.top;var tilerow=Math.ceil(offsetlat/tilelat)+this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=-(tilerowremain+1)*this.tileSize.h;var tileoffsetlat=tilerow*tilelat;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.KaMap(this.name,this.url,this.params,this.getOptions());}
60734 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);if(this.tileSize!=null){obj.tileSize=this.tileSize.clone();}
60735 obj.grid=[];return obj;},getTileBounds:function(viewPortPx){var resolution=this.getResolution();var tileMapWidth=resolution*this.tileSize.w;var tileMapHeight=resolution*this.tileSize.h;var mapPoint=this.getLonLatFromViewPortPx(viewPortPx);var tileLeft=tileMapWidth*Math.floor(mapPoint.lon/tileMapWidth);var tileBottom=tileMapHeight*Math.floor(mapPoint.lat/tileMapHeight);return new OpenLayers.Bounds(tileLeft,tileBottom,tileLeft+tileMapWidth,tileBottom+tileMapHeight);},CLASS_NAME:"OpenLayers.Layer.KaMap"});OpenLayers.Layer.MapGuide=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,useHttpTile:false,singleTile:false,useOverlay:false,useAsyncOverlay:true,TILE_PARAMS:{operation:'GETTILEIMAGE',version:'1.2.0'},SINGLE_TILE_PARAMS:{operation:'GETMAPIMAGE',format:'PNG',locale:'en',clip:'1',version:'1.0.0'},OVERLAY_PARAMS:{operation:'GETDYNAMICMAPOVERLAYIMAGE',format:'PNG',locale:'en',clip:'1',version:'2.0.0'},FOLDER_PARAMS:{tileColumnsPerFolder:30,tileRowsPerFolder:30,format:'png',querystring:null},defaultSize:new OpenLayers.Size(300,300),initialize:function(name,url,params,options){OpenLayers.Layer.Grid.prototype.initialize.apply(this,arguments);if(options==null||options.isBaseLayer==null){this.isBaseLayer=((this.transparent!="true")&&(this.transparent!=true));}
60736 if(options&&options.useOverlay!=null){this.useOverlay=options.useOverlay;}
60737 if(this.singleTile){if(this.useOverlay){OpenLayers.Util.applyDefaults(this.params,this.OVERLAY_PARAMS);if(!this.useAsyncOverlay){this.params.version="1.0.0";}}else{OpenLayers.Util.applyDefaults(this.params,this.SINGLE_TILE_PARAMS);}}else{if(this.useHttpTile){OpenLayers.Util.applyDefaults(this.params,this.FOLDER_PARAMS);}else{OpenLayers.Util.applyDefaults(this.params,this.TILE_PARAMS);}
60738 this.setTileSize(this.defaultSize);}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapGuide(this.name,this.url,this.params,this.getOptions());}
60739 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getURL:function(bounds){var url;var center=bounds.getCenterLonLat();var mapSize=this.map.getSize();if(this.singleTile){var params={setdisplaydpi:OpenLayers.DOTS_PER_INCH,setdisplayheight:mapSize.h*this.ratio,setdisplaywidth:mapSize.w*this.ratio,setviewcenterx:center.lon,setviewcentery:center.lat,setviewscale:this.map.getScale()};if(this.useOverlay&&!this.useAsyncOverlay){var getVisParams={};getVisParams=OpenLayers.Util.extend(getVisParams,params);getVisParams.operation="GETVISIBLEMAPEXTENT";getVisParams.version="1.0.0";getVisParams.session=this.params.session;getVisParams.mapName=this.params.mapName;getVisParams.format='text/xml';url=this.getFullRequestString(getVisParams);OpenLayers.Request.GET({url:url,async:false});}
60740 url=this.getFullRequestString(params);}else{var currentRes=this.map.getResolution();var colidx=Math.floor((bounds.left-this.maxExtent.left)/currentRes);colidx=Math.round(colidx/this.tileSize.w);var rowidx=Math.floor((this.maxExtent.top-bounds.top)/currentRes);rowidx=Math.round(rowidx/this.tileSize.h);if(this.useHttpTile){url=this.getImageFilePath({tilecol:colidx,tilerow:rowidx,scaleindex:this.resolutions.length-this.map.zoom-1});}else{url=this.getFullRequestString({tilecol:colidx,tilerow:rowidx,scaleindex:this.resolutions.length-this.map.zoom-1});}}
60741 return url;},getFullRequestString:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;if(typeof url=="object"){url=url[Math.floor(Math.random()*url.length)];}
60742 var requestString=url;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
60743 var paramsString=OpenLayers.Util.getParameterString(allParams);paramsString=paramsString.replace(/,/g,"+");if(paramsString!=""){var lastServerChar=url.charAt(url.length-1);if((lastServerChar=="&")||(lastServerChar=="?")){requestString+=paramsString;}else{if(url.indexOf('?')==-1){requestString+='?'+paramsString;}else{requestString+='&'+paramsString;}}}
60744 return requestString;},getImageFilePath:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;if(typeof url=="object"){url=url[Math.floor(Math.random()*url.length)];}
60745 var requestString=url;var tileRowGroup="";var tileColGroup="";if(newParams.tilerow<0){tileRowGroup='-';}
60746 if(newParams.tilerow==0){tileRowGroup+='0';}else{tileRowGroup+=Math.floor(Math.abs(newParams.tilerow/this.params.tileRowsPerFolder))*this.params.tileRowsPerFolder;}
60747 if(newParams.tilecol<0){tileColGroup='-';}
60748 if(newParams.tilecol==0){tileColGroup+='0';}else{tileColGroup+=Math.floor(Math.abs(newParams.tilecol/this.params.tileColumnsPerFolder))*this.params.tileColumnsPerFolder;}
60749 var tilePath='/S'+Math.floor(newParams.scaleindex)
60750 +'/'+this.params.basemaplayergroupname
60751 +'/R'+tileRowGroup
60752 +'/C'+tileColGroup
60753 +'/'+(newParams.tilerow%this.params.tileRowsPerFolder)
60754 +'_'+(newParams.tilecol%this.params.tileColumnsPerFolder)
60755 +'.'+this.params.format;if(this.params.querystring){tilePath+="?"+this.params.querystring;}
60756 requestString+=tilePath;return requestString;},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=extent.top-bounds.top+tilelat;var tilerow=Math.floor(offsetlat/tilelat)-this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=tilerowremain*this.tileSize.h;var tileoffsetlat=extent.top-tilelat*tilerow;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},CLASS_NAME:"OpenLayers.Layer.MapGuide"});OpenLayers.Layer.MapServer=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{mode:"map",map_imagetype:"png"},initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);if(options==null||options.isBaseLayer==null){this.isBaseLayer=((this.params.transparent!="true")&&(this.params.transparent!=true));}},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapServer(this.name,this.url,this.params,this.getOptions());}
60757 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var extent=[bounds.left,bounds.bottom,bounds.right,bounds.top];var imageSize=this.getImageSize();var url=this.getFullRequestString({mapext:extent,imgext:extent,map_size:[imageSize.w,imageSize.h],imgx:imageSize.w/2,imgy:imageSize.h/2,imgxy:[imageSize.w,imageSize.h]});return url;},getFullRequestString:function(newParams,altUrl){var url=(altUrl==null)?this.url:altUrl;var allParams=OpenLayers.Util.extend({},this.params);allParams=OpenLayers.Util.extend(allParams,newParams);var paramsString=OpenLayers.Util.getParameterString(allParams);if(url instanceof Array){url=this.selectUrl(paramsString,url);}
60758 var urlParams=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));for(var key in allParams){if(key.toUpperCase()in urlParams){delete allParams[key];}}
60759 paramsString=OpenLayers.Util.getParameterString(allParams);var requestString=url;paramsString=paramsString.replace(/,/g,"+");if(paramsString!=""){var lastServerChar=url.charAt(url.length-1);if((lastServerChar=="&")||(lastServerChar=="?")){requestString+=paramsString;}else{if(url.indexOf('?')==-1){requestString+='?'+paramsString;}else{requestString+='&'+paramsString;}}}
60760 return requestString;},CLASS_NAME:"OpenLayers.Layer.MapServer"});OpenLayers.Layer.TMS=OpenLayers.Class(OpenLayers.Layer.Grid,{serviceVersion:"1.0.0",isBaseLayer:true,tileOrigin:null,serverResolutions:null,zoomOffset:0,initialize:function(name,url,options){var newArguments=[];newArguments.push(name,url,{},options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.TMS(this.name,this.url,this.getOptions());}
60761 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((bounds.bottom-this.tileOrigin.lat)/(res*this.tileSize.h));var z=this.serverResolutions!=null?OpenLayers.Util.indexOf(this.serverResolutions,res):this.map.getZoom()+this.zoomOffset;var path=this.serviceVersion+"/"+this.layername+"/"+z+"/"+x+"/"+y+"."+this.type;var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
60762 return url+path;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.map.maxExtent.left,this.map.maxExtent.bottom);}},CLASS_NAME:"OpenLayers.Layer.TMS"});OpenLayers.Layer.TileCache=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,format:'image/png',serverResolutions:null,initialize:function(name,url,layername,options){this.layername=layername;OpenLayers.Layer.Grid.prototype.initialize.apply(this,[name,url,{},options]);this.extension=this.format.split('/')[1].toLowerCase();this.extension=(this.extension=='jpg')?'jpeg':this.extension;},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.TileCache(this.name,this.url,this.layername,this.getOptions());}
60763 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){var res=this.map.getResolution();var bbox=this.maxExtent;var size=this.tileSize;var tileX=Math.round((bounds.left-bbox.left)/(res*size.w));var tileY=Math.round((bounds.bottom-bbox.bottom)/(res*size.h));var tileZ=this.serverResolutions!=null?OpenLayers.Util.indexOf(this.serverResolutions,res):this.map.getZoom();function zeroPad(number,length){number=String(number);var zeros=[];for(var i=0;i<length;++i){zeros.push('0');}
60764 return zeros.join('').substring(0,length-number.length)+number;}
60765 var components=[this.layername,zeroPad(tileZ,2),zeroPad(parseInt(tileX/1000000),3),zeroPad((parseInt(tileX/1000)%1000),3),zeroPad((parseInt(tileX)%1000),3),zeroPad(parseInt(tileY/1000000),3),zeroPad((parseInt(tileY/1000)%1000),3),zeroPad((parseInt(tileY)%1000),3)+'.'+this.extension];var path=components.join('/');var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
60766 url=(url.charAt(url.length-1)=='/')?url:url+'/';return url+path;},addTile:function(bounds,position){var url=this.getURL(bounds);return new OpenLayers.Tile.Image(this,position,bounds,url,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.TileCache"});OpenLayers.Layer.WMS=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{service:"WMS",version:"1.1.1",request:"GetMap",styles:"",exceptions:"application/vnd.ogc.se_inimage",format:"image/jpeg"},reproject:false,isBaseLayer:true,encodeBBOX:false,noMagic:false,yx:{'EPSG:4326':true},initialize:function(name,url,params,options){var newArguments=[];params=OpenLayers.Util.upperCaseObject(params);if(parseFloat(params.VERSION)>=1.3&&!params.EXCEPTIONS){params.EXCEPTIONS="INIMAGE";}
60767 newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);OpenLayers.Util.applyDefaults(this.params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));if(!this.noMagic&&this.params.TRANSPARENT&&this.params.TRANSPARENT.toString().toLowerCase()=="true"){if((options==null)||(!options.isBaseLayer)){this.isBaseLayer=false;}
60768 if(this.params.FORMAT=="image/jpeg"){this.params.FORMAT=OpenLayers.Util.alphaHack()?"image/gif":"image/png";}}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMS(this.name,this.url,this.params,this.getOptions());}
60769 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},reverseAxisOrder:function(){return(parseFloat(this.params.VERSION)>=1.3&&!!this.yx[this.map.getProjectionObject().getCode()]);},getURL:function(bounds){bounds=this.adjustBounds(bounds);var imageSize=this.getImageSize();var newParams={};var reverseAxisOrder=this.reverseAxisOrder();newParams.BBOX=this.encodeBBOX?bounds.toBBOX(null,reverseAxisOrder):bounds.toArray(reverseAxisOrder);newParams.WIDTH=imageSize.w;newParams.HEIGHT=imageSize.h;var requestString=this.getFullRequestString(newParams);return requestString;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,newArguments);},getFullRequestString:function(newParams,altUrl){var projectionCode=this.map.getProjection();var value=(projectionCode=="none")?null:projectionCode
60770 if(parseFloat(this.params.VERSION)>=1.3){this.params.CRS=value;}else{this.params.SRS=value;}
60771 return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,arguments);},CLASS_NAME:"OpenLayers.Layer.WMS"});OpenLayers.Layer.WMTS=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,version:"1.0.0",requestEncoding:"KVP",url:null,layer:null,matrixSet:null,style:null,format:"image/jpeg",tileOrigin:null,tileFullExtent:null,formatSuffix:null,matrixIds:null,dimensions:null,params:null,zoomOffset:0,formatSuffixMap:{"image/png":"png","image/png8":"png","image/png24":"png","image/png32":"png","png":"png","image/jpeg":"jpg","image/jpg":"jpg","jpeg":"jpg","jpg":"jpg"},matrix:null,initialize:function(config){var required={url:true,layer:true,style:true,matrixSet:true};for(var prop in required){if(!(prop in config)){throw new Error("Missing property '"+prop+"' in layer configuration.");}}
60772 config.params=OpenLayers.Util.upperCaseObject(config.params);var args=[config.name,config.url,config.params,config];OpenLayers.Layer.Grid.prototype.initialize.apply(this,args);if(!this.formatSuffix){this.formatSuffix=this.formatSuffixMap[this.format]||this.format.split("/").pop();}
60773 if(this.matrixIds){var len=this.matrixIds.length;if(len&&typeof this.matrixIds[0]==="string"){var ids=this.matrixIds;this.matrixIds=new Array(len);for(var i=0;i<len;++i){this.matrixIds[i]={identifier:ids[i]};}}}},setMap:function(){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.updateMatrixProperties();},updateMatrixProperties:function(){this.matrix=this.getMatrix();if(this.matrix){if(this.matrix.topLeftCorner){this.tileOrigin=this.matrix.topLeftCorner;}
60774 if(this.matrix.tileWidth&&this.matrix.tileHeight){this.tileSize=new OpenLayers.Size(this.matrix.tileWidth,this.matrix.tileHeight);}
60775 if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.maxExtent.left,this.maxExtent.top);}
60776 if(!this.tileFullExtent){this.tileFullExtent=this.maxExtent;}}},moveTo:function(bounds,zoomChanged,dragging){if(zoomChanged||!this.matrix){this.updateMatrixProperties();}
60777 return OpenLayers.Layer.Grid.prototype.moveTo.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMTS(this.options);}
60778 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getMatrix:function(){var matrix;if(!this.matrixIds||this.matrixIds.length===0){matrix={identifier:this.map.getZoom()+this.zoomOffset};}else{if("scaleDenominator"in this.matrixIds[0]){var denom=OpenLayers.METERS_PER_INCH*OpenLayers.INCHES_PER_UNIT[this.units]*this.map.getResolution()/0.28E-3;var diff=Number.POSITIVE_INFINITY;var delta;for(var i=0,ii=this.matrixIds.length;i<ii;++i){delta=Math.abs(1-(this.matrixIds[i].scaleDenominator/denom));if(delta<diff){diff=delta;matrix=this.matrixIds[i];}}}else{matrix=this.matrixIds[this.map.getZoom()+this.zoomOffset];}}
60779 return matrix;},getTileInfo:function(loc){var res=this.map.getResolution();var fx=(loc.lon-this.tileOrigin.lon)/(res*this.tileSize.w);var fy=(this.tileOrigin.lat-loc.lat)/(res*this.tileSize.h);var col=Math.floor(fx);var row=Math.floor(fy);return{col:col,row:row,i:Math.floor((fx-col)*this.tileSize.w),j:Math.floor((fy-row)*this.tileSize.h)};},getURL:function(bounds){bounds=this.adjustBounds(bounds);var url="";if(!this.tileFullExtent||this.tileFullExtent.intersectsBounds(bounds)){var center=bounds.getCenterLonLat();var info=this.getTileInfo(center);var matrixId=this.matrix.identifier;if(this.requestEncoding.toUpperCase()==="REST"){var path=this.version+"/"+this.layer+"/"+this.style+"/";if(this.dimensions){for(var i=0;i<this.dimensions.length;i++){if(this.params[this.dimensions[i]]){path=path+this.params[this.dimensions[i]]+"/";}}}
60780 path=path+this.matrixSet+"/"+this.matrix.identifier+"/"+info.row+"/"+info.col+"."+this.formatSuffix;if(this.url instanceof Array){url=this.selectUrl(path,this.url);}else{url=this.url;}
60781 if(!url.match(/\/$/)){url=url+"/";}
60782 url=url+path;}else if(this.requestEncoding.toUpperCase()==="KVP"){var params={SERVICE:"WMTS",REQUEST:"GetTile",VERSION:this.version,LAYER:this.layer,STYLE:this.style,TILEMATRIXSET:this.matrixSet,TILEMATRIX:this.matrix.identifier,TILEROW:info.row,TILECOL:info.col,FORMAT:this.format};url=OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,[params]);}}
60783 return url;},mergeNewParams:function(newParams){if(this.requestEncoding.toUpperCase()==="KVP"){return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,[OpenLayers.Util.upperCaseObject(newParams)]);}},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.WMTS"});OpenLayers.Layer.WorldWind=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{},isBaseLayer:true,lzd:null,zoomLevels:null,initialize:function(name,url,lzd,zoomLevels,params,options){this.lzd=lzd;this.zoomLevels=zoomLevels;var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},getZoom:function(){var zoom=this.map.getZoom();var extent=this.map.getMaxExtent();zoom=zoom-Math.log(this.maxResolution/(this.lzd/512))/Math.log(2);return zoom;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var zoom=this.getZoom();var extent=this.map.getMaxExtent();var deg=this.lzd/Math.pow(2,this.getZoom());var x=Math.floor((bounds.left-extent.left)/deg);var y=Math.floor((bounds.bottom-extent.bottom)/deg);if(this.map.getResolution()<=(this.lzd/512)&&this.getZoom()<=this.zoomLevels){return this.getFullRequestString({L:zoom,X:x,Y:y});}else{return OpenLayers.Util.getImagesLocation()+"blank.gif";}},CLASS_NAME:"OpenLayers.Layer.WorldWind"});OpenLayers.Layer.XYZ=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:true,sphericalMercator:false,zoomOffset:0,initialize:function(name,url,options){if(options&&options.sphericalMercator||this.sphericalMercator){options=OpenLayers.Util.extend({maxExtent:new OpenLayers.Bounds(-128*156543.0339,-128*156543.0339,128*156543.0339,128*156543.0339),maxResolution:156543.0339,numZoomLevels:19,units:"m",projection:"EPSG:900913"},options);}
60784 url=url||this.url;name=name||this.name;var newArguments=[name,url,{},options];OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.XYZ(this.name,this.url,this.getOptions());}
60785 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){var res=this.map.getResolution();var x=Math.round((bounds.left-this.maxExtent.left)/(res*this.tileSize.w));var y=Math.round((this.maxExtent.top-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom()+this.zoomOffset;var url=this.url;var s=''+x+y+z;if(url instanceof Array)
60786 {url=this.selectUrl(s,url);}
60787 var path=OpenLayers.String.format(url,{'x':x,'y':y,'z':z});return path;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);if(!this.tileOrigin){this.tileOrigin=new OpenLayers.LonLat(this.maxExtent.left,this.maxExtent.bottom);}},CLASS_NAME:"OpenLayers.Layer.XYZ"});OpenLayers.Layer.OSM=OpenLayers.Class(OpenLayers.Layer.XYZ,{name:"OpenStreetMap",attribution:"Data CC-By-SA by <a href='http://openstreetmap.org/'>OpenStreetMap</a>",sphericalMercator:true,url:'http://tile.openstreetmap.org/${z}/${x}/${y}.png',clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.OSM(this.name,this.url,this.getOptions());}
60788 obj=OpenLayers.Layer.XYZ.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.OSM"});OpenLayers.Layer.Zoomify=OpenLayers.Class(OpenLayers.Layer.Grid,{url:null,size:null,isBaseLayer:true,standardTileSize:256,numberOfTiers:0,tileCountUpToTier:new Array(),tierSizeInTiles:new Array(),tierImageSize:new Array(),initialize:function(name,url,size,options){this.initializeZoomify(size);var newArguments=[];newArguments.push(name,url,size,{},options);OpenLayers.Layer.Grid.prototype.initialize.apply(this,newArguments);},initializeZoomify:function(size){var imageSize=size.clone()
60789 var tiles=new OpenLayers.Size(Math.ceil(imageSize.w/this.standardTileSize),Math.ceil(imageSize.h/this.standardTileSize));this.tierSizeInTiles.push(tiles);this.tierImageSize.push(imageSize);while(imageSize.w>this.standardTileSize||imageSize.h>this.standardTileSize){imageSize=new OpenLayers.Size(Math.floor(imageSize.w/2),Math.floor(imageSize.h/2));tiles=new OpenLayers.Size(Math.ceil(imageSize.w/this.standardTileSize),Math.ceil(imageSize.h/this.standardTileSize));this.tierSizeInTiles.push(tiles);this.tierImageSize.push(imageSize);}
60790 this.tierSizeInTiles.reverse();this.tierImageSize.reverse();this.numberOfTiers=this.tierSizeInTiles.length;this.tileCountUpToTier[0]=0;for(var i=1;i<this.numberOfTiers;i++){this.tileCountUpToTier.push(this.tierSizeInTiles[i-1].w*this.tierSizeInTiles[i-1].h+
60791 this.tileCountUpToTier[i-1]);}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);this.tileCountUpToTier.length=0
60792 this.tierSizeInTiles.length=0
60793 this.tierImageSize.length=0},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Zoomify(this.name,this.url,this.size,this.options);}
60794 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},getURL:function(bounds){bounds=this.adjustBounds(bounds);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((this.tileOrigin.lat-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom();var tileIndex=x+y*this.tierSizeInTiles[z].w+this.tileCountUpToTier[z];var path="TileGroup"+Math.floor((tileIndex)/256)+"/"+z+"-"+x+"-"+y+".jpg";var url=this.url;if(url instanceof Array){url=this.selectUrl(path,url);}
60795 return url+path;},getImageSize:function(){if(arguments.length>0){bounds=this.adjustBounds(arguments[0]);var res=this.map.getResolution();var x=Math.round((bounds.left-this.tileOrigin.lon)/(res*this.tileSize.w));var y=Math.round((this.tileOrigin.lat-bounds.top)/(res*this.tileSize.h));var z=this.map.getZoom();var w=this.standardTileSize;var h=this.standardTileSize;if(x==this.tierSizeInTiles[z].w-1){var w=this.tierImageSize[z].w%this.standardTileSize;};if(y==this.tierSizeInTiles[z].h-1){var h=this.tierImageSize[z].h%this.standardTileSize;};return(new OpenLayers.Size(w,h));}else{return this.tileSize;}},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},setMap:function(map){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.tileOrigin=new OpenLayers.LonLat(this.map.maxExtent.left,this.map.maxExtent.top);},calculateGridLayout:function(bounds,extent,resolution){var tilelon=resolution*this.tileSize.w;var tilelat=resolution*this.tileSize.h;var offsetlon=bounds.left-extent.left;var tilecol=Math.floor(offsetlon/tilelon)-this.buffer;var tilecolremain=offsetlon/tilelon-tilecol;var tileoffsetx=-tilecolremain*this.tileSize.w;var tileoffsetlon=extent.left+tilecol*tilelon;var offsetlat=extent.top-bounds.top+tilelat;var tilerow=Math.floor(offsetlat/tilelat)-this.buffer;var tilerowremain=tilerow-offsetlat/tilelat;var tileoffsety=tilerowremain*this.tileSize.h;var tileoffsetlat=extent.top-tilelat*tilerow;return{tilelon:tilelon,tilelat:tilelat,tileoffsetlon:tileoffsetlon,tileoffsetlat:tileoffsetlat,tileoffsetx:tileoffsetx,tileoffsety:tileoffsety};},CLASS_NAME:"OpenLayers.Layer.Zoomify"});OpenLayers.Protocol.SQL.Gears=OpenLayers.Class(OpenLayers.Protocol.SQL,{FID_PREFIX:'__gears_fid__',NULL_GEOMETRY:'__gears_null_geometry__',NULL_FEATURE_STATE:'__gears_null_feature_state__',jsonParser:null,wktParser:null,fidRegExp:null,saveFeatureState:true,typeOfFid:"string",db:null,initialize:function(options){if(!this.supported()){return;}
60796 OpenLayers.Protocol.SQL.prototype.initialize.apply(this,[options]);this.jsonParser=new OpenLayers.Format.JSON();this.wktParser=new OpenLayers.Format.WKT();this.fidRegExp=new RegExp('^'+this.FID_PREFIX);this.initializeDatabase();},initializeDatabase:function(){this.db=google.gears.factory.create('beta.database');this.db.open(this.databaseName);this.db.execute("CREATE TABLE IF NOT EXISTS "+this.tableName+" (fid TEXT UNIQUE, geometry TEXT, properties TEXT,"+"  state TEXT)");},destroy:function(){this.db.close();this.db=null;this.jsonParser=null;this.wktParser=null;OpenLayers.Protocol.SQL.prototype.destroy.apply(this);},supported:function(){return!!(window.google&&google.gears);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.applyDefaults(options,this.options);var feature,features=[];var rs=this.db.execute("SELECT * FROM "+this.tableName);while(rs.isValidRow()){feature=this.unfreezeFeature(rs);if(this.evaluateFilter(feature,options.filter)){if(!options.noFeatureStateReset){feature.state=null;}
60797 features.push(feature);}
60798 rs.next();}
60799 rs.close();var resp=new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,requestType:"read",features:features});if(options&&options.callback){options.callback.call(options.scope,resp);}
60800 return resp;},unfreezeFeature:function(row){var feature;var wkt=row.fieldByName('geometry');if(wkt==this.NULL_GEOMETRY){feature=new OpenLayers.Feature.Vector();}else{feature=this.wktParser.read(wkt);}
60801 feature.attributes=this.jsonParser.read(row.fieldByName('properties'));feature.fid=this.extractFidFromField(row.fieldByName('fid'));var state=row.fieldByName('state');if(state==this.NULL_FEATURE_STATE){state=null;}
60802 feature.state=state;return feature;},extractFidFromField:function(field){if(!field.match(this.fidRegExp)&&this.typeOfFid=="number"){field=parseFloat(field);}
60803 return field;},create:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=this.createOrUpdate(features);resp.requestType="create";if(options&&options.callback){options.callback.call(options.scope,resp);}
60804 return resp;},update:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=this.createOrUpdate(features);resp.requestType="update";if(options&&options.callback){options.callback.call(options.scope,resp);}
60805 return resp;},createOrUpdate:function(features){if(!(features instanceof Array)){features=[features];}
60806 var i,len=features.length,feature;var insertedFeatures=new Array(len);for(i=0;i<len;i++){feature=features[i];var params=this.freezeFeature(feature);this.db.execute("REPLACE INTO "+this.tableName+" (fid, geometry, properties, state)"+" VALUES (?, ?, ?, ?)",params);var clone=feature.clone();clone.fid=this.extractFidFromField(params[0]);insertedFeatures[i]=clone;}
60807 return new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,features:insertedFeatures,reqFeatures:features});},freezeFeature:function(feature){feature.fid=feature.fid!=null?""+feature.fid:OpenLayers.Util.createUniqueID(this.FID_PREFIX);var geometry=feature.geometry!=null?feature.geometry.toString():this.NULL_GEOMETRY;var properties=this.jsonParser.write(feature.attributes);var state=this.getFeatureStateForFreeze(feature);return[feature.fid,geometry,properties,state];},getFeatureStateForFreeze:function(feature){var state;if(!this.saveFeatureState){state=this.NULL_FEATURE_STATE;}else if(this.createdOffline(feature)){state=OpenLayers.State.INSERT;}else{state=feature.state;}
60808 return state;},"delete":function(features,options){if(!(features instanceof Array)){features=[features];}
60809 options=OpenLayers.Util.applyDefaults(options,this.options);var i,len,feature;for(i=0,len=features.length;i<len;i++){feature=features[i];if(this.saveFeatureState&&!this.createdOffline(feature)){var toDelete=feature.clone();toDelete.fid=feature.fid;if(toDelete.geometry){toDelete.geometry.destroy();toDelete.geometry=null;}
60810 toDelete.state=feature.state;this.createOrUpdate(toDelete);}else{this.db.execute("DELETE FROM "+this.tableName+" WHERE fid = ?",[feature.fid]);}}
60811 var resp=new OpenLayers.Protocol.Response({code:OpenLayers.Protocol.Response.SUCCESS,requestType:"delete",reqFeatures:features});if(options&&options.callback){options.callback.call(options.scope,resp);}
60812 return resp;},createdOffline:function(feature){return(typeof feature.fid=="string"&&!!(feature.fid.match(this.fidRegExp)));},commit:function(features,options){var opt,resp=[],nRequests=0,nResponses=0;function callback(resp){if(++nResponses<nRequests){resp.last=false;}
60813 this.callUserCallback(options,resp);}
60814 var feature,toCreate=[],toUpdate=[],toDelete=[];for(var i=features.length-1;i>=0;i--){feature=features[i];switch(feature.state){case OpenLayers.State.INSERT:toCreate.push(feature);break;case OpenLayers.State.UPDATE:toUpdate.push(feature);break;case OpenLayers.State.DELETE:toDelete.push(feature);break;}}
60815 if(toCreate.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options.create);resp.push(this.create(toCreate,opt));}
60816 if(toUpdate.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options.update);resp.push(this.update(toUpdate,opt));}
60817 if(toDelete.length>0){nRequests++;opt=OpenLayers.Util.applyDefaults({"callback":callback,"scope":this},options["delete"]);resp.push(this["delete"](toDelete,opt));}
60818 return resp;},clear:function(){this.db.execute("DELETE FROM "+this.tableName);},callUserCallback:function(options,resp){var opt=options[resp.requestType];if(opt&&opt.callback){opt.callback.call(opt.scope,resp);}
60819 if(resp.last&&options.callback){options.callback.call(options.scope);}},CLASS_NAME:"OpenLayers.Protocol.SQL.Gears"});OpenLayers.Rule=OpenLayers.Class({id:null,name:null,title:null,description:null,context:null,filter:null,elseFilter:false,symbolizer:null,symbolizers:null,minScaleDenominator:null,maxScaleDenominator:null,initialize:function(options){this.symbolizer={};OpenLayers.Util.extend(this,options);if(this.symbolizers){delete this.symbolizer;}
60820 this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i in this.symbolizer){this.symbolizer[i]=null;}
60821 this.symbolizer=null;delete this.symbolizers;},evaluate:function(feature){var context=this.getContext(feature);var applies=true;if(this.minScaleDenominator||this.maxScaleDenominator){var scale=feature.layer.map.getScale();}
60822 if(this.minScaleDenominator){applies=scale>=OpenLayers.Style.createLiteral(this.minScaleDenominator,context);}
60823 if(applies&&this.maxScaleDenominator){applies=scale<OpenLayers.Style.createLiteral(this.maxScaleDenominator,context);}
60824 if(applies&&this.filter){if(this.filter.CLASS_NAME=="OpenLayers.Filter.FeatureId"){applies=this.filter.evaluate(feature);}else{applies=this.filter.evaluate(context);}}
60825 return applies;},getContext:function(feature){var context=this.context;if(!context){context=feature.attributes||feature.data;}
60826 if(typeof this.context=="function"){context=this.context(feature);}
60827 return context;},clone:function(){var options=OpenLayers.Util.extend({},this);if(this.symbolizers){var len=this.symbolizers.length;options.symbolizers=new Array(len);for(var i=0;i<len;++i){options.symbolizers[i]=this.symbolizers[i].clone();}}else{options.symbolizer={};var value,type;for(var key in this.symbolizer){value=this.symbolizer[key];type=typeof value;if(type==="object"){options.symbolizer[key]=OpenLayers.Util.extend({},value);}else if(type==="string"){options.symbolizer[key]=value;}}}
60828 options.filter=this.filter&&this.filter.clone();options.context=this.context&&OpenLayers.Util.extend({},this.context);return new OpenLayers.Rule(options);},CLASS_NAME:"OpenLayers.Rule"});OpenLayers.StyleMap=OpenLayers.Class({styles:null,extendDefault:true,initialize:function(style,options){this.styles={"default":new OpenLayers.Style(OpenLayers.Feature.Vector.style["default"]),"select":new OpenLayers.Style(OpenLayers.Feature.Vector.style["select"]),"temporary":new OpenLayers.Style(OpenLayers.Feature.Vector.style["temporary"]),"delete":new OpenLayers.Style(OpenLayers.Feature.Vector.style["delete"])};if(style instanceof OpenLayers.Style){this.styles["default"]=style;this.styles["select"]=style;this.styles["temporary"]=style;this.styles["delete"]=style;}else if(typeof style=="object"){for(var key in style){if(style[key]instanceof OpenLayers.Style){this.styles[key]=style[key];}else if(typeof style[key]=="object"){this.styles[key]=new OpenLayers.Style(style[key]);}else{this.styles["default"]=new OpenLayers.Style(style);this.styles["select"]=new OpenLayers.Style(style);this.styles["temporary"]=new OpenLayers.Style(style);this.styles["delete"]=new OpenLayers.Style(style);break;}}}
60829 OpenLayers.Util.extend(this,options);},destroy:function(){for(var key in this.styles){this.styles[key].destroy();}
60830 this.styles=null;},createSymbolizer:function(feature,intent){if(!feature){feature=new OpenLayers.Feature.Vector();}
60831 if(!this.styles[intent]){intent="default";}
60832 feature.renderIntent=intent;var defaultSymbolizer={};if(this.extendDefault&&intent!="default"){defaultSymbolizer=this.styles["default"].createSymbolizer(feature);}
60833 return OpenLayers.Util.extend(defaultSymbolizer,this.styles[intent].createSymbolizer(feature));},addUniqueValueRules:function(renderIntent,property,symbolizers,context){var rules=[];for(var value in symbolizers){rules.push(new OpenLayers.Rule({symbolizer:symbolizers[value],context:context,filter:new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO,property:property,value:value})}));}
60834 this.styles[renderIntent].addRules(rules);},CLASS_NAME:"OpenLayers.StyleMap"});OpenLayers.Control.NavToolbar=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Navigation(),new OpenLayers.Control.ZoomBox()]);},draw:function(){var div=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);this.activateControl(this.controls[0]);return div;},CLASS_NAME:"OpenLayers.Control.NavToolbar"});OpenLayers.Filter.Comparison=OpenLayers.Class(OpenLayers.Filter,{type:null,property:null,value:null,matchCase:true,lowerBoundary:null,upperBoundary:null,initialize:function(options){OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(context){if(context instanceof OpenLayers.Feature.Vector){context=context.attributes;}
60835 var result=false;var got=context[this.property];switch(this.type){case OpenLayers.Filter.Comparison.EQUAL_TO:var exp=this.value;if(!this.matchCase&&typeof got=="string"&&typeof exp=="string"){result=(got.toUpperCase()==exp.toUpperCase());}else{result=(got==exp);}
60836 break;case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:var exp=this.value;if(!this.matchCase&&typeof got=="string"&&typeof exp=="string"){result=(got.toUpperCase()!=exp.toUpperCase());}else{result=(got!=exp);}
60837 break;case OpenLayers.Filter.Comparison.LESS_THAN:result=got<this.value;break;case OpenLayers.Filter.Comparison.GREATER_THAN:result=got>this.value;break;case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:result=got<=this.value;break;case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:result=got>=this.value;break;case OpenLayers.Filter.Comparison.BETWEEN:result=(got>=this.lowerBoundary)&&(got<=this.upperBoundary);break;case OpenLayers.Filter.Comparison.LIKE:var regexp=new RegExp(this.value,"gi");result=regexp.test(got);break;}
60838 return result;},value2regex:function(wildCard,singleChar,escapeChar){if(wildCard=="."){var msg="'.' is an unsupported wildCard character for "+"OpenLayers.Filter.Comparison";OpenLayers.Console.error(msg);return null;}
60839 wildCard=wildCard?wildCard:"*";singleChar=singleChar?singleChar:".";escapeChar=escapeChar?escapeChar:"!";this.value=this.value.replace(new RegExp("\\"+escapeChar+"(.|$)","g"),"\\$1");this.value=this.value.replace(new RegExp("\\"+singleChar,"g"),".");this.value=this.value.replace(new RegExp("\\"+wildCard,"g"),".*");this.value=this.value.replace(new RegExp("\\\\.\\*","g"),"\\"+wildCard);this.value=this.value.replace(new RegExp("\\\\\\.","g"),"\\"+singleChar);return this.value;},regex2value:function(){var value=this.value;value=value.replace(/!/g,"!!");value=value.replace(/(\\)?\\\./g,function($0,$1){return $1?$0:"!.";});value=value.replace(/(\\)?\\\*/g,function($0,$1){return $1?$0:"!*";});value=value.replace(/\\\\/g,"\\");value=value.replace(/\.\*/g,"*");return value;},clone:function(){return OpenLayers.Util.extend(new OpenLayers.Filter.Comparison(),this);},CLASS_NAME:"OpenLayers.Filter.Comparison"});OpenLayers.Filter.Comparison.EQUAL_TO="==";OpenLayers.Filter.Comparison.NOT_EQUAL_TO="!=";OpenLayers.Filter.Comparison.LESS_THAN="<";OpenLayers.Filter.Comparison.GREATER_THAN=">";OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO="<=";OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO=">=";OpenLayers.Filter.Comparison.BETWEEN="..";OpenLayers.Filter.Comparison.LIKE="~";OpenLayers.Filter.FeatureId=OpenLayers.Class(OpenLayers.Filter,{fids:null,initialize:function(options){this.fids=[];OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(feature){for(var i=0,len=this.fids.length;i<len;i++){var fid=feature.fid||feature.id;if(fid==this.fids[i]){return true;}}
60840 return false;},clone:function(){var filter=new OpenLayers.Filter.FeatureId();OpenLayers.Util.extend(filter,this);filter.fids=this.fids.slice();return filter;},CLASS_NAME:"OpenLayers.Filter.FeatureId"});OpenLayers.Filter.Logical=OpenLayers.Class(OpenLayers.Filter,{filters:null,type:null,initialize:function(options){this.filters=[];OpenLayers.Filter.prototype.initialize.apply(this,[options]);},destroy:function(){this.filters=null;OpenLayers.Filter.prototype.destroy.apply(this);},evaluate:function(context){switch(this.type){case OpenLayers.Filter.Logical.AND:for(var i=0,len=this.filters.length;i<len;i++){if(this.filters[i].evaluate(context)==false){return false;}}
60841 return true;case OpenLayers.Filter.Logical.OR:for(var i=0,len=this.filters.length;i<len;i++){if(this.filters[i].evaluate(context)==true){return true;}}
60842 return false;case OpenLayers.Filter.Logical.NOT:return(!this.filters[0].evaluate(context));}},clone:function(){var filters=[];for(var i=0,len=this.filters.length;i<len;++i){filters.push(this.filters[i].clone());}
60843 return new OpenLayers.Filter.Logical({type:this.type,filters:filters});},CLASS_NAME:"OpenLayers.Filter.Logical"});OpenLayers.Filter.Logical.AND="&&";OpenLayers.Filter.Logical.OR="||";OpenLayers.Filter.Logical.NOT="!";OpenLayers.Filter.Spatial=OpenLayers.Class(OpenLayers.Filter,{type:null,property:null,value:null,distance:null,distanceUnits:null,initialize:function(options){OpenLayers.Filter.prototype.initialize.apply(this,[options]);},evaluate:function(feature){var intersect=false;switch(this.type){case OpenLayers.Filter.Spatial.BBOX:case OpenLayers.Filter.Spatial.INTERSECTS:if(feature.geometry){var geom=this.value;if(this.value.CLASS_NAME=="OpenLayers.Bounds"){geom=this.value.toGeometry();}
60844 if(feature.geometry.intersects(geom)){intersect=true;}}
60845 break;default:OpenLayers.Console.error(OpenLayers.i18n("filterEvaluateNotImplemented"));break;}
60846 return intersect;},clone:function(){var options=OpenLayers.Util.applyDefaults({value:this.value&&this.value.clone&&this.value.clone()},this);return new OpenLayers.Filter.Spatial(options);},CLASS_NAME:"OpenLayers.Filter.Spatial"});OpenLayers.Filter.Spatial.BBOX="BBOX";OpenLayers.Filter.Spatial.INTERSECTS="INTERSECTS";OpenLayers.Filter.Spatial.DWITHIN="DWITHIN";OpenLayers.Filter.Spatial.WITHIN="WITHIN";OpenLayers.Filter.Spatial.CONTAINS="CONTAINS";OpenLayers.Geometry.Collection=OpenLayers.Class(OpenLayers.Geometry,{components:null,componentTypes:null,initialize:function(components){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.components=[];if(components!=null){this.addComponents(components);}},destroy:function(){this.components.length=0;this.components=null;OpenLayers.Geometry.prototype.destroy.apply(this,arguments);},clone:function(){var geometry=eval("new "+this.CLASS_NAME+"()");for(var i=0,len=this.components.length;i<len;i++){geometry.addComponent(this.components[i].clone());}
60847 OpenLayers.Util.applyDefaults(geometry,this);return geometry;},getComponentsString:function(){var strings=[];for(var i=0,len=this.components.length;i<len;i++){strings.push(this.components[i].toShortString());}
60848 return strings.join(",");},calculateBounds:function(){this.bounds=null;if(this.components&&this.components.length>0){this.setBounds(this.components[0].getBounds());for(var i=1,len=this.components.length;i<len;i++){this.extendBounds(this.components[i].getBounds());}}},addComponents:function(components){if(!(components instanceof Array)){components=[components];}
60849 for(var i=0,len=components.length;i<len;i++){this.addComponent(components[i]);}},addComponent:function(component,index){var added=false;if(component){if(this.componentTypes==null||(OpenLayers.Util.indexOf(this.componentTypes,component.CLASS_NAME)>-1)){if(index!=null&&(index<this.components.length)){var components1=this.components.slice(0,index);var components2=this.components.slice(index,this.components.length);components1.push(component);this.components=components1.concat(components2);}else{this.components.push(component);}
60850 component.parent=this;this.clearBounds();added=true;}}
60851 return added;},removeComponents:function(components){if(!(components instanceof Array)){components=[components];}
60852 for(var i=components.length-1;i>=0;--i){this.removeComponent(components[i]);}},removeComponent:function(component){OpenLayers.Util.removeItem(this.components,component);this.clearBounds();},getLength:function(){var length=0.0;for(var i=0,len=this.components.length;i<len;i++){length+=this.components[i].getLength();}
60853 return length;},getArea:function(){var area=0.0;for(var i=0,len=this.components.length;i<len;i++){area+=this.components[i].getArea();}
60854 return area;},getGeodesicArea:function(projection){var area=0.0;for(var i=0,len=this.components.length;i<len;i++){area+=this.components[i].getGeodesicArea(projection);}
60855 return area;},getCentroid:function(weighted){if(!weighted){return this.components.length&&this.components[0].getCentroid();}
60856 var len=this.components.length;if(!len){return false;}
60857 var areas=[];var centroids=[];var areaSum=0;var minArea=Number.MAX_VALUE;var component;for(var i=0;i<len;++i){component=this.components[i];var area=component.getArea();var centroid=component.getCentroid(true);if(isNaN(area)||isNaN(centroid.x)||isNaN(centroid.y)){continue;}
60858 areas.push(area);areaSum+=area;minArea=(area<minArea&&area>0)?area:minArea;centroids.push(centroid);}
60859 len=areas.length;if(areaSum===0){for(var i=0;i<len;++i){areas[i]=1;}
60860 areaSum=areas.length;}else{for(var i=0;i<len;++i){areas[i]/=minArea;}
60861 areaSum/=minArea;}
60862 var xSum=0,ySum=0,centroid,area;for(var i=0;i<len;++i){centroid=centroids[i];area=areas[i];xSum+=centroid.x*area;ySum+=centroid.y*area;}
60863 return new OpenLayers.Geometry.Point(xSum/areaSum,ySum/areaSum);},getGeodesicLength:function(projection){var length=0.0;for(var i=0,len=this.components.length;i<len;i++){length+=this.components[i].getGeodesicLength(projection);}
60864 return length;},move:function(x,y){for(var i=0,len=this.components.length;i<len;i++){this.components[i].move(x,y);}},rotate:function(angle,origin){for(var i=0,len=this.components.length;i<len;++i){this.components[i].rotate(angle,origin);}},resize:function(scale,origin,ratio){for(var i=0;i<this.components.length;++i){this.components[i].resize(scale,origin,ratio);}
60865 return this;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var result,best,distance;var min=Number.POSITIVE_INFINITY;for(var i=0,len=this.components.length;i<len;++i){result=this.components[i].distanceTo(geometry,options);distance=details?result.distance:result;if(distance<min){min=distance;best=result;if(min==0){break;}}}
60866 return best;},equals:function(geometry){var equivalent=true;if(!geometry||!geometry.CLASS_NAME||(this.CLASS_NAME!=geometry.CLASS_NAME)){equivalent=false;}else if(!(geometry.components instanceof Array)||(geometry.components.length!=this.components.length)){equivalent=false;}else{for(var i=0,len=this.components.length;i<len;++i){if(!this.components[i].equals(geometry.components[i])){equivalent=false;break;}}}
60867 return equivalent;},transform:function(source,dest){if(source&&dest){for(var i=0,len=this.components.length;i<len;i++){var component=this.components[i];component.transform(source,dest);}
60868 this.bounds=null;}
60869 return this;},intersects:function(geometry){var intersect=false;for(var i=0,len=this.components.length;i<len;++i){intersect=geometry.intersects(this.components[i]);if(intersect){break;}}
60870 return intersect;},getVertices:function(nodes){var vertices=[];for(var i=0,len=this.components.length;i<len;++i){Array.prototype.push.apply(vertices,this.components[i].getVertices(nodes));}
60871 return vertices;},CLASS_NAME:"OpenLayers.Geometry.Collection"});OpenLayers.Geometry.Point=OpenLayers.Class(OpenLayers.Geometry,{x:null,y:null,initialize:function(x,y){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.x=parseFloat(x);this.y=parseFloat(y);},clone:function(obj){if(obj==null){obj=new OpenLayers.Geometry.Point(this.x,this.y);}
60872 OpenLayers.Util.applyDefaults(obj,this);return obj;},calculateBounds:function(){this.bounds=new OpenLayers.Bounds(this.x,this.y,this.x,this.y);},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var distance,x0,y0,x1,y1,result;if(geometry instanceof OpenLayers.Geometry.Point){x0=this.x;y0=this.y;x1=geometry.x;y1=geometry.y;distance=Math.sqrt(Math.pow(x0-x1,2)+Math.pow(y0-y1,2));result=!details?distance:{x0:x0,y0:y0,x1:x1,y1:y1,distance:distance};}else{result=geometry.distanceTo(this,options);if(details){result={x0:result.x1,y0:result.y1,x1:result.x0,y1:result.y0,distance:result.distance};}}
60873 return result;},equals:function(geom){var equals=false;if(geom!=null){equals=((this.x==geom.x&&this.y==geom.y)||(isNaN(this.x)&&isNaN(this.y)&&isNaN(geom.x)&&isNaN(geom.y)));}
60874 return equals;},toShortString:function(){return(this.x+", "+this.y);},move:function(x,y){this.x=this.x+x;this.y=this.y+y;this.clearBounds();},rotate:function(angle,origin){angle*=Math.PI/180;var radius=this.distanceTo(origin);var theta=angle+Math.atan2(this.y-origin.y,this.x-origin.x);this.x=origin.x+(radius*Math.cos(theta));this.y=origin.y+(radius*Math.sin(theta));this.clearBounds();},getCentroid:function(){return new OpenLayers.Geometry.Point(this.x,this.y);},resize:function(scale,origin,ratio){ratio=(ratio==undefined)?1:ratio;this.x=origin.x+(scale*ratio*(this.x-origin.x));this.y=origin.y+(scale*(this.y-origin.y));this.clearBounds();return this;},intersects:function(geometry){var intersect=false;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.equals(geometry);}else{intersect=geometry.intersects(this);}
60875 return intersect;},transform:function(source,dest){if((source&&dest)){OpenLayers.Projection.transform(this,source,dest);this.bounds=null;}
60876 return this;},getVertices:function(nodes){return[this];},CLASS_NAME:"OpenLayers.Geometry.Point"});OpenLayers.Geometry.Rectangle=OpenLayers.Class(OpenLayers.Geometry,{x:null,y:null,width:null,height:null,initialize:function(x,y,width,height){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.x=x;this.y=y;this.width=width;this.height=height;},calculateBounds:function(){this.bounds=new OpenLayers.Bounds(this.x,this.y,this.x+this.width,this.y+this.height);},getLength:function(){var length=(2*this.width)+(2*this.height);return length;},getArea:function(){var area=this.width*this.height;return area;},CLASS_NAME:"OpenLayers.Geometry.Rectangle"});OpenLayers.Geometry.Surface=OpenLayers.Class(OpenLayers.Geometry,{initialize:function(){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Geometry.Surface"});OpenLayers.Layer.KaMapCache=OpenLayers.Class(OpenLayers.Layer.KaMap,{IMAGE_EXTENSIONS:{'jpeg':'jpg','gif':'gif','png':'png','png8':'png','png24':'png','dithered':'png'},DEFAULT_FORMAT:'jpeg',initialize:function(name,url,params,options){OpenLayers.Layer.KaMap.prototype.initialize.apply(this,arguments);this.extension=this.IMAGE_EXTENSIONS[this.params.i.toLowerCase()||DEFAULT_FORMAT];},getURL:function(bounds){bounds=this.adjustBounds(bounds);var mapRes=this.map.getResolution();var scale=Math.round((this.map.getScale()*10000))/10000;var pX=Math.round(bounds.left/mapRes);var pY=-Math.round(bounds.top/mapRes);var metaX=Math.floor(pX/this.tileSize.w/this.params.metaTileSize.w)*this.tileSize.w*this.params.metaTileSize.w;var metaY=Math.floor(pY/this.tileSize.h/this.params.metaTileSize.h)*this.tileSize.h*this.params.metaTileSize.h;var url=this.url;if(url instanceof Array){url=this.selectUrl(paramsString,url);}
60877 var components=[url,"/",this.params.map,"/",scale,"/",this.params.g.replace(/\s/g,'_'),"/def/t",metaY,"/l",metaX,"/t",pY,"l",pX,".",this.extension];return components.join("");},CLASS_NAME:"OpenLayers.Layer.KaMapCache"});OpenLayers.Layer.MapServer.Untiled=OpenLayers.Class(OpenLayers.Layer.MapServer,{singleTile:true,initialize:function(name,url,params,options){OpenLayers.Layer.MapServer.prototype.initialize.apply(this,arguments);var msg="The OpenLayers.Layer.MapServer.Untiled class is deprecated and "+"will be removed in 3.0. Instead, you should use the "+"normal OpenLayers.Layer.MapServer class, passing it the option "+"'singleTile' as true.";OpenLayers.Console.warn(msg);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.MapServer.Untiled(this.name,this.url,this.params,this.getOptions());}
60878 obj=OpenLayers.Layer.MapServer.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.MapServer.Untiled"});OpenLayers.Layer.Vector=OpenLayers.Class(OpenLayers.Layer,{EVENT_TYPES:["beforefeatureadded","beforefeaturesadded","featureadded","featuresadded","beforefeatureremoved","beforefeaturesremoved","featureremoved","featuresremoved","beforefeatureselected","featureselected","featureunselected","beforefeaturemodified","featuremodified","afterfeaturemodified","vertexmodified","sketchstarted","sketchmodified","sketchcomplete","refresh"],isBaseLayer:false,isFixed:false,isVector:true,features:null,filter:null,selectedFeatures:null,unrenderedFeatures:null,reportError:true,style:null,styleMap:null,strategies:null,protocol:null,renderers:['SVG','VML','Canvas'],renderer:null,rendererOptions:null,geometryType:null,drawn:false,initialize:function(name,options){this.EVENT_TYPES=OpenLayers.Layer.Vector.prototype.EVENT_TYPES.concat(OpenLayers.Layer.prototype.EVENT_TYPES);OpenLayers.Layer.prototype.initialize.apply(this,arguments);if(!this.renderer||!this.renderer.supported()){this.assignRenderer();}
60879 if(!this.renderer||!this.renderer.supported()){this.renderer=null;this.displayError();}
60880 if(!this.styleMap){this.styleMap=new OpenLayers.StyleMap();}
60881 this.features=[];this.selectedFeatures=[];this.unrenderedFeatures={};if(this.strategies){for(var i=0,len=this.strategies.length;i<len;i++){this.strategies[i].setLayer(this);}}},destroy:function(){if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoDestroy){strategy.destroy();}}
60882 this.strategies=null;}
60883 if(this.protocol){if(this.protocol.autoDestroy){this.protocol.destroy();}
60884 this.protocol=null;}
60885 this.destroyFeatures();this.features=null;this.selectedFeatures=null;this.unrenderedFeatures=null;if(this.renderer){this.renderer.destroy();}
60886 this.renderer=null;this.geometryType=null;this.drawn=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.Vector(this.name,this.getOptions());}
60887 obj=OpenLayers.Layer.prototype.clone.apply(this,[obj]);var features=this.features;var len=features.length;var clonedFeatures=new Array(len);for(var i=0;i<len;++i){clonedFeatures[i]=features[i].clone();}
60888 obj.features=clonedFeatures;return obj;},refresh:function(obj){if(this.calculateInRange()&&this.visibility){this.events.triggerEvent("refresh",obj);}},assignRenderer:function(){for(var i=0,len=this.renderers.length;i<len;i++){var rendererClass=this.renderers[i];var renderer=(typeof rendererClass=="function")?rendererClass:OpenLayers.Renderer[rendererClass];if(renderer&&renderer.prototype.supported()){this.renderer=new renderer(this.div,this.rendererOptions);break;}}},displayError:function(){if(this.reportError){OpenLayers.Console.userError(OpenLayers.i18n("browserNotSupported",{'renderers':this.renderers.join("\n")}));}},setMap:function(map){OpenLayers.Layer.prototype.setMap.apply(this,arguments);if(!this.renderer){this.map.removeLayer(this);}else{this.renderer.map=this.map;this.renderer.setSize(this.map.getSize());}},afterAdd:function(){if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoActivate){strategy.activate();}}}},removeMap:function(map){this.drawn=false;if(this.strategies){var strategy,i,len;for(i=0,len=this.strategies.length;i<len;i++){strategy=this.strategies[i];if(strategy.autoActivate){strategy.deactivate();}}}},onMapResize:function(){OpenLayers.Layer.prototype.onMapResize.apply(this,arguments);this.renderer.setSize(this.map.getSize());},moveTo:function(bounds,zoomChanged,dragging){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);var coordSysUnchanged=true;if(!dragging){this.renderer.root.style.visibility="hidden";this.div.style.left=-parseInt(this.map.layerContainerDiv.style.left)+"px";this.div.style.top=-parseInt(this.map.layerContainerDiv.style.top)+"px";var extent=this.map.getExtent();coordSysUnchanged=this.renderer.setExtent(extent,zoomChanged);this.renderer.root.style.visibility="visible";if(navigator.userAgent.toLowerCase().indexOf("gecko")!=-1){this.div.scrollLeft=this.div.scrollLeft;}
60889 if(!zoomChanged&&coordSysUnchanged){for(var i in this.unrenderedFeatures){var feature=this.unrenderedFeatures[i];this.drawFeature(feature);}}}
60890 if(!this.drawn||zoomChanged||!coordSysUnchanged){this.drawn=true;var feature;for(var i=0,len=this.features.length;i<len;i++){this.renderer.locked=(i!==(len-1));feature=this.features[i];this.drawFeature(feature);}}},display:function(display){OpenLayers.Layer.prototype.display.apply(this,arguments);var currentDisplay=this.div.style.display;if(currentDisplay!=this.renderer.root.style.display){this.renderer.root.style.display=currentDisplay;}},addFeatures:function(features,options){if(!(features instanceof Array)){features=[features];}
60891 var notify=!options||!options.silent;if(notify){var event={features:features};var ret=this.events.triggerEvent("beforefeaturesadded",event);if(ret===false){return;}
60892 features=event.features;}
60893 var featuresAdded=[];for(var i=0,len=features.length;i<len;i++){if(i!=(features.length-1)){this.renderer.locked=true;}else{this.renderer.locked=false;}
60894 var feature=features[i];if(this.geometryType&&!(feature.geometry instanceof this.geometryType)){var throwStr=OpenLayers.i18n('componentShouldBe',{'geomType':this.geometryType.prototype.CLASS_NAME});throw throwStr;}
60895 feature.layer=this;if(!feature.style&&this.style){feature.style=OpenLayers.Util.extend({},this.style);}
60896 if(notify){if(this.events.triggerEvent("beforefeatureadded",{feature:feature})===false){continue;};this.preFeatureInsert(feature);}
60897 featuresAdded.push(feature);this.features.push(feature);this.drawFeature(feature);if(notify){this.events.triggerEvent("featureadded",{feature:feature});this.onFeatureInsert(feature);}}
60898 if(notify){this.events.triggerEvent("featuresadded",{features:featuresAdded});}},removeFeatures:function(features,options){if(!features||features.length===0){return;}
60899 if(features===this.features){return this.removeAllFeatures(options);}
60900 if(!(features instanceof Array)){features=[features];}
60901 if(features===this.selectedFeatures){features=features.slice();}
60902 var notify=!options||!options.silent;if(notify){this.events.triggerEvent("beforefeaturesremoved",{features:features});}
60903 for(var i=features.length-1;i>=0;i--){if(i!=0&&features[i-1].geometry){this.renderer.locked=true;}else{this.renderer.locked=false;}
60904 var feature=features[i];delete this.unrenderedFeatures[feature.id];if(notify){this.events.triggerEvent("beforefeatureremoved",{feature:feature});}
60905 this.features=OpenLayers.Util.removeItem(this.features,feature);feature.layer=null;if(feature.geometry){this.renderer.eraseFeatures(feature);}
60906 if(OpenLayers.Util.indexOf(this.selectedFeatures,feature)!=-1){OpenLayers.Util.removeItem(this.selectedFeatures,feature);}
60907 if(notify){this.events.triggerEvent("featureremoved",{feature:feature});}}
60908 if(notify){this.events.triggerEvent("featuresremoved",{features:features});}},removeAllFeatures:function(options){var notify=!options||!options.silent;var features=this.features;if(notify){this.events.triggerEvent("beforefeaturesremoved",{features:features});}
60909 var feature;for(var i=features.length-1;i>=0;i--){feature=features[i];if(notify){this.events.triggerEvent("beforefeatureremoved",{feature:feature});}
60910 feature.layer=null;if(notify){this.events.triggerEvent("featureremoved",{feature:feature});}}
60911 this.renderer.clear();this.features=[];this.unrenderedFeatures={};this.selectedFeatures=[];if(notify){this.events.triggerEvent("featuresremoved",{features:features});}},destroyFeatures:function(features,options){var all=(features==undefined);if(all){features=this.features;}
60912 if(features){this.removeFeatures(features,options);for(var i=features.length-1;i>=0;i--){features[i].destroy();}}},drawFeature:function(feature,style){if(!this.drawn){return}
60913 if(typeof style!="object"){if(!style&&feature.state===OpenLayers.State.DELETE){style="delete";}
60914 var renderIntent=style||feature.renderIntent;style=feature.style||this.style;if(!style){style=this.styleMap.createSymbolizer(feature,renderIntent);}}
60915 if(!this.renderer.drawFeature(feature,style)){this.unrenderedFeatures[feature.id]=feature;}else{delete this.unrenderedFeatures[feature.id];};},eraseFeatures:function(features){this.renderer.eraseFeatures(features);},getFeatureFromEvent:function(evt){if(!this.renderer){OpenLayers.Console.error(OpenLayers.i18n("getFeatureError"));return null;}
60916 var featureId=this.renderer.getFeatureIdFromEvent(evt);return this.getFeatureById(featureId);},getFeatureBy:function(property,value){var feature=null;for(var i=0,len=this.features.length;i<len;++i){if(this.features[i][property]==value){feature=this.features[i];break;}}
60917 return feature;},getFeatureById:function(featureId){return this.getFeatureBy('id',featureId);},getFeatureByFid:function(featureFid){return this.getFeatureBy('fid',featureFid);},onFeatureInsert:function(feature){},preFeatureInsert:function(feature){},getDataExtent:function(){var maxExtent=null;var features=this.features;if(features&&(features.length>0)){maxExtent=new OpenLayers.Bounds();var geometry=null;for(var i=0,len=features.length;i<len;i++){geometry=features[i].geometry;if(geometry){maxExtent.extend(geometry.getBounds());}}}
60918 return maxExtent;},CLASS_NAME:"OpenLayers.Layer.Vector"});OpenLayers.Layer.WMS.Post=OpenLayers.Class(OpenLayers.Layer.WMS,{tileClass:null,unsupportedBrowsers:["mozilla","firefox","opera"],SUPPORTED_TRANSITIONS:[],initialize:function(name,url,params,options){var newArguments=[];newArguments.push(name,url,params,options);OpenLayers.Layer.WMS.prototype.initialize.apply(this,newArguments);this.tileClass=OpenLayers.Util.indexOf(this.unsupportedBrowsers,OpenLayers.Util.getBrowserName())!=-1?OpenLayers.Tile.Image:OpenLayers.Tile.Image.IFrame;},addTile:function(bounds,position){return new this.tileClass(this,position,bounds,null,this.tileSize);},CLASS_NAME:'OpenLayers.Layer.WMS.Post'});OpenLayers.Layer.WMS.Untiled=OpenLayers.Class(OpenLayers.Layer.WMS,{singleTile:true,initialize:function(name,url,params,options){OpenLayers.Layer.WMS.prototype.initialize.apply(this,arguments);var msg="The OpenLayers.Layer.WMS.Untiled class is deprecated and "+"will be removed in 3.0. Instead, you should use the "+"normal OpenLayers.Layer.WMS class, passing it the option "+"'singleTile' as true.";OpenLayers.Console.warn(msg);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WMS.Untiled(this.name,this.url,this.params,this.getOptions());}
60919 obj=OpenLayers.Layer.WMS.prototype.clone.apply(this,[obj]);return obj;},CLASS_NAME:"OpenLayers.Layer.WMS.Untiled"});OpenLayers.Strategy.Filter=OpenLayers.Class(OpenLayers.Strategy,{filter:null,cache:null,caching:false,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);if(!this.filter||!(this.filter instanceof OpenLayers.Filter)){throw new Error("Filter strategy must be constructed with a filter");}},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.apply(this,arguments);if(activated){this.cache=[];this.layer.events.on({"beforefeaturesadded":this.handleAdd,"beforefeaturesremoved":this.handleRemove,scope:this});}
60920 return activated;},deactivate:function(){this.cache=null;if(this.layer&&this.layer.events){this.layer.events.un({"beforefeaturesadded":this.handleAdd,"beforefeaturesremoved":this.handleRemove,scope:this});}
60921 return OpenLayers.Strategy.prototype.deactivate.apply(this,arguments);},handleAdd:function(event){if(!this.caching){var features=event.features;event.features=[];var feature;for(var i=0,ii=features.length;i<ii;++i){feature=features[i];if(this.filter.evaluate(feature)){event.features.push(feature);}else{this.cache.push(feature);}}}},handleRemove:function(event){if(!this.caching){this.cache=[];}},setFilter:function(filter){this.filter=filter;var previousCache=this.cache;this.cache=[];this.handleAdd({features:this.layer.features});if(this.cache.length>0){this.caching=true;this.layer.removeFeatures(this.cache.slice(),{silent:true});this.caching=false;}
60922 if(previousCache.length>0){var event={features:previousCache};this.handleAdd(event);this.caching=true;this.layer.addFeatures(event.features,{silent:true});this.caching=false;}},CLASS_NAME:"OpenLayers.Strategy.Filter"});OpenLayers.Style2=OpenLayers.Class({id:null,name:null,title:null,description:null,layerName:null,isDefault:false,rules:null,initialize:function(config){OpenLayers.Util.extend(this,config);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_");},destroy:function(){for(var i=0,len=this.rules.length;i<len;i++){this.rules[i].destroy();}
60923 delete this.rules;},clone:function(){var config=OpenLayers.Util.extend({},this);if(this.rules){config.rules=[];for(var i=0,len=this.rules.length;i<len;++i){config.rules.push(this.rules[i].clone());}}
60924 return new OpenLayers.Style2(config);},CLASS_NAME:"OpenLayers.Style2"});OpenLayers.Control.GetFeature=OpenLayers.Class(OpenLayers.Control,{protocol:null,multipleKey:null,toggleKey:null,modifiers:null,multiple:false,click:true,single:true,clickout:true,toggle:false,clickTolerance:5,hover:false,box:false,maxFeatures:10,features:null,hoverFeature:null,handlerOptions:null,handlers:null,hoverResponse:null,filterType:OpenLayers.Filter.Spatial.BBOX,EVENT_TYPES:["featureselected","featuresselected","featureunselected","clickout","beforefeatureselected","beforefeaturesselected","hoverfeature","outfeature"],initialize:function(options){this.EVENT_TYPES=OpenLayers.Control.GetFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);options.handlerOptions=options.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[options]);this.features={};this.handlers={};if(this.click){this.handlers.click=new OpenLayers.Handler.Click(this,{click:this.selectClick},this.handlerOptions.click||{});}
60925 if(this.box){this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},OpenLayers.Util.extend(this.handlerOptions.box,{boxDivClassName:"olHandlerBoxSelectFeature"}));}
60926 if(this.hover){this.handlers.hover=new OpenLayers.Handler.Hover(this,{'move':this.cancelHover,'pause':this.selectHover},OpenLayers.Util.extend(this.handlerOptions.hover,{'delay':250}));}},activate:function(){if(!this.active){for(var i in this.handlers){this.handlers[i].activate();}}
60927 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){if(this.active){for(var i in this.handlers){this.handlers[i].deactivate();}}
60928 return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},selectClick:function(evt){var bounds=this.pixelToBounds(evt.xy);this.setModifiers(evt);this.request(bounds,{single:this.single});},selectBox:function(position){var bounds;if(position instanceof OpenLayers.Bounds){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);}else{if(this.click){return;}
60929 bounds=this.pixelToBounds(position);}
60930 this.setModifiers(this.handlers.box.dragHandler.evt);this.request(bounds);},selectHover:function(evt){var bounds=this.pixelToBounds(evt.xy);this.request(bounds,{single:true,hover:true});},cancelHover:function(){if(this.hoverResponse){this.protocol.abort(this.hoverResponse);this.hoverResponse=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");}},request:function(bounds,options){options=options||{};var filter=new OpenLayers.Filter.Spatial({type:this.filterType,value:bounds});OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");var response=this.protocol.read({maxFeatures:options.single==true?this.maxFeatures:undefined,filter:filter,callback:function(result){if(result.success()){if(result.features.length){if(options.single==true){this.selectBestFeature(result.features,bounds.getCenterLonLat(),options);}else{this.select(result.features);}}else if(options.hover){this.hoverSelect();}else{this.events.triggerEvent("clickout");if(this.clickout){this.unselectAll();}}}
60931 OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait");},scope:this});if(options.hover==true){this.hoverResponse=response;}},selectBestFeature:function(features,clickPosition,options){options=options||{};if(features.length){var point=new OpenLayers.Geometry.Point(clickPosition.lon,clickPosition.lat);var feature,resultFeature,dist;var minDist=Number.MAX_VALUE;for(var i=0;i<features.length;++i){feature=features[i];if(feature.geometry){dist=point.distanceTo(feature.geometry,{edge:false});if(dist<minDist){minDist=dist;resultFeature=feature;if(minDist==0){break;}}}}
60932 if(options.hover==true){this.hoverSelect(resultFeature);}else{this.select(resultFeature||features);}}},setModifiers:function(evt){this.modifiers={multiple:this.multiple||(this.multipleKey&&evt[this.multipleKey]),toggle:this.toggle||(this.toggleKey&&evt[this.toggleKey])};},select:function(features){if(!this.modifiers.multiple&&!this.modifiers.toggle){this.unselectAll();}
60933 if(!(features instanceof Array)){features=[features];}
60934 var cont=this.events.triggerEvent("beforefeaturesselected",{features:features});if(cont!==false){var selectedFeatures=[];var feature;for(var i=0,len=features.length;i<len;++i){feature=features[i];if(this.features[feature.fid||feature.id]){if(this.modifiers.toggle){this.unselect(this.features[feature.fid||feature.id]);}}else{cont=this.events.triggerEvent("beforefeatureselected",{feature:feature});if(cont!==false){this.features[feature.fid||feature.id]=feature;selectedFeatures.push(feature);this.events.triggerEvent("featureselected",{feature:feature});}}}
60935 this.events.triggerEvent("featuresselected",{features:selectedFeatures});}},hoverSelect:function(feature){var fid=feature?feature.fid||feature.id:null;var hfid=this.hoverFeature?this.hoverFeature.fid||this.hoverFeature.id:null;if(hfid&&hfid!=fid){this.events.triggerEvent("outfeature",{feature:this.hoverFeature});this.hoverFeature=null;}
60936 if(fid&&fid!=hfid){this.events.triggerEvent("hoverfeature",{feature:feature});this.hoverFeature=feature;}},unselect:function(feature){delete this.features[feature.fid||feature.id];this.events.triggerEvent("featureunselected",{feature:feature});},unselectAll:function(){for(var fid in this.features){this.unselect(this.features[fid]);}},setMap:function(map){for(var i in this.handlers){this.handlers[i].setMap(map);}
60937 OpenLayers.Control.prototype.setMap.apply(this,arguments);},pixelToBounds:function(pixel){var llPx=pixel.add(-this.clickTolerance/2,this.clickTolerance/2);var urPx=pixel.add(this.clickTolerance/2,-this.clickTolerance/2);var ll=this.map.getLonLatFromPixel(llPx);var ur=this.map.getLonLatFromPixel(urPx);return new OpenLayers.Bounds(ll.lon,ll.lat,ur.lon,ur.lat);},CLASS_NAME:"OpenLayers.Control.GetFeature"});OpenLayers.Control.Snapping=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesnap","snap","unsnap"],DEFAULTS:{tolerance:10,node:true,edge:true,vertex:true},greedy:true,precedence:["node","vertex","edge"],resolution:null,geoToleranceCache:null,layer:null,feature:null,point:null,initialize:function(options){Array.prototype.push.apply(this.EVENT_TYPES,OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.options=options||{};if(this.options.layer){this.setLayer(this.options.layer);}
60938 var defaults=OpenLayers.Util.extend({},this.options.defaults);this.defaults=OpenLayers.Util.applyDefaults(defaults,this.DEFAULTS);this.setTargets(this.options.targets);if(this.targets.length===0&&this.layer){this.addTargetLayer(this.layer);}
60939 this.geoToleranceCache={};},setLayer:function(layer){if(this.active){this.deactivate();this.layer=layer;this.activate();}else{this.layer=layer;}},setTargets:function(targets){this.targets=[];if(targets&&targets.length){var target;for(var i=0,len=targets.length;i<len;++i){target=targets[i];if(target instanceof OpenLayers.Layer.Vector){this.addTargetLayer(target);}else{this.addTarget(target);}}}},addTargetLayer:function(layer){this.addTarget({layer:layer});},addTarget:function(target){target=OpenLayers.Util.applyDefaults(target,this.defaults);target.nodeTolerance=target.nodeTolerance||target.tolerance;target.vertexTolerance=target.vertexTolerance||target.tolerance;target.edgeTolerance=target.edgeTolerance||target.tolerance;this.targets.push(target);},removeTargetLayer:function(layer){var target;for(var i=this.targets.length-1;i>=0;--i){target=this.targets[i];if(target.layer===layer){this.removeTarget(target);}}},removeTarget:function(target){return OpenLayers.Util.removeItem(this.targets,target);},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){if(this.layer&&this.layer.events){this.layer.events.on({sketchstarted:this.onSketchModified,sketchmodified:this.onSketchModified,vertexmodified:this.onVertexModified,scope:this});}}
60940 return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){if(this.layer&&this.layer.events){this.layer.events.un({sketchstarted:this.onSketchModified,sketchmodified:this.onSketchModified,vertexmodified:this.onVertexModified,scope:this});}}
60941 this.feature=null;this.point=null;return deactivated;},onSketchModified:function(event){this.feature=event.feature;this.considerSnapping(event.vertex,event.vertex);},onVertexModified:function(event){this.feature=event.feature;var loc=this.layer.map.getLonLatFromViewPortPx(event.pixel);this.considerSnapping(event.vertex,new OpenLayers.Geometry.Point(loc.lon,loc.lat));},considerSnapping:function(point,loc){var best={rank:Number.POSITIVE_INFINITY,dist:Number.POSITIVE_INFINITY,x:null,y:null};var snapped=false;var result,target;for(var i=0,len=this.targets.length;i<len;++i){target=this.targets[i];result=this.testTarget(target,loc);if(result){if(this.greedy){best=result;best.target=target;snapped=true;break;}else{if((result.rank<best.rank)||(result.rank===best.rank&&result.dist<best.dist)){best=result;best.target=target;snapped=true;}}}}
60942 if(snapped){var proceed=this.events.triggerEvent("beforesnap",{point:point,x:best.x,y:best.y,distance:best.dist,layer:best.target.layer,snapType:this.precedence[best.rank]});if(proceed!==false){point.x=best.x;point.y=best.y;this.point=point;this.events.triggerEvent("snap",{point:point,snapType:this.precedence[best.rank],layer:best.target.layer,distance:best.dist});}else{snapped=false;}}
60943 if(this.point&&!snapped){point.x=loc.x;point.y=loc.y;this.point=null;this.events.triggerEvent("unsnap",{point:point});}},testTarget:function(target,loc){var tolerance={node:this.getGeoTolerance(target.nodeTolerance),vertex:this.getGeoTolerance(target.vertexTolerance),edge:this.getGeoTolerance(target.edgeTolerance)};var maxTolerance=Math.max(tolerance.node,tolerance.vertex,tolerance.edge);var result={rank:Number.POSITIVE_INFINITY,dist:Number.POSITIVE_INFINITY};var eligible=false;var features=target.layer.features;var feature,type,vertices,vertex,closest,dist,found;var numTypes=this.precedence.length;var ll=new OpenLayers.LonLat(loc.x,loc.y);for(var i=0,len=features.length;i<len;++i){feature=features[i];if(feature!==this.feature&&!feature._sketch&&feature.state!==OpenLayers.State.DELETE&&(!target.filter||target.filter.evaluate(feature.attributes))){if(feature.atPoint(ll,maxTolerance,maxTolerance)){for(var j=0,stop=Math.min(result.rank+1,numTypes);j<stop;++j){type=this.precedence[j];if(target[type]){if(type==="edge"){closest=feature.geometry.distanceTo(loc,{details:true});dist=closest.distance;if(dist<=tolerance[type]&&dist<result.dist){result={rank:j,dist:dist,x:closest.x0,y:closest.y0};eligible=true;break;}}else{vertices=feature.geometry.getVertices(type==="node");found=false;for(var k=0,klen=vertices.length;k<klen;++k){vertex=vertices[k];dist=vertex.distanceTo(loc);if(dist<=tolerance[type]&&(j<result.rank||(j===result.rank&&dist<result.dist))){result={rank:j,dist:dist,x:vertex.x,y:vertex.y};eligible=true;found=true;}}
60944 if(found){break;}}}}}}}
60945 return eligible?result:null;},getGeoTolerance:function(tolerance){var resolution=this.layer.map.getResolution();if(resolution!==this.resolution){this.resolution=resolution;this.geoToleranceCache={};}
60946 var geoTolerance=this.geoToleranceCache[tolerance];if(geoTolerance===undefined){geoTolerance=tolerance*resolution;this.geoToleranceCache[tolerance]=geoTolerance;}
60947 return geoTolerance;},destroy:function(){if(this.active){this.deactivate();}
60948 delete this.layer;delete this.targets;OpenLayers.Control.prototype.destroy.call(this);},CLASS_NAME:"OpenLayers.Control.Snapping"});OpenLayers.Format.Filter=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},write:function(filter,options){var version=(options&&options.version)||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.Filter["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a Filter parser for version "+
60949 version;}
60950 this.parser=new format(this.options);}
60951 return this.parser.write(filter);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60952 var version=this.version;if(!version){version=this.defaultVersion;}
60953 if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.Filter["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a Filter parser for version "+
60954 version;}
60955 this.parser=new format(this.options);}
60956 var filter=this.parser.read(data);return filter;},CLASS_NAME:"OpenLayers.Format.Filter"});OpenLayers.Format.SLD=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:"1.0.0",version:null,namedLayersAsArray:false,parser:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},write:function(sld,options){var version=(options&&options.version)||this.version||this.defaultVersion;if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.SLD["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a SLD parser for version "+
60957 version;}
60958 this.parser=new format(this.options);}
60959 var root=this.parser.write(sld);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},read:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
60960 var root=data.documentElement;var version=this.version;if(!version){version=root.getAttribute("version");if(!version){version=this.defaultVersion;}}
60961 if(!this.parser||this.parser.VERSION!=version){var format=OpenLayers.Format.SLD["v"+version.replace(/\./g,"_")];if(!format){throw"Can't find a SLD parser for version "+
60962 version;}
60963 this.parser=new format(this.options);}
60964 var sld=this.parser.read(data,options);return sld;},CLASS_NAME:"OpenLayers.Format.SLD"});OpenLayers.Format.Text=OpenLayers.Class(OpenLayers.Format,{defaultStyle:null,extractStyles:true,initialize:function(options){options=options||{};if(options.extractStyles!==false){options.defaultStyle={'externalGraphic':OpenLayers.Util.getImagesLocation()+"marker.png",'graphicWidth':21,'graphicHeight':25,'graphicXOffset':-10.5,'graphicYOffset':-12.5};}
60965 OpenLayers.Format.prototype.initialize.apply(this,[options]);},read:function(text){var lines=text.split('\n');var columns;var features=[];for(var lcv=0;lcv<(lines.length-1);lcv++){var currLine=lines[lcv].replace(/^\s*/,'').replace(/\s*$/,'');if(currLine.charAt(0)!='#'){if(!columns){columns=currLine.split('\t');}else{var vals=currLine.split('\t');var geometry=new OpenLayers.Geometry.Point(0,0);var attributes={};var style=this.defaultStyle?OpenLayers.Util.applyDefaults({},this.defaultStyle):null;var icon,iconSize,iconOffset,overflow;var set=false;for(var valIndex=0;valIndex<vals.length;valIndex++){if(vals[valIndex]){if(columns[valIndex]=='point'){var coords=vals[valIndex].split(',');geometry.y=parseFloat(coords[0]);geometry.x=parseFloat(coords[1]);set=true;}else if(columns[valIndex]=='lat'){geometry.y=parseFloat(vals[valIndex]);set=true;}else if(columns[valIndex]=='lon'){geometry.x=parseFloat(vals[valIndex]);set=true;}else if(columns[valIndex]=='title')
60966 attributes['title']=vals[valIndex];else if(columns[valIndex]=='image'||columns[valIndex]=='icon'&&style){style['externalGraphic']=vals[valIndex];}else if(columns[valIndex]=='iconSize'&&style){var size=vals[valIndex].split(',');style['graphicWidth']=parseFloat(size[0]);style['graphicHeight']=parseFloat(size[1]);}else if(columns[valIndex]=='iconOffset'&&style){var offset=vals[valIndex].split(',');style['graphicXOffset']=parseFloat(offset[0]);style['graphicYOffset']=parseFloat(offset[1]);}else if(columns[valIndex]=='description'){attributes['description']=vals[valIndex];}else if(columns[valIndex]=='overflow'){attributes['overflow']=vals[valIndex];}else{attributes[columns[valIndex]]=vals[valIndex];}}}
60967 if(set){if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
60968 var feature=new OpenLayers.Feature.Vector(geometry,attributes,style);features.push(feature);}}}}
60969 return features;},CLASS_NAME:"OpenLayers.Format.Text"});OpenLayers.Geometry.MultiPoint=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},addPoint:function(point,index){this.addComponent(point,index);},removePoint:function(point){this.removeComponent(point);},CLASS_NAME:"OpenLayers.Geometry.MultiPoint"});OpenLayers.Handler.Point=OpenLayers.Class(OpenLayers.Handler,{point:null,layer:null,multi:false,drawing:false,mouseDown:false,lastDown:null,lastUp:null,persist:false,layerOptions:null,initialize:function(control,callbacks,options){if(!(options&&options.layerOptions&&options.layerOptions.styleMap)){this.style=OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'],{});}
60970 OpenLayers.Handler.prototype.initialize.apply(this,arguments);},activate:function(){if(!OpenLayers.Handler.prototype.activate.apply(this,arguments)){return false;}
60971 var options=OpenLayers.Util.extend({displayInLayerSwitcher:false,calculateInRange:OpenLayers.Function.True},this.layerOptions);this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,options);this.map.addLayer(this.layer);return true;},createFeature:function(pixel){var lonlat=this.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.callback("create",[this.point.geometry,this.point]);this.point.geometry.clearBounds();this.layer.addFeatures([this.point],{silent:true});},deactivate:function(){if(!OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){return false;}
60972 if(this.drawing){this.cancel();}
60973 this.destroyFeature();if(this.layer.map!=null){this.layer.destroy(false);}
60974 this.layer=null;return true;},destroyFeature:function(){if(this.layer){this.layer.destroyFeatures();}
60975 this.point=null;},finalize:function(cancel){var key=cancel?"cancel":"done";this.drawing=false;this.mouseDown=false;this.lastDown=null;this.lastUp=null;this.callback(key,[this.geometryClone()]);if(cancel||!this.persist){this.destroyFeature();}},cancel:function(){this.finalize(true);},click:function(evt){OpenLayers.Event.stop(evt);return false;},dblclick:function(evt){OpenLayers.Event.stop(evt);return false;},modifyFeature:function(pixel){var lonlat=this.map.getLonLatFromPixel(pixel);this.point.geometry.x=lonlat.lon;this.point.geometry.y=lonlat.lat;this.callback("modify",[this.point.geometry,this.point]);this.point.geometry.clearBounds();this.drawFeature();},drawFeature:function(){this.layer.drawFeature(this.point,this.style);},getGeometry:function(){var geometry=this.point&&this.point.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiPoint([geometry]);}
60976 return geometry;},geometryClone:function(){var geom=this.getGeometry();return geom&&geom.clone();},mousedown:function(evt){if(!this.checkModifiers(evt)){return true;}
60977 if(this.lastDown&&this.lastDown.equals(evt.xy)){return true;}
60978 this.drawing=true;if(this.lastDown==null){if(this.persist){this.destroyFeature();}
60979 this.createFeature(evt.xy);}else{this.modifyFeature(evt.xy);}
60980 this.lastDown=evt.xy;return false;},mousemove:function(evt){if(this.drawing){this.modifyFeature(evt.xy);}
60981 return true;},mouseup:function(evt){if(this.drawing){this.finalize();return false;}else{return true;}},CLASS_NAME:"OpenLayers.Handler.Point"});OpenLayers.Layer.GML=OpenLayers.Class(OpenLayers.Layer.Vector,{loaded:false,format:null,formatOptions:null,initialize:function(name,url,options){var newArguments=[];newArguments.push(name,options);OpenLayers.Layer.Vector.prototype.initialize.apply(this,newArguments);this.url=url;},setVisibility:function(visibility,noEvent){OpenLayers.Layer.Vector.prototype.setVisibility.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadGML();}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Vector.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadGML();}},loadGML:function(){if(!this.loaded){this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.url,success:this.requestSuccess,failure:this.requestFailure,scope:this});this.loaded=true;}},setUrl:function(url){this.url=url;this.destroyFeatures();this.loaded=false;this.loadGML();},requestSuccess:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
60982 var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
60983 var gml=this.format?new this.format(options):new OpenLayers.Format.GML(options);this.addFeatures(gml.read(doc));this.events.triggerEvent("loadend");},requestFailure:function(request){OpenLayers.Console.userError(OpenLayers.i18n("errorLoadingGML",{'url':this.url}));this.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Layer.GML"});OpenLayers.Layer.PointTrack=OpenLayers.Class(OpenLayers.Layer.Vector,{dataFrom:null,initialize:function(name,options){OpenLayers.Layer.Vector.prototype.initialize.apply(this,arguments);},addNodes:function(pointFeatures){if(pointFeatures.length<2){OpenLayers.Console.error("At least two point features have to be added to create"+"a line from");return;}
60984 var lines=new Array(pointFeatures.length-1);var pointFeature,startPoint,endPoint;for(var i=0,len=pointFeatures.length;i<len;i++){pointFeature=pointFeatures[i];endPoint=pointFeature.geometry;if(!endPoint){var lonlat=pointFeature.lonlat;endPoint=new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat);}else if(endPoint.CLASS_NAME!="OpenLayers.Geometry.Point"){OpenLayers.Console.error("Only features with point geometries are supported.");return;}
60985 if(i>0){var attributes=(this.dataFrom!=null)?(pointFeatures[i+this.dataFrom].data||pointFeatures[i+this.dataFrom].attributes):null;var line=new OpenLayers.Geometry.LineString([startPoint,endPoint]);lines[i-1]=new OpenLayers.Feature.Vector(line,attributes);}
60986 startPoint=endPoint;}
60987 this.addFeatures(lines);},CLASS_NAME:"OpenLayers.Layer.PointTrack"});OpenLayers.Layer.PointTrack.dataFrom={'SOURCE_NODE':-1,'TARGET_NODE':0};OpenLayers.Layer.Vector.RootContainer=OpenLayers.Class(OpenLayers.Layer.Vector,{displayInLayerSwitcher:false,layers:null,initialize:function(name,options){OpenLayers.Layer.Vector.prototype.initialize.apply(this,arguments);},display:function(){},getFeatureFromEvent:function(evt){var layers=this.layers;var feature;for(var i=0;i<layers.length;i++){feature=layers[i].getFeatureFromEvent(evt);if(feature){return feature;}}},setMap:function(map){OpenLayers.Layer.Vector.prototype.setMap.apply(this,arguments);this.collectRoots();map.events.register("changelayer",this,this.handleChangeLayer);},removeMap:function(map){map.events.unregister("changelayer",this,this.handleChangeLayer);this.resetRoots();OpenLayers.Layer.Vector.prototype.removeMap.apply(this,arguments);},collectRoots:function(){var layer;for(var i=0;i<this.map.layers.length;++i){layer=this.map.layers[i];if(OpenLayers.Util.indexOf(this.layers,layer)!=-1){layer.renderer.moveRoot(this.renderer);}}},resetRoots:function(){var layer;for(var i=0;i<this.layers.length;++i){layer=this.layers[i];if(this.renderer&&layer.renderer.getRenderLayerId()==this.id){this.renderer.moveRoot(layer.renderer);}}},handleChangeLayer:function(evt){var layer=evt.layer;if(evt.property=="order"&&OpenLayers.Util.indexOf(this.layers,layer)!=-1){this.resetRoots();this.collectRoots();}},CLASS_NAME:"OpenLayers.Layer.Vector.RootContainer"});OpenLayers.Layer.WFS=OpenLayers.Class(OpenLayers.Layer.Vector,OpenLayers.Layer.Markers,{isBaseLayer:false,tile:null,ratio:2,DEFAULT_PARAMS:{service:"WFS",version:"1.0.0",request:"GetFeature"},featureClass:null,format:null,formatObject:null,formatOptions:null,vectorMode:true,encodeBBOX:false,extractAttributes:false,initialize:function(name,url,params,options){if(options==undefined){options={};}
60988 if(options.featureClass||!OpenLayers.Layer.Vector||!OpenLayers.Feature.Vector){this.vectorMode=false;}
60989 params=OpenLayers.Util.upperCaseObject(params);OpenLayers.Util.extend(options,{'reportError':false});var newArguments=[];newArguments.push(name,options);OpenLayers.Layer.Vector.prototype.initialize.apply(this,newArguments);if(!this.renderer||!this.vectorMode){this.vectorMode=false;if(!options.featureClass){options.featureClass=OpenLayers.Feature.WFS;}
60990 OpenLayers.Layer.Markers.prototype.initialize.apply(this,newArguments);}
60991 if(this.params&&this.params.typename&&!this.options.typename){this.options.typename=this.params.typename;}
60992 if(!this.options.geometry_column){this.options.geometry_column="the_geom";}
60993 this.params=OpenLayers.Util.applyDefaults(params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));this.url=url;},destroy:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.destroy.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);}
60994 if(this.tile){this.tile.destroy();}
60995 this.tile=null;this.ratio=null;this.featureClass=null;this.format=null;if(this.formatObject&&this.formatObject.destroy){this.formatObject.destroy();}
60996 this.formatObject=null;this.formatOptions=null;this.vectorMode=null;this.encodeBBOX=null;this.extractAttributes=null;},setMap:function(map){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.setMap.apply(this,arguments);var options={'extractAttributes':this.extractAttributes};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
60997 this.formatObject=this.format?new this.format(options):new OpenLayers.Format.GML(options);}else{OpenLayers.Layer.Markers.prototype.setMap.apply(this,arguments);}},moveTo:function(bounds,zoomChanged,dragging){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.moveTo.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);}
60998 if(dragging){return false;}
60999 if(zoomChanged){if(this.vectorMode){this.renderer.clear();}}
61000 if(this.options.minZoomLevel){OpenLayers.Console.warn(OpenLayers.i18n('minZoomLevelError'));if(this.map.getZoom()<this.options.minZoomLevel){return null;}}
61001 if(bounds==null){bounds=this.map.getExtent();}
61002 var firstRendering=(this.tile==null);var outOfBounds=(!firstRendering&&!this.tile.bounds.containsBounds(bounds));if(zoomChanged||firstRendering||(!dragging&&outOfBounds)){var center=bounds.getCenterLonLat();var tileWidth=bounds.getWidth()*this.ratio;var tileHeight=bounds.getHeight()*this.ratio;var tileBounds=new OpenLayers.Bounds(center.lon-(tileWidth/2),center.lat-(tileHeight/2),center.lon+(tileWidth/2),center.lat+(tileHeight/2));var tileSize=this.map.getSize();tileSize.w=tileSize.w*this.ratio;tileSize.h=tileSize.h*this.ratio;var ul=new OpenLayers.LonLat(tileBounds.left,tileBounds.top);var pos=this.map.getLayerPxFromLonLat(ul);var url=this.getFullRequestString();var params=null;var filter=this.params.filter||this.params.FILTER;if(filter){params={FILTER:filter};}
61003 else{params={BBOX:this.encodeBBOX?tileBounds.toBBOX():tileBounds.toArray()};}
61004 if(this.map&&!this.projection.equals(this.map.getProjectionObject())){var projectedBounds=tileBounds.clone();projectedBounds.transform(this.map.getProjectionObject(),this.projection);if(!filter){params.BBOX=this.encodeBBOX?projectedBounds.toBBOX():projectedBounds.toArray();}}
61005 url+="&"+OpenLayers.Util.getParameterString(params);if(!this.tile){this.tile=new OpenLayers.Tile.WFS(this,pos,tileBounds,url,tileSize);this.addTileMonitoringHooks(this.tile);this.tile.draw();}else{if(this.vectorMode){this.destroyFeatures();this.renderer.clear();}else{this.clearMarkers();}
61006 this.removeTileMonitoringHooks(this.tile);this.tile.destroy();this.tile=null;this.tile=new OpenLayers.Tile.WFS(this,pos,tileBounds,url,tileSize);this.addTileMonitoringHooks(this.tile);this.tile.draw();}}},addTileMonitoringHooks:function(tile){tile.onLoadStart=function(){if(this==this.layer.tile){this.layer.events.triggerEvent("loadstart");}};tile.events.register("loadstart",tile,tile.onLoadStart);tile.onLoadEnd=function(){if(this==this.layer.tile){this.layer.events.triggerEvent("tileloaded");this.layer.events.triggerEvent("loadend");}};tile.events.register("loadend",tile,tile.onLoadEnd);tile.events.register("unload",tile,tile.onLoadEnd);},removeTileMonitoringHooks:function(tile){tile.unload();tile.events.un({"loadstart":tile.onLoadStart,"loadend":tile.onLoadEnd,"unload":tile.onLoadEnd,scope:tile});},onMapResize:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.onMapResize.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.onMapResize.apply(this,arguments);}},display:function(){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.display.apply(this,arguments);}else{OpenLayers.Layer.Markers.prototype.display.apply(this,arguments);}},mergeNewParams:function(newParams){var upperParams=OpenLayers.Util.upperCaseObject(newParams);var newArguments=[upperParams];return OpenLayers.Layer.HTTPRequest.prototype.mergeNewParams.apply(this,newArguments);},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.WFS(this.name,this.url,this.params,this.getOptions());}
61007 if(this.vectorMode){obj=OpenLayers.Layer.Vector.prototype.clone.apply(this,[obj]);}else{obj=OpenLayers.Layer.Markers.prototype.clone.apply(this,[obj]);}
61008 return obj;},getFullRequestString:function(newParams,altUrl){var projectionCode=this.projection.getCode()||this.map.getProjection();this.params.SRS=(projectionCode=="none")?null:projectionCode;return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,arguments);},commit:function(){if(!this.writer){var options={};if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
61009 this.writer=new OpenLayers.Format.WFS(options,this);}
61010 var data=this.writer.write(this.features);OpenLayers.Request.POST({url:this.url,data:data,success:this.commitSuccess,failure:this.commitFailure,scope:this});},commitSuccess:function(request){var response=request.responseText;if(response.indexOf('SUCCESS')!=-1){this.commitReport(OpenLayers.i18n("commitSuccess",{'response':response}));for(var i=0;i<this.features.length;i++){this.features[i].state=null;}}else if(response.indexOf('FAILED')!=-1||response.indexOf('Exception')!=-1){this.commitReport(OpenLayers.i18n("commitFailed",{'response':response}));}},commitFailure:function(request){},commitReport:function(string,response){OpenLayers.Console.userError(string);},refresh:function(){if(this.tile){if(this.vectorMode){this.renderer.clear();this.features.length=0;}else{this.clearMarkers();this.markers.length=0;}
61011 this.tile.draw();}},getDataExtent:function(){var extent;if(this.vectorMode){extent=OpenLayers.Layer.Vector.prototype.getDataExtent.apply(this);}else{extent=OpenLayers.Layer.Markers.prototype.getDataExtent.apply(this);}
61012 return extent;},setOpacity:function(opacity){if(this.vectorMode){OpenLayers.Layer.Vector.prototype.setOpacity.apply(this,[opacity]);}else{OpenLayers.Layer.Markers.prototype.setOpacity.apply(this,[opacity]);}},CLASS_NAME:"OpenLayers.Layer.WFS"});OpenLayers.Protocol.HTTP=OpenLayers.Class(OpenLayers.Protocol,{url:null,headers:null,params:null,callback:null,scope:null,readWithPOST:false,wildcarded:false,initialize:function(options){options=options||{};this.params={};this.headers={};OpenLayers.Protocol.prototype.initialize.apply(this,arguments);},destroy:function(){this.params=null;this.headers=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){OpenLayers.Protocol.prototype.read.apply(this,arguments);options=OpenLayers.Util.applyDefaults(options,this.options);options.params=OpenLayers.Util.applyDefaults(options.params,this.options.params);if(options.filter){options.params=this.filterToParams(options.filter,options.params);}
61013 var readWithPOST=(options.readWithPOST!==undefined)?options.readWithPOST:this.readWithPOST;var resp=new OpenLayers.Protocol.Response({requestType:"read"});if(readWithPOST){resp.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,resp,options),data:OpenLayers.Util.getParameterString(options.params),headers:{"Content-Type":"application/x-www-form-urlencoded"}});}else{resp.priv=OpenLayers.Request.GET({url:options.url,callback:this.createCallback(this.handleRead,resp,options),params:options.params,headers:options.headers});}
61014 return resp;},handleRead:function(resp,options){this.handleResponse(resp,options);},filterToParams:function(filter,params){params=params||{};var className=filter.CLASS_NAME;var filterType=className.substring(className.lastIndexOf(".")+1);switch(filterType){case"Spatial":switch(filter.type){case OpenLayers.Filter.Spatial.BBOX:params.bbox=filter.value.toArray();break;case OpenLayers.Filter.Spatial.DWITHIN:params.tolerance=filter.distance;case OpenLayers.Filter.Spatial.WITHIN:params.lon=filter.value.x;params.lat=filter.value.y;break;default:OpenLayers.Console.warn("Unknown spatial filter type "+filter.type);}
61015 break;case"Comparison":var op=OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR[filter.type];if(op!==undefined){var value=filter.value;if(filter.type==OpenLayers.Filter.Comparison.LIKE){value=this.regex2value(value);if(this.wildcarded){value="%"+value+"%";}}
61016 params[filter.property+"__"+op]=value;params.queryable=params.queryable||[];params.queryable.push(filter.property);}else{OpenLayers.Console.warn("Unknown comparison filter type "+filter.type);}
61017 break;case"Logical":if(filter.type===OpenLayers.Filter.Logical.AND){for(var i=0,len=filter.filters.length;i<len;i++){params=this.filterToParams(filter.filters[i],params);}}else{OpenLayers.Console.warn("Unsupported logical filter type "+filter.type);}
61018 break;default:OpenLayers.Console.warn("Unknown filter type "+filterType);}
61019 return params;},regex2value:function(value){value=value.replace(/%/g,"\\%");value=value.replace(/\\\\\.(\*)?/g,function($0,$1){return $1?$0:"\\\\_";});value=value.replace(/\\\\\.\*/g,"\\\\%");value=value.replace(/(\\)?\.(\*)?/g,function($0,$1,$2){return $1||$2?$0:"_";});value=value.replace(/(\\)?\.\*/g,function($0,$1){return $1?$0:"%";});value=value.replace(/\\\./g,".");value=value.replace(/(\\)?\\\*/g,function($0,$1){return $1?$0:"*";});return value;},create:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:features,requestType:"create"});resp.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleCreate,resp,options),headers:options.headers,data:this.format.write(features)});return resp;},handleCreate:function(resp,options){this.handleResponse(resp,options);},update:function(feature,options){options=options||{};var url=options.url||feature.url||this.options.url+"/"+feature.fid;options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:feature,requestType:"update"});resp.priv=OpenLayers.Request.PUT({url:url,callback:this.createCallback(this.handleUpdate,resp,options),headers:options.headers,data:this.format.write(feature)});return resp;},handleUpdate:function(resp,options){this.handleResponse(resp,options);},"delete":function(feature,options){options=options||{};var url=options.url||feature.url||this.options.url+"/"+feature.fid;options=OpenLayers.Util.applyDefaults(options,this.options);var resp=new OpenLayers.Protocol.Response({reqFeatures:feature,requestType:"delete"});resp.priv=OpenLayers.Request.DELETE({url:url,callback:this.createCallback(this.handleDelete,resp,options),headers:options.headers});return resp;},handleDelete:function(resp,options){this.handleResponse(resp,options);},handleResponse:function(resp,options){var request=resp.priv;if(options.callback){if(request.status>=200&&request.status<300){if(resp.requestType!="delete"){resp.features=this.parseFeatures(request);}
61020 resp.code=OpenLayers.Protocol.Response.SUCCESS;}else{resp.code=OpenLayers.Protocol.Response.FAILURE;}
61021 options.callback.call(options.scope,resp);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
61022 if(!doc||doc.length<=0){return null;}
61023 return this.format.read(doc);},commit:function(features,options){options=OpenLayers.Util.applyDefaults(options,this.options);var resp=[],nResponses=0;var types={};types[OpenLayers.State.INSERT]=[];types[OpenLayers.State.UPDATE]=[];types[OpenLayers.State.DELETE]=[];var feature,list,requestFeatures=[];for(var i=0,len=features.length;i<len;++i){feature=features[i];list=types[feature.state];if(list){list.push(feature);requestFeatures.push(feature);}}
61024 var nRequests=(types[OpenLayers.State.INSERT].length>0?1:0)+
61025 types[OpenLayers.State.UPDATE].length+
61026 types[OpenLayers.State.DELETE].length;var success=true;var finalResponse=new OpenLayers.Protocol.Response({reqFeatures:requestFeatures});function insertCallback(response){var len=response.features?response.features.length:0;var fids=new Array(len);for(var i=0;i<len;++i){fids[i]=response.features[i].fid;}
61027 finalResponse.insertIds=fids;callback.apply(this,[response]);}
61028 function callback(response){this.callUserCallback(response,options);success=success&&response.success();nResponses++;if(nResponses>=nRequests){if(options.callback){finalResponse.code=success?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE;options.callback.apply(options.scope,[finalResponse]);}}}
61029 var queue=types[OpenLayers.State.INSERT];if(queue.length>0){resp.push(this.create(queue,OpenLayers.Util.applyDefaults({callback:insertCallback,scope:this},options.create)));}
61030 queue=types[OpenLayers.State.UPDATE];for(var i=queue.length-1;i>=0;--i){resp.push(this.update(queue[i],OpenLayers.Util.applyDefaults({callback:callback,scope:this},options.update)));}
61031 queue=types[OpenLayers.State.DELETE];for(var i=queue.length-1;i>=0;--i){resp.push(this["delete"](queue[i],OpenLayers.Util.applyDefaults({callback:callback,scope:this},options["delete"])));}
61032 return resp;},abort:function(response){if(response){response.priv.abort();}},callUserCallback:function(resp,options){var opt=options[resp.requestType];if(opt&&opt.callback){opt.callback.call(opt.scope,resp);}},CLASS_NAME:"OpenLayers.Protocol.HTTP"});(function(){var o=OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR={};o[OpenLayers.Filter.Comparison.EQUAL_TO]="eq";o[OpenLayers.Filter.Comparison.NOT_EQUAL_TO]="ne";o[OpenLayers.Filter.Comparison.LESS_THAN]="lt";o[OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO]="lte";o[OpenLayers.Filter.Comparison.GREATER_THAN]="gt";o[OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO]="gte";o[OpenLayers.Filter.Comparison.LIKE]="ilike";})();OpenLayers.Strategy.BBOX=OpenLayers.Class(OpenLayers.Strategy,{bounds:null,resolution:null,ratio:2,resFactor:null,response:null,initialize:function(options){OpenLayers.Strategy.prototype.initialize.apply(this,[options]);},activate:function(){var activated=OpenLayers.Strategy.prototype.activate.call(this);if(activated){this.layer.events.on({"moveend":this.update,scope:this});this.layer.events.on({"refresh":this.update,scope:this});}
61033 return activated;},deactivate:function(){var deactivated=OpenLayers.Strategy.prototype.deactivate.call(this);if(deactivated){this.layer.events.un({"moveend":this.update,scope:this});this.layer.events.un({"refresh":this.update,scope:this});}
61034 return deactivated;},update:function(options){var mapBounds=this.getMapBounds();if((options&&options.force)||this.invalidBounds(mapBounds)){this.calculateBounds(mapBounds);this.resolution=this.layer.map.getResolution();this.triggerRead();}},getMapBounds:function(){var bounds=this.layer.map.getExtent();if(!this.layer.projection.equals(this.layer.map.getProjectionObject())){bounds=bounds.clone().transform(this.layer.map.getProjectionObject(),this.layer.projection);}
61035 return bounds;},invalidBounds:function(mapBounds){if(!mapBounds){mapBounds=this.getMapBounds();}
61036 var invalid=!this.bounds||!this.bounds.containsBounds(mapBounds);if(!invalid&&this.resFactor){var ratio=this.resolution/this.layer.map.getResolution();invalid=(ratio>=this.resFactor||ratio<=(1/this.resFactor));}
61037 return invalid;},calculateBounds:function(mapBounds){if(!mapBounds){mapBounds=this.getMapBounds();}
61038 var center=mapBounds.getCenterLonLat();var dataWidth=mapBounds.getWidth()*this.ratio;var dataHeight=mapBounds.getHeight()*this.ratio;this.bounds=new OpenLayers.Bounds(center.lon-(dataWidth/2),center.lat-(dataHeight/2),center.lon+(dataWidth/2),center.lat+(dataHeight/2));},triggerRead:function(){if(this.response){this.layer.protocol.abort(this.response);this.layer.events.triggerEvent("loadend");}
61039 this.layer.events.triggerEvent("loadstart");this.response=this.layer.protocol.read({filter:this.createFilter(),callback:this.merge,scope:this});},createFilter:function(){var filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,value:this.bounds,projection:this.layer.projection});if(this.layer.filter){filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,filters:[this.layer.filter,filter]});}
61040 return filter;},merge:function(resp){this.layer.destroyFeatures();var features=resp.features;if(features&&features.length>0){var remote=this.layer.projection;var local=this.layer.map.getProjectionObject();if(!local.equals(remote)){var geom;for(var i=0,len=features.length;i<len;++i){geom=features[i].geometry;if(geom){geom.transform(remote,local);}}}
61041 this.layer.addFeatures(features);}
61042 this.response=null;this.layer.events.triggerEvent("loadend");},CLASS_NAME:"OpenLayers.Strategy.BBOX"});OpenLayers.Control.SelectFeature=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforefeaturehighlighted","featurehighlighted","featureunhighlighted"],multipleKey:null,toggleKey:null,multiple:false,clickout:true,toggle:false,hover:false,highlightOnly:false,box:false,onBeforeSelect:function(){},onSelect:function(){},onUnselect:function(){},scope:null,geometryTypes:null,layer:null,layers:null,callbacks:null,selectStyle:null,renderIntent:"select",handlers:null,initialize:function(layers,options){this.EVENT_TYPES=OpenLayers.Control.SelectFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);if(this.scope===null){this.scope=this;}
61043 this.initLayer(layers);var callbacks={click:this.clickFeature,clickout:this.clickoutFeature};if(this.hover){callbacks.over=this.overFeature;callbacks.out=this.outFeature;}
61044 this.callbacks=OpenLayers.Util.extend(callbacks,this.callbacks);this.handlers={feature:new OpenLayers.Handler.Feature(this,this.layer,this.callbacks,{geometryTypes:this.geometryTypes})};if(this.box){this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},{boxDivClassName:"olHandlerBoxSelectFeature"});}},initLayer:function(layers){if(layers instanceof Array){this.layers=layers;this.layer=new OpenLayers.Layer.Vector.RootContainer(this.id+"_container",{layers:layers});}else{this.layer=layers;}},destroy:function(){if(this.active&&this.layers){this.map.removeLayer(this.layer);}
61045 OpenLayers.Control.prototype.destroy.apply(this,arguments);if(this.layers){this.layer.destroy();}},activate:function(){if(!this.active){if(this.layers){this.map.addLayer(this.layer);}
61046 this.handlers.feature.activate();if(this.box&&this.handlers.box){this.handlers.box.activate();}}
61047 return OpenLayers.Control.prototype.activate.apply(this,arguments);},deactivate:function(){if(this.active){this.handlers.feature.deactivate();if(this.handlers.box){this.handlers.box.deactivate();}
61048 if(this.layers){this.map.removeLayer(this.layer);}}
61049 return OpenLayers.Control.prototype.deactivate.apply(this,arguments);},unselectAll:function(options){var layers=this.layers||[this.layer];var layer,feature;for(var l=0;l<layers.length;++l){layer=layers[l];for(var i=layer.selectedFeatures.length-1;i>=0;--i){feature=layer.selectedFeatures[i];if(!options||options.except!=feature){this.unselect(feature);}}}},clickFeature:function(feature){if(!this.hover){var selected=(OpenLayers.Util.indexOf(feature.layer.selectedFeatures,feature)>-1);if(selected){if(this.toggleSelect()){this.unselect(feature);}else if(!this.multipleSelect()){this.unselectAll({except:feature});}}else{if(!this.multipleSelect()){this.unselectAll({except:feature});}
61050 this.select(feature);}}},multipleSelect:function(){return this.multiple||(this.handlers.feature.evt&&this.handlers.feature.evt[this.multipleKey]);},toggleSelect:function(){return this.toggle||(this.handlers.feature.evt&&this.handlers.feature.evt[this.toggleKey]);},clickoutFeature:function(feature){if(!this.hover&&this.clickout){this.unselectAll();}},overFeature:function(feature){var layer=feature.layer;if(this.hover){if(this.highlightOnly){this.highlight(feature);}else if(OpenLayers.Util.indexOf(layer.selectedFeatures,feature)==-1){this.select(feature);}}},outFeature:function(feature){if(this.hover){if(this.highlightOnly){if(feature._lastHighlighter==this.id){if(feature._prevHighlighter&&feature._prevHighlighter!=this.id){delete feature._lastHighlighter;var control=this.map.getControl(feature._prevHighlighter);if(control){control.highlight(feature);}}else{this.unhighlight(feature);}}}else{this.unselect(feature);}}},highlight:function(feature){var layer=feature.layer;var cont=this.events.triggerEvent("beforefeaturehighlighted",{feature:feature});if(cont!==false){feature._prevHighlighter=feature._lastHighlighter;feature._lastHighlighter=this.id;var style=this.selectStyle||this.renderIntent;layer.drawFeature(feature,style);this.events.triggerEvent("featurehighlighted",{feature:feature});}},unhighlight:function(feature){var layer=feature.layer;feature._lastHighlighter=feature._prevHighlighter;delete feature._prevHighlighter;layer.drawFeature(feature,feature.style||feature.layer.style||"default");this.events.triggerEvent("featureunhighlighted",{feature:feature});},select:function(feature){var cont=this.onBeforeSelect.call(this.scope,feature);var layer=feature.layer;if(cont!==false){cont=layer.events.triggerEvent("beforefeatureselected",{feature:feature});if(cont!==false){layer.selectedFeatures.push(feature);this.highlight(feature);if(!this.handlers.feature.lastFeature){this.handlers.feature.lastFeature=layer.selectedFeatures[0];}
61051 layer.events.triggerEvent("featureselected",{feature:feature});this.onSelect.call(this.scope,feature);}}},unselect:function(feature){var layer=feature.layer;this.unhighlight(feature);OpenLayers.Util.removeItem(layer.selectedFeatures,feature);layer.events.triggerEvent("featureunselected",{feature:feature});this.onUnselect.call(this.scope,feature);},selectBox:function(position){if(position instanceof OpenLayers.Bounds){var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));var bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);if(!this.multipleSelect()){this.unselectAll();}
61052 var prevMultiple=this.multiple;this.multiple=true;var layers=this.layers||[this.layer];var layer;for(var l=0;l<layers.length;++l){layer=layers[l];for(var i=0,len=layer.features.length;i<len;++i){var feature=layer.features[i];if(!feature.getVisibility()){continue;}
61053 if(this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)>-1){if(bounds.toGeometry().intersects(feature.geometry)){if(OpenLayers.Util.indexOf(layer.selectedFeatures,feature)==-1){this.select(feature);}}}}}
61054 this.multiple=prevMultiple;}},setMap:function(map){this.handlers.feature.setMap(map);if(this.box){this.handlers.box.setMap(map);}
61055 OpenLayers.Control.prototype.setMap.apply(this,arguments);},setLayer:function(layers){var isActive=this.active;this.unselectAll();this.deactivate();if(this.layers){this.layer.destroy();this.layers=null;}
61056 this.initLayer(layers);this.handlers.feature.layer=this.layer;if(isActive){this.activate();}},CLASS_NAME:"OpenLayers.Control.SelectFeature"});OpenLayers.Format.Filter.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ogc:"http://www.opengis.net/ogc",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"ogc",schemaLocation:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){var obj={};this.readers.ogc["Filter"].apply(this,[data,obj]);return obj.filter;},readers:{"ogc":{"Filter":function(node,parent){var obj={fids:[],filters:[]};this.readChildNodes(node,obj);if(obj.fids.length>0){parent.filter=new OpenLayers.Filter.FeatureId({fids:obj.fids});}else if(obj.filters.length>0){parent.filter=obj.filters[0];}},"FeatureId":function(node,obj){var fid=node.getAttribute("fid");if(fid){obj.fids.push(fid);}},"And":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND});this.readChildNodes(node,filter);obj.filters.push(filter);},"Or":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.OR});this.readChildNodes(node,filter);obj.filters.push(filter);},"Not":function(node,obj){var filter=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.NOT});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLessThan":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LESS_THAN});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsGreaterThan":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.GREATER_THAN});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLessThanOrEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsGreaterThanOrEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsBetween":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.BETWEEN});this.readChildNodes(node,filter);obj.filters.push(filter);},"Literal":function(node,obj){obj.value=OpenLayers.String.numericIf(this.getChildValue(node));},"PropertyName":function(node,filter){filter.property=this.getChildValue(node);},"LowerBoundary":function(node,filter){filter.lowerBoundary=OpenLayers.String.numericIf(this.readOgcExpression(node));},"UpperBoundary":function(node,filter){filter.upperBoundary=OpenLayers.String.numericIf(this.readOgcExpression(node));},"Intersects":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.INTERSECTS);},"Within":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.WITHIN);},"Contains":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.CONTAINS);},"DWithin":function(node,obj){this.readSpatial(node,obj,OpenLayers.Filter.Spatial.DWITHIN);},"Distance":function(node,obj){obj.distance=parseInt(this.getChildValue(node));obj.distanceUnits=node.getAttribute("units");}}},readSpatial:function(node,obj,type){var filter=new OpenLayers.Filter.Spatial({type:type});this.readChildNodes(node,filter);filter.value=filter.components[0];delete filter.components;obj.filters.push(filter);},readOgcExpression:function(node){var obj={};this.readChildNodes(node,obj);var value=obj.value;if(value===undefined){value=this.getChildValue(node);}
61057 return value;},write:function(filter){return this.writers.ogc["Filter"].apply(this,[filter]);},writers:{"ogc":{"Filter":function(filter){var node=this.createElementNSPlus("ogc:Filter");var sub=filter.CLASS_NAME.split(".").pop();if(sub=="FeatureId"){for(var i=0;i<filter.fids.length;++i){this.writeNode("FeatureId",filter.fids[i],node);}}else{this.writeNode(this.getFilterType(filter),filter,node);}
61058 return node;},"FeatureId":function(fid){return this.createElementNSPlus("ogc:FeatureId",{attributes:{fid:fid}});},"And":function(filter){var node=this.createElementNSPlus("ogc:And");var childFilter;for(var i=0;i<filter.filters.length;++i){childFilter=filter.filters[i];this.writeNode(this.getFilterType(childFilter),childFilter,node);}
61059 return node;},"Or":function(filter){var node=this.createElementNSPlus("ogc:Or");var childFilter;for(var i=0;i<filter.filters.length;++i){childFilter=filter.filters[i];this.writeNode(this.getFilterType(childFilter),childFilter,node);}
61060 return node;},"Not":function(filter){var node=this.createElementNSPlus("ogc:Not");var childFilter=filter.filters[0];this.writeNode(this.getFilterType(childFilter),childFilter,node);return node;},"PropertyIsLessThan":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLessThan");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsGreaterThan":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsGreaterThan");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLessThanOrEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLessThanOrEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsGreaterThanOrEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsGreaterThanOrEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsBetween":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsBetween");this.writeNode("PropertyName",filter,node);this.writeNode("LowerBoundary",filter,node);this.writeNode("UpperBoundary",filter,node);return node;},"PropertyName":function(filter){return this.createElementNSPlus("ogc:PropertyName",{value:filter.property});},"Literal":function(value){return this.createElementNSPlus("ogc:Literal",{value:value});},"LowerBoundary":function(filter){var node=this.createElementNSPlus("ogc:LowerBoundary");this.writeNode("Literal",filter.lowerBoundary,node);return node;},"UpperBoundary":function(filter){var node=this.createElementNSPlus("ogc:UpperBoundary");this.writeNode("Literal",filter.upperBoundary,node);return node;},"INTERSECTS":function(filter){return this.writeSpatial(filter,"Intersects");},"WITHIN":function(filter){return this.writeSpatial(filter,"Within");},"CONTAINS":function(filter){return this.writeSpatial(filter,"Contains");},"DWITHIN":function(filter){var node=this.writeSpatial(filter,"DWithin");this.writeNode("Distance",filter,node);return node;},"Distance":function(filter){return this.createElementNSPlus("ogc:Distance",{attributes:{units:filter.distanceUnits},value:filter.distance});}}},getFilterType:function(filter){var filterType=this.filterMap[filter.type];if(!filterType){throw"Filter writing not supported for rule type: "+filter.type;}
61061 return filterType;},filterMap:{"&&":"And","||":"Or","!":"Not","==":"PropertyIsEqualTo","!=":"PropertyIsNotEqualTo","<":"PropertyIsLessThan",">":"PropertyIsGreaterThan","<=":"PropertyIsLessThanOrEqualTo",">=":"PropertyIsGreaterThanOrEqualTo","..":"PropertyIsBetween","~":"PropertyIsLike","BBOX":"BBOX","DWITHIN":"DWITHIN","WITHIN":"WITHIN","CONTAINS":"CONTAINS","INTERSECTS":"INTERSECTS"},CLASS_NAME:"OpenLayers.Format.Filter.v1"});OpenLayers.Geometry.Curve=OpenLayers.Class(OpenLayers.Geometry.MultiPoint,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(points){OpenLayers.Geometry.MultiPoint.prototype.initialize.apply(this,arguments);},getLength:function(){var length=0.0;if(this.components&&(this.components.length>1)){for(var i=1,len=this.components.length;i<len;i++){length+=this.components[i-1].distanceTo(this.components[i]);}}
61062 return length;},getGeodesicLength:function(projection){var geom=this;if(projection){var gg=new OpenLayers.Projection("EPSG:4326");if(!gg.equals(projection)){geom=this.clone().transform(projection,gg);}}
61063 var length=0.0;if(geom.components&&(geom.components.length>1)){var p1,p2;for(var i=1,len=geom.components.length;i<len;i++){p1=geom.components[i-1];p2=geom.components[i];length+=OpenLayers.Util.distVincenty({lon:p1.x,lat:p1.y},{lon:p2.x,lat:p2.y});}}
61064 return length*1000;},CLASS_NAME:"OpenLayers.Geometry.Curve"});OpenLayers.Layer.Text=OpenLayers.Class(OpenLayers.Layer.Markers,{location:null,features:null,formatOptions:null,selectedFeature:null,initialize:function(name,options){OpenLayers.Layer.Markers.prototype.initialize.apply(this,arguments);this.features=new Array();},destroy:function(){OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);this.clearFeatures();this.features=null;},loadText:function(){if(!this.loaded){if(this.location!=null){var onFail=function(e){this.events.triggerEvent("loadend");};this.events.triggerEvent("loadstart");OpenLayers.Request.GET({url:this.location,success:this.parseData,failure:onFail,scope:this});this.loaded=true;}}},moveTo:function(bounds,zoomChanged,minor){OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);if(this.visibility&&!this.loaded){this.loadText();}},parseData:function(ajaxRequest){var text=ajaxRequest.responseText;var options={};OpenLayers.Util.extend(options,this.formatOptions);if(this.map&&!this.projection.equals(this.map.getProjectionObject())){options.externalProjection=this.projection;options.internalProjection=this.map.getProjectionObject();}
61065 var parser=new OpenLayers.Format.Text(options);var features=parser.read(text);for(var i=0,len=features.length;i<len;i++){var data={};var feature=features[i];var location;var iconSize,iconOffset;location=new OpenLayers.LonLat(feature.geometry.x,feature.geometry.y);if(feature.style.graphicWidth&&feature.style.graphicHeight){iconSize=new OpenLayers.Size(feature.style.graphicWidth,feature.style.graphicHeight);}
61066 if(feature.style.graphicXOffset!==undefined&&feature.style.graphicYOffset!==undefined){iconOffset=new OpenLayers.Pixel(feature.style.graphicXOffset,feature.style.graphicYOffset);}
61067 if(feature.style.externalGraphic!=null){data.icon=new OpenLayers.Icon(feature.style.externalGraphic,iconSize,iconOffset);}else{data.icon=OpenLayers.Marker.defaultIcon();if(iconSize!=null){data.icon.setSize(iconSize);}}
61068 if((feature.attributes.title!=null)&&(feature.attributes.description!=null)){data['popupContentHTML']='<h2>'+feature.attributes.title+'</h2>'+'<p>'+feature.attributes.description+'</p>';}
61069 data['overflow']=feature.attributes.overflow||"auto";var markerFeature=new OpenLayers.Feature(this,location,data);this.features.push(markerFeature);var marker=markerFeature.createMarker();if((feature.attributes.title!=null)&&(feature.attributes.description!=null)){marker.events.register('click',markerFeature,this.markerClick);}
61070 this.addMarker(marker);}
61071 this.events.triggerEvent("loadend");},markerClick:function(evt){var sameMarkerClicked=(this==this.layer.selectedFeature);this.layer.selectedFeature=(!sameMarkerClicked)?this:null;for(var i=0,len=this.layer.map.popups.length;i<len;i++){this.layer.map.removePopup(this.layer.map.popups[i]);}
61072 if(!sameMarkerClicked){this.layer.map.addPopup(this.createPopup());}
61073 OpenLayers.Event.stop(evt);},clearFeatures:function(){if(this.features!=null){while(this.features.length>0){var feature=this.features[0];OpenLayers.Util.removeItem(this.features,feature);feature.destroy();}}},CLASS_NAME:"OpenLayers.Layer.Text"});OpenLayers.Control.ModifyFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,clickout:true,toggle:true,standalone:false,layer:null,feature:null,vertices:null,virtualVertices:null,selectControl:null,dragControl:null,handlers:null,deleteCodes:null,virtualStyle:null,mode:null,modified:false,radiusHandle:null,dragHandle:null,onModificationStart:function(){},onModification:function(){},onModificationEnd:function(){},initialize:function(layer,options){this.layer=layer;this.vertices=[];this.virtualVertices=[];this.virtualStyle=OpenLayers.Util.extend({},this.layer.style||this.layer.styleMap.createSymbolizer());this.virtualStyle.fillOpacity=0.3;this.virtualStyle.strokeOpacity=0.3;this.deleteCodes=[46,68];this.mode=OpenLayers.Control.ModifyFeature.RESHAPE;OpenLayers.Control.prototype.initialize.apply(this,[options]);if(!(this.deleteCodes instanceof Array)){this.deleteCodes=[this.deleteCodes];}
61074 var control=this;var selectOptions={geometryTypes:this.geometryTypes,clickout:this.clickout,toggle:this.toggle,onBeforeSelect:this.beforeSelectFeature,onSelect:this.selectFeature,onUnselect:this.unselectFeature,scope:this};if(this.standalone===false){this.selectControl=new OpenLayers.Control.SelectFeature(layer,selectOptions);}
61075 var dragOptions={geometryTypes:["OpenLayers.Geometry.Point"],snappingOptions:this.snappingOptions,onStart:function(feature,pixel){control.dragStart.apply(control,[feature,pixel]);},onDrag:function(feature,pixel){control.dragVertex.apply(control,[feature,pixel]);},onComplete:function(feature){control.dragComplete.apply(control,[feature]);},featureCallbacks:{over:function(feature){if(control.standalone!==true||feature._sketch||control.feature===feature){control.dragControl.overFeature.apply(control.dragControl,[feature]);}}}};this.dragControl=new OpenLayers.Control.DragFeature(layer,dragOptions);var keyboardOptions={keydown:this.handleKeypress};this.handlers={keyboard:new OpenLayers.Handler.Keyboard(this,keyboardOptions)};},destroy:function(){this.layer=null;this.standalone||this.selectControl.destroy();this.dragControl.destroy();OpenLayers.Control.prototype.destroy.apply(this,[]);},activate:function(){return((this.standalone||this.selectControl.activate())&&this.handlers.keyboard.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments));},deactivate:function(){var deactivated=false;if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.layer.removeFeatures(this.vertices,{silent:true});this.layer.removeFeatures(this.virtualVertices,{silent:true});this.vertices=[];this.dragControl.deactivate();var feature=this.feature;var valid=feature&&feature.geometry&&feature.layer;if(this.standalone===false){if(valid){this.selectControl.unselect.apply(this.selectControl,[feature]);}
61076 this.selectControl.deactivate();}else{if(valid){this.unselectFeature(feature);}}
61077 this.handlers.keyboard.deactivate();deactivated=true;}
61078 return deactivated;},beforeSelectFeature:function(feature){return this.layer.events.triggerEvent("beforefeaturemodified",{feature:feature});},selectFeature:function(feature){this.feature=feature;this.modified=false;this.resetVertices();this.dragControl.activate();this.onModificationStart(this.feature);},unselectFeature:function(feature){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];this.layer.destroyFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];if(this.dragHandle){this.layer.destroyFeatures([this.dragHandle],{silent:true});delete this.dragHandle;}
61079 if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});delete this.radiusHandle;}
61080 this.feature=null;this.dragControl.deactivate();this.onModificationEnd(feature);this.layer.events.triggerEvent("afterfeaturemodified",{feature:feature,modified:this.modified});this.modified=false;},dragStart:function(feature,pixel){if(feature!=this.feature&&!feature.geometry.parent&&feature!=this.dragHandle&&feature!=this.radiusHandle){if(this.standalone===false&&this.feature){this.selectControl.clickFeature.apply(this.selectControl,[this.feature]);}
61081 if(this.geometryTypes==null||OpenLayers.Util.indexOf(this.geometryTypes,feature.geometry.CLASS_NAME)!=-1){this.standalone||this.selectControl.clickFeature.apply(this.selectControl,[feature]);this.dragControl.overFeature.apply(this.dragControl,[feature]);this.dragControl.lastPixel=pixel;this.dragControl.handlers.drag.started=true;this.dragControl.handlers.drag.start=pixel;this.dragControl.handlers.drag.last=pixel;}}},dragVertex:function(vertex,pixel){this.modified=true;if(this.feature.geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){if(this.feature!=vertex){this.feature=vertex;}
61082 this.layer.events.triggerEvent("vertexmodified",{vertex:vertex.geometry,feature:this.feature,pixel:pixel});}else{if(vertex._index){vertex.geometry.parent.addComponent(vertex.geometry,vertex._index);delete vertex._index;OpenLayers.Util.removeItem(this.virtualVertices,vertex);this.vertices.push(vertex);}else if(vertex==this.dragHandle){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});this.radiusHandle=null;}}else if(vertex!==this.radiusHandle){this.layer.events.triggerEvent("vertexmodified",{vertex:vertex.geometry,feature:this.feature,pixel:pixel});}
61083 if(this.virtualVertices.length>0){this.layer.destroyFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];}
61084 this.layer.drawFeature(this.feature,this.standalone?undefined:this.selectControl.renderIntent);}
61085 this.layer.drawFeature(vertex);},dragComplete:function(vertex){this.resetVertices();this.setFeatureState();this.onModification(this.feature);this.layer.events.triggerEvent("featuremodified",{feature:this.feature});},setFeatureState:function(){if(this.feature.state!=OpenLayers.State.INSERT&&this.feature.state!=OpenLayers.State.DELETE){this.feature.state=OpenLayers.State.UPDATE;}},resetVertices:function(){if(this.dragControl.feature){this.dragControl.outFeature(this.dragControl.feature);}
61086 if(this.vertices.length>0){this.layer.removeFeatures(this.vertices,{silent:true});this.vertices=[];}
61087 if(this.virtualVertices.length>0){this.layer.removeFeatures(this.virtualVertices,{silent:true});this.virtualVertices=[];}
61088 if(this.dragHandle){this.layer.destroyFeatures([this.dragHandle],{silent:true});this.dragHandle=null;}
61089 if(this.radiusHandle){this.layer.destroyFeatures([this.radiusHandle],{silent:true});this.radiusHandle=null;}
61090 if(this.feature&&this.feature.geometry.CLASS_NAME!="OpenLayers.Geometry.Point"){if((this.mode&OpenLayers.Control.ModifyFeature.DRAG)){this.collectDragHandle();}
61091 if((this.mode&(OpenLayers.Control.ModifyFeature.ROTATE|OpenLayers.Control.ModifyFeature.RESIZE))){this.collectRadiusHandle();}
61092 if(this.mode&OpenLayers.Control.ModifyFeature.RESHAPE){if(!(this.mode&OpenLayers.Control.ModifyFeature.RESIZE)){this.collectVertices();}}}},handleKeypress:function(evt){var code=evt.keyCode;if(this.feature&&OpenLayers.Util.indexOf(this.deleteCodes,code)!=-1){var vertex=this.dragControl.feature;if(vertex&&OpenLayers.Util.indexOf(this.vertices,vertex)!=-1&&!this.dragControl.handlers.drag.dragging&&vertex.geometry.parent){vertex.geometry.parent.removeComponent(vertex.geometry);this.layer.drawFeature(this.feature,this.standalone?undefined:this.selectControl.renderIntent);this.resetVertices();this.setFeatureState();this.onModification(this.feature);this.layer.events.triggerEvent("featuremodified",{feature:this.feature});}}},collectVertices:function(){this.vertices=[];this.virtualVertices=[];var control=this;function collectComponentVertices(geometry){var i,vertex,component,len;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){vertex=new OpenLayers.Feature.Vector(geometry);vertex._sketch=true;control.vertices.push(vertex);}else{var numVert=geometry.components.length;if(geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){numVert-=1;}
61093 for(i=0;i<numVert;++i){component=geometry.components[i];if(component.CLASS_NAME=="OpenLayers.Geometry.Point"){vertex=new OpenLayers.Feature.Vector(component);vertex._sketch=true;control.vertices.push(vertex);}else{collectComponentVertices(component);}}
61094 if(geometry.CLASS_NAME!="OpenLayers.Geometry.MultiPoint"){for(i=0,len=geometry.components.length;i<len-1;++i){var prevVertex=geometry.components[i];var nextVertex=geometry.components[i+1];if(prevVertex.CLASS_NAME=="OpenLayers.Geometry.Point"&&nextVertex.CLASS_NAME=="OpenLayers.Geometry.Point"){var x=(prevVertex.x+nextVertex.x)/2;var y=(prevVertex.y+nextVertex.y)/2;var point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(x,y),null,control.virtualStyle);point.geometry.parent=geometry;point._index=i+1;point._sketch=true;control.virtualVertices.push(point);}}}}}
61095 collectComponentVertices.call(this,this.feature.geometry);this.layer.addFeatures(this.virtualVertices,{silent:true});this.layer.addFeatures(this.vertices,{silent:true});},collectDragHandle:function(){var geometry=this.feature.geometry;var center=geometry.getBounds().getCenterLonLat();var originGeometry=new OpenLayers.Geometry.Point(center.lon,center.lat);var origin=new OpenLayers.Feature.Vector(originGeometry);originGeometry.move=function(x,y){OpenLayers.Geometry.Point.prototype.move.call(this,x,y);geometry.move(x,y);};origin._sketch=true;this.dragHandle=origin;this.layer.addFeatures([this.dragHandle],{silent:true});},collectRadiusHandle:function(){var geometry=this.feature.geometry;var bounds=geometry.getBounds();var center=bounds.getCenterLonLat();var originGeometry=new OpenLayers.Geometry.Point(center.lon,center.lat);var radiusGeometry=new OpenLayers.Geometry.Point(bounds.right,bounds.bottom);var radius=new OpenLayers.Feature.Vector(radiusGeometry);var resize=(this.mode&OpenLayers.Control.ModifyFeature.RESIZE);var reshape=(this.mode&OpenLayers.Control.ModifyFeature.RESHAPE);var rotate=(this.mode&OpenLayers.Control.ModifyFeature.ROTATE);radiusGeometry.move=function(x,y){OpenLayers.Geometry.Point.prototype.move.call(this,x,y);var dx1=this.x-originGeometry.x;var dy1=this.y-originGeometry.y;var dx0=dx1-x;var dy0=dy1-y;if(rotate){var a0=Math.atan2(dy0,dx0);var a1=Math.atan2(dy1,dx1);var angle=a1-a0;angle*=180/Math.PI;geometry.rotate(angle,originGeometry);}
61096 if(resize){var scale,ratio;if(reshape){scale=dy1/dy0;ratio=(dx1/dx0)/scale;}else{var l0=Math.sqrt((dx0*dx0)+(dy0*dy0));var l1=Math.sqrt((dx1*dx1)+(dy1*dy1));scale=l1/l0;}
61097 geometry.resize(scale,originGeometry,ratio);}};radius._sketch=true;this.radiusHandle=radius;this.layer.addFeatures([this.radiusHandle],{silent:true});},setMap:function(map){this.standalone||this.selectControl.setMap(map);this.dragControl.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.ModifyFeature"});OpenLayers.Control.ModifyFeature.RESHAPE=1;OpenLayers.Control.ModifyFeature.RESIZE=2;OpenLayers.Control.ModifyFeature.ROTATE=4;OpenLayers.Control.ModifyFeature.DRAG=8;OpenLayers.Geometry.LineString=OpenLayers.Class(OpenLayers.Geometry.Curve,{initialize:function(points){OpenLayers.Geometry.Curve.prototype.initialize.apply(this,arguments);},removeComponent:function(point){if(this.components&&(this.components.length>2)){OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,arguments);}},intersects:function(geometry){var intersect=false;var type=geometry.CLASS_NAME;if(type=="OpenLayers.Geometry.LineString"||type=="OpenLayers.Geometry.LinearRing"||type=="OpenLayers.Geometry.Point"){var segs1=this.getSortedSegments();var segs2;if(type=="OpenLayers.Geometry.Point"){segs2=[{x1:geometry.x,y1:geometry.y,x2:geometry.x,y2:geometry.y}];}else{segs2=geometry.getSortedSegments();}
61098 var seg1,seg1x1,seg1x2,seg1y1,seg1y2,seg2,seg2y1,seg2y2;outer:for(var i=0,len=segs1.length;i<len;++i){seg1=segs1[i];seg1x1=seg1.x1;seg1x2=seg1.x2;seg1y1=seg1.y1;seg1y2=seg1.y2;inner:for(var j=0,jlen=segs2.length;j<jlen;++j){seg2=segs2[j];if(seg2.x1>seg1x2){break;}
61099 if(seg2.x2<seg1x1){continue;}
61100 seg2y1=seg2.y1;seg2y2=seg2.y2;if(Math.min(seg2y1,seg2y2)>Math.max(seg1y1,seg1y2)){continue;}
61101 if(Math.max(seg2y1,seg2y2)<Math.min(seg1y1,seg1y2)){continue;}
61102 if(OpenLayers.Geometry.segmentsIntersect(seg1,seg2)){intersect=true;break outer;}}}}else{intersect=geometry.intersects(this);}
61103 return intersect;},getSortedSegments:function(){var numSeg=this.components.length-1;var segments=new Array(numSeg),point1,point2;for(var i=0;i<numSeg;++i){point1=this.components[i];point2=this.components[i+1];if(point1.x<point2.x){segments[i]={x1:point1.x,y1:point1.y,x2:point2.x,y2:point2.y};}else{segments[i]={x1:point2.x,y1:point2.y,x2:point1.x,y2:point1.y};}}
61104 function byX1(seg1,seg2){return seg1.x1-seg2.x1;}
61105 return segments.sort(byX1);},splitWithSegment:function(seg,options){var edge=!(options&&options.edge===false);var tolerance=options&&options.tolerance;var lines=[];var verts=this.getVertices();var points=[];var intersections=[];var split=false;var vert1,vert2,point;var node,vertex,target;var interOptions={point:true,tolerance:tolerance};var result=null;for(var i=0,stop=verts.length-2;i<=stop;++i){vert1=verts[i];points.push(vert1.clone());vert2=verts[i+1];target={x1:vert1.x,y1:vert1.y,x2:vert2.x,y2:vert2.y};point=OpenLayers.Geometry.segmentsIntersect(seg,target,interOptions);if(point instanceof OpenLayers.Geometry.Point){if((point.x===seg.x1&&point.y===seg.y1)||(point.x===seg.x2&&point.y===seg.y2)||point.equals(vert1)||point.equals(vert2)){vertex=true;}else{vertex=false;}
61106 if(vertex||edge){if(!point.equals(intersections[intersections.length-1])){intersections.push(point.clone());}
61107 if(i===0){if(point.equals(vert1)){continue;}}
61108 if(point.equals(vert2)){continue;}
61109 split=true;if(!point.equals(vert1)){points.push(point);}
61110 lines.push(new OpenLayers.Geometry.LineString(points));points=[point.clone()];}}}
61111 if(split){points.push(vert2.clone());lines.push(new OpenLayers.Geometry.LineString(points));}
61112 if(intersections.length>0){var xDir=seg.x1<seg.x2?1:-1;var yDir=seg.y1<seg.y2?1:-1;result={lines:lines,points:intersections.sort(function(p1,p2){return(xDir*p1.x-xDir*p2.x)||(yDir*p1.y-yDir*p2.y);})};}
61113 return result;},split:function(target,options){var results=null;var mutual=options&&options.mutual;var sourceSplit,targetSplit,sourceParts,targetParts;if(target instanceof OpenLayers.Geometry.LineString){var verts=this.getVertices();var vert1,vert2,seg,splits,lines,point;var points=[];sourceParts=[];for(var i=0,stop=verts.length-2;i<=stop;++i){vert1=verts[i];vert2=verts[i+1];seg={x1:vert1.x,y1:vert1.y,x2:vert2.x,y2:vert2.y};targetParts=targetParts||[target];if(mutual){points.push(vert1.clone());}
61114 for(var j=0;j<targetParts.length;++j){splits=targetParts[j].splitWithSegment(seg,options);if(splits){lines=splits.lines;if(lines.length>0){lines.unshift(j,1);Array.prototype.splice.apply(targetParts,lines);j+=lines.length-2;}
61115 if(mutual){for(var k=0,len=splits.points.length;k<len;++k){point=splits.points[k];if(!point.equals(vert1)){points.push(point);sourceParts.push(new OpenLayers.Geometry.LineString(points));if(point.equals(vert2)){points=[];}else{points=[point.clone()];}}}}}}}
61116 if(mutual&&sourceParts.length>0&&points.length>0){points.push(vert2.clone());sourceParts.push(new OpenLayers.Geometry.LineString(points));}}else{results=target.splitWith(this,options);}
61117 if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
61118 if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
61119 if(targetSplit||sourceSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
61120 return results;},splitWith:function(geometry,options){return geometry.split(this,options);},getVertices:function(nodes){var vertices;if(nodes===true){vertices=[this.components[0],this.components[this.components.length-1]];}else if(nodes===false){vertices=this.components.slice(1,this.components.length-1);}else{vertices=this.components.slice();}
61121 return vertices;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var details=edge&&options&&options.details;var result,best={};var min=Number.POSITIVE_INFINITY;if(geometry instanceof OpenLayers.Geometry.Point){var segs=this.getSortedSegments();var x=geometry.x;var y=geometry.y;var seg;for(var i=0,len=segs.length;i<len;++i){seg=segs[i];result=OpenLayers.Geometry.distanceToSegment(geometry,seg);if(result.distance<min){min=result.distance;best=result;if(min===0){break;}}else{if(seg.x2>x&&((y>seg.y1&&y<seg.y2)||(y<seg.y1&&y>seg.y2))){break;}}}
61122 if(details){best={distance:best.distance,x0:best.x,y0:best.y,x1:x,y1:y};}else{best=best.distance;}}else if(geometry instanceof OpenLayers.Geometry.LineString){var segs0=this.getSortedSegments();var segs1=geometry.getSortedSegments();var seg0,seg1,intersection,x0,y0;var len1=segs1.length;var interOptions={point:true};outer:for(var i=0,len=segs0.length;i<len;++i){seg0=segs0[i];x0=seg0.x1;y0=seg0.y1;for(var j=0;j<len1;++j){seg1=segs1[j];intersection=OpenLayers.Geometry.segmentsIntersect(seg0,seg1,interOptions);if(intersection){min=0;best={distance:0,x0:intersection.x,y0:intersection.y,x1:intersection.x,y1:intersection.y};break outer;}else{result=OpenLayers.Geometry.distanceToSegment({x:x0,y:y0},seg1);if(result.distance<min){min=result.distance;best={distance:min,x0:x0,y0:y0,x1:result.x,y1:result.y};}}}}
61123 if(!details){best=best.distance;}
61124 if(min!==0){if(seg0){result=geometry.distanceTo(new OpenLayers.Geometry.Point(seg0.x2,seg0.y2),options);var dist=details?result.distance:result;if(dist<min){if(details){best={distance:min,x0:result.x1,y0:result.y1,x1:result.x0,y1:result.y0};}else{best=dist;}}}}}else{best=geometry.distanceTo(this,options);if(details){best={distance:best.distance,x0:best.x1,y0:best.y1,x1:best.x0,y1:best.y0};}}
61125 return best;},CLASS_NAME:"OpenLayers.Geometry.LineString"});OpenLayers.Control.TransformFeature=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesetfeature","setfeature","beforetransform","transform","transformcomplete"],geometryTypes:null,layer:null,preserveAspectRatio:false,rotate:true,feature:null,renderIntent:"temporary",rotationHandleSymbolizer:null,box:null,center:null,scale:1,ratio:1,rotation:0,handles:null,rotationHandles:null,dragControl:null,initialize:function(layer,options){this.EVENT_TYPES=OpenLayers.Control.TransformFeature.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.layer=layer;if(!this.rotationHandleSymbolizer){this.rotationHandleSymbolizer={stroke:false,pointRadius:10,fillOpacity:0,cursor:"pointer"};}
61126 this.createBox();this.createControl();},activate:function(){var activated=false;if(OpenLayers.Control.prototype.activate.apply(this,arguments)){this.dragControl.activate();this.layer.addFeatures([this.box]);this.rotate&&this.layer.addFeatures(this.rotationHandles);this.layer.addFeatures(this.handles);activated=true;}
61127 return activated;},deactivate:function(){var deactivated=false;if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.layer.removeFeatures(this.handles);this.rotate&&this.layer.removeFeatures(this.rotationHandles);this.layer.removeFeatures([this.box]);this.dragControl.deactivate();deactivated=true;}
61128 return deactivated;},setMap:function(map){this.dragControl.setMap(map);OpenLayers.Control.prototype.setMap.apply(this,arguments);},setFeature:function(feature,initialParams){initialParams=OpenLayers.Util.applyDefaults(initialParams,{rotation:0,scale:1,ratio:1});var evt={feature:feature};var oldRotation=this.rotation;var oldCenter=this.center;OpenLayers.Util.extend(this,initialParams);if(this.events.triggerEvent("beforesetfeature",evt)===false){return;}
61129 this.feature=feature;this.activate();this._setfeature=true;var featureBounds=this.feature.geometry.getBounds();this.box.move(featureBounds.getCenterLonLat());this.box.geometry.rotate(-oldRotation,oldCenter);this._angle=0;var ll;if(this.rotation){var geom=feature.geometry.clone();geom.rotate(-this.rotation,this.center);var box=new OpenLayers.Feature.Vector(geom.getBounds().toGeometry());box.geometry.rotate(this.rotation,this.center);this.box.geometry.rotate(this.rotation,this.center);this.box.move(box.geometry.getBounds().getCenterLonLat());var llGeom=box.geometry.components[0].components[0];ll=llGeom.getBounds().getCenterLonLat();}else{ll=new OpenLayers.LonLat(featureBounds.left,featureBounds.bottom);}
61130 this.handles[0].move(ll);delete this._setfeature;this.events.triggerEvent("setfeature",evt);},createBox:function(){var control=this;this.center=new OpenLayers.Geometry.Point(0,0);var box=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([new OpenLayers.Geometry.Point(-1,-1),new OpenLayers.Geometry.Point(0,-1),new OpenLayers.Geometry.Point(1,-1),new OpenLayers.Geometry.Point(1,0),new OpenLayers.Geometry.Point(1,1),new OpenLayers.Geometry.Point(0,1),new OpenLayers.Geometry.Point(-1,1),new OpenLayers.Geometry.Point(-1,0),new OpenLayers.Geometry.Point(-1,-1)]),null,typeof this.renderIntent=="string"?null:this.renderIntent);box.geometry.move=function(x,y){control._moving=true;OpenLayers.Geometry.LineString.prototype.move.apply(this,arguments);control.center.move(x,y);delete control._moving;};var vertexMoveFn=function(x,y){OpenLayers.Geometry.Point.prototype.move.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.move(x,y);this._handle.geometry.move(x,y);};var vertexResizeFn=function(scale,center,ratio){OpenLayers.Geometry.Point.prototype.resize.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.resize(scale,center,ratio);this._handle.geometry.resize(scale,center,ratio);};var vertexRotateFn=function(angle,center){OpenLayers.Geometry.Point.prototype.rotate.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.rotate(angle,center);this._handle.geometry.rotate(angle,center);};var handleMoveFn=function(x,y){var oldX=this.x,oldY=this.y;OpenLayers.Geometry.Point.prototype.move.call(this,x,y);if(control._moving){return;}
61131 var evt=control.dragControl.handlers.drag.evt;var preserveAspectRatio=!control._setfeature&&control.preserveAspectRatio;var reshape=!preserveAspectRatio&&!(evt&&evt.shiftKey);var oldGeom=new OpenLayers.Geometry.Point(oldX,oldY);var centerGeometry=control.center;this.rotate(-control.rotation,centerGeometry);oldGeom.rotate(-control.rotation,centerGeometry);var dx1=this.x-centerGeometry.x;var dy1=this.y-centerGeometry.y;var dx0=dx1-(this.x-oldGeom.x);var dy0=dy1-(this.y-oldGeom.y);this.x=oldX;this.y=oldY;var scale,ratio=1;if(reshape){scale=Math.abs(dy0)<0.00001?1:dy1/dy0;ratio=(Math.abs(dx0)<0.00001?1:(dx1/dx0))/scale;}else{var l0=Math.sqrt((dx0*dx0)+(dy0*dy0));var l1=Math.sqrt((dx1*dx1)+(dy1*dy1));scale=l1/l0;}
61132 control._moving=true;control.box.geometry.rotate(-control.rotation,centerGeometry);delete control._moving;control.box.geometry.resize(scale,centerGeometry,ratio);control.box.geometry.rotate(control.rotation,centerGeometry);control.transformFeature({scale:scale,ratio:ratio});};var rotationHandleMoveFn=function(x,y){var oldX=this.x,oldY=this.y;OpenLayers.Geometry.Point.prototype.move.call(this,x,y);if(control._moving){return;}
61133 var evt=control.dragControl.handlers.drag.evt;var constrain=(evt&&evt.shiftKey)?45:1;var centerGeometry=control.center;var dx1=this.x-centerGeometry.x;var dy1=this.y-centerGeometry.y;var dx0=dx1-x;var dy0=dy1-y;this.x=oldX;this.y=oldY;var a0=Math.atan2(dy0,dx0);var a1=Math.atan2(dy1,dx1);var angle=a1-a0;angle*=180/Math.PI;control._angle=(control._angle+angle)%360;var diff=control.rotation%constrain;if(Math.abs(control._angle)>=constrain||diff!==0){angle=Math.round(control._angle/constrain)*constrain-
61134 diff;control._angle=0;control.box.geometry.rotate(angle,centerGeometry);control.transformFeature({rotation:angle});}};var handles=new Array(8);var rotationHandles=new Array(4);var geom,handle,rotationHandle;for(var i=0;i<8;++i){geom=box.geometry.components[i];handle=new OpenLayers.Feature.Vector(geom.clone(),null,typeof this.renderIntent=="string"?null:this.renderIntent);if(i%2==0){rotationHandle=new OpenLayers.Feature.Vector(geom.clone(),null,typeof this.rotationHandleSymbolizer=="string"?null:this.rotationHandleSymbolizer);rotationHandle.geometry.move=rotationHandleMoveFn;geom._rotationHandle=rotationHandle;rotationHandles[i/2]=rotationHandle;}
61135 geom.move=vertexMoveFn;geom.resize=vertexResizeFn;geom.rotate=vertexRotateFn;handle.geometry.move=handleMoveFn;geom._handle=handle;handles[i]=handle;}
61136 this.box=box;this.rotationHandles=rotationHandles;this.handles=handles;},createControl:function(){var control=this;this.dragControl=new OpenLayers.Control.DragFeature(this.layer,{documentDrag:true,moveFeature:function(pixel){if(this.feature===control.feature){this.feature=control.box;}
61137 OpenLayers.Control.DragFeature.prototype.moveFeature.apply(this,arguments);},onDrag:function(feature,pixel){if(feature===control.box){control.transformFeature({center:control.center});control.drawHandles();}},onStart:function(feature,pixel){var eligible=!control.geometryTypes||OpenLayers.Util.indexOf(control.geometryTypes,feature.geometry.CLASS_NAME)!==-1;var i=OpenLayers.Util.indexOf(control.handles,feature);i+=OpenLayers.Util.indexOf(control.rotationHandles,feature);if(feature!==control.feature&&feature!==control.box&&i==-2&&eligible){control.setFeature(feature);}},onComplete:function(feature,pixel){control.events.triggerEvent("transformcomplete",{feature:control.feature});}});},drawHandles:function(){var layer=this.layer;for(var i=0;i<8;++i){if(this.rotate&&i%2===0){layer.drawFeature(this.rotationHandles[i/2],this.rotationHandleSymbolizer);}
61138 layer.drawFeature(this.handles[i],this.renderIntent);}},transformFeature:function(mods){if(!this._setfeature){this.scale*=(mods.scale||1);this.ratio*=(mods.ratio||1);var oldRotation=this.rotation;this.rotation=(this.rotation+(mods.rotation||0))%360;if(this.events.triggerEvent("beforetransform",mods)!==false){var feature=this.feature;var geom=feature.geometry;var center=this.center;geom.rotate(-oldRotation,center);if(mods.scale||mods.ratio){geom.resize(mods.scale,center,mods.ratio);}else if(mods.center){feature.move(mods.center.getBounds().getCenterLonLat());}
61139 geom.rotate(this.rotation,center);this.layer.drawFeature(feature);feature.toState(OpenLayers.State.UPDATE);this.events.triggerEvent("transform",mods);}}
61140 this.layer.drawFeature(this.box,this.renderIntent);this.drawHandles();},destroy:function(){var geom;for(var i=0;i<8;++i){geom=this.box.geometry.components[i];geom._handle.destroy();geom._handle=null;geom._rotationHandle&&geom._rotationHandle.destroy();geom._rotationHandle=null;}
61141 this.box.destroy();this.box=null;this.layer=null;this.dragControl.destroy();OpenLayers.Control.prototype.destroy.apply(this,arguments);},CLASS_NAME:"OpenLayers.Control.TransformFeature"});OpenLayers.Format.GPX=OpenLayers.Class(OpenLayers.Format.XML,{extractWaypoints:true,extractTracks:true,extractRoutes:true,extractAttributes:true,initialize:function(options){this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
61142 var features=[];if(this.extractTracks){var tracks=doc.getElementsByTagName("trk");for(var i=0,len=tracks.length;i<len;i++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(tracks[i]);}
61143 var segs=this.getElementsByTagNameNS(tracks[i],tracks[i].namespaceURI,"trkseg");for(var j=0,seglen=segs.length;j<seglen;j++){var track=this.extractSegment(segs[j],"trkpt");features.push(new OpenLayers.Feature.Vector(track,attrs));}}}
61144 if(this.extractRoutes){var routes=doc.getElementsByTagName("rte");for(var k=0,klen=routes.length;k<klen;k++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(routes[k]);}
61145 var route=this.extractSegment(routes[k],"rtept");features.push(new OpenLayers.Feature.Vector(route,attrs));}}
61146 if(this.extractWaypoints){var waypoints=doc.getElementsByTagName("wpt");for(var l=0,len=waypoints.length;l<len;l++){var attrs={};if(this.extractAttributes){attrs=this.parseAttributes(waypoints[l]);}
61147 var wpt=new OpenLayers.Geometry.Point(waypoints[l].getAttribute("lon"),waypoints[l].getAttribute("lat"));features.push(new OpenLayers.Feature.Vector(wpt,attrs));}}
61148 if(this.internalProjection&&this.externalProjection){for(var g=0,featLength=features.length;g<featLength;g++){features[g].geometry.transform(this.externalProjection,this.internalProjection);}}
61149 return features;},extractSegment:function(segment,segmentType){var points=this.getElementsByTagNameNS(segment,segment.namespaceURI,segmentType);var point_features=[];for(var i=0,len=points.length;i<len;i++){point_features.push(new OpenLayers.Geometry.Point(points[i].getAttribute("lon"),points[i].getAttribute("lat")));}
61150 return new OpenLayers.Geometry.LineString(point_features);},parseAttributes:function(node){var attributes={};var attrNode=node.firstChild;while(attrNode){if(attrNode.nodeType==1){var value=attrNode.firstChild;if(value.nodeType==3||value.nodeType==4){name=(attrNode.prefix)?attrNode.nodeName.split(":")[1]:attrNode.nodeName;if(name!="trkseg"&&name!="rtept"){attributes[name]=value.nodeValue;}}}
61151 attrNode=attrNode.nextSibling;}
61152 return attributes;},CLASS_NAME:"OpenLayers.Format.GPX"});OpenLayers.Geometry.LinearRing=OpenLayers.Class(OpenLayers.Geometry.LineString,{componentTypes:["OpenLayers.Geometry.Point"],initialize:function(points){OpenLayers.Geometry.LineString.prototype.initialize.apply(this,arguments);},addComponent:function(point,index){var added=false;var lastPoint=this.components.pop();if(index!=null||!point.equals(lastPoint)){added=OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,arguments);}
61153 var firstPoint=this.components[0];OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,[firstPoint]);return added;},removeComponent:function(point){if(this.components.length>4){this.components.pop();OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,arguments);var firstPoint=this.components[0];OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,[firstPoint]);}},move:function(x,y){for(var i=0,len=this.components.length;i<len-1;i++){this.components[i].move(x,y);}},rotate:function(angle,origin){for(var i=0,len=this.components.length;i<len-1;++i){this.components[i].rotate(angle,origin);}},resize:function(scale,origin,ratio){for(var i=0,len=this.components.length;i<len-1;++i){this.components[i].resize(scale,origin,ratio);}
61154 return this;},transform:function(source,dest){if(source&&dest){for(var i=0,len=this.components.length;i<len-1;i++){var component=this.components[i];component.transform(source,dest);}
61155 this.bounds=null;}
61156 return this;},getCentroid:function(){if(this.components&&(this.components.length>2)){var sumX=0.0;var sumY=0.0;for(var i=0;i<this.components.length-1;i++){var b=this.components[i];var c=this.components[i+1];sumX+=(b.x+c.x)*(b.x*c.y-c.x*b.y);sumY+=(b.y+c.y)*(b.x*c.y-c.x*b.y);}
61157 var area=-1*this.getArea();var x=sumX/(6*area);var y=sumY/(6*area);return new OpenLayers.Geometry.Point(x,y);}else{return null;}},getArea:function(){var area=0.0;if(this.components&&(this.components.length>2)){var sum=0.0;for(var i=0,len=this.components.length;i<len-1;i++){var b=this.components[i];var c=this.components[i+1];sum+=(b.x+c.x)*(c.y-b.y);}
61158 area=-sum/2.0;}
61159 return area;},getGeodesicArea:function(projection){var ring=this;if(projection){var gg=new OpenLayers.Projection("EPSG:4326");if(!gg.equals(projection)){ring=this.clone().transform(projection,gg);}}
61160 var area=0.0;var len=ring.components&&ring.components.length;if(len>2){var p1,p2;for(var i=0;i<len-1;i++){p1=ring.components[i];p2=ring.components[i+1];area+=OpenLayers.Util.rad(p2.x-p1.x)*(2+Math.sin(OpenLayers.Util.rad(p1.y))+
61161 Math.sin(OpenLayers.Util.rad(p2.y)));}
61162 area=area*6378137.0*6378137.0/2.0;}
61163 return area;},containsPoint:function(point){var approx=OpenLayers.Number.limitSigDigs;var digs=14;var px=approx(point.x,digs);var py=approx(point.y,digs);function getX(y,x1,y1,x2,y2){return(((x1-x2)*y)+((x2*y1)-(x1*y2)))/(y1-y2);}
61164 var numSeg=this.components.length-1;var start,end,x1,y1,x2,y2,cx,cy;var crosses=0;for(var i=0;i<numSeg;++i){start=this.components[i];x1=approx(start.x,digs);y1=approx(start.y,digs);end=this.components[i+1];x2=approx(end.x,digs);y2=approx(end.y,digs);if(y1==y2){if(py==y1){if(x1<=x2&&(px>=x1&&px<=x2)||x1>=x2&&(px<=x1&&px>=x2)){crosses=-1;break;}}
61165 continue;}
61166 cx=approx(getX(py,x1,y1,x2,y2),digs);if(cx==px){if(y1<y2&&(py>=y1&&py<=y2)||y1>y2&&(py<=y1&&py>=y2)){crosses=-1;break;}}
61167 if(cx<=px){continue;}
61168 if(x1!=x2&&(cx<Math.min(x1,x2)||cx>Math.max(x1,x2))){continue;}
61169 if(y1<y2&&(py>=y1&&py<y2)||y1>y2&&(py<y1&&py>=y2)){++crosses;}}
61170 var contained=(crosses==-1)?1:!!(crosses&1);return contained;},intersects:function(geometry){var intersect=false;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.containsPoint(geometry);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"){intersect=geometry.intersects(this);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){intersect=OpenLayers.Geometry.LineString.prototype.intersects.apply(this,[geometry]);}else{for(var i=0,len=geometry.components.length;i<len;++i){intersect=geometry.components[i].intersects(this);if(intersect){break;}}}
61171 return intersect;},getVertices:function(nodes){return(nodes===true)?[]:this.components.slice(0,this.components.length-1);},CLASS_NAME:"OpenLayers.Geometry.LinearRing"});OpenLayers.Geometry.MultiLineString=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.LineString"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},split:function(geometry,options){var results=null;var mutual=options&&options.mutual;var splits,sourceLine,sourceLines,sourceSplit,targetSplit;var sourceParts=[];var targetParts=[geometry];for(var i=0,len=this.components.length;i<len;++i){sourceLine=this.components[i];sourceSplit=false;for(var j=0;j<targetParts.length;++j){splits=sourceLine.split(targetParts[j],options);if(splits){if(mutual){sourceLines=splits[0];for(var k=0,klen=sourceLines.length;k<klen;++k){if(k===0&&sourceParts.length){sourceParts[sourceParts.length-1].addComponent(sourceLines[k]);}else{sourceParts.push(new OpenLayers.Geometry.MultiLineString([sourceLines[k]]));}}
61172 sourceSplit=true;splits=splits[1];}
61173 if(splits.length){splits.unshift(j,1);Array.prototype.splice.apply(targetParts,splits);break;}}}
61174 if(!sourceSplit){if(sourceParts.length){sourceParts[sourceParts.length-1].addComponent(sourceLine.clone());}else{sourceParts=[new OpenLayers.Geometry.MultiLineString(sourceLine.clone())];}}}
61175 if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
61176 if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
61177 if(sourceSplit||targetSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
61178 return results;},splitWith:function(geometry,options){var results=null;var mutual=options&&options.mutual;var splits,targetLine,sourceLines,sourceSplit,targetSplit,sourceParts,targetParts;if(geometry instanceof OpenLayers.Geometry.LineString){targetParts=[];sourceParts=[geometry];for(var i=0,len=this.components.length;i<len;++i){targetSplit=false;targetLine=this.components[i];for(var j=0;j<sourceParts.length;++j){splits=sourceParts[j].split(targetLine,options);if(splits){if(mutual){sourceLines=splits[0];if(sourceLines.length){sourceLines.unshift(j,1);Array.prototype.splice.apply(sourceParts,sourceLines);j+=sourceLines.length-2;}
61179 splits=splits[1];if(splits.length===0){splits=[targetLine.clone()];}}
61180 for(var k=0,klen=splits.length;k<klen;++k){if(k===0&&targetParts.length){targetParts[targetParts.length-1].addComponent(splits[k]);}else{targetParts.push(new OpenLayers.Geometry.MultiLineString([splits[k]]));}}
61181 targetSplit=true;}}
61182 if(!targetSplit){if(targetParts.length){targetParts[targetParts.length-1].addComponent(targetLine.clone());}else{targetParts=[new OpenLayers.Geometry.MultiLineString([targetLine.clone()])];}}}}else{results=geometry.split(this);}
61183 if(sourceParts&&sourceParts.length>1){sourceSplit=true;}else{sourceParts=[];}
61184 if(targetParts&&targetParts.length>1){targetSplit=true;}else{targetParts=[];}
61185 if(sourceSplit||targetSplit){if(mutual){results=[sourceParts,targetParts];}else{results=targetParts;}}
61186 return results;},CLASS_NAME:"OpenLayers.Geometry.MultiLineString"});OpenLayers.Handler.Path=OpenLayers.Class(OpenLayers.Handler.Point,{line:null,freehand:false,freehandToggle:'shiftKey',initialize:function(control,callbacks,options){OpenLayers.Handler.Point.prototype.initialize.apply(this,arguments);},createFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([this.point.geometry]));this.callback("create",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.layer.addFeatures([this.line,this.point],{silent:true});},destroyFeature:function(){OpenLayers.Handler.Point.prototype.destroyFeature.apply(this);this.line=null;},removePoint:function(){if(this.point){this.layer.removeFeatures([this.point]);}},addPoint:function(pixel){this.layer.removeFeatures([this.point]);var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line.geometry.addComponent(this.point.geometry,this.line.geometry.components.length);this.callback("point",[this.point.geometry,this.getGeometry()]);this.callback("modify",[this.point.geometry,this.getSketch()]);this.drawFeature();},freehandMode:function(evt){return(this.freehandToggle&&evt[this.freehandToggle])?!this.freehand:this.freehand;},modifyFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point.geometry.x=lonlat.lon;this.point.geometry.y=lonlat.lat;this.callback("modify",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.drawFeature();},drawFeature:function(){this.layer.drawFeature(this.line,this.style);this.layer.drawFeature(this.point,this.style);},getSketch:function(){return this.line;},getGeometry:function(){var geometry=this.line&&this.line.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiLineString([geometry]);}
61187 return geometry;},mousedown:function(evt){if(this.lastDown&&this.lastDown.equals(evt.xy)){return false;}
61188 if(this.lastDown==null){if(this.persist){this.destroyFeature();}
61189 this.createFeature(evt.xy);}else if((this.lastUp==null)||!this.lastUp.equals(evt.xy)){this.addPoint(evt.xy);}
61190 this.mouseDown=true;this.lastDown=evt.xy;this.drawing=true;return false;},mousemove:function(evt){if(this.drawing){if(this.mouseDown&&this.freehandMode(evt)){this.addPoint(evt.xy);}else{this.modifyFeature(evt.xy);}}
61191 return true;},mouseup:function(evt){this.mouseDown=false;if(this.drawing){if(this.freehandMode(evt)){this.removePoint();this.finalize();}else{if(this.lastUp==null){this.addPoint(evt.xy);}
61192 this.lastUp=evt.xy;}
61193 return false;}
61194 return true;},dblclick:function(evt){if(!this.freehandMode(evt)){var index=this.line.geometry.components.length-1;this.line.geometry.removeComponent(this.line.geometry.components[index]);this.removePoint();this.finalize();}
61195 return false;},CLASS_NAME:"OpenLayers.Handler.Path"});OpenLayers.Control.Split=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["beforesplit","split","aftersplit"],layer:null,source:null,sourceOptions:null,tolerance:null,edge:true,deferDelete:false,mutual:true,targetFilter:null,sourceFilter:null,handler:null,initialize:function(options){Array.prototype.push.apply(this.EVENT_TYPES,OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.options=options||{};if(this.options.source){this.setSource(this.options.source);}},setSource:function(layer){if(this.active){this.deactivate();if(this.handler){this.handler.destroy();delete this.handler;}
61196 this.source=layer;this.activate();}else{this.source=layer;}},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){if(!this.source){if(!this.handler){this.handler=new OpenLayers.Handler.Path(this,{done:function(geometry){this.onSketchComplete({feature:new OpenLayers.Feature.Vector(geometry)});}},{layerOptions:this.sourceOptions});}
61197 this.handler.activate();}else if(this.source.events){this.source.events.on({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this});}}
61198 return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){if(this.source&&this.source.events){this.layer.events.un({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this});}}
61199 return deactivated;},onSketchComplete:function(event){this.feature=null;return!this.considerSplit(event.feature);},afterFeatureModified:function(event){if(event.modified){var feature=event.feature;if(feature.geometry instanceof OpenLayers.Geometry.LineString||feature.geometry instanceof OpenLayers.Geometry.MultiLineString){this.feature=event.feature;this.considerSplit(event.feature);}}},removeByGeometry:function(features,geometry){for(var i=0,len=features.length;i<len;++i){if(features[i].geometry===geometry){features.splice(i,1);break;}}},isEligible:function(target){return(target.state!==OpenLayers.State.DELETE)&&(target.geometry instanceof OpenLayers.Geometry.LineString||target.geometry instanceof OpenLayers.Geometry.MultiLineString)&&(this.feature!==target)&&(!this.targetFilter||this.targetFilter.evaluate(target.attributes));},considerSplit:function(feature){var sourceSplit=false;var targetSplit=false;if(!this.sourceFilter||this.sourceFilter.evaluate(feature.attributes)){var features=this.layer&&this.layer.features||[];var target,results,proceed;var additions=[],removals=[];var mutual=(this.layer===this.source)&&this.mutual;var options={edge:this.edge,tolerance:this.tolerance,mutual:mutual};var sourceParts=[feature.geometry];var targetFeature,targetParts;var source,parts;for(var i=0,len=features.length;i<len;++i){targetFeature=features[i];if(this.isEligible(targetFeature)){targetParts=[targetFeature.geometry];for(var j=0;j<sourceParts.length;++j){source=sourceParts[j];for(var k=0;k<targetParts.length;++k){target=targetParts[k];if(source.getBounds().intersectsBounds(target.getBounds())){results=source.split(target,options);if(results){proceed=this.events.triggerEvent("beforesplit",{source:feature,target:targetFeature});if(proceed!==false){if(mutual){parts=results[0];if(parts.length>1){parts.unshift(j,1);Array.prototype.splice.apply(sourceParts,parts);j+=parts.length-3;}
61200 results=results[1];}
61201 if(results.length>1){results.unshift(k,1);Array.prototype.splice.apply(targetParts,results);k+=results.length-3;}}}}}}
61202 if(targetParts&&targetParts.length>1){this.geomsToFeatures(targetFeature,targetParts);this.events.triggerEvent("split",{original:targetFeature,features:targetParts});Array.prototype.push.apply(additions,targetParts);removals.push(targetFeature);targetSplit=true;}}}
61203 if(sourceParts&&sourceParts.length>1){this.geomsToFeatures(feature,sourceParts);this.events.triggerEvent("split",{original:feature,features:sourceParts});Array.prototype.push.apply(additions,sourceParts);removals.push(feature);sourceSplit=true;}
61204 if(sourceSplit||targetSplit){if(this.deferDelete){var feat,destroys=[];for(var i=0,len=removals.length;i<len;++i){feat=removals[i];if(feat.state===OpenLayers.State.INSERT){destroys.push(feat);}else{feat.state=OpenLayers.State.DELETE;this.layer.drawFeature(feat);}}
61205 this.layer.destroyFeatures(destroys,{silent:true});for(var i=0,len=additions.length;i<len;++i){additions[i].state=OpenLayers.State.INSERT;}}else{this.layer.destroyFeatures(removals,{silent:true});}
61206 this.layer.addFeatures(additions,{silent:true});this.events.triggerEvent("aftersplit",{source:feature,features:additions});}}
61207 return sourceSplit;},geomsToFeatures:function(feature,geoms){var clone=feature.clone();delete clone.geometry;var newFeature;for(var i=0,len=geoms.length;i<len;++i){newFeature=clone.clone();newFeature.geometry=geoms[i];newFeature.state=OpenLayers.State.INSERT;geoms[i]=newFeature;}},destroy:function(){if(this.active){this.deactivate();}
61208 OpenLayers.Control.prototype.destroy.call(this);},CLASS_NAME:"OpenLayers.Control.Split"});OpenLayers.Geometry.Polygon=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.LinearRing"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},getArea:function(){var area=0.0;if(this.components&&(this.components.length>0)){area+=Math.abs(this.components[0].getArea());for(var i=1,len=this.components.length;i<len;i++){area-=Math.abs(this.components[i].getArea());}}
61209 return area;},getGeodesicArea:function(projection){var area=0.0;if(this.components&&(this.components.length>0)){area+=Math.abs(this.components[0].getGeodesicArea(projection));for(var i=1,len=this.components.length;i<len;i++){area-=Math.abs(this.components[i].getGeodesicArea(projection));}}
61210 return area;},containsPoint:function(point){var numRings=this.components.length;var contained=false;if(numRings>0){contained=this.components[0].containsPoint(point);if(contained!==1){if(contained&&numRings>1){var hole;for(var i=1;i<numRings;++i){hole=this.components[i].containsPoint(point);if(hole){if(hole===1){contained=1;}else{contained=false;}
61211 break;}}}}}
61212 return contained;},intersects:function(geometry){var intersect=false;var i,len;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){intersect=this.containsPoint(geometry);}else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"||geometry.CLASS_NAME=="OpenLayers.Geometry.LinearRing"){for(i=0,len=this.components.length;i<len;++i){intersect=geometry.intersects(this.components[i]);if(intersect){break;}}
61213 if(!intersect){for(i=0,len=geometry.components.length;i<len;++i){intersect=this.containsPoint(geometry.components[i]);if(intersect){break;}}}}else{for(i=0,len=geometry.components.length;i<len;++i){intersect=this.intersects(geometry.components[i]);if(intersect){break;}}}
61214 if(!intersect&&geometry.CLASS_NAME=="OpenLayers.Geometry.Polygon"){var ring=this.components[0];for(i=0,len=ring.components.length;i<len;++i){intersect=geometry.containsPoint(ring.components[i]);if(intersect){break;}}}
61215 return intersect;},distanceTo:function(geometry,options){var edge=!(options&&options.edge===false);var result;if(!edge&&this.intersects(geometry)){result=0;}else{result=OpenLayers.Geometry.Collection.prototype.distanceTo.apply(this,[geometry,options]);}
61216 return result;},CLASS_NAME:"OpenLayers.Geometry.Polygon"});OpenLayers.Geometry.Polygon.createRegularPolygon=function(origin,radius,sides,rotation){var angle=Math.PI*((1/sides)-(1/2));if(rotation){angle+=(rotation/180)*Math.PI;}
61217 var rotatedAngle,x,y;var points=[];for(var i=0;i<sides;++i){rotatedAngle=angle+(i*2*Math.PI/sides);x=origin.x+(radius*Math.cos(rotatedAngle));y=origin.y+(radius*Math.sin(rotatedAngle));points.push(new OpenLayers.Geometry.Point(x,y));}
61218 var ring=new OpenLayers.Geometry.LinearRing(points);return new OpenLayers.Geometry.Polygon([ring]);};OpenLayers.Format.GeoRSS=OpenLayers.Class(OpenLayers.Format.XML,{rssns:"http://backend.userland.com/rss2",featureNS:"http://mapserver.gis.umn.edu/mapserver",georssns:"http://www.georss.org/georss",geons:"http://www.w3.org/2003/01/geo/wgs84_pos#",featureTitle:"Untitled",featureDescription:"No Description",gmlParser:null,xy:false,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},createGeometryFromItem:function(item){var point=this.getElementsByTagNameNS(item,this.georssns,"point");var lat=this.getElementsByTagNameNS(item,this.geons,'lat');var lon=this.getElementsByTagNameNS(item,this.geons,'long');var line=this.getElementsByTagNameNS(item,this.georssns,"line");var polygon=this.getElementsByTagNameNS(item,this.georssns,"polygon");var where=this.getElementsByTagNameNS(item,this.georssns,"where");var box=this.getElementsByTagNameNS(item,this.georssns,"box");if(point.length>0||(lat.length>0&&lon.length>0)){var location;if(point.length>0){location=OpenLayers.String.trim(point[0].firstChild.nodeValue).split(/\s+/);if(location.length!=2){location=OpenLayers.String.trim(point[0].firstChild.nodeValue).split(/\s*,\s*/);}}else{location=[parseFloat(lat[0].firstChild.nodeValue),parseFloat(lon[0].firstChild.nodeValue)];}
61219 var geometry=new OpenLayers.Geometry.Point(parseFloat(location[1]),parseFloat(location[0]));}else if(line.length>0){var coords=OpenLayers.String.trim(this.concatChildValues(line[0])).split(/\s+/);var components=[];var point;for(var i=0,len=coords.length;i<len;i+=2){point=new OpenLayers.Geometry.Point(parseFloat(coords[i+1]),parseFloat(coords[i]));components.push(point);}
61220 geometry=new OpenLayers.Geometry.LineString(components);}else if(polygon.length>0){var coords=OpenLayers.String.trim(this.concatChildValues(polygon[0])).split(/\s+/);var components=[];var point;for(var i=0,len=coords.length;i<len;i+=2){point=new OpenLayers.Geometry.Point(parseFloat(coords[i+1]),parseFloat(coords[i]));components.push(point);}
61221 geometry=new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);}else if(where.length>0){if(!this.gmlParser){this.gmlParser=new OpenLayers.Format.GML({'xy':this.xy});}
61222 var feature=this.gmlParser.parseFeature(where[0]);geometry=feature.geometry;}else if(box.length>0){var coords=OpenLayers.String.trim(box[0].firstChild.nodeValue).split(/\s+/);var components=[];var point;if(coords.length>3){point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[0]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[2]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[3]),parseFloat(coords[2]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[3]),parseFloat(coords[0]));components.push(point);point=new OpenLayers.Geometry.Point(parseFloat(coords[1]),parseFloat(coords[0]));components.push(point);}
61223 geometry=new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);}
61224 if(geometry&&this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
61225 return geometry;},createFeatureFromItem:function(item){var geometry=this.createGeometryFromItem(item);var title=this.getChildValue(item,"*","title",this.featureTitle);var description=this.getChildValue(item,"*","description",this.getChildValue(item,"*","content",this.getChildValue(item,"*","summary",this.featureDescription)));var link=this.getChildValue(item,"*","link");if(!link){try{link=this.getElementsByTagNameNS(item,"*","link")[0].getAttribute("href");}catch(e){link=null;}}
61226 var id=this.getChildValue(item,"*","id",null);var data={"title":title,"description":description,"link":link};var feature=new OpenLayers.Feature.Vector(geometry,data);feature.fid=id;return feature;},getChildValue:function(node,nsuri,name,def){var value;var eles=this.getElementsByTagNameNS(node,nsuri,name);if(eles&&eles[0]&&eles[0].firstChild&&eles[0].firstChild.nodeValue){value=eles[0].firstChild.nodeValue;}else{value=(def==undefined)?"":def;}
61227 return value;},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
61228 var itemlist=null;itemlist=this.getElementsByTagNameNS(doc,'*','item');if(itemlist.length==0){itemlist=this.getElementsByTagNameNS(doc,'*','entry');}
61229 var numItems=itemlist.length;var features=new Array(numItems);for(var i=0;i<numItems;i++){features[i]=this.createFeatureFromItem(itemlist[i]);}
61230 return features;},write:function(features){var georss;if(features instanceof Array){georss=this.createElementNS(this.rssns,"rss");for(var i=0,len=features.length;i<len;i++){georss.appendChild(this.createFeatureXML(features[i]));}}else{georss=this.createFeatureXML(features);}
61231 return OpenLayers.Format.XML.prototype.write.apply(this,[georss]);},createFeatureXML:function(feature){var geometryNode=this.buildGeometryNode(feature.geometry);var featureNode=this.createElementNS(this.rssns,"item");var titleNode=this.createElementNS(this.rssns,"title");titleNode.appendChild(this.createTextNode(feature.attributes.title?feature.attributes.title:""));var descNode=this.createElementNS(this.rssns,"description");descNode.appendChild(this.createTextNode(feature.attributes.description?feature.attributes.description:""));featureNode.appendChild(titleNode);featureNode.appendChild(descNode);if(feature.attributes.link){var linkNode=this.createElementNS(this.rssns,"link");linkNode.appendChild(this.createTextNode(feature.attributes.link));featureNode.appendChild(linkNode);}
61232 for(var attr in feature.attributes){if(attr=="link"||attr=="title"||attr=="description"){continue;}
61233 var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr;if(attr.search(":")!=-1){nodename=attr.split(":")[1];}
61234 var attrContainer=this.createElementNS(this.featureNS,"feature:"+nodename);attrContainer.appendChild(attrText);featureNode.appendChild(attrContainer);}
61235 featureNode.appendChild(geometryNode);return featureNode;},buildGeometryNode:function(geometry){if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
61236 var node;if(geometry.CLASS_NAME=="OpenLayers.Geometry.Polygon"){node=this.createElementNS(this.georssns,'georss:polygon');node.appendChild(this.buildCoordinatesNode(geometry.components[0]));}
61237 else if(geometry.CLASS_NAME=="OpenLayers.Geometry.LineString"){node=this.createElementNS(this.georssns,'georss:line');node.appendChild(this.buildCoordinatesNode(geometry));}
61238 else if(geometry.CLASS_NAME=="OpenLayers.Geometry.Point"){node=this.createElementNS(this.georssns,'georss:point');node.appendChild(this.buildCoordinatesNode(geometry));}else{throw"Couldn't parse "+geometry.CLASS_NAME;}
61239 return node;},buildCoordinatesNode:function(geometry){var points=null;if(geometry.components){points=geometry.components;}
61240 var path;if(points){var numPoints=points.length;var parts=new Array(numPoints);for(var i=0;i<numPoints;i++){parts[i]=points[i].y+" "+points[i].x;}
61241 path=parts.join(" ");}else{path=geometry.y+" "+geometry.x;}
61242 return this.createTextNode(path);},CLASS_NAME:"OpenLayers.Format.GeoRSS"});OpenLayers.Format.KML=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{kml:"http://www.opengis.net/kml/2.2",gx:"http://www.google.com/kml/ext/2.2"},kmlns:"http://earth.google.com/kml/2.0",placemarksDesc:"No description available",foldersName:"OpenLayers export",foldersDesc:"Exported on "+new Date(),extractAttributes:true,extractStyles:false,extractTracks:false,trackAttributes:null,internalns:null,features:null,styles:null,styleBaseUrl:"",fetched:null,maxDepth:0,initialize:function(options){this.regExes={trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g),kmlColor:(/(\w{2})(\w{2})(\w{2})(\w{2})/),kmlIconPalette:(/root:\/\/icons\/palette-(\d+)(\.\w+)/),straightBracket:(/\$\[(.*?)\]/g)};this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){this.features=[];this.styles={};this.fetched={};var options={depth:0,styleBaseUrl:this.styleBaseUrl};return this.parseData(data,options);},parseData:function(data,options){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61243 var types=["Link","NetworkLink","Style","StyleMap","Placemark"];for(var i=0,len=types.length;i<len;++i){var type=types[i];var nodes=this.getElementsByTagNameNS(data,"*",type);if(nodes.length==0){continue;}
61244 switch(type.toLowerCase()){case"link":case"networklink":this.parseLinks(nodes,options);break;case"style":if(this.extractStyles){this.parseStyles(nodes,options);}
61245 break;case"stylemap":if(this.extractStyles){this.parseStyleMaps(nodes,options);}
61246 break;case"placemark":this.parseFeatures(nodes,options);break;}}
61247 return this.features;},parseLinks:function(nodes,options){if(options.depth>=this.maxDepth){return false;}
61248 var newOptions=OpenLayers.Util.extend({},options);newOptions.depth++;for(var i=0,len=nodes.length;i<len;i++){var href=this.parseProperty(nodes[i],"*","href");if(href&&!this.fetched[href]){this.fetched[href]=true;var data=this.fetchLink(href);if(data){this.parseData(data,newOptions);}}}},fetchLink:function(href){var request=OpenLayers.Request.GET({url:href,async:false});if(request){return request.responseText;}},parseStyles:function(nodes,options){for(var i=0,len=nodes.length;i<len;i++){var style=this.parseStyle(nodes[i]);if(style){var styleName=(options.styleBaseUrl||"")+"#"+style.id;this.styles[styleName]=style;}}},parseKmlColor:function(kmlColor){var color=null;if(kmlColor){var matches=kmlColor.match(this.regExes.kmlColor);if(matches){color={color:'#'+matches[4]+matches[3]+matches[2],opacity:parseInt(matches[1],16)/255};}}
61249 return color;},parseStyle:function(node){var style={};var types=["LineStyle","PolyStyle","IconStyle","BalloonStyle","LabelStyle"];var type,nodeList,geometry,parser;for(var i=0,len=types.length;i<len;++i){type=types[i];styleTypeNode=this.getElementsByTagNameNS(node,"*",type)[0];if(!styleTypeNode){continue;}
61250 switch(type.toLowerCase()){case"linestyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["strokeColor"]=color.color;style["strokeOpacity"]=color.opacity;}
61251 var width=this.parseProperty(styleTypeNode,"*","width");if(width){style["strokeWidth"]=width;}
61252 break;case"polystyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["fillOpacity"]=color.opacity;style["fillColor"]=color.color;}
61253 var fill=this.parseProperty(styleTypeNode,"*","fill");if(fill=="0"){style["fillColor"]="none";}
61254 var outline=this.parseProperty(styleTypeNode,"*","outline");if(outline=="0"){style["strokeWidth"]="0";}
61255 break;case"iconstyle":var scale=parseFloat(this.parseProperty(styleTypeNode,"*","scale")||1);var width=32*scale;var height=32*scale;var iconNode=this.getElementsByTagNameNS(styleTypeNode,"*","Icon")[0];if(iconNode){var href=this.parseProperty(iconNode,"*","href");if(href){var w=this.parseProperty(iconNode,"*","w");var h=this.parseProperty(iconNode,"*","h");var google="http://maps.google.com/mapfiles/kml";if(OpenLayers.String.startsWith(href,google)&&!w&&!h){w=64;h=64;scale=scale/2;}
61256 w=w||h;h=h||w;if(w){width=parseInt(w)*scale;}
61257 if(h){height=parseInt(h)*scale;}
61258 var matches=href.match(this.regExes.kmlIconPalette);if(matches){var palette=matches[1];var file_extension=matches[2];var x=this.parseProperty(iconNode,"*","x");var y=this.parseProperty(iconNode,"*","y");var posX=x?x/32:0;var posY=y?(7-y/32):7;var pos=posY*8+posX;href="http://maps.google.com/mapfiles/kml/pal"
61259 +palette+"/icon"+pos+file_extension;}
61260 style["graphicOpacity"]=1;style["externalGraphic"]=href;}}
61261 var hotSpotNode=this.getElementsByTagNameNS(styleTypeNode,"*","hotSpot")[0];if(hotSpotNode){var x=parseFloat(hotSpotNode.getAttribute("x"));var y=parseFloat(hotSpotNode.getAttribute("y"));var xUnits=hotSpotNode.getAttribute("xunits");if(xUnits=="pixels"){style["graphicXOffset"]=-x*scale;}
61262 else if(xUnits=="insetPixels"){style["graphicXOffset"]=-width+(x*scale);}
61263 else if(xUnits=="fraction"){style["graphicXOffset"]=-width*x;}
61264 var yUnits=hotSpotNode.getAttribute("yunits");if(yUnits=="pixels"){style["graphicYOffset"]=-height+(y*scale)+1;}
61265 else if(yUnits=="insetPixels"){style["graphicYOffset"]=-(y*scale)+1;}
61266 else if(yUnits=="fraction"){style["graphicYOffset"]=-height*(1-y)+1;}}
61267 style["graphicWidth"]=width;style["graphicHeight"]=height;break;case"balloonstyle":var balloonStyle=OpenLayers.Util.getXmlNodeValue(styleTypeNode);if(balloonStyle){style["balloonStyle"]=balloonStyle.replace(this.regExes.straightBracket,"${$1}");}
61268 break;case"labelstyle":var kmlColor=this.parseProperty(styleTypeNode,"*","color");var color=this.parseKmlColor(kmlColor);if(color){style["fontColor"]=color.color;style["fontOpacity"]=color.opacity;}
61269 break;default:}}
61270 if(!style["strokeColor"]&&style["fillColor"]){style["strokeColor"]=style["fillColor"];}
61271 var id=node.getAttribute("id");if(id&&style){style.id=id;}
61272 return style;},parseStyleMaps:function(nodes,options){for(var i=0,len=nodes.length;i<len;i++){var node=nodes[i];var pairs=this.getElementsByTagNameNS(node,"*","Pair");var id=node.getAttribute("id");for(var j=0,jlen=pairs.length;j<jlen;j++){var pair=pairs[j];var key=this.parseProperty(pair,"*","key");var styleUrl=this.parseProperty(pair,"*","styleUrl");if(styleUrl&&key=="normal"){this.styles[(options.styleBaseUrl||"")+"#"+id]=this.styles[(options.styleBaseUrl||"")+styleUrl];}
61273 if(styleUrl&&key=="highlight"){}}}},parseFeatures:function(nodes,options){var features=[];for(var i=0,len=nodes.length;i<len;i++){var featureNode=nodes[i];var feature=this.parseFeature.apply(this,[featureNode]);if(feature){if(this.extractStyles&&feature.attributes&&feature.attributes.styleUrl){feature.style=this.getStyle(feature.attributes.styleUrl,options);}
61274 if(this.extractStyles){var inlineStyleNode=this.getElementsByTagNameNS(featureNode,"*","Style")[0];if(inlineStyleNode){var inlineStyle=this.parseStyle(inlineStyleNode);if(inlineStyle){feature.style=OpenLayers.Util.extend(feature.style,inlineStyle);}}}
61275 if(this.extractTracks){var tracks=this.getElementsByTagNameNS(featureNode,this.namespaces.gx,"Track");if(tracks&&tracks.length>0){var track=tracks[0];var container={features:[],feature:feature};this.readNode(track,container);if(container.features.length>0){features.push.apply(features,container.features);}}}else{features.push(feature);}}else{throw"Bad Placemark: "+i;}}
61276 this.features=this.features.concat(features);},readers:{"kml":{"when":function(node,container){container.whens.push(OpenLayers.Date.parse(this.getChildValue(node)));},"_trackPointAttribute":function(node,container){var name=node.nodeName.split(":").pop();container.attributes[name].push(this.getChildValue(node));}},"gx":{"Track":function(node,container){var obj={whens:[],points:[],angles:[]};if(this.trackAttributes){var name;obj.attributes={};for(var i=0,ii=this.trackAttributes.length;i<ii;++i){name=this.trackAttributes[i];obj.attributes[name]=[];if(!(name in this.readers.kml)){this.readers.kml[name]=this.readers.kml._trackPointAttribute;}}}
61277 this.readChildNodes(node,obj);if(obj.whens.length!==obj.points.length){throw new Error("gx:Track with unequal number of when ("+obj.whens.length+") and gx:coord ("+obj.points.length+") elements.");}
61278 var hasAngles=obj.angles.length>0;if(hasAngles&&obj.whens.length!==obj.angles.length){throw new Error("gx:Track with unequal number of when ("+obj.whens.length+") and gx:angles ("+obj.angles.length+") elements.");}
61279 var feature,point,angles;for(var i=0,ii=obj.whens.length;i<ii;++i){feature=container.feature.clone();feature.fid=container.feature.fid||container.feature.id;point=obj.points[i];feature.geometry=point;if("z"in point){feature.attributes.altitude=point.z;}
61280 if(this.internalProjection&&this.externalProjection){feature.geometry.transform(this.externalProjection,this.internalProjection);}
61281 if(this.trackAttributes){for(var j=0,jj=this.trackAttributes.length;j<jj;++j){feature.attributes[name]=obj.attributes[this.trackAttributes[j]][i];}}
61282 feature.attributes.when=obj.whens[i];feature.attributes.trackId=container.feature.id;if(hasAngles){angles=obj.angles[i];feature.attributes.heading=parseFloat(angles[0]);feature.attributes.tilt=parseFloat(angles[1]);feature.attributes.roll=parseFloat(angles[2]);}
61283 container.features.push(feature);}},"coord":function(node,container){var str=this.getChildValue(node);var coords=str.replace(this.regExes.trimSpace,"").split(/\s+/);var point=new OpenLayers.Geometry.Point(coords[0],coords[1]);if(coords.length>2){point.z=parseFloat(coords[2]);}
61284 container.points.push(point);},"angles":function(node,container){var str=this.getChildValue(node);var parts=str.replace(this.regExes.trimSpace,"").split(/\s+/);container.angles.push(parts);}}},parseFeature:function(node){var order=["MultiGeometry","Polygon","LineString","Point"];var type,nodeList,geometry,parser;for(var i=0,len=order.length;i<len;++i){type=order[i];this.internalns=node.namespaceURI?node.namespaceURI:this.kmlns;nodeList=this.getElementsByTagNameNS(node,this.internalns,type);if(nodeList.length>0){var parser=this.parseGeometry[type.toLowerCase()];if(parser){geometry=parser.apply(this,[nodeList[0]]);if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}}else{OpenLayers.Console.error(OpenLayers.i18n("unsupportedGeometryType",{'geomType':type}));}
61285 break;}}
61286 var attributes;if(this.extractAttributes){attributes=this.parseAttributes(node);}
61287 var feature=new OpenLayers.Feature.Vector(geometry,attributes);var fid=node.getAttribute("id")||node.getAttribute("name");if(fid!=null){feature.fid=fid;}
61288 return feature;},getStyle:function(styleUrl,options){var styleBaseUrl=OpenLayers.Util.removeTail(styleUrl);var newOptions=OpenLayers.Util.extend({},options);newOptions.depth++;newOptions.styleBaseUrl=styleBaseUrl;if(!this.styles[styleUrl]&&!OpenLayers.String.startsWith(styleUrl,"#")&&newOptions.depth<=this.maxDepth&&!this.fetched[styleBaseUrl]){var data=this.fetchLink(styleBaseUrl);if(data){this.parseData(data,newOptions);}}
61289 var style=OpenLayers.Util.extend({},this.styles[styleUrl]);return style;},parseGeometry:{point:function(node){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"coordinates");var coords=[];if(nodeList.length>0){var coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.removeSpace,"");coords=coordString.split(",");}
61290 var point=null;if(coords.length>1){if(coords.length==2){coords[2]=null;}
61291 point=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{throw"Bad coordinate string: "+coordString;}
61292 return point;},linestring:function(node,ring){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"coordinates");var line=null;if(nodeList.length>0){var coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coordString=coordString.replace(this.regExes.trimComma,",");var pointList=coordString.split(this.regExes.splitSpace);var numPoints=pointList.length;var points=new Array(numPoints);var coords,numCoords;for(var i=0;i<numPoints;++i){coords=pointList[i].split(",");numCoords=coords.length;if(numCoords>1){if(coords.length==2){coords[2]=null;}
61293 points[i]=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{throw"Bad LineString point coordinates: "+
61294 pointList[i];}}
61295 if(numPoints){if(ring){line=new OpenLayers.Geometry.LinearRing(points);}else{line=new OpenLayers.Geometry.LineString(points);}}else{throw"Bad LineString coordinates: "+coordString;}}
61296 return line;},polygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.internalns,"LinearRing");var numRings=nodeList.length;var components=new Array(numRings);if(numRings>0){var ring;for(var i=0,len=nodeList.length;i<len;++i){ring=this.parseGeometry.linestring.apply(this,[nodeList[i],true]);if(ring){components[i]=ring;}else{throw"Bad LinearRing geometry: "+i;}}}
61297 return new OpenLayers.Geometry.Polygon(components);},multigeometry:function(node){var child,parser;var parts=[];var children=node.childNodes;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){var type=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var parser=this.parseGeometry[type.toLowerCase()];if(parser){parts.push(parser.apply(this,[child]));}}}
61298 return new OpenLayers.Geometry.Collection(parts);}},parseAttributes:function(node){var attributes={};var edNodes=node.getElementsByTagName("ExtendedData");if(edNodes.length){attributes=this.parseExtendedData(edNodes[0]);}
61299 var child,grandchildren,grandchild;var children=node.childNodes;for(var i=0,len=children.length;i<len;++i){child=children[i];if(child.nodeType==1){grandchildren=child.childNodes;if(grandchildren.length>=1&&grandchildren.length<=3){var grandchild;switch(grandchildren.length){case 1:grandchild=grandchildren[0];break;case 2:var c1=grandchildren[0];var c2=grandchildren[1];grandchild=(c1.nodeType==3||c1.nodeType==4)?c1:c2;break;case 3:default:grandchild=grandchildren[1];break;}
61300 if(grandchild.nodeType==3||grandchild.nodeType==4){var name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;var value=OpenLayers.Util.getXmlNodeValue(grandchild);if(value){value=value.replace(this.regExes.trimSpace,"");attributes[name]=value;}}}}}
61301 return attributes;},parseExtendedData:function(node){var attributes={};var i,len,data,key;var dataNodes=node.getElementsByTagName("Data");for(i=0,len=dataNodes.length;i<len;i++){data=dataNodes[i];key=data.getAttribute("name");var ed={};var valueNode=data.getElementsByTagName("value");if(valueNode.length){ed['value']=this.getChildValue(valueNode[0]);}
61302 var nameNode=data.getElementsByTagName("displayName");if(nameNode.length){ed['displayName']=this.getChildValue(nameNode[0]);}
61303 attributes[key]=ed;}
61304 var simpleDataNodes=node.getElementsByTagName("SimpleData");for(i=0,len=simpleDataNodes.length;i<len;i++){var ed={};data=simpleDataNodes[i];key=data.getAttribute("name");ed['value']=this.getChildValue(data);ed['displayName']=key;attributes[key]=ed;}
61305 return attributes;},parseProperty:function(xmlNode,namespace,tagName){var value;var nodeList=this.getElementsByTagNameNS(xmlNode,namespace,tagName);try{value=OpenLayers.Util.getXmlNodeValue(nodeList[0]);}catch(e){value=null;}
61306 return value;},write:function(features){if(!(features instanceof Array)){features=[features];}
61307 var kml=this.createElementNS(this.kmlns,"kml");var folder=this.createFolderXML();for(var i=0,len=features.length;i<len;++i){folder.appendChild(this.createPlacemarkXML(features[i]));}
61308 kml.appendChild(folder);return OpenLayers.Format.XML.prototype.write.apply(this,[kml]);},createFolderXML:function(){var folder=this.createElementNS(this.kmlns,"Folder");if(this.foldersName){var folderName=this.createElementNS(this.kmlns,"name");var folderNameText=this.createTextNode(this.foldersName);folderName.appendChild(folderNameText);folder.appendChild(folderName);}
61309 if(this.foldersDesc){var folderDesc=this.createElementNS(this.kmlns,"description");var folderDescText=this.createTextNode(this.foldersDesc);folderDesc.appendChild(folderDescText);folder.appendChild(folderDesc);}
61310 return folder;},createPlacemarkXML:function(feature){var placemarkName=this.createElementNS(this.kmlns,"name");var name=feature.style&&feature.style.label?feature.style.label:feature.attributes.name||feature.id;placemarkName.appendChild(this.createTextNode(name));var placemarkDesc=this.createElementNS(this.kmlns,"description");var desc=feature.attributes.description||this.placemarksDesc;placemarkDesc.appendChild(this.createTextNode(desc));var placemarkNode=this.createElementNS(this.kmlns,"Placemark");if(feature.fid!=null){placemarkNode.setAttribute("id",feature.fid);}
61311 placemarkNode.appendChild(placemarkName);placemarkNode.appendChild(placemarkDesc);var geometryNode=this.buildGeometryNode(feature.geometry);placemarkNode.appendChild(geometryNode);return placemarkNode;},buildGeometryNode:function(geometry){if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
61312 var className=geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);var builder=this.buildGeometry[type.toLowerCase()];var node=null;if(builder){node=builder.apply(this,[geometry]);}
61313 return node;},buildGeometry:{point:function(geometry){var kml=this.createElementNS(this.kmlns,"Point");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},multipoint:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},linestring:function(geometry){var kml=this.createElementNS(this.kmlns,"LineString");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},multilinestring:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},linearring:function(geometry){var kml=this.createElementNS(this.kmlns,"LinearRing");kml.appendChild(this.buildCoordinatesNode(geometry));return kml;},polygon:function(geometry){var kml=this.createElementNS(this.kmlns,"Polygon");var rings=geometry.components;var ringMember,ringGeom,type;for(var i=0,len=rings.length;i<len;++i){type=(i==0)?"outerBoundaryIs":"innerBoundaryIs";ringMember=this.createElementNS(this.kmlns,type);ringGeom=this.buildGeometry.linearring.apply(this,[rings[i]]);ringMember.appendChild(ringGeom);kml.appendChild(ringMember);}
61314 return kml;},multipolygon:function(geometry){return this.buildGeometry.collection.apply(this,[geometry]);},collection:function(geometry){var kml=this.createElementNS(this.kmlns,"MultiGeometry");var child;for(var i=0,len=geometry.components.length;i<len;++i){child=this.buildGeometryNode.apply(this,[geometry.components[i]]);if(child){kml.appendChild(child);}}
61315 return kml;}},buildCoordinatesNode:function(geometry){var coordinatesNode=this.createElementNS(this.kmlns,"coordinates");var path;var points=geometry.components;if(points){var point;var numPoints=points.length;var parts=new Array(numPoints);for(var i=0;i<numPoints;++i){point=points[i];parts[i]=point.x+","+point.y;}
61316 path=parts.join(" ");}else{path=geometry.x+","+geometry.y;}
61317 var txtNode=this.createTextNode(path);coordinatesNode.appendChild(txtNode);return coordinatesNode;},CLASS_NAME:"OpenLayers.Format.KML"});OpenLayers.Format.OSM=OpenLayers.Class(OpenLayers.Format.XML,{checkTags:false,interestingTagsExclude:null,areaTags:null,initialize:function(options){var layer_defaults={'interestingTagsExclude':['source','source_ref','source:ref','history','attribution','created_by'],'areaTags':['area','building','leisure','tourism','ruins','historic','landuse','military','natural','sport']};layer_defaults=OpenLayers.Util.extend(layer_defaults,options);var interesting={};for(var i=0;i<layer_defaults.interestingTagsExclude.length;i++){interesting[layer_defaults.interestingTagsExclude[i]]=true;}
61318 layer_defaults.interestingTagsExclude=interesting;var area={};for(var i=0;i<layer_defaults.areaTags.length;i++){area[layer_defaults.areaTags[i]]=true;}
61319 layer_defaults.areaTags=area;this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[layer_defaults]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
61320 var nodes=this.getNodes(doc);var ways=this.getWays(doc);var feat_list=new Array(ways.length);for(var i=0;i<ways.length;i++){var point_list=new Array(ways[i].nodes.length);var poly=this.isWayArea(ways[i])?1:0;for(var j=0;j<ways[i].nodes.length;j++){var node=nodes[ways[i].nodes[j]];var point=new OpenLayers.Geometry.Point(node.lon,node.lat);point.osm_id=parseInt(ways[i].nodes[j]);point_list[j]=point;node.used=true;}
61321 var geometry=null;if(poly){geometry=new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(point_list));}else{geometry=new OpenLayers.Geometry.LineString(point_list);}
61322 if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}
61323 var feat=new OpenLayers.Feature.Vector(geometry,ways[i].tags);feat.osm_id=parseInt(ways[i].id);feat.fid="way."+feat.osm_id;feat_list[i]=feat;}
61324 for(var node_id in nodes){var node=nodes[node_id];if(!node.used||this.checkTags){var tags=null;if(this.checkTags){var result=this.getTags(node.node,true);if(node.used&&!result[1]){continue;}
61325 tags=result[0];}else{tags=this.getTags(node.node);}
61326 var feat=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(node['lon'],node['lat']),tags);if(this.internalProjection&&this.externalProjection){feat.geometry.transform(this.externalProjection,this.internalProjection);}
61327 feat.osm_id=parseInt(node_id);feat.fid="node."+feat.osm_id;feat_list.push(feat);}
61328 node.node=null;}
61329 return feat_list;},getNodes:function(doc){var node_list=doc.getElementsByTagName("node");var nodes={};for(var i=0;i<node_list.length;i++){var node=node_list[i];var id=node.getAttribute("id");nodes[id]={'lat':node.getAttribute("lat"),'lon':node.getAttribute("lon"),'node':node};}
61330 return nodes;},getWays:function(doc){var way_list=doc.getElementsByTagName("way");var return_ways=[];for(var i=0;i<way_list.length;i++){var way=way_list[i];var way_object={id:way.getAttribute("id")};way_object.tags=this.getTags(way);var node_list=way.getElementsByTagName("nd");way_object.nodes=new Array(node_list.length);for(var j=0;j<node_list.length;j++){way_object.nodes[j]=node_list[j].getAttribute("ref");}
61331 return_ways.push(way_object);}
61332 return return_ways;},getTags:function(dom_node,interesting_tags){var tag_list=dom_node.getElementsByTagName("tag");var tags={};var interesting=false;for(var j=0;j<tag_list.length;j++){var key=tag_list[j].getAttribute("k");tags[key]=tag_list[j].getAttribute("v");if(interesting_tags){if(!this.interestingTagsExclude[key]){interesting=true;}}}
61333 return interesting_tags?[tags,interesting]:tags;},isWayArea:function(way){var poly_shaped=false;var poly_tags=false;if(way.nodes[0]==way.nodes[way.nodes.length-1]){poly_shaped=true;}
61334 if(this.checkTags){for(var key in way.tags){if(this.areaTags[key]){poly_tags=true;break;}}}
61335 return poly_shaped&&(this.checkTags?poly_tags:true);},write:function(features){if(!(features instanceof Array)){features=[features];}
61336 this.osm_id=1;this.created_nodes={};var root_node=this.createElementNS(null,"osm");root_node.setAttribute("version","0.5");root_node.setAttribute("generator","OpenLayers "+OpenLayers.VERSION_NUMBER);for(var i=features.length-1;i>=0;i--){var nodes=this.createFeatureNodes(features[i]);for(var j=0;j<nodes.length;j++){root_node.appendChild(nodes[j]);}}
61337 return OpenLayers.Format.XML.prototype.write.apply(this,[root_node]);},createFeatureNodes:function(feature){var nodes=[];var className=feature.geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);type=type.toLowerCase();var builder=this.createXML[type];if(builder){nodes=builder.apply(this,[feature]);}
61338 return nodes;},createXML:{'point':function(point){var id=null;var geometry=point.geometry?point.geometry:point;var already_exists=false;if(point.osm_id){id=point.osm_id;if(this.created_nodes[id]){already_exists=true;}}else{id=-this.osm_id;this.osm_id++;}
61339 if(already_exists){node=this.created_nodes[id];}else{var node=this.createElementNS(null,"node");}
61340 this.created_nodes[id]=node;node.setAttribute("id",id);node.setAttribute("lon",geometry.x);node.setAttribute("lat",geometry.y);if(point.attributes){this.serializeTags(point,node);}
61341 this.setState(point,node);return already_exists?[]:[node];},linestring:function(feature){var nodes=[];var geometry=feature.geometry;if(feature.osm_id){id=feature.osm_id;}else{id=-this.osm_id;this.osm_id++;}
61342 var way=this.createElementNS(null,"way");way.setAttribute("id",id);for(var i=0;i<geometry.components.length;i++){var node=this.createXML['point'].apply(this,[geometry.components[i]]);if(node.length){node=node[0];var node_ref=node.getAttribute("id");nodes.push(node);}else{node_ref=geometry.components[i].osm_id;node=this.created_nodes[node_ref];}
61343 this.setState(feature,node);var nd_dom=this.createElementNS(null,"nd");nd_dom.setAttribute("ref",node_ref);way.appendChild(nd_dom);}
61344 this.serializeTags(feature,way);nodes.push(way);return nodes;},polygon:function(feature){var attrs=OpenLayers.Util.extend({'area':'yes'},feature.attributes);var feat=new OpenLayers.Feature.Vector(feature.geometry.components[0],attrs);feat.osm_id=feature.osm_id;return this.createXML['linestring'].apply(this,[feat]);}},serializeTags:function(feature,node){for(var key in feature.attributes){var tag=this.createElementNS(null,"tag");tag.setAttribute("k",key);tag.setAttribute("v",feature.attributes[key]);node.appendChild(tag);}},setState:function(feature,node){if(feature.state){var state=null;switch(feature.state){case OpenLayers.State.UPDATE:state="modify";case OpenLayers.State.DELETE:state="delete";}
61345 if(state){node.setAttribute("action",state);}}},CLASS_NAME:"OpenLayers.Format.OSM"});OpenLayers.Geometry.MultiPolygon=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.Polygon"],initialize:function(components){OpenLayers.Geometry.Collection.prototype.initialize.apply(this,arguments);},CLASS_NAME:"OpenLayers.Geometry.MultiPolygon"});OpenLayers.Handler.Polygon=OpenLayers.Class(OpenLayers.Handler.Path,{polygon:null,initialize:function(control,callbacks,options){OpenLayers.Handler.Path.prototype.initialize.apply(this,arguments);},createFeature:function(pixel){var lonlat=this.control.map.getLonLatFromPixel(pixel);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon,lonlat.lat));this.line=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LinearRing([this.point.geometry]));this.polygon=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([this.line.geometry]));this.callback("create",[this.point.geometry,this.getSketch()]);this.point.geometry.clearBounds();this.layer.addFeatures([this.polygon,this.point],{silent:true});},destroyFeature:function(){OpenLayers.Handler.Path.prototype.destroyFeature.apply(this);this.polygon=null;},drawFeature:function(){this.layer.drawFeature(this.polygon,this.style);this.layer.drawFeature(this.point,this.style);},getSketch:function(){return this.polygon;},getGeometry:function(){var geometry=this.polygon&&this.polygon.geometry;if(geometry&&this.multi){geometry=new OpenLayers.Geometry.MultiPolygon([geometry]);}
61346 return geometry;},dblclick:function(evt){if(!this.freehandMode(evt)){var index=this.line.geometry.components.length-2;this.line.geometry.removeComponent(this.line.geometry.components[index]);this.removePoint();this.finalize();}
61347 return false;},CLASS_NAME:"OpenLayers.Handler.Polygon"});OpenLayers.Control.EditingToolbar=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(layer,options){OpenLayers.Control.Panel.prototype.initialize.apply(this,[options]);this.addControls([new OpenLayers.Control.Navigation()]);var controls=[new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Point,{'displayClass':'olControlDrawFeaturePoint'}),new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Path,{'displayClass':'olControlDrawFeaturePath'}),new OpenLayers.Control.DrawFeature(layer,OpenLayers.Handler.Polygon,{'displayClass':'olControlDrawFeaturePolygon'})];this.addControls(controls);},draw:function(){var div=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);this.activateControl(this.controls[0]);return div;},CLASS_NAME:"OpenLayers.Control.EditingToolbar"});OpenLayers.Control.SLDSelect=OpenLayers.Class(OpenLayers.Control,{EVENT_TYPES:["selected"],clearOnDeactivate:false,layers:null,callbacks:null,selectionSymbolizer:{'Polygon':{fillColor:'#FF0000',stroke:false},'Line':{strokeColor:'#FF0000',strokeWidth:2},'Point':{graphicName:'square',fillColor:'#FF0000',pointRadius:5}},layerOptions:null,handlerOptions:null,sketchStyle:null,wfsCache:{},layerCache:{},initialize:function(handler,options){this.EVENT_TYPES=OpenLayers.Control.SLDSelect.prototype.EVENT_TYPES.concat(OpenLayers.Control.prototype.EVENT_TYPES);OpenLayers.Control.prototype.initialize.apply(this,[options]);this.callbacks=OpenLayers.Util.extend({done:this.select,click:this.select},this.callbacks);this.handlerOptions=this.handlerOptions||{};this.layerOptions=OpenLayers.Util.applyDefaults(this.layerOptions,{displayInLayerSwitcher:false});if(this.sketchStyle){this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{styleMap:new OpenLayers.StyleMap({"default":this.sketchStyle})});}
61348 this.handler=new handler(this,this.callbacks,this.handlerOptions);},destroy:function(){for(var key in this.layerCache){delete this.layerCache[key];}
61349 for(var key in this.wfsCache){delete this.wfsCache[key];}
61350 OpenLayers.Control.prototype.destroy.apply(this,arguments);},coupleLayerVisiblity:function(evt){this.setVisibility(evt.object.getVisibility());},createSelectionLayer:function(source){var selectionLayer;if(!this.layerCache[source.id]){selectionLayer=new OpenLayers.Layer.WMS.Post(source.name,source.url,source.params,OpenLayers.Util.applyDefaults(this.layerOptions,source.getOptions()));this.layerCache[source.id]=selectionLayer;if(this.layerOptions.displayInLayerSwitcher===false){source.events.on({"visibilitychanged":this.coupleLayerVisiblity,scope:selectionLayer});}
61351 this.map.addLayer(selectionLayer);}else{selectionLayer=this.layerCache[source.id];}
61352 return selectionLayer;},createSLD:function(layer,filters,geometryAttributes){var sld={version:"1.0.0",namedLayers:{}};var layerNames=[layer.params.LAYERS].join(",").split(",");for(var i=0,len=layerNames.length;i<len;i++){var name=layerNames[i];sld.namedLayers[name]={name:name,userStyles:[]};var symbolizer=this.selectionSymbolizer;var geometryAttribute=geometryAttributes[i];if(geometryAttribute.type.indexOf('Polygon')>=0){symbolizer={Polygon:this.selectionSymbolizer['Polygon']};}else if(geometryAttribute.type.indexOf('LineString')>=0){symbolizer={Line:this.selectionSymbolizer['Line']};}else if(geometryAttribute.type.indexOf('Point')>=0){symbolizer={Point:this.selectionSymbolizer['Point']};}
61353 var filter=filters[i];sld.namedLayers[name].userStyles.push({name:'default',rules:[new OpenLayers.Rule({symbolizer:symbolizer,filter:filter,maxScaleDenominator:layer.options.minScale})]});}
61354 return new OpenLayers.Format.SLD().write(sld);},parseDescribeLayer:function(request){var format=new OpenLayers.Format.WMSDescribeLayer();var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
61355 var describeLayer=format.read(doc);var typeNames=[];var url=null;for(var i=0,len=describeLayer.length;i<len;i++){if(describeLayer[i].owsType=="WFS"){typeNames.push(describeLayer[i].typeName);url=describeLayer[i].owsURL;}}
61356 var options={url:url,params:{SERVICE:"WFS",TYPENAME:typeNames.toString(),REQUEST:"DescribeFeatureType",VERSION:"1.0.0"},callback:function(request){var format=new OpenLayers.Format.WFSDescribeFeatureType();var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
61357 var describeFeatureType=format.read(doc);this.control.wfsCache[this.layer.id]=describeFeatureType;this.control._queue&&this.control.applySelection();},scope:this};OpenLayers.Request.GET(options);},getGeometryAttributes:function(layer){var result=[];var cache=this.wfsCache[layer.id];for(var i=0,len=cache.featureTypes.length;i<len;i++){var typeName=cache.featureTypes[i];var properties=typeName.properties;for(var j=0,lenj=properties.length;j<lenj;j++){var property=properties[j];var type=property.type;if((type.indexOf('LineString')>=0)||(type.indexOf('GeometryAssociationType')>=0)||(type.indexOf('GeometryPropertyType')>=0)||(type.indexOf('Point')>=0)||(type.indexOf('Polygon')>=0)){result.push(property);}}}
61358 return result;},activate:function(){var activated=OpenLayers.Control.prototype.activate.call(this);if(activated){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer&&!this.wfsCache[layer.id]){var options={url:layer.url,params:{SERVICE:"WMS",VERSION:layer.params.VERSION,LAYERS:layer.params.LAYERS,REQUEST:"DescribeLayer"},callback:this.parseDescribeLayer,scope:{layer:layer,control:this}};OpenLayers.Request.GET(options);}}}
61359 return activated;},deactivate:function(){var deactivated=OpenLayers.Control.prototype.deactivate.call(this);if(deactivated){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];if(layer&&this.clearOnDeactivate===true){var layerCache=this.layerCache;var selectionLayer=layerCache[layer.id];if(selectionLayer){layer.events.un({"visibilitychanged":this.coupleLayerVisiblity,scope:selectionLayer});selectionLayer.destroy();delete layerCache[layer.id];}}}}
61360 return deactivated;},setLayers:function(layers){if(this.active){this.deactivate();this.layers=layers;this.activate();}else{this.layers=layers;}},createFilter:function(geometryAttribute,geometry){var filter=null;if(this.handler instanceof OpenLayers.Handler.RegularPolygon){if(this.handler.irregular===true){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,property:geometryAttribute.name,value:geometry.getBounds()});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}}else if(this.handler instanceof OpenLayers.Handler.Polygon){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}else if(this.handler instanceof OpenLayers.Handler.Path){if(geometryAttribute.type.indexOf('Point')>=0){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN,property:geometryAttribute.name,distance:this.map.getExtent().getWidth()*0.01,distanceUnits:this.map.getUnits(),value:geometry});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}}else if(this.handler instanceof OpenLayers.Handler.Click){if(geometryAttribute.type.indexOf('Polygon')>=0){filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:geometryAttribute.name,value:geometry});}else{filter=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN,property:geometryAttribute.name,distance:this.map.getExtent().getWidth()*0.01,distanceUnits:this.map.getUnits(),value:geometry});}}
61361 return filter;},select:function(geometry){this._queue=function(){for(var i=0,len=this.layers.length;i<len;i++){var layer=this.layers[i];var geometryAttributes=this.getGeometryAttributes(layer);var filters=[];for(var j=0,lenj=geometryAttributes.length;j<lenj;j++){var geometryAttribute=geometryAttributes[j];if(geometryAttribute!==null){if(!(geometry instanceof OpenLayers.Geometry)){var point=this.map.getLonLatFromPixel(geometry.xy);geometry=new OpenLayers.Geometry.Point(point.lon,point.lat);}
61362 var filter=this.createFilter(geometryAttribute,geometry);if(filter!==null){filters.push(filter);}}}
61363 var selectionLayer=this.createSelectionLayer(layer);var sld=this.createSLD(layer,filters,geometryAttributes);this.events.triggerEvent("selected",{layer:layer,filters:filters});selectionLayer.mergeNewParams({SLD_BODY:sld});delete this._queue;}};this.applySelection();},applySelection:function(){var canApply=true;for(var i=0,len=this.layers.length;i<len;i++){if(!this.wfsCache[this.layers[i].id]){canApply=false;break;}}
61364 canApply&&this._queue.call(this);},CLASS_NAME:"OpenLayers.Control.SLDSelect"});OpenLayers.Format.ArcXML=OpenLayers.Class(OpenLayers.Format.XML,{fontStyleKeys:['antialiasing','blockout','font','fontcolor','fontsize','fontstyle','glowing','interval','outline','printmode','shadow','transparency'],request:null,response:null,initialize:function(options){this.request=new OpenLayers.Format.ArcXML.Request();this.response=new OpenLayers.Format.ArcXML.Response();if(options){if(options.requesttype=="feature"){this.request.get_image=null;var qry=this.request.get_feature.query;this.addCoordSys(qry.featurecoordsys,options.featureCoordSys);this.addCoordSys(qry.filtercoordsys,options.filterCoordSys);if(options.polygon){qry.isspatial=true;qry.spatialfilter.polygon=options.polygon;}else if(options.envelope){qry.isspatial=true;qry.spatialfilter.envelope={minx:0,miny:0,maxx:0,maxy:0};this.parseEnvelope(qry.spatialfilter.envelope,options.envelope);}}else if(options.requesttype=="image"){this.request.get_feature=null;var props=this.request.get_image.properties;this.parseEnvelope(props.envelope,options.envelope);this.addLayers(props.layerlist,options.layers);this.addImageSize(props.imagesize,options.tileSize);this.addCoordSys(props.featurecoordsys,options.featureCoordSys);this.addCoordSys(props.filtercoordsys,options.filterCoordSys);}else{this.request=null;}}
61365 OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},parseEnvelope:function(env,arr){if(arr&&arr.length==4){env.minx=arr[0];env.miny=arr[1];env.maxx=arr[2];env.maxy=arr[3];}},addLayers:function(ll,lyrs){for(var lind=0,len=lyrs.length;lind<len;lind++){ll.push(lyrs[lind]);}},addImageSize:function(imsize,olsize){if(olsize!==null){imsize.width=olsize.w;imsize.height=olsize.h;imsize.printwidth=olsize.w;imsize.printheight=olsize.h;}},addCoordSys:function(featOrFilt,fsys){if(typeof fsys=="string"){featOrFilt.id=parseInt(fsys);featOrFilt.string=fsys;}
61366 else if(typeof fsys=="object"&&fsys.proj!==null){featOrFilt.id=fsys.proj.srsProjNumber;featOrFilt.string=fsys.proj.srsCode;}else{featOrFilt=fsys;}},iserror:function(data){var ret=null;if(!data){ret=(this.response.error!=='');}else{data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);var errorNodes=data.documentElement.getElementsByTagName("ERROR");ret=(errorNodes!==null&&errorNodes.length>0);}
61367 return ret;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61368 var arcNode=null;if(data&&data.documentElement){if(data.documentElement.nodeName=="ARCXML"){arcNode=data.documentElement;}else{arcNode=data.documentElement.getElementsByTagName("ARCXML")[0];}}
61369 if(!arcNode||arcNode.firstChild.nodeName==='parsererror'){var error,source;try{error=data.firstChild.nodeValue;source=data.firstChild.childNodes[1].firstChild.nodeValue;}catch(err){}
61370 throw{message:"Error parsing the ArcXML request",error:error,source:source};}
61371 var response=this.parseResponse(arcNode);return response;},write:function(request){if(!request){request=this.request;}
61372 var root=this.createElementNS("","ARCXML");root.setAttribute("version","1.1");var reqElem=this.createElementNS("","REQUEST");if(request.get_image!=null){var getElem=this.createElementNS("","GET_IMAGE");reqElem.appendChild(getElem);var propElem=this.createElementNS("","PROPERTIES");getElem.appendChild(propElem);var props=request.get_image.properties;if(props.featurecoordsys!=null){var feat=this.createElementNS("","FEATURECOORDSYS");propElem.appendChild(feat);if(props.featurecoordsys.id===0){feat.setAttribute("string",props.featurecoordsys['string']);}
61373 else{feat.setAttribute("id",props.featurecoordsys.id);}}
61374 if(props.filtercoordsys!=null){var filt=this.createElementNS("","FILTERCOORDSYS");propElem.appendChild(filt);if(props.filtercoordsys.id===0){filt.setAttribute("string",props.filtercoordsys.string);}
61375 else{filt.setAttribute("id",props.filtercoordsys.id);}}
61376 if(props.envelope!=null){var env=this.createElementNS("","ENVELOPE");propElem.appendChild(env);env.setAttribute("minx",props.envelope.minx);env.setAttribute("miny",props.envelope.miny);env.setAttribute("maxx",props.envelope.maxx);env.setAttribute("maxy",props.envelope.maxy);}
61377 var imagesz=this.createElementNS("","IMAGESIZE");propElem.appendChild(imagesz);imagesz.setAttribute("height",props.imagesize.height);imagesz.setAttribute("width",props.imagesize.width);if(props.imagesize.height!=props.imagesize.printheight||props.imagesize.width!=props.imagesize.printwidth){imagesz.setAttribute("printheight",props.imagesize.printheight);imagesz.setArrtibute("printwidth",props.imagesize.printwidth);}
61378 if(props.background!=null){var backgrnd=this.createElementNS("","BACKGROUND");propElem.appendChild(backgrnd);backgrnd.setAttribute("color",props.background.color.r+","+
61379 props.background.color.g+","+
61380 props.background.color.b);if(props.background.transcolor!==null){backgrnd.setAttribute("transcolor",props.background.transcolor.r+","+
61381 props.background.transcolor.g+","+
61382 props.background.transcolor.b);}}
61383 if(props.layerlist!=null&&props.layerlist.length>0){var layerlst=this.createElementNS("","LAYERLIST");propElem.appendChild(layerlst);for(var ld=0;ld<props.layerlist.length;ld++){var ldef=this.createElementNS("","LAYERDEF");layerlst.appendChild(ldef);ldef.setAttribute("id",props.layerlist[ld].id);ldef.setAttribute("visible",props.layerlist[ld].visible);if(typeof props.layerlist[ld].query=="object"){var query=props.layerlist[ld].query;if(query.where.length<0){continue;}
61384 var queryElem=null;if(typeof query.spatialfilter=="boolean"&&query.spatialfilter){queryElem=this.createElementNS("","SPATIALQUERY");}
61385 else{queryElem=this.createElementNS("","QUERY");}
61386 queryElem.setAttribute("where",query.where);if(typeof query.accuracy=="number"&&query.accuracy>0){queryElem.setAttribute("accuracy",query.accuracy);}
61387 if(typeof query.featurelimit=="number"&&query.featurelimit<2000){queryElem.setAttribute("featurelimit",query.featurelimit);}
61388 if(typeof query.subfields=="string"&&query.subfields!="#ALL#"){queryElem.setAttribute("subfields",query.subfields);}
61389 if(typeof query.joinexpression=="string"&&query.joinexpression.length>0){queryElem.setAttribute("joinexpression",query.joinexpression);}
61390 if(typeof query.jointables=="string"&&query.jointables.length>0){queryElem.setAttribute("jointables",query.jointables);}
61391 ldef.appendChild(queryElem);}
61392 if(typeof props.layerlist[ld].renderer=="object"){this.addRenderer(ldef,props.layerlist[ld].renderer);}}}}else if(request.get_feature!=null){var getElem=this.createElementNS("","GET_FEATURES");getElem.setAttribute("outputmode","newxml");getElem.setAttribute("checkesc","true");if(request.get_feature.geometry){getElem.setAttribute("geometry",request.get_feature.geometry);}
61393 else{getElem.setAttribute("geometry","false");}
61394 if(request.get_feature.compact){getElem.setAttribute("compact",request.get_feature.compact);}
61395 if(request.get_feature.featurelimit=="number"){getElem.setAttribute("featurelimit",request.get_feature.featurelimit);}
61396 getElem.setAttribute("globalenvelope","true");reqElem.appendChild(getElem);if(request.get_feature.layer!=null&&request.get_feature.layer.length>0){var lyrElem=this.createElementNS("","LAYER");lyrElem.setAttribute("id",request.get_feature.layer);getElem.appendChild(lyrElem);}
61397 var fquery=request.get_feature.query;if(fquery!=null){var qElem=null;if(fquery.isspatial){qElem=this.createElementNS("","SPATIALQUERY");}else{qElem=this.createElementNS("","QUERY");}
61398 getElem.appendChild(qElem);if(typeof fquery.accuracy=="number"){qElem.setAttribute("accuracy",fquery.accuracy);}
61399 if(fquery.featurecoordsys!=null){var fcsElem1=this.createElementNS("","FEATURECOORDSYS");if(fquery.featurecoordsys.id==0){fcsElem1.setAttribute("string",fquery.featurecoordsys.string);}else{fcsElem1.setAttribute("id",fquery.featurecoordsys.id);}
61400 qElem.appendChild(fcsElem1);}
61401 if(fquery.filtercoordsys!=null){var fcsElem2=this.createElementNS("","FILTERCOORDSYS");if(fquery.filtercoordsys.id===0){fcsElem2.setAttribute("string",fquery.filtercoordsys.string);}else{fcsElem2.setAttribute("id",fquery.filtercoordsys.id);}
61402 qElem.appendChild(fcsElem2);}
61403 if(fquery.buffer>0){var bufElem=this.createElementNS("","BUFFER");bufElem.setAttribute("distance",fquery.buffer);qElem.appendChild(bufElem);}
61404 if(fquery.isspatial){var spfElem=this.createElementNS("","SPATIALFILTER");spfElem.setAttribute("relation",fquery.spatialfilter.relation);qElem.appendChild(spfElem);if(fquery.spatialfilter.envelope){var envElem=this.createElementNS("","ENVELOPE");envElem.setAttribute("minx",fquery.spatialfilter.envelope.minx);envElem.setAttribute("miny",fquery.spatialfilter.envelope.miny);envElem.setAttribute("maxx",fquery.spatialfilter.envelope.maxx);envElem.setAttribute("maxy",fquery.spatialfilter.envelope.maxy);spfElem.appendChild(envElem);}else if(typeof fquery.spatialfilter.polygon=="object"){spfElem.appendChild(this.writePolygonGeometry(fquery.spatialfilter.polygon));}}
61405 if(fquery.where!=null&&fquery.where.length>0){qElem.setAttribute("where",fquery.where);}}}
61406 root.appendChild(reqElem);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},addGroupRenderer:function(ldef,toprenderer){var topRelem=this.createElementNS("","GROUPRENDERER");ldef.appendChild(topRelem);for(var rind=0;rind<toprenderer.length;rind++){var renderer=toprenderer[rind];this.addRenderer(topRelem,renderer);}},addRenderer:function(topRelem,renderer){if(renderer instanceof Array){this.addGroupRenderer(topRelem,renderer);}else{var renderElem=this.createElementNS("",renderer.type.toUpperCase()+"RENDERER");topRelem.appendChild(renderElem);if(renderElem.tagName=="VALUEMAPRENDERER"){this.addValueMapRenderer(renderElem,renderer);}else if(renderElem.tagName=="VALUEMAPLABELRENDERER"){this.addValueMapLabelRenderer(renderElem,renderer);}else if(renderElem.tagName=="SIMPLELABELRENDERER"){this.addSimpleLabelRenderer(renderElem,renderer);}else if(renderElem.tagName=="SCALEDEPENDENTRENDERER"){this.addScaleDependentRenderer(renderElem,renderer);}}},addScaleDependentRenderer:function(renderElem,renderer){if(typeof renderer.lower=="string"||typeof renderer.lower=="number"){renderElem.setAttribute("lower",renderer.lower);}
61407 if(typeof renderer.upper=="string"||typeof renderer.upper=="number"){renderElem.setAttribute("upper",renderer.upper);}
61408 this.addRenderer(renderElem,renderer.renderer);},addValueMapLabelRenderer:function(renderElem,renderer){renderElem.setAttribute("lookupfield",renderer.lookupfield);renderElem.setAttribute("labelfield",renderer.labelfield);if(typeof renderer.exacts=="object"){for(var ext=0,extlen=renderer.exacts.length;ext<extlen;ext++){var exact=renderer.exacts[ext];var eelem=this.createElementNS("","EXACT");if(typeof exact.value=="string"){eelem.setAttribute("value",exact.value);}
61409 if(typeof exact.label=="string"){eelem.setAttribute("label",exact.label);}
61410 if(typeof exact.method=="string"){eelem.setAttribute("method",exact.method);}
61411 renderElem.appendChild(eelem);if(typeof exact.symbol=="object"){var selem=null;if(exact.symbol.type=="text"){selem=this.createElementNS("","TEXTSYMBOL");}
61412 if(selem!=null){var keys=this.fontStyleKeys;for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(exact.symbol[key]){selem.setAttribute(key,exact.symbol[key]);}}
61413 eelem.appendChild(selem);}}}}},addValueMapRenderer:function(renderElem,renderer){renderElem.setAttribute("lookupfield",renderer.lookupfield);if(typeof renderer.ranges=="object"){for(var rng=0,rnglen=renderer.ranges.length;rng<rnglen;rng++){var range=renderer.ranges[rng];var relem=this.createElementNS("","RANGE");relem.setAttribute("lower",range.lower);relem.setAttribute("upper",range.upper);renderElem.appendChild(relem);if(typeof range.symbol=="object"){var selem=null;if(range.symbol.type=="simplepolygon"){selem=this.createElementNS("","SIMPLEPOLYGONSYMBOL");}
61414 if(selem!=null){if(typeof range.symbol.boundarycolor=="string"){selem.setAttribute("boundarycolor",range.symbol.boundarycolor);}
61415 if(typeof range.symbol.fillcolor=="string"){selem.setAttribute("fillcolor",range.symbol.fillcolor);}
61416 if(typeof range.symbol.filltransparency=="number"){selem.setAttribute("filltransparency",range.symbol.filltransparency);}
61417 relem.appendChild(selem);}}}}else if(typeof renderer.exacts=="object"){for(var ext=0,extlen=renderer.exacts.length;ext<extlen;ext++){var exact=renderer.exacts[ext];var eelem=this.createElementNS("","EXACT");if(typeof exact.value=="string"){eelem.setAttribute("value",exact.value);}
61418 if(typeof exact.label=="string"){eelem.setAttribute("label",exact.label);}
61419 if(typeof exact.method=="string"){eelem.setAttribute("method",exact.method);}
61420 renderElem.appendChild(eelem);if(typeof exact.symbol=="object"){var selem=null;if(exact.symbol.type=="simplemarker"){selem=this.createElementNS("","SIMPLEMARKERSYMBOL");}
61421 if(selem!=null){if(typeof exact.symbol.antialiasing=="string"){selem.setAttribute("antialiasing",exact.symbol.antialiasing);}
61422 if(typeof exact.symbol.color=="string"){selem.setAttribute("color",exact.symbol.color);}
61423 if(typeof exact.symbol.outline=="string"){selem.setAttribute("outline",exact.symbol.outline);}
61424 if(typeof exact.symbol.overlap=="string"){selem.setAttribute("overlap",exact.symbol.overlap);}
61425 if(typeof exact.symbol.shadow=="string"){selem.setAttribute("shadow",exact.symbol.shadow);}
61426 if(typeof exact.symbol.transparency=="number"){selem.setAttribute("transparency",exact.symbol.transparency);}
61427 if(typeof exact.symbol.usecentroid=="string"){selem.setAttribute("usecentroid",exact.symbol.usecentroid);}
61428 if(typeof exact.symbol.width=="number"){selem.setAttribute("width",exact.symbol.width);}
61429 eelem.appendChild(selem);}}}}},addSimpleLabelRenderer:function(renderElem,renderer){renderElem.setAttribute("field",renderer.field);var keys=['featureweight','howmanylabels','labelbufferratio','labelpriorities','labelweight','linelabelposition','rotationalangles'];for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(renderer[key]){renderElem.setAttribute(key,renderer[key]);}}
61430 if(renderer.symbol.type=="text"){var symbol=renderer.symbol;var selem=this.createElementNS("","TEXTSYMBOL");renderElem.appendChild(selem);var keys=this.fontStyleKeys;for(var i=0,len=keys.length;i<len;i++){var key=keys[i];if(symbol[key]){selem.setAttribute(key,renderer[key]);}}}},writePolygonGeometry:function(polygon){if(!(polygon instanceof OpenLayers.Geometry.Polygon)){throw{message:'Cannot write polygon geometry to ArcXML with an '+
61431 polygon.CLASS_NAME+' object.',geometry:polygon};}
61432 var polyElem=this.createElementNS("","POLYGON");for(var ln=0,lnlen=polygon.components.length;ln<lnlen;ln++){var ring=polygon.components[ln];var ringElem=this.createElementNS("","RING");for(var rn=0,rnlen=ring.components.length;rn<rnlen;rn++){var point=ring.components[rn];var pointElem=this.createElementNS("","POINT");pointElem.setAttribute("x",point.x);pointElem.setAttribute("y",point.y);ringElem.appendChild(pointElem);}
61433 polyElem.appendChild(ringElem);}
61434 return polyElem;},parseResponse:function(data){if(typeof data=="string"){var newData=new OpenLayers.Format.XML();data=newData.read(data);}
61435 var response=new OpenLayers.Format.ArcXML.Response();var errorNode=data.getElementsByTagName("ERROR");if(errorNode!=null&&errorNode.length>0){response.error=this.getChildValue(errorNode,"Unknown error.");}else{var responseNode=data.getElementsByTagName("RESPONSE");if(responseNode==null||responseNode.length==0){response.error="No RESPONSE tag found in ArcXML response.";return response;}
61436 var rtype=responseNode[0].firstChild.nodeName;if(rtype=="#text"){rtype=responseNode[0].firstChild.nextSibling.nodeName;}
61437 if(rtype=="IMAGE"){var envelopeNode=data.getElementsByTagName("ENVELOPE");var outputNode=data.getElementsByTagName("OUTPUT");if(envelopeNode==null||envelopeNode.length==0){response.error="No ENVELOPE tag found in ArcXML response.";}else if(outputNode==null||outputNode.length==0){response.error="No OUTPUT tag found in ArcXML response.";}else{var envAttr=this.parseAttributes(envelopeNode[0]);var outputAttr=this.parseAttributes(outputNode[0]);if(typeof outputAttr.type=="string"){response.image={envelope:envAttr,output:{type:outputAttr.type,data:this.getChildValue(outputNode[0])}};}else{response.image={envelope:envAttr,output:outputAttr};}}}else if(rtype=="FEATURES"){var features=responseNode[0].getElementsByTagName("FEATURES");var featureCount=features[0].getElementsByTagName("FEATURECOUNT");response.features.featurecount=featureCount[0].getAttribute("count");if(response.features.featurecount>0){var envelope=features[0].getElementsByTagName("ENVELOPE");response.features.envelope=this.parseAttributes(envelope[0],typeof(0));var featureList=features[0].getElementsByTagName("FEATURE");for(var fn=0;fn<featureList.length;fn++){var feature=new OpenLayers.Feature.Vector();var fields=featureList[fn].getElementsByTagName("FIELD");for(var fdn=0;fdn<fields.length;fdn++){var fieldName=fields[fdn].getAttribute("name");var fieldValue=fields[fdn].getAttribute("value");feature.attributes[fieldName]=fieldValue;}
61438 var geom=featureList[fn].getElementsByTagName("POLYGON");if(geom.length>0){var ring=geom[0].getElementsByTagName("RING");var polys=[];for(var rn=0;rn<ring.length;rn++){var linearRings=[];linearRings.push(this.parsePointGeometry(ring[rn]));var holes=ring[rn].getElementsByTagName("HOLE");for(var hn=0;hn<holes.length;hn++){linearRings.push(this.parsePointGeometry(holes[hn]));}
61439 holes=null;polys.push(new OpenLayers.Geometry.Polygon(linearRings));linearRings=null;}
61440 ring=null;if(polys.length==1){feature.geometry=polys[0];}else
61441 {feature.geometry=new OpenLayers.Geometry.MultiPolygon(polys);}}
61442 response.features.feature.push(feature);}}}else{response.error="Unidentified response type.";}}
61443 return response;},parseAttributes:function(node,type){var attributes={};for(var attr=0;attr<node.attributes.length;attr++){if(type=="number"){attributes[node.attributes[attr].nodeName]=parseFloat(node.attributes[attr].nodeValue);}else{attributes[node.attributes[attr].nodeName]=node.attributes[attr].nodeValue;}}
61444 return attributes;},parsePointGeometry:function(node){var ringPoints=[];var coords=node.getElementsByTagName("COORDS");if(coords.length>0){var coordArr=this.getChildValue(coords[0]);coordArr=coordArr.split(/;/);for(var cn=0;cn<coordArr.length;cn++){var coordItems=coordArr[cn].split(/ /);ringPoints.push(new OpenLayers.Geometry.Point(parseFloat(coordItems[0]),parseFloat(coordItems[1])));}
61445 coords=null;}else{var point=node.getElementsByTagName("POINT");if(point.length>0){for(var pn=0;pn<point.length;pn++){ringPoints.push(new OpenLayers.Geometry.Point(parseFloat(point[pn].getAttribute("x")),parseFloat(point[pn].getAttribute("y"))));}}
61446 point=null;}
61447 return new OpenLayers.Geometry.LinearRing(ringPoints);},CLASS_NAME:"OpenLayers.Format.ArcXML"});OpenLayers.Format.ArcXML.Request=OpenLayers.Class({initialize:function(params){var defaults={get_image:{properties:{background:null,draw:true,envelope:{minx:0,miny:0,maxx:0,maxy:0},featurecoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},filtercoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},imagesize:{height:0,width:0,dpi:96,printheight:0,printwidth:0,scalesymbols:false},layerlist:[],output:{baseurl:"",legendbaseurl:"",legendname:"",legendpath:"",legendurl:"",name:"",path:"",type:"jpg",url:""}}},get_feature:{layer:"",query:{isspatial:false,featurecoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},filtercoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},buffer:0,where:"",spatialfilter:{relation:"envelope_intersection",envelope:null}}},environment:{separators:{cs:" ",ts:";"}},layer:[],workspaces:[]};return OpenLayers.Util.extend(this,defaults);},CLASS_NAME:"OpenLayers.Format.ArcXML.Request"});OpenLayers.Format.ArcXML.Response=OpenLayers.Class({initialize:function(params){var defaults={image:{envelope:null,output:''},features:{featurecount:0,envelope:null,feature:[]},error:''};return OpenLayers.Util.extend(this,defaults);},CLASS_NAME:"OpenLayers.Format.ArcXML.Response"});OpenLayers.Format.GML=OpenLayers.Class(OpenLayers.Format.XML,{featureNS:"http://mapserver.gis.umn.edu/mapserver",featurePrefix:"feature",featureName:"featureMember",layerName:"features",geometryName:"geometry",collectionName:"FeatureCollection",gmlns:"http://www.opengis.net/gml",extractAttributes:true,xy:true,initialize:function(options){this.regExes={trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)};OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61448 var featureNodes=this.getElementsByTagNameNS(data.documentElement,this.gmlns,this.featureName);var features=[];for(var i=0;i<featureNodes.length;i++){var feature=this.parseFeature(featureNodes[i]);if(feature){features.push(feature);}}
61449 return features;},parseFeature:function(node){var order=["MultiPolygon","Polygon","MultiLineString","LineString","MultiPoint","Point","Envelope"];var type,nodeList,geometry,parser;for(var i=0;i<order.length;++i){type=order[i];nodeList=this.getElementsByTagNameNS(node,this.gmlns,type);if(nodeList.length>0){parser=this.parseGeometry[type.toLowerCase()];if(parser){geometry=parser.apply(this,[nodeList[0]]);if(this.internalProjection&&this.externalProjection){geometry.transform(this.externalProjection,this.internalProjection);}}else{OpenLayers.Console.error(OpenLayers.i18n("unsupportedGeometryType",{'geomType':type}));}
61450 break;}}
61451 var bounds;var boxNodes=this.getElementsByTagNameNS(node,this.gmlns,"Box");for(i=0;i<boxNodes.length;++i){var boxNode=boxNodes[i];var box=this.parseGeometry["box"].apply(this,[boxNode]);var parentNode=boxNode.parentNode;var parentName=parentNode.localName||parentNode.nodeName.split(":").pop();if(parentName==="boundedBy"){bounds=box;}else{geometry=box.toGeometry();}}
61452 var attributes;if(this.extractAttributes){attributes=this.parseAttributes(node);}
61453 var feature=new OpenLayers.Feature.Vector(geometry,attributes);feature.bounds=bounds;feature.gml={featureType:node.firstChild.nodeName.split(":")[1],featureNS:node.firstChild.namespaceURI,featureNSPrefix:node.firstChild.prefix};var childNode=node.firstChild;var fid;while(childNode){if(childNode.nodeType==1){fid=childNode.getAttribute("fid")||childNode.getAttribute("id");if(fid){break;}}
61454 childNode=childNode.nextSibling;}
61455 feature.fid=fid;return feature;},parseGeometry:{point:function(node){var nodeList,coordString;var coords=[];var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"pos");if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
61456 if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.removeSpace,"");coords=coordString.split(",");}}
61457 if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coord");if(nodeList.length>0){var xList=this.getElementsByTagNameNS(nodeList[0],this.gmlns,"X");var yList=this.getElementsByTagNameNS(nodeList[0],this.gmlns,"Y");if(xList.length>0&&yList.length>0){coords=[xList[0].firstChild.nodeValue,yList[0].firstChild.nodeValue];}}}
61458 if(coords.length==2){coords[2]=null;}
61459 if(this.xy){return new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}
61460 else{return new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}},multipoint:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"Point");var components=[];if(nodeList.length>0){var point;for(var i=0;i<nodeList.length;++i){point=this.parseGeometry.point.apply(this,[nodeList[i]]);if(point){components.push(point);}}}
61461 return new OpenLayers.Geometry.MultiPoint(components);},linestring:function(node,ring){var nodeList,coordString;var coords=[];var points=[];nodeList=this.getElementsByTagNameNS(node,this.gmlns,"posList");if(nodeList.length>0){coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);var dim=parseInt(nodeList[0].getAttribute("dimension"));var j,x,y,z;for(var i=0;i<coords.length/dim;++i){j=i*dim;x=coords[j];y=coords[j+1];z=(dim==2)?null:coords[j+2];if(this.xy){points.push(new OpenLayers.Geometry.Point(x,y,z));}else{points.push(new OpenLayers.Geometry.Point(y,x,z));}}}
61462 if(coords.length==0){nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");if(nodeList.length>0){coordString=this.getChildValue(nodeList[0]);coordString=coordString.replace(this.regExes.trimSpace,"");coordString=coordString.replace(this.regExes.trimComma,",");var pointList=coordString.split(this.regExes.splitSpace);for(var i=0;i<pointList.length;++i){coords=pointList[i].split(",");if(coords.length==2){coords[2]=null;}
61463 if(this.xy){points.push(new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]));}else{points.push(new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]));}}}}
61464 var line=null;if(points.length!=0){if(ring){line=new OpenLayers.Geometry.LinearRing(points);}else{line=new OpenLayers.Geometry.LineString(points);}}
61465 return line;},multilinestring:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"LineString");var components=[];if(nodeList.length>0){var line;for(var i=0;i<nodeList.length;++i){line=this.parseGeometry.linestring.apply(this,[nodeList[i]]);if(line){components.push(line);}}}
61466 return new OpenLayers.Geometry.MultiLineString(components);},polygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"LinearRing");var components=[];if(nodeList.length>0){var ring;for(var i=0;i<nodeList.length;++i){ring=this.parseGeometry.linestring.apply(this,[nodeList[i],true]);if(ring){components.push(ring);}}}
61467 return new OpenLayers.Geometry.Polygon(components);},multipolygon:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"Polygon");var components=[];if(nodeList.length>0){var polygon;for(var i=0;i<nodeList.length;++i){polygon=this.parseGeometry.polygon.apply(this,[nodeList[i]]);if(polygon){components.push(polygon);}}}
61468 return new OpenLayers.Geometry.MultiPolygon(components);},envelope:function(node){var components=[];var coordString;var envelope;var lpoint=this.getElementsByTagNameNS(node,this.gmlns,"lowerCorner");if(lpoint.length>0){var coords=[];if(lpoint.length>0){coordString=lpoint[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
61469 if(coords.length==2){coords[2]=null;}
61470 if(this.xy){var lowerPoint=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{var lowerPoint=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
61471 var upoint=this.getElementsByTagNameNS(node,this.gmlns,"upperCorner");if(upoint.length>0){var coords=[];if(upoint.length>0){coordString=upoint[0].firstChild.nodeValue;coordString=coordString.replace(this.regExes.trimSpace,"");coords=coordString.split(this.regExes.splitSpace);}
61472 if(coords.length==2){coords[2]=null;}
61473 if(this.xy){var upperPoint=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{var upperPoint=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
61474 if(lowerPoint&&upperPoint){components.push(new OpenLayers.Geometry.Point(lowerPoint.x,lowerPoint.y));components.push(new OpenLayers.Geometry.Point(upperPoint.x,lowerPoint.y));components.push(new OpenLayers.Geometry.Point(upperPoint.x,upperPoint.y));components.push(new OpenLayers.Geometry.Point(lowerPoint.x,upperPoint.y));components.push(new OpenLayers.Geometry.Point(lowerPoint.x,lowerPoint.y));var ring=new OpenLayers.Geometry.LinearRing(components);envelope=new OpenLayers.Geometry.Polygon([ring]);}
61475 return envelope;},box:function(node){var nodeList=this.getElementsByTagNameNS(node,this.gmlns,"coordinates");var coordString;var coords,beginPoint=null,endPoint=null;if(nodeList.length>0){coordString=nodeList[0].firstChild.nodeValue;coords=coordString.split(" ");if(coords.length==2){beginPoint=coords[0].split(",");endPoint=coords[1].split(",");}}
61476 if(beginPoint!==null&&endPoint!==null){return new OpenLayers.Bounds(parseFloat(beginPoint[0]),parseFloat(beginPoint[1]),parseFloat(endPoint[0]),parseFloat(endPoint[1]));}}},parseAttributes:function(node){var attributes={};var childNode=node.firstChild;var children,i,child,grandchildren,grandchild,name,value;while(childNode){if(childNode.nodeType==1){children=childNode.childNodes;for(i=0;i<children.length;++i){child=children[i];if(child.nodeType==1){grandchildren=child.childNodes;if(grandchildren.length==1){grandchild=grandchildren[0];if(grandchild.nodeType==3||grandchild.nodeType==4){name=(child.prefix)?child.nodeName.split(":")[1]:child.nodeName;value=grandchild.nodeValue.replace(this.regExes.trimSpace,"");attributes[name]=value;}}else{attributes[child.nodeName.split(":").pop()]=null;}}}
61477 break;}
61478 childNode=childNode.nextSibling;}
61479 return attributes;},write:function(features){if(!(features instanceof Array)){features=[features];}
61480 var gml=this.createElementNS("http://www.opengis.net/wfs","wfs:"+this.collectionName);for(var i=0;i<features.length;i++){gml.appendChild(this.createFeatureXML(features[i]));}
61481 return OpenLayers.Format.XML.prototype.write.apply(this,[gml]);},createFeatureXML:function(feature){var geometry=feature.geometry;var geometryNode=this.buildGeometryNode(geometry);var geomContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
61482 this.geometryName);geomContainer.appendChild(geometryNode);var featureNode=this.createElementNS(this.gmlns,"gml:"+this.featureName);var featureContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
61483 this.layerName);var fid=feature.fid||feature.id;featureContainer.setAttribute("fid",fid);featureContainer.appendChild(geomContainer);for(var attr in feature.attributes){var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr.substring(attr.lastIndexOf(":")+1);var attrContainer=this.createElementNS(this.featureNS,this.featurePrefix+":"+
61484 nodename);attrContainer.appendChild(attrText);featureContainer.appendChild(attrContainer);}
61485 featureNode.appendChild(featureContainer);return featureNode;},buildGeometryNode:function(geometry){if(this.externalProjection&&this.internalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
61486 var className=geometry.CLASS_NAME;var type=className.substring(className.lastIndexOf(".")+1);var builder=this.buildGeometry[type.toLowerCase()];return builder.apply(this,[geometry]);},buildGeometry:{point:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:Point");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},multipoint:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiPoint");var points=geometry.components;var pointMember,pointGeom;for(var i=0;i<points.length;i++){pointMember=this.createElementNS(this.gmlns,"gml:pointMember");pointGeom=this.buildGeometry.point.apply(this,[points[i]]);pointMember.appendChild(pointGeom);gml.appendChild(pointMember);}
61487 return gml;},linestring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:LineString");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},multilinestring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiLineString");var lines=geometry.components;var lineMember,lineGeom;for(var i=0;i<lines.length;++i){lineMember=this.createElementNS(this.gmlns,"gml:lineStringMember");lineGeom=this.buildGeometry.linestring.apply(this,[lines[i]]);lineMember.appendChild(lineGeom);gml.appendChild(lineMember);}
61488 return gml;},linearring:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:LinearRing");gml.appendChild(this.buildCoordinatesNode(geometry));return gml;},polygon:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:Polygon");var rings=geometry.components;var ringMember,ringGeom,type;for(var i=0;i<rings.length;++i){type=(i==0)?"outerBoundaryIs":"innerBoundaryIs";ringMember=this.createElementNS(this.gmlns,"gml:"+type);ringGeom=this.buildGeometry.linearring.apply(this,[rings[i]]);ringMember.appendChild(ringGeom);gml.appendChild(ringMember);}
61489 return gml;},multipolygon:function(geometry){var gml=this.createElementNS(this.gmlns,"gml:MultiPolygon");var polys=geometry.components;var polyMember,polyGeom;for(var i=0;i<polys.length;++i){polyMember=this.createElementNS(this.gmlns,"gml:polygonMember");polyGeom=this.buildGeometry.polygon.apply(this,[polys[i]]);polyMember.appendChild(polyGeom);gml.appendChild(polyMember);}
61490 return gml;},bounds:function(bounds){var gml=this.createElementNS(this.gmlns,"gml:Box");gml.appendChild(this.buildCoordinatesNode(bounds));return gml;}},buildCoordinatesNode:function(geometry){var coordinatesNode=this.createElementNS(this.gmlns,"gml:coordinates");coordinatesNode.setAttribute("decimal",".");coordinatesNode.setAttribute("cs",",");coordinatesNode.setAttribute("ts"," ");var parts=[];if(geometry instanceof OpenLayers.Bounds){parts.push(geometry.left+","+geometry.bottom);parts.push(geometry.right+","+geometry.top);}else{var points=(geometry.components)?geometry.components:[geometry];for(var i=0;i<points.length;i++){parts.push(points[i].x+","+points[i].y);}}
61491 var txtNode=this.createTextNode(parts.join(" "));coordinatesNode.appendChild(txtNode);return coordinatesNode;},CLASS_NAME:"OpenLayers.Format.GML"});OpenLayers.Format.GeoJSON=OpenLayers.Class(OpenLayers.Format.JSON,{ignoreExtraDims:false,initialize:function(options){OpenLayers.Format.JSON.prototype.initialize.apply(this,[options]);},read:function(json,type,filter){type=(type)?type:"FeatureCollection";var results=null;var obj=null;if(typeof json=="string"){obj=OpenLayers.Format.JSON.prototype.read.apply(this,[json,filter]);}else{obj=json;}
61492 if(!obj){OpenLayers.Console.error("Bad JSON: "+json);}else if(typeof(obj.type)!="string"){OpenLayers.Console.error("Bad GeoJSON - no type: "+json);}else if(this.isValidType(obj,type)){switch(type){case"Geometry":try{results=this.parseGeometry(obj);}catch(err){OpenLayers.Console.error(err);}
61493 break;case"Feature":try{results=this.parseFeature(obj);results.type="Feature";}catch(err){OpenLayers.Console.error(err);}
61494 break;case"FeatureCollection":results=[];switch(obj.type){case"Feature":try{results.push(this.parseFeature(obj));}catch(err){results=null;OpenLayers.Console.error(err);}
61495 break;case"FeatureCollection":for(var i=0,len=obj.features.length;i<len;++i){try{results.push(this.parseFeature(obj.features[i]));}catch(err){results=null;OpenLayers.Console.error(err);}}
61496 break;default:try{var geom=this.parseGeometry(obj);results.push(new OpenLayers.Feature.Vector(geom));}catch(err){results=null;OpenLayers.Console.error(err);}}
61497 break;}}
61498 return results;},isValidType:function(obj,type){var valid=false;switch(type){case"Geometry":if(OpenLayers.Util.indexOf(["Point","MultiPoint","LineString","MultiLineString","Polygon","MultiPolygon","Box","GeometryCollection"],obj.type)==-1){OpenLayers.Console.error("Unsupported geometry type: "+
61499 obj.type);}else{valid=true;}
61500 break;case"FeatureCollection":valid=true;break;default:if(obj.type==type){valid=true;}else{OpenLayers.Console.error("Cannot convert types from "+
61501 obj.type+" to "+type);}}
61502 return valid;},parseFeature:function(obj){var feature,geometry,attributes,bbox;attributes=(obj.properties)?obj.properties:{};bbox=(obj.geometry&&obj.geometry.bbox)||obj.bbox;try{geometry=this.parseGeometry(obj.geometry);}catch(err){throw err;}
61503 feature=new OpenLayers.Feature.Vector(geometry,attributes);if(bbox){feature.bounds=OpenLayers.Bounds.fromArray(bbox);}
61504 if(obj.id){feature.fid=obj.id;}
61505 return feature;},parseGeometry:function(obj){if(obj==null){return null;}
61506 var geometry,collection=false;if(obj.type=="GeometryCollection"){if(!(obj.geometries instanceof Array)){throw"GeometryCollection must have geometries array: "+obj;}
61507 var numGeom=obj.geometries.length;var components=new Array(numGeom);for(var i=0;i<numGeom;++i){components[i]=this.parseGeometry.apply(this,[obj.geometries[i]]);}
61508 geometry=new OpenLayers.Geometry.Collection(components);collection=true;}else{if(!(obj.coordinates instanceof Array)){throw"Geometry must have coordinates array: "+obj;}
61509 if(!this.parseCoords[obj.type.toLowerCase()]){throw"Unsupported geometry type: "+obj.type;}
61510 try{geometry=this.parseCoords[obj.type.toLowerCase()].apply(this,[obj.coordinates]);}catch(err){throw err;}}
61511 if(this.internalProjection&&this.externalProjection&&!collection){geometry.transform(this.externalProjection,this.internalProjection);}
61512 return geometry;},parseCoords:{"point":function(array){if(this.ignoreExtraDims==false&&array.length!=2){throw"Only 2D points are supported: "+array;}
61513 return new OpenLayers.Geometry.Point(array[0],array[1]);},"multipoint":function(array){var points=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["point"].apply(this,[array[i]]);}catch(err){throw err;}
61514 points.push(p);}
61515 return new OpenLayers.Geometry.MultiPoint(points);},"linestring":function(array){var points=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["point"].apply(this,[array[i]]);}catch(err){throw err;}
61516 points.push(p);}
61517 return new OpenLayers.Geometry.LineString(points);},"multilinestring":function(array){var lines=[];var l=null;for(var i=0,len=array.length;i<len;++i){try{l=this.parseCoords["linestring"].apply(this,[array[i]]);}catch(err){throw err;}
61518 lines.push(l);}
61519 return new OpenLayers.Geometry.MultiLineString(lines);},"polygon":function(array){var rings=[];var r,l;for(var i=0,len=array.length;i<len;++i){try{l=this.parseCoords["linestring"].apply(this,[array[i]]);}catch(err){throw err;}
61520 r=new OpenLayers.Geometry.LinearRing(l.components);rings.push(r);}
61521 return new OpenLayers.Geometry.Polygon(rings);},"multipolygon":function(array){var polys=[];var p=null;for(var i=0,len=array.length;i<len;++i){try{p=this.parseCoords["polygon"].apply(this,[array[i]]);}catch(err){throw err;}
61522 polys.push(p);}
61523 return new OpenLayers.Geometry.MultiPolygon(polys);},"box":function(array){if(array.length!=2){throw"GeoJSON box coordinates must have 2 elements";}
61524 return new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(array[0][0],array[0][1]),new OpenLayers.Geometry.Point(array[1][0],array[0][1]),new OpenLayers.Geometry.Point(array[1][0],array[1][1]),new OpenLayers.Geometry.Point(array[0][0],array[1][1]),new OpenLayers.Geometry.Point(array[0][0],array[0][1])])]);}},write:function(obj,pretty){var geojson={"type":null};if(obj instanceof Array){geojson.type="FeatureCollection";var numFeatures=obj.length;geojson.features=new Array(numFeatures);for(var i=0;i<numFeatures;++i){var element=obj[i];if(!element instanceof OpenLayers.Feature.Vector){var msg="FeatureCollection only supports collections "+"of features: "+element;throw msg;}
61525 geojson.features[i]=this.extract.feature.apply(this,[element]);}}else if(obj.CLASS_NAME.indexOf("OpenLayers.Geometry")==0){geojson=this.extract.geometry.apply(this,[obj]);}else if(obj instanceof OpenLayers.Feature.Vector){geojson=this.extract.feature.apply(this,[obj]);if(obj.layer&&obj.layer.projection){geojson.crs=this.createCRSObject(obj);}}
61526 return OpenLayers.Format.JSON.prototype.write.apply(this,[geojson,pretty]);},createCRSObject:function(object){var proj=object.layer.projection.toString();var crs={};if(proj.match(/epsg:/i)){var code=parseInt(proj.substring(proj.indexOf(":")+1));if(code==4326){crs={"type":"OGC","properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}};}else{crs={"type":"EPSG","properties":{"code":code}};}}
61527 return crs;},extract:{'feature':function(feature){var geom=this.extract.geometry.apply(this,[feature.geometry]);return{"type":"Feature","id":feature.fid==null?feature.id:feature.fid,"properties":feature.attributes,"geometry":geom};},'geometry':function(geometry){if(geometry==null){return null;}
61528 if(this.internalProjection&&this.externalProjection){geometry=geometry.clone();geometry.transform(this.internalProjection,this.externalProjection);}
61529 var geometryType=geometry.CLASS_NAME.split('.')[2];var data=this.extract[geometryType.toLowerCase()].apply(this,[geometry]);var json;if(geometryType=="Collection"){json={"type":"GeometryCollection","geometries":data};}else{json={"type":geometryType,"coordinates":data};}
61530 return json;},'point':function(point){return[point.x,point.y];},'multipoint':function(multipoint){var array=[];for(var i=0,len=multipoint.components.length;i<len;++i){array.push(this.extract.point.apply(this,[multipoint.components[i]]));}
61531 return array;},'linestring':function(linestring){var array=[];for(var i=0,len=linestring.components.length;i<len;++i){array.push(this.extract.point.apply(this,[linestring.components[i]]));}
61532 return array;},'multilinestring':function(multilinestring){var array=[];for(var i=0,len=multilinestring.components.length;i<len;++i){array.push(this.extract.linestring.apply(this,[multilinestring.components[i]]));}
61533 return array;},'polygon':function(polygon){var array=[];for(var i=0,len=polygon.components.length;i<len;++i){array.push(this.extract.linestring.apply(this,[polygon.components[i]]));}
61534 return array;},'multipolygon':function(multipolygon){var array=[];for(var i=0,len=multipolygon.components.length;i<len;++i){array.push(this.extract.polygon.apply(this,[multipolygon.components[i]]));}
61535 return array;},'collection':function(collection){var len=collection.components.length;var array=new Array(len);for(var i=0;i<len;++i){array[i]=this.extract.geometry.apply(this,[collection.components[i]]);}
61536 return array;}},CLASS_NAME:"OpenLayers.Format.GeoJSON"});OpenLayers.Format.ArcXML.Features=OpenLayers.Class(OpenLayers.Format.XML,{initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){var axl=new OpenLayers.Format.ArcXML();var parsed=axl.read(data);return parsed.features.feature;}});if(!OpenLayers.Format.GML){OpenLayers.Format.GML={};}
61537 OpenLayers.Format.GML.Base=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",wfs:"http://www.opengis.net/wfs"},defaultPrefix:"gml",schemaLocation:null,featureType:null,featureNS:null,geometryName:"geometry",extractAttributes:true,srsName:null,xy:true,geometryTypes:null,singleFeatureType:null,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.setGeometryTypes();if(options&&options.featureNS){this.setNamespace("feature",options.featureNS);}
61538 this.singleFeatureType=!options||(typeof options.featureType==="string");},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61539 if(data&&data.nodeType==9){data=data.documentElement;}
61540 var features=[];this.readNode(data,{features:features});if(features.length==0){var elements=this.getElementsByTagNameNS(data,this.namespaces.gml,"featureMember");if(elements.length){for(var i=0,len=elements.length;i<len;++i){this.readNode(elements[i],{features:features});}}else{var elements=this.getElementsByTagNameNS(data,this.namespaces.gml,"featureMembers");if(elements.length){this.readNode(elements[0],{features:features});}}}
61541 return features;},readers:{"gml":{"featureMember":function(node,obj){this.readChildNodes(node,obj);},"featureMembers":function(node,obj){this.readChildNodes(node,obj);},"name":function(node,obj){obj.name=this.getChildValue(node);},"boundedBy":function(node,obj){var container={};this.readChildNodes(node,container);if(container.components&&container.components.length>0){obj.bounds=container.components[0];}},"Point":function(node,container){var obj={points:[]};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61542 container.components.push(obj.points[0]);},"coordinates":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");str=str.replace(this.regExes.trimComma,",");var pointList=str.split(this.regExes.splitSpace);var coords;var numPoints=pointList.length;var points=new Array(numPoints);for(var i=0;i<numPoints;++i){coords=pointList[i].split(",");if(this.xy){points[i]=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{points[i]=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}}
61543 obj.points=points;},"coord":function(node,obj){var coord={};this.readChildNodes(node,coord);if(!obj.points){obj.points=[];}
61544 obj.points.push(new OpenLayers.Geometry.Point(coord.x,coord.y,coord.z));},"X":function(node,coord){coord.x=this.getChildValue(node);},"Y":function(node,coord){coord.y=this.getChildValue(node);},"Z":function(node,coord){coord.z=this.getChildValue(node);},"MultiPoint":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiPoint(obj.components)];},"pointMember":function(node,obj){this.readChildNodes(node,obj);},"LineString":function(node,container){var obj={};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61545 container.components.push(new OpenLayers.Geometry.LineString(obj.points));},"MultiLineString":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiLineString(obj.components)];},"lineStringMember":function(node,obj){this.readChildNodes(node,obj);},"Polygon":function(node,container){var obj={outer:null,inner:[]};this.readChildNodes(node,obj);obj.inner.unshift(obj.outer);if(!container.components){container.components=[];}
61546 container.components.push(new OpenLayers.Geometry.Polygon(obj.inner));},"LinearRing":function(node,obj){var container={};this.readChildNodes(node,container);obj.components=[new OpenLayers.Geometry.LinearRing(container.points)];},"MultiPolygon":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.MultiPolygon(obj.components)];},"polygonMember":function(node,obj){this.readChildNodes(node,obj);},"GeometryCollection":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);container.components=[new OpenLayers.Geometry.Collection(obj.components)];},"geometryMember":function(node,obj){this.readChildNodes(node,obj);}},"feature":{"*":function(node,obj){var name;var local=node.localName||node.nodeName.split(":").pop();if(obj.features){if(!this.singleFeatureType&&(OpenLayers.Util.indexOf(this.featureType,local)!==-1)){name="_typeName";}else if(local===this.featureType){name="_typeName";}}else{if(node.childNodes.length==0||(node.childNodes.length==1&&node.firstChild.nodeType==3)){if(this.extractAttributes){name="_attribute";}}else{name="_geometry";}}
61547 if(name){this.readers.feature[name].apply(this,[node,obj]);}},"_typeName":function(node,obj){var container={components:[],attributes:{}};this.readChildNodes(node,container);if(container.name){container.attributes.name=container.name;}
61548 var feature=new OpenLayers.Feature.Vector(container.components[0],container.attributes);if(!this.singleFeatureType){feature.type=node.nodeName.split(":").pop();feature.namespace=node.namespaceURI;}
61549 var fid=node.getAttribute("fid")||this.getAttributeNS(node,this.namespaces["gml"],"id");if(fid){feature.fid=fid;}
61550 if(this.internalProjection&&this.externalProjection&&feature.geometry){feature.geometry.transform(this.externalProjection,this.internalProjection);}
61551 if(container.bounds){feature.bounds=container.bounds;}
61552 obj.features.push(feature);},"_geometry":function(node,obj){this.readChildNodes(node,obj);},"_attribute":function(node,obj){var local=node.localName||node.nodeName.split(":").pop();var value=this.getChildValue(node);obj.attributes[local]=value;}},"wfs":{"FeatureCollection":function(node,obj){this.readChildNodes(node,obj);}}},write:function(features){var name;if(features instanceof Array){name="featureMembers";}else{name="featureMember";}
61553 var root=this.writeNode("gml:"+name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":{"featureMember":function(feature){var node=this.createElementNSPlus("gml:featureMember");this.writeNode("feature:_typeName",feature,node);return node;},"MultiPoint":function(geometry){var node=this.createElementNSPlus("gml:MultiPoint");for(var i=0;i<geometry.components.length;++i){this.writeNode("pointMember",geometry.components[i],node);}
61554 return node;},"pointMember":function(geometry){var node=this.createElementNSPlus("gml:pointMember");this.writeNode("Point",geometry,node);return node;},"MultiLineString":function(geometry){var node=this.createElementNSPlus("gml:MultiLineString");for(var i=0;i<geometry.components.length;++i){this.writeNode("lineStringMember",geometry.components[i],node);}
61555 return node;},"lineStringMember":function(geometry){var node=this.createElementNSPlus("gml:lineStringMember");this.writeNode("LineString",geometry,node);return node;},"MultiPolygon":function(geometry){var node=this.createElementNSPlus("gml:MultiPolygon");for(var i=0;i<geometry.components.length;++i){this.writeNode("polygonMember",geometry.components[i],node);}
61556 return node;},"polygonMember":function(geometry){var node=this.createElementNSPlus("gml:polygonMember");this.writeNode("Polygon",geometry,node);return node;},"GeometryCollection":function(geometry){var node=this.createElementNSPlus("gml:GeometryCollection");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("geometryMember",geometry.components[i],node);}
61557 return node;},"geometryMember":function(geometry){var node=this.createElementNSPlus("gml:geometryMember");var child=this.writeNode("feature:_geometry",geometry);node.appendChild(child.firstChild);return node;}},"feature":{"_typeName":function(feature){var node=this.createElementNSPlus("feature:"+this.featureType,{attributes:{fid:feature.fid}});if(feature.geometry){this.writeNode("feature:_geometry",feature.geometry,node);}
61558 for(var name in feature.attributes){var value=feature.attributes[name];if(value!=null){this.writeNode("feature:_attribute",{name:name,value:value},node);}}
61559 return node;},"_geometry":function(geometry){if(this.externalProjection&&this.internalProjection){geometry=geometry.clone().transform(this.internalProjection,this.externalProjection);}
61560 var node=this.createElementNSPlus("feature:"+this.geometryName);var type=this.geometryTypes[geometry.CLASS_NAME];var child=this.writeNode("gml:"+type,geometry,node);if(this.srsName){child.setAttribute("srsName",this.srsName);}
61561 return node;},"_attribute":function(obj){return this.createElementNSPlus("feature:"+obj.name,{value:obj.value});}},"wfs":{"FeatureCollection":function(features){var node=this.createElementNSPlus("wfs:FeatureCollection");for(var i=0,len=features.length;i<len;++i){this.writeNode("gml:featureMember",features[i],node);}
61562 return node;}}},setGeometryTypes:function(){this.geometryTypes={"OpenLayers.Geometry.Point":"Point","OpenLayers.Geometry.MultiPoint":"MultiPoint","OpenLayers.Geometry.LineString":"LineString","OpenLayers.Geometry.MultiLineString":"MultiLineString","OpenLayers.Geometry.Polygon":"Polygon","OpenLayers.Geometry.MultiPolygon":"MultiPolygon","OpenLayers.Geometry.Collection":"GeometryCollection"};},CLASS_NAME:"OpenLayers.Format.GML.Base"});OpenLayers.Format.WFS=OpenLayers.Class(OpenLayers.Format.GML,{layer:null,wfsns:"http://www.opengis.net/wfs",ogcns:"http://www.opengis.net/ogc",initialize:function(options,layer){OpenLayers.Format.GML.prototype.initialize.apply(this,[options]);this.layer=layer;if(this.layer.featureNS){this.featureNS=this.layer.featureNS;}
61563 if(this.layer.options.geometry_column){this.geometryName=this.layer.options.geometry_column;}
61564 if(this.layer.options.typename){this.featureName=this.layer.options.typename;}},write:function(features){var transaction=this.createElementNS(this.wfsns,'wfs:Transaction');transaction.setAttribute("version","1.0.0");transaction.setAttribute("service","WFS");for(var i=0;i<features.length;i++){switch(features[i].state){case OpenLayers.State.INSERT:transaction.appendChild(this.insert(features[i]));break;case OpenLayers.State.UPDATE:transaction.appendChild(this.update(features[i]));break;case OpenLayers.State.DELETE:transaction.appendChild(this.remove(features[i]));break;}}
61565 return OpenLayers.Format.XML.prototype.write.apply(this,[transaction]);},createFeatureXML:function(feature){var geometryNode=this.buildGeometryNode(feature.geometry);var geomContainer=this.createElementNS(this.featureNS,"feature:"+this.geometryName);geomContainer.appendChild(geometryNode);var featureContainer=this.createElementNS(this.featureNS,"feature:"+this.featureName);featureContainer.appendChild(geomContainer);for(var attr in feature.attributes){var attrText=this.createTextNode(feature.attributes[attr]);var nodename=attr;if(attr.search(":")!=-1){nodename=attr.split(":")[1];}
61566 var attrContainer=this.createElementNS(this.featureNS,"feature:"+nodename);attrContainer.appendChild(attrText);featureContainer.appendChild(attrContainer);}
61567 return featureContainer;},insert:function(feature){var insertNode=this.createElementNS(this.wfsns,'wfs:Insert');insertNode.appendChild(this.createFeatureXML(feature));return insertNode;},update:function(feature){if(!feature.fid){OpenLayers.Console.userError(OpenLayers.i18n("noFID"));}
61568 var updateNode=this.createElementNS(this.wfsns,'wfs:Update');updateNode.setAttribute("typeName",this.featurePrefix+':'+this.featureName);updateNode.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);var propertyNode=this.createElementNS(this.wfsns,'wfs:Property');var nameNode=this.createElementNS(this.wfsns,'wfs:Name');var txtNode=this.createTextNode(this.geometryName);nameNode.appendChild(txtNode);propertyNode.appendChild(nameNode);var valueNode=this.createElementNS(this.wfsns,'wfs:Value');var geometryNode=this.buildGeometryNode(feature.geometry);if(feature.layer){geometryNode.setAttribute("srsName",feature.layer.projection.getCode());}
61569 valueNode.appendChild(geometryNode);propertyNode.appendChild(valueNode);updateNode.appendChild(propertyNode);for(var propName in feature.attributes){propertyNode=this.createElementNS(this.wfsns,'wfs:Property');nameNode=this.createElementNS(this.wfsns,'wfs:Name');nameNode.appendChild(this.createTextNode(propName));propertyNode.appendChild(nameNode);valueNode=this.createElementNS(this.wfsns,'wfs:Value');valueNode.appendChild(this.createTextNode(feature.attributes[propName]));propertyNode.appendChild(valueNode);updateNode.appendChild(propertyNode);}
61570 var filterNode=this.createElementNS(this.ogcns,'ogc:Filter');var filterIdNode=this.createElementNS(this.ogcns,'ogc:FeatureId');filterIdNode.setAttribute("fid",feature.fid);filterNode.appendChild(filterIdNode);updateNode.appendChild(filterNode);return updateNode;},remove:function(feature){if(!feature.fid){OpenLayers.Console.userError(OpenLayers.i18n("noFID"));return false;}
61571 var deleteNode=this.createElementNS(this.wfsns,'wfs:Delete');deleteNode.setAttribute("typeName",this.featurePrefix+':'+this.featureName);deleteNode.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);var filterNode=this.createElementNS(this.ogcns,'ogc:Filter');var filterIdNode=this.createElementNS(this.ogcns,'ogc:FeatureId');filterIdNode.setAttribute("fid",feature.fid);filterNode.appendChild(filterIdNode);deleteNode.appendChild(filterNode);return deleteNode;},destroy:function(){this.layer=null;},CLASS_NAME:"OpenLayers.Format.WFS"});OpenLayers.Layer.ArcIMS=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{ClientVersion:"9.2",ServiceName:''},tileSize:null,featureCoordSys:"4326",filterCoordSys:"4326",layers:null,async:true,name:"ArcIMS",isBaseLayer:true,DEFAULT_OPTIONS:{tileSize:new OpenLayers.Size(512,512),featureCoordSys:"4326",filterCoordSys:"4326",layers:null,isBaseLayer:true,async:true,name:"ArcIMS"},initialize:function(name,url,options){this.tileSize=new OpenLayers.Size(512,512);this.params=OpenLayers.Util.applyDefaults({ServiceName:options.serviceName},this.DEFAULT_PARAMS);this.options=OpenLayers.Util.applyDefaults(options,this.DEFAULT_OPTIONS);OpenLayers.Layer.Grid.prototype.initialize.apply(this,[name,url,this.params,options]);if(this.transparent){if(!this.isBaseLayer){this.isBaseLayer=false;}
61572 if(this.format=="image/jpeg"){this.format=OpenLayers.Util.alphaHack()?"image/gif":"image/png";}}
61573 if(this.options.layers===null){this.options.layers=[];}},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);},getURL:function(bounds){var url="";bounds=this.adjustBounds(bounds);var axlReq=new OpenLayers.Format.ArcXML(OpenLayers.Util.extend(this.options,{requesttype:"image",envelope:bounds.toArray(),tileSize:this.tileSize}));var req=new OpenLayers.Request.POST({url:this.getFullRequestString(),data:axlReq.write(),async:false});if(req!=null){var doc=req.responseXML;if(!doc||!doc.documentElement){doc=req.responseText;}
61574 var axlResp=new OpenLayers.Format.ArcXML();var arcxml=axlResp.read(doc);url=this.getUrlOrImage(arcxml.image.output);}
61575 return url;},getURLasync:function(bounds,scope,prop,callback){bounds=this.adjustBounds(bounds);var axlReq=new OpenLayers.Format.ArcXML(OpenLayers.Util.extend(this.options,{requesttype:"image",envelope:bounds.toArray(),tileSize:this.tileSize}));OpenLayers.Request.POST({url:this.getFullRequestString(),async:true,data:axlReq.write(),callback:function(req){var doc=req.responseXML;if(!doc||!doc.documentElement){doc=req.responseText;}
61576 var axlResp=new OpenLayers.Format.ArcXML();var arcxml=axlResp.read(doc);scope[prop]=this.getUrlOrImage(arcxml.image.output);callback.apply(scope);},scope:this});},getUrlOrImage:function(output){var ret="";if(output.url){ret=output.url;}else if(output.data){ret="data:image/"+output.type+";base64,"+output.data;}
61577 return ret;},setLayerQuery:function(id,querydef){for(var lyr=0;lyr<this.options.layers.length;lyr++){if(id==this.options.layers[lyr].id){this.options.layers[lyr].query=querydef;return;}}
61578 this.options.layers.push({id:id,visible:true,query:querydef});},getFeatureInfo:function(geometry,layer,options){var buffer=options.buffer||1;var callback=options.callback||function(){};var scope=options.scope||window;var requestOptions={};OpenLayers.Util.extend(requestOptions,this.options);requestOptions.requesttype="feature";if(geometry instanceof OpenLayers.LonLat){requestOptions.polygon=null;requestOptions.envelope=[geometry.lon-buffer,geometry.lat-buffer,geometry.lon+buffer,geometry.lat+buffer];}else if(geometry instanceof OpenLayers.Geometry.Polygon){requestOptions.envelope=null;requestOptions.polygon=geometry;}
61579 var arcxml=new OpenLayers.Format.ArcXML(requestOptions);OpenLayers.Util.extend(arcxml.request.get_feature,options);arcxml.request.get_feature.layer=layer.id;if(typeof layer.query.accuracy=="number"){arcxml.request.get_feature.query.accuracy=layer.query.accuracy;}else{var mapCenter=this.map.getCenter();var viewPx=this.map.getViewPortPxFromLonLat(mapCenter);viewPx.x++;var mapOffCenter=this.map.getLonLatFromPixel(viewPx);arcxml.request.get_feature.query.accuracy=mapOffCenter.lon-mapCenter.lon;}
61580 arcxml.request.get_feature.query.where=layer.query.where;arcxml.request.get_feature.query.spatialfilter.relation="area_intersection";OpenLayers.Request.POST({url:this.getFullRequestString({'CustomService':'Query'}),data:arcxml.write(),callback:function(request){var response=arcxml.parseResponse(request.responseText);if(!arcxml.iserror()){callback.call(scope,response.features);}else{callback.call(scope,null);}}});},clone:function(obj){if(obj==null){obj=new OpenLayers.Layer.ArcIMS(this.name,this.url,this.getOptions());}
61581 obj=OpenLayers.Layer.Grid.prototype.clone.apply(this,[obj]);return obj;},addTile:function(bounds,position){return new OpenLayers.Tile.Image(this,position,bounds,null,this.tileSize);},CLASS_NAME:"OpenLayers.Layer.ArcIMS"});OpenLayers.Format.GML.v2=OpenLayers.Class(OpenLayers.Format.GML.Base,{schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd",initialize:function(options){OpenLayers.Format.GML.Base.prototype.initialize.apply(this,[options]);},readers:{"gml":OpenLayers.Util.applyDefaults({"outerBoundaryIs":function(node,container){var obj={};this.readChildNodes(node,obj);container.outer=obj.components[0];},"innerBoundaryIs":function(node,container){var obj={};this.readChildNodes(node,obj);container.inner.push(obj.components[0]);},"Box":function(node,container){var obj={};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61582 var min=obj.points[0];var max=obj.points[1];container.components.push(new OpenLayers.Bounds(min.x,min.y,max.x,max.y));}},OpenLayers.Format.GML.Base.prototype.readers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.readers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.readers["wfs"]},write:function(features){var name;if(features instanceof Array){name="wfs:FeatureCollection";}else{name="gml:featureMember";}
61583 var root=this.writeNode(name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":OpenLayers.Util.applyDefaults({"Point":function(geometry){var node=this.createElementNSPlus("gml:Point");this.writeNode("coordinates",[geometry],node);return node;},"coordinates":function(points){var numPoints=points.length;var parts=new Array(numPoints);var point;for(var i=0;i<numPoints;++i){point=points[i];if(this.xy){parts[i]=point.x+","+point.y;}else{parts[i]=point.y+","+point.x;}
61584 if(point.z!=undefined){parts[i]+=","+point.z;}}
61585 return this.createElementNSPlus("gml:coordinates",{attributes:{decimal:".",cs:",",ts:" "},value:(numPoints==1)?parts[0]:parts.join(" ")});},"LineString":function(geometry){var node=this.createElementNSPlus("gml:LineString");this.writeNode("coordinates",geometry.components,node);return node;},"Polygon":function(geometry){var node=this.createElementNSPlus("gml:Polygon");this.writeNode("outerBoundaryIs",geometry.components[0],node);for(var i=1;i<geometry.components.length;++i){this.writeNode("innerBoundaryIs",geometry.components[i],node);}
61586 return node;},"outerBoundaryIs":function(ring){var node=this.createElementNSPlus("gml:outerBoundaryIs");this.writeNode("LinearRing",ring,node);return node;},"innerBoundaryIs":function(ring){var node=this.createElementNSPlus("gml:innerBoundaryIs");this.writeNode("LinearRing",ring,node);return node;},"LinearRing":function(ring){var node=this.createElementNSPlus("gml:LinearRing");this.writeNode("coordinates",ring.components,node);return node;},"Box":function(bounds){var node=this.createElementNSPlus("gml:Box");this.writeNode("coordinates",[{x:bounds.left,y:bounds.bottom},{x:bounds.right,y:bounds.top}],node);if(this.srsName){node.setAttribute("srsName",this.srsName);}
61587 return node;}},OpenLayers.Format.GML.Base.prototype.writers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.writers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.writers["wfs"]},CLASS_NAME:"OpenLayers.Format.GML.v2"});OpenLayers.Format.GML.v3=OpenLayers.Class(OpenLayers.Format.GML.Base,{schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd",curve:false,multiCurve:true,surface:false,multiSurface:true,initialize:function(options){OpenLayers.Format.GML.Base.prototype.initialize.apply(this,[options]);},readers:{"gml":OpenLayers.Util.applyDefaults({"featureMembers":function(node,obj){this.readChildNodes(node,obj);},"Curve":function(node,container){var obj={points:[]};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61588 container.components.push(new OpenLayers.Geometry.LineString(obj.points));},"segments":function(node,obj){this.readChildNodes(node,obj);},"LineStringSegment":function(node,container){var obj={};this.readChildNodes(node,obj);if(obj.points){Array.prototype.push.apply(container.points,obj.points);}},"pos":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");var coords=str.split(this.regExes.splitSpace);var point;if(this.xy){point=new OpenLayers.Geometry.Point(coords[0],coords[1],coords[2]);}else{point=new OpenLayers.Geometry.Point(coords[1],coords[0],coords[2]);}
61589 obj.points=[point];},"posList":function(node,obj){var str=this.getChildValue(node).replace(this.regExes.trimSpace,"");var coords=str.split(this.regExes.splitSpace);var dim=parseInt(node.getAttribute("dimension"))||2;var j,x,y,z;var numPoints=coords.length/dim;var points=new Array(numPoints);for(var i=0,len=coords.length;i<len;i+=dim){x=coords[i];y=coords[i+1];z=(dim==2)?undefined:coords[i+2];if(this.xy){points[i/dim]=new OpenLayers.Geometry.Point(x,y,z);}else{points[i/dim]=new OpenLayers.Geometry.Point(y,x,z);}}
61590 obj.points=points;},"Surface":function(node,obj){this.readChildNodes(node,obj);},"patches":function(node,obj){this.readChildNodes(node,obj);},"PolygonPatch":function(node,obj){this.readers.gml.Polygon.apply(this,[node,obj]);},"exterior":function(node,container){var obj={};this.readChildNodes(node,obj);container.outer=obj.components[0];},"interior":function(node,container){var obj={};this.readChildNodes(node,obj);container.inner.push(obj.components[0]);},"MultiCurve":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);if(obj.components.length>0){container.components=[new OpenLayers.Geometry.MultiLineString(obj.components)];}},"curveMember":function(node,obj){this.readChildNodes(node,obj);},"MultiSurface":function(node,container){var obj={components:[]};this.readChildNodes(node,obj);if(obj.components.length>0){container.components=[new OpenLayers.Geometry.MultiPolygon(obj.components)];}},"surfaceMember":function(node,obj){this.readChildNodes(node,obj);},"surfaceMembers":function(node,obj){this.readChildNodes(node,obj);},"pointMembers":function(node,obj){this.readChildNodes(node,obj);},"lineStringMembers":function(node,obj){this.readChildNodes(node,obj);},"polygonMembers":function(node,obj){this.readChildNodes(node,obj);},"geometryMembers":function(node,obj){this.readChildNodes(node,obj);},"Envelope":function(node,container){var obj={points:new Array(2)};this.readChildNodes(node,obj);if(!container.components){container.components=[];}
61591 var min=obj.points[0];var max=obj.points[1];container.components.push(new OpenLayers.Bounds(min.x,min.y,max.x,max.y));},"lowerCorner":function(node,container){var obj={};this.readers.gml.pos.apply(this,[node,obj]);container.points[0]=obj.points[0];},"upperCorner":function(node,container){var obj={};this.readers.gml.pos.apply(this,[node,obj]);container.points[1]=obj.points[0];}},OpenLayers.Format.GML.Base.prototype.readers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.readers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.readers["wfs"]},write:function(features){var name;if(features instanceof Array){name="featureMembers";}else{name="featureMember";}
61592 var root=this.writeNode("gml:"+name,features);this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},writers:{"gml":OpenLayers.Util.applyDefaults({"featureMembers":function(features){var node=this.createElementNSPlus("gml:featureMembers");for(var i=0,len=features.length;i<len;++i){this.writeNode("feature:_typeName",features[i],node);}
61593 return node;},"Point":function(geometry){var node=this.createElementNSPlus("gml:Point");this.writeNode("pos",geometry,node);return node;},"pos":function(point){var pos=(this.xy)?(point.x+" "+point.y):(point.y+" "+point.x);return this.createElementNSPlus("gml:pos",{value:pos});},"LineString":function(geometry){var node=this.createElementNSPlus("gml:LineString");this.writeNode("posList",geometry.components,node);return node;},"Curve":function(geometry){var node=this.createElementNSPlus("gml:Curve");this.writeNode("segments",geometry,node);return node;},"segments":function(geometry){var node=this.createElementNSPlus("gml:segments");this.writeNode("LineStringSegment",geometry,node);return node;},"LineStringSegment":function(geometry){var node=this.createElementNSPlus("gml:LineStringSegment");this.writeNode("posList",geometry.components,node);return node;},"posList":function(points){var len=points.length;var parts=new Array(len);var point;for(var i=0;i<len;++i){point=points[i];if(this.xy){parts[i]=point.x+" "+point.y;}else{parts[i]=point.y+" "+point.x;}}
61594 return this.createElementNSPlus("gml:posList",{value:parts.join(" ")});},"Surface":function(geometry){var node=this.createElementNSPlus("gml:Surface");this.writeNode("patches",geometry,node);return node;},"patches":function(geometry){var node=this.createElementNSPlus("gml:patches");this.writeNode("PolygonPatch",geometry,node);return node;},"PolygonPatch":function(geometry){var node=this.createElementNSPlus("gml:PolygonPatch",{attributes:{interpolation:"planar"}});this.writeNode("exterior",geometry.components[0],node);for(var i=1,len=geometry.components.length;i<len;++i){this.writeNode("interior",geometry.components[i],node);}
61595 return node;},"Polygon":function(geometry){var node=this.createElementNSPlus("gml:Polygon");this.writeNode("exterior",geometry.components[0],node);for(var i=1,len=geometry.components.length;i<len;++i){this.writeNode("interior",geometry.components[i],node);}
61596 return node;},"exterior":function(ring){var node=this.createElementNSPlus("gml:exterior");this.writeNode("LinearRing",ring,node);return node;},"interior":function(ring){var node=this.createElementNSPlus("gml:interior");this.writeNode("LinearRing",ring,node);return node;},"LinearRing":function(ring){var node=this.createElementNSPlus("gml:LinearRing");this.writeNode("posList",ring.components,node);return node;},"MultiCurve":function(geometry){var node=this.createElementNSPlus("gml:MultiCurve");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("curveMember",geometry.components[i],node);}
61597 return node;},"curveMember":function(geometry){var node=this.createElementNSPlus("gml:curveMember");if(this.curve){this.writeNode("Curve",geometry,node);}else{this.writeNode("LineString",geometry,node);}
61598 return node;},"MultiSurface":function(geometry){var node=this.createElementNSPlus("gml:MultiSurface");for(var i=0,len=geometry.components.length;i<len;++i){this.writeNode("surfaceMember",geometry.components[i],node);}
61599 return node;},"surfaceMember":function(polygon){var node=this.createElementNSPlus("gml:surfaceMember");if(this.surface){this.writeNode("Surface",polygon,node);}else{this.writeNode("Polygon",polygon,node);}
61600 return node;},"Envelope":function(bounds){var node=this.createElementNSPlus("gml:Envelope");this.writeNode("lowerCorner",bounds,node);this.writeNode("upperCorner",bounds,node);if(this.srsName){node.setAttribute("srsName",this.srsName);}
61601 return node;},"lowerCorner":function(bounds){var pos=(this.xy)?(bounds.left+" "+bounds.bottom):(bounds.bottom+" "+bounds.left);return this.createElementNSPlus("gml:lowerCorner",{value:pos});},"upperCorner":function(bounds){var pos=(this.xy)?(bounds.right+" "+bounds.top):(bounds.top+" "+bounds.right);return this.createElementNSPlus("gml:upperCorner",{value:pos});}},OpenLayers.Format.GML.Base.prototype.writers["gml"]),"feature":OpenLayers.Format.GML.Base.prototype.writers["feature"],"wfs":OpenLayers.Format.GML.Base.prototype.writers["wfs"]},setGeometryTypes:function(){this.geometryTypes={"OpenLayers.Geometry.Point":"Point","OpenLayers.Geometry.MultiPoint":"MultiPoint","OpenLayers.Geometry.LineString":(this.curve===true)?"Curve":"LineString","OpenLayers.Geometry.MultiLineString":(this.multiCurve===false)?"MultiLineString":"MultiCurve","OpenLayers.Geometry.Polygon":(this.surface===true)?"Surface":"Polygon","OpenLayers.Geometry.MultiPolygon":(this.multiSurface===false)?"MultiPolygon":"MultiSurface","OpenLayers.Geometry.Collection":"GeometryCollection"};},CLASS_NAME:"OpenLayers.Format.GML.v3"});OpenLayers.Format.Atom=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{atom:"http://www.w3.org/2005/Atom",georss:"http://www.georss.org/georss"},feedTitle:"untitled",defaultEntryTitle:"untitled",gmlParser:null,xy:false,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(doc){if(typeof doc=="string"){doc=OpenLayers.Format.XML.prototype.read.apply(this,[doc]);}
61602 return this.parseFeatures(doc);},write:function(features){var doc;if(features instanceof Array){doc=this.createElementNSPlus("atom:feed");doc.appendChild(this.createElementNSPlus("atom:title",{value:this.feedTitle}));for(var i=0,ii=features.length;i<ii;i++){doc.appendChild(this.buildEntryNode(features[i]));}}
61603 else{doc=this.buildEntryNode(features);}
61604 return OpenLayers.Format.XML.prototype.write.apply(this,[doc]);},buildContentNode:function(content){var node=this.createElementNSPlus("atom:content",{attributes:{type:content.type||null}});if(content.src){node.setAttribute("src",content.src);}else{if(content.type=="text"||content.type==null){node.appendChild(this.createTextNode(content.value));}else if(content.type=="html"){if(typeof content.value!="string"){throw"HTML content must be in form of an escaped string";}
61605 node.appendChild(this.createTextNode(content.value));}else if(content.type=="xhtml"){node.appendChild(content.value);}else if(content.type=="xhtml"||content.type.match(/(\+|\/)xml$/)){node.appendChild(content.value);}
61606 else{node.appendChild(this.createTextNode(content.value));}}
61607 return node;},buildEntryNode:function(feature){var attrib=feature.attributes;var atomAttrib=attrib.atom||{};var entryNode=this.createElementNSPlus("atom:entry");if(atomAttrib.authors){var authors=atomAttrib.authors instanceof Array?atomAttrib.authors:[atomAttrib.authors];for(var i=0,ii=authors.length;i<ii;i++){entryNode.appendChild(this.buildPersonConstructNode("author",authors[i]));}}
61608 if(atomAttrib.categories){var categories=atomAttrib.categories instanceof Array?atomAttrib.categories:[atomAttrib.categories];var category;for(var i=0,ii=categories.length;i<ii;i++){category=categories[i];entryNode.appendChild(this.createElementNSPlus("atom:category",{attributes:{term:category.term,scheme:category.scheme||null,label:category.label||null}}));}}
61609 if(atomAttrib.content){entryNode.appendChild(this.buildContentNode(atomAttrib.content));}
61610 if(atomAttrib.contributors){var contributors=atomAttrib.contributors instanceof Array?atomAttrib.contributors:[atomAttrib.contributors];for(var i=0,ii=contributors.length;i<ii;i++){entryNode.appendChild(this.buildPersonConstructNode("contributor",contributors[i]));}}
61611 if(feature.fid){entryNode.appendChild(this.createElementNSPlus("atom:id",{value:feature.fid}));}
61612 if(atomAttrib.links){var links=atomAttrib.links instanceof Array?atomAttrib.links:[atomAttrib.links];var link;for(var i=0,ii=links.length;i<ii;i++){link=links[i];entryNode.appendChild(this.createElementNSPlus("atom:link",{attributes:{href:link.href,rel:link.rel||null,type:link.type||null,hreflang:link.hreflang||null,title:link.title||null,length:link.length||null}}));}}
61613 if(atomAttrib.published){entryNode.appendChild(this.createElementNSPlus("atom:published",{value:atomAttrib.published}));}
61614 if(atomAttrib.rights){entryNode.appendChild(this.createElementNSPlus("atom:rights",{value:atomAttrib.rights}));}
61615 if(atomAttrib.summary||attrib.description){entryNode.appendChild(this.createElementNSPlus("atom:summary",{value:atomAttrib.summary||attrib.description}));}
61616 entryNode.appendChild(this.createElementNSPlus("atom:title",{value:atomAttrib.title||attrib.title||this.defaultEntryTitle}));if(atomAttrib.updated){entryNode.appendChild(this.createElementNSPlus("atom:updated",{value:atomAttrib.updated}));}
61617 if(feature.geometry){var whereNode=this.createElementNSPlus("georss:where");whereNode.appendChild(this.buildGeometryNode(feature.geometry));entryNode.appendChild(whereNode);}
61618 return entryNode;},initGmlParser:function(){this.gmlParser=new OpenLayers.Format.GML.v3({xy:this.xy,featureNS:"http://example.com#feature",internalProjection:this.internalProjection,externalProjection:this.externalProjection});},buildGeometryNode:function(geometry){if(!this.gmlParser){this.initGmlParser();}
61619 var node=this.gmlParser.writeNode("feature:_geometry",geometry);return node.firstChild;},buildPersonConstructNode:function(name,value){var oNames=["uri","email"];var personNode=this.createElementNSPlus("atom:"+name);personNode.appendChild(this.createElementNSPlus("atom:name",{value:value.name}));for(var i=0,ii=oNames.length;i<ii;i++){if(value[oNames[i]]){personNode.appendChild(this.createElementNSPlus("atom:"+oNames[i],{value:value[oNames[i]]}));}}
61620 return personNode;},getFirstChildValue:function(node,nsuri,name,def){var value;var nodes=this.getElementsByTagNameNS(node,nsuri,name);if(nodes&&nodes.length>0){value=this.getChildValue(nodes[0],def);}else{value=def;}
61621 return value;},parseFeature:function(node){var atomAttrib={};var value=null;var nodes=null;var attval=null;var atomns=this.namespaces.atom;this.parsePersonConstructs(node,"author",atomAttrib);nodes=this.getElementsByTagNameNS(node,atomns,"category");if(nodes.length>0){atomAttrib.categories=[];}
61622 for(var i=0,ii=nodes.length;i<ii;i++){value={};value.term=nodes[i].getAttribute("term");attval=nodes[i].getAttribute("scheme");if(attval){value.scheme=attval;}
61623 attval=nodes[i].getAttribute("label");if(attval){value.label=attval;}
61624 atomAttrib.categories.push(value);}
61625 nodes=this.getElementsByTagNameNS(node,atomns,"content");if(nodes.length>0){value={};attval=nodes[0].getAttribute("type");if(attval){value.type=attval;}
61626 attval=nodes[0].getAttribute("src");if(attval){value.src=attval;}else{if(value.type=="text"||value.type=="html"||value.type==null){value.value=this.getFirstChildValue(node,atomns,"content",null);}else if(value.type=="xhtml"||value.type.match(/(\+|\/)xml$/)){value.value=this.getChildEl(nodes[0]);}else{value.value=this.getFirstChildValue(node,atomns,"content",null);}
61627 atomAttrib.content=value;}}
61628 this.parsePersonConstructs(node,"contributor",atomAttrib);atomAttrib.id=this.getFirstChildValue(node,atomns,"id",null);nodes=this.getElementsByTagNameNS(node,atomns,"link");if(nodes.length>0){atomAttrib.links=new Array(nodes.length);}
61629 var oAtts=["rel","type","hreflang","title","length"];for(var i=0,ii=nodes.length;i<ii;i++){value={};value.href=nodes[i].getAttribute("href");for(var j=0,jj=oAtts.length;j<jj;j++){attval=nodes[i].getAttribute(oAtts[j]);if(attval){value[oAtts[j]]=attval;}}
61630 atomAttrib.links[i]=value;}
61631 value=this.getFirstChildValue(node,atomns,"published",null);if(value){atomAttrib.published=value;}
61632 value=this.getFirstChildValue(node,atomns,"rights",null);if(value){atomAttrib.rights=value;}
61633 value=this.getFirstChildValue(node,atomns,"summary",null);if(value){atomAttrib.summary=value;}
61634 atomAttrib.title=this.getFirstChildValue(node,atomns,"title",null);atomAttrib.updated=this.getFirstChildValue(node,atomns,"updated",null);var featureAttrib={title:atomAttrib.title,description:atomAttrib.summary,atom:atomAttrib};var geometry=this.parseLocations(node)[0];var feature=new OpenLayers.Feature.Vector(geometry,featureAttrib);feature.fid=atomAttrib.id;return feature;},parseFeatures:function(node){var features=[];var entries=this.getElementsByTagNameNS(node,this.namespaces.atom,"entry");if(entries.length==0){entries=[node];}
61635 for(var i=0,ii=entries.length;i<ii;i++){features.push(this.parseFeature(entries[i]));}
61636 return features;},parseLocations:function(node){var georssns=this.namespaces.georss;var locations={components:[]};var where=this.getElementsByTagNameNS(node,georssns,"where");if(where&&where.length>0){if(!this.gmlParser){this.initGmlParser();}
61637 for(var i=0,ii=where.length;i<ii;i++){this.gmlParser.readChildNodes(where[i],locations);}}
61638 var components=locations.components;var point=this.getElementsByTagNameNS(node,georssns,"point");if(point&&point.length>0){for(var i=0,ii=point.length;i<ii;i++){var xy=OpenLayers.String.trim(point[i].firstChild.nodeValue).split(/\s+/);if(xy.length!=2){xy=OpenLayers.String.trim(point[i].firstChild.nodeValue).split(/\s*,\s*/);}
61639 components.push(new OpenLayers.Geometry.Point(parseFloat(xy[1]),parseFloat(xy[0])));}}
61640 var line=this.getElementsByTagNameNS(node,georssns,"line");if(line&&line.length>0){var coords;var p;var points;for(var i=0,ii=line.length;i<ii;i++){coords=OpenLayers.String.trim(line[i].firstChild.nodeValue).split(/\s+/);points=[];for(var j=0,jj=coords.length;j<jj;j+=2){p=new OpenLayers.Geometry.Point(parseFloat(coords[j+1]),parseFloat(coords[j]));points.push(p);}
61641 components.push(new OpenLayers.Geometry.LineString(points));}}
61642 var polygon=this.getElementsByTagNameNS(node,georssns,"polygon");if(polygon&&polygon.length>0){var coords;var p;var points;for(var i=0,ii=polygon.length;i<ii;i++){coords=OpenLayers.String.trim(polygon[i].firstChild.nodeValue).split(/\s+/);points=[];for(var j=0,jj=coords.length;j<jj;j+=2){p=new OpenLayers.Geometry.Point(parseFloat(coords[j+1]),parseFloat(coords[j]));points.push(p);}
61643 components.push(new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]));}}
61644 if(this.internalProjection&&this.externalProjection){for(var i=0,ii=components.length;i<ii;i++){if(components[i]){components[i].transform(this.externalProjection,this.internalProjection);}}}
61645 return components;},parsePersonConstructs:function(node,name,data){var persons=[];var atomns=this.namespaces.atom;var nodes=this.getElementsByTagNameNS(node,atomns,name);var oAtts=["uri","email"];for(var i=0,ii=nodes.length;i<ii;i++){var value={};value.name=this.getFirstChildValue(nodes[i],atomns,"name",null);for(var j=0,jj=oAtts.length;j<jj;j++){var attval=this.getFirstChildValue(nodes[i],atomns,oAtts[j],null);if(attval){value[oAtts[j]]=attval;}}
61646 persons.push(value);}
61647 if(persons.length>0){data[name+"s"]=persons;}},CLASS_NAME:"OpenLayers.Format.Atom"});OpenLayers.Format.Filter.v1_0_0=OpenLayers.Class(OpenLayers.Format.GML.v2,OpenLayers.Format.Filter.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/ogc/filter/1.0.0/filter.xsd",initialize:function(options){OpenLayers.Format.GML.v2.prototype.initialize.apply(this,[options]);},readers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsNotEqualTo":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.NOT_EQUAL_TO});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLike":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LIKE});this.readChildNodes(node,filter);var wildCard=node.getAttribute("wildCard");var singleChar=node.getAttribute("singleChar");var esc=node.getAttribute("escape");filter.value2regex(wildCard,singleChar,esc);obj.filters.push(filter);}},OpenLayers.Format.Filter.v1.prototype.readers["ogc"]),"gml":OpenLayers.Format.GML.v2.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.readers["feature"]},writers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsNotEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsNotEqualTo");this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLike":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLike",{attributes:{wildCard:"*",singleChar:".",escape:"!"}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.regex2value(),node);return node;},"BBOX":function(filter){var node=this.createElementNSPlus("ogc:BBOX");this.writeNode("PropertyName",filter,node);var box=this.writeNode("gml:Box",filter.value,node);if(filter.projection){box.setAttribute("srsName",filter.projection);}
61648 return node;}},OpenLayers.Format.Filter.v1.prototype.writers["ogc"]),"gml":OpenLayers.Format.GML.v2.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.writers["feature"]},writeSpatial:function(filter,name){var node=this.createElementNSPlus("ogc:"+name);this.writeNode("PropertyName",filter,node);var child;if(filter.value instanceof OpenLayers.Geometry){child=this.writeNode("feature:_geometry",filter.value).firstChild;}else{child=this.writeNode("gml:Box",filter.value);}
61649 if(filter.projection){child.setAttribute("srsName",filter.projection);}
61650 node.appendChild(child);return node;},CLASS_NAME:"OpenLayers.Format.Filter.v1_0_0"});OpenLayers.Format.Filter.v1_1_0=OpenLayers.Class(OpenLayers.Format.GML.v3,OpenLayers.Format.Filter.v1,{VERSION:"1.1.0",schemaLocation:"http://www.opengis.net/ogc/filter/1.1.0/filter.xsd",initialize:function(options){OpenLayers.Format.GML.v3.prototype.initialize.apply(this,[options]);},readers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(node,obj){var matchCase=node.getAttribute("matchCase");var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO,matchCase:!(matchCase==="false"||matchCase==="0")});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsNotEqualTo":function(node,obj){var matchCase=node.getAttribute("matchCase");var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.NOT_EQUAL_TO,matchCase:!(matchCase==="false"||matchCase==="0")});this.readChildNodes(node,filter);obj.filters.push(filter);},"PropertyIsLike":function(node,obj){var filter=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LIKE});this.readChildNodes(node,filter);var wildCard=node.getAttribute("wildCard");var singleChar=node.getAttribute("singleChar");var esc=node.getAttribute("escapeChar");filter.value2regex(wildCard,singleChar,esc);obj.filters.push(filter);}},OpenLayers.Format.Filter.v1.prototype.readers["ogc"]),"gml":OpenLayers.Format.GML.v3.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.readers["feature"]},writers:{"ogc":OpenLayers.Util.applyDefaults({"PropertyIsEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsEqualTo",{attributes:{matchCase:filter.matchCase}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsNotEqualTo":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsNotEqualTo",{attributes:{matchCase:filter.matchCase}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.value,node);return node;},"PropertyIsLike":function(filter){var node=this.createElementNSPlus("ogc:PropertyIsLike",{attributes:{wildCard:"*",singleChar:".",escapeChar:"!"}});this.writeNode("PropertyName",filter,node);this.writeNode("Literal",filter.regex2value(),node);return node;},"BBOX":function(filter){var node=this.createElementNSPlus("ogc:BBOX");this.writeNode("PropertyName",filter,node);var box=this.writeNode("gml:Envelope",filter.value);if(filter.projection){box.setAttribute("srsName",filter.projection);}
61651 node.appendChild(box);return node;}},OpenLayers.Format.Filter.v1.prototype.writers["ogc"]),"gml":OpenLayers.Format.GML.v3.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.writers["feature"]},writeSpatial:function(filter,name){var node=this.createElementNSPlus("ogc:"+name);this.writeNode("PropertyName",filter,node);var child;if(filter.value instanceof OpenLayers.Geometry){child=this.writeNode("feature:_geometry",filter.value).firstChild;}else{child=this.writeNode("gml:Envelope",filter.value);}
61652 if(filter.projection){child.setAttribute("srsName",filter.projection);}
61653 node.appendChild(child);return node;},CLASS_NAME:"OpenLayers.Format.Filter.v1_1_0"});OpenLayers.Format.SOSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.SOSCapabilities,{namespaces:{ows:"http://www.opengis.net/ows/1.1",sos:"http://www.opengis.net/sos/1.0",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink"},regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);this.options=options;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61654 if(data&&data.nodeType==9){data=data.documentElement;}
61655 var capabilities={};this.readNode(data,capabilities);return capabilities;},readers:{"gml":OpenLayers.Util.applyDefaults({"name":function(node,obj){obj.name=this.getChildValue(node);},"TimePeriod":function(node,obj){obj.timePeriod={};this.readChildNodes(node,obj.timePeriod);},"beginPosition":function(node,timePeriod){timePeriod.beginPosition=this.getChildValue(node);},"endPosition":function(node,timePeriod){timePeriod.endPosition=this.getChildValue(node);}},OpenLayers.Format.GML.v3.prototype.readers["gml"]),"sos":{"Capabilities":function(node,obj){this.readChildNodes(node,obj);},"Contents":function(node,obj){obj.contents={};this.readChildNodes(node,obj.contents);},"ObservationOfferingList":function(node,contents){contents.offeringList={};this.readChildNodes(node,contents.offeringList);},"ObservationOffering":function(node,offeringList){var id=this.getAttributeNS(node,this.namespaces.gml,"id");offeringList[id]={procedures:[],observedProperties:[],featureOfInterestIds:[],responseFormats:[],resultModels:[],responseModes:[]};this.readChildNodes(node,offeringList[id]);},"time":function(node,offering){offering.time={};this.readChildNodes(node,offering.time);},"procedure":function(node,offering){offering.procedures.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"observedProperty":function(node,offering){offering.observedProperties.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"featureOfInterest":function(node,offering){offering.featureOfInterestIds.push(this.getAttributeNS(node,this.namespaces.xlink,"href"));},"responseFormat":function(node,offering){offering.responseFormats.push(this.getChildValue(node));},"resultModel":function(node,offering){offering.resultModels.push(this.getChildValue(node));},"responseMode":function(node,offering){offering.responseModes.push(this.getChildValue(node));;}},"ows":OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers["ows"]},CLASS_NAME:"OpenLayers.Format.SOSCapabilities.v1_0_0"});OpenLayers.Format.SOSGetFeatureOfInterest=OpenLayers.Class(OpenLayers.Format.XML,{VERSION:"1.0.0",namespaces:{sos:"http://www.opengis.net/sos/1.0",gml:"http://www.opengis.net/gml",sa:"http://www.opengis.net/sampling/1.0",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd",defaultPrefix:"sos",regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61656 if(data&&data.nodeType==9){data=data.documentElement;}
61657 var info={features:[]};this.readNode(data,info);var features=[];for(var i=0,len=info.features.length;i<len;i++){var container=info.features[i];if(this.internalProjection&&this.externalProjection&&container.components[0]){container.components[0].transform(this.externalProjection,this.internalProjection);}
61658 var feature=new OpenLayers.Feature.Vector(container.components[0],container.attributes);features.push(feature);}
61659 return features;},readers:{"sa":{"SamplingPoint":function(node,obj){if(!obj.attributes){var feature={attributes:{}};obj.features.push(feature);obj=feature;}
61660 obj.attributes.id=this.getAttributeNS(node,this.namespaces.gml,"id");this.readChildNodes(node,obj);},"position":function(node,obj){this.readChildNodes(node,obj);}},"gml":OpenLayers.Util.applyDefaults({"FeatureCollection":function(node,obj){this.readChildNodes(node,obj);},"featureMember":function(node,obj){var feature={attributes:{}};obj.features.push(feature);this.readChildNodes(node,feature);},"name":function(node,obj){obj.attributes.name=this.getChildValue(node);},"pos":function(node,obj){if(!this.externalProjection){this.externalProjection=new OpenLayers.Projection(node.getAttribute("srsName"));}
61661 OpenLayers.Format.GML.v3.prototype.readers.gml.pos.apply(this,[node,obj]);}},OpenLayers.Format.GML.v3.prototype.readers.gml)},writers:{"sos":{"GetFeatureOfInterest":function(options){var node=this.createElementNSPlus("GetFeatureOfInterest",{attributes:{version:this.VERSION,service:'SOS',"xsi:schemaLocation":this.schemaLocation}});for(var i=0,len=options.fois.length;i<len;i++){this.writeNode("FeatureOfInterestId",{foi:options.fois[i]},node);}
61662 return node;},"FeatureOfInterestId":function(options){var node=this.createElementNSPlus("FeatureOfInterestId",{value:options.foi});return node;}}},CLASS_NAME:"OpenLayers.Format.SOSGetFeatureOfInterest"});OpenLayers.Format.SOSGetObservation=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ows:"http://www.opengis.net/ows",gml:"http://www.opengis.net/gml",sos:"http://www.opengis.net/sos/1.0",ogc:"http://www.opengis.net/ogc",om:"http://www.opengis.net/om/1.0",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd",defaultPrefix:"sos",initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61663 if(data&&data.nodeType==9){data=data.documentElement;}
61664 var info={measurements:[]};this.readNode(data,info);return info;},write:function(options){var node=this.writeNode("sos:GetObservation",options);node.setAttribute("xmlns:om",this.namespaces.om);this.setAttributeNS(node,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},readers:{"om":{"ObservationCollection":function(node,obj){obj.id=this.getAttributeNS(node,this.namespaces.gml,"id");this.readChildNodes(node,obj);},"member":function(node,observationCollection){this.readChildNodes(node,observationCollection);},"Measurement":function(node,observationCollection){var measurement={};observationCollection.measurements.push(measurement);this.readChildNodes(node,measurement);},"samplingTime":function(node,measurement){var samplingTime={};measurement.samplingTime=samplingTime;this.readChildNodes(node,samplingTime);},"observedProperty":function(node,measurement){measurement.observedProperty=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,measurement);},"procedure":function(node,measurement){measurement.procedure=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,measurement);},"result":function(node,measurement){var result={};measurement.result=result;if(this.getChildValue(node)!==''){result.value=this.getChildValue(node);result.uom=node.getAttribute("uom");}else{this.readChildNodes(node,result);}}},"gml":OpenLayers.Util.applyDefaults({"TimeInstant":function(node,samplingTime){var timeInstant={};samplingTime.timeInstant=timeInstant;this.readChildNodes(node,timeInstant);},"timePosition":function(node,timeInstant){timeInstant.timePosition=this.getChildValue(node);}},OpenLayers.Format.GML.v3.prototype.readers.gml)},writers:{"sos":{"GetObservation":function(options){var node=this.createElementNSPlus("GetObservation",{attributes:{version:this.VERSION,service:'SOS'}});this.writeNode("offering",options,node);this.writeNode("eventTime",options,node);this.writeNode("procedure",options,node);this.writeNode("observedProperty",options,node);this.writeNode("responseFormat",options,node);this.writeNode("resultModel",options,node);this.writeNode("responseMode",options,node);return node;},"responseFormat":function(options){return this.createElementNSPlus("responseFormat",{value:options.responseFormat});},"procedure":function(options){return this.createElementNSPlus("procedure",{value:options.procedure});},"offering":function(options){return this.createElementNSPlus("offering",{value:options.offering});},"observedProperty":function(options){return this.createElementNSPlus("observedProperty",{value:options.observedProperty});},"eventTime":function(options){var node=this.createElementNSPlus("eventTime");if(options.eventTime==='latest'){this.writeNode("ogc:TM_Equals",options,node);}
61665 return node;},"resultModel":function(options){return this.createElementNSPlus("resultModel",{value:options.resultModel});},"responseMode":function(options){return this.createElementNSPlus("responseMode",{value:options.responseMode});}},"ogc":{"TM_Equals":function(options){var node=this.createElementNSPlus("ogc:TM_Equals");this.writeNode("ogc:PropertyName",{property:"urn:ogc:data:time:iso8601"},node);if(options.eventTime==='latest'){this.writeNode("gml:TimeInstant",{value:'latest'},node);}
61666 return node;},"PropertyName":function(options){return this.createElementNSPlus("ogc:PropertyName",{value:options.property});}},"gml":{"TimeInstant":function(options){var node=this.createElementNSPlus("gml:TimeInstant");this.writeNode("gml:timePosition",options,node);return node;},"timePosition":function(options){var node=this.createElementNSPlus("gml:timePosition",{value:options.value});return node;}}},CLASS_NAME:"OpenLayers.Format.SOSGetObservation"});OpenLayers.Format.CSWGetRecords.v2_0_2=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",csw:"http://www.opengis.net/cat/csw/2.0.2",dc:"http://purl.org/dc/elements/1.1/",dct:"http://purl.org/dc/terms/",ows:"http://www.opengis.net/ows"},defaultPrefix:"csw",version:"2.0.2",schemaLocation:"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",requestId:null,resultType:null,outputFormat:null,outputSchema:null,startPosition:null,maxRecords:null,DistributedSearch:null,ResponseHandler:null,Query:null,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61667 if(data&&data.nodeType==9){data=data.documentElement;}
61668 var obj={};this.readNode(data,obj);return obj;},readers:{"csw":{"GetRecordsResponse":function(node,obj){obj.records=[];this.readChildNodes(node,obj);var version=this.getAttributeNS(node,"",'version');if(version!=""){obj.version=version;}},"RequestId":function(node,obj){obj.RequestId=this.getChildValue(node);},"SearchStatus":function(node,obj){obj.SearchStatus={};var timestamp=this.getAttributeNS(node,"",'timestamp');if(timestamp!=""){obj.SearchStatus.timestamp=timestamp;}},"SearchResults":function(node,obj){this.readChildNodes(node,obj);var attrs=node.attributes;var SearchResults={};for(var i=0,len=attrs.length;i<len;++i){if((attrs[i].name=="numberOfRecordsMatched")||(attrs[i].name=="numberOfRecordsReturned")||(attrs[i].name=="nextRecord")){SearchResults[attrs[i].name]=parseInt(attrs[i].nodeValue);}else{SearchResults[attrs[i].name]=attrs[i].nodeValue;}}
61669 obj.SearchResults=SearchResults;},"SummaryRecord":function(node,obj){var record={type:"SummaryRecord"};this.readChildNodes(node,record);obj.records.push(record);},"BriefRecord":function(node,obj){var record={type:"BriefRecord"};this.readChildNodes(node,record);obj.records.push(record);},"DCMIRecord":function(node,obj){var record={type:"DCMIRecord"};this.readChildNodes(node,record);obj.records.push(record);},"Record":function(node,obj){var record={type:"Record"};this.readChildNodes(node,record);obj.records.push(record);}},"dc":{"*":function(node,obj){var name=node.localName||node.nodeName.split(":").pop();if(!(obj[name]instanceof Array)){obj[name]=new Array();}
61670 var dc_element={};var attrs=node.attributes;for(var i=0,len=attrs.length;i<len;++i){dc_element[attrs[i].name]=attrs[i].nodeValue;}
61671 dc_element.value=this.getChildValue(node);obj[name].push(dc_element);}},"dct":{"*":function(node,obj){var name=node.localName||node.nodeName.split(":").pop();if(!(obj[name]instanceof Array)){obj[name]=new Array();}
61672 obj[name].push(this.getChildValue(node));}},"ows":OpenLayers.Util.applyDefaults({"BoundingBox":function(node,obj){if(obj.bounds){obj.BoundingBox=[{crs:obj.projection,value:[obj.bounds.left,obj.bounds.bottom,obj.bounds.right,obj.bounds.top]}];delete obj.projection;delete obj.bounds;}
61673 OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers["ows"]["BoundingBox"].apply(this,arguments);}},OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers["ows"])},write:function(options){var node=this.writeNode("csw:GetRecords",options);return OpenLayers.Format.XML.prototype.write.apply(this,[node]);},writers:{"csw":{"GetRecords":function(options){if(!options){options={};}
61674 var node=this.createElementNSPlus("csw:GetRecords",{attributes:{service:"CSW",version:this.version,requestId:options.requestId||this.requestId,resultType:options.resultType||this.resultType,outputFormat:options.outputFormat||this.outputFormat,outputSchema:options.outputSchema||this.outputSchema,startPosition:options.startPosition||this.startPosition,maxRecords:options.maxRecords||this.maxRecords}});if(options.DistributedSearch||this.DistributedSearch){this.writeNode("csw:DistributedSearch",options.DistributedSearch||this.DistributedSearch,node);}
61675 var ResponseHandler=options.ResponseHandler||this.ResponseHandler;if(ResponseHandler instanceof Array&&ResponseHandler.length>0){for(var i=0,len=ResponseHandler.length;i<len;i++){this.writeNode("csw:ResponseHandler",ResponseHandler[i],node);}}
61676 this.writeNode("Query",options.Query||this.Query,node);return node;},"DistributedSearch":function(options){var node=this.createElementNSPlus("csw:DistributedSearch",{attributes:{hopCount:options.hopCount}});return node;},"ResponseHandler":function(options){var node=this.createElementNSPlus("csw:ResponseHandler",{value:options.value});return node;},"Query":function(options){if(!options){options={};}
61677 var node=this.createElementNSPlus("csw:Query",{attributes:{typeNames:options.typeNames||"csw:Record"}});var ElementName=options.ElementName;if(ElementName instanceof Array&&ElementName.length>0){for(var i=0,len=ElementName.length;i<len;i++){this.writeNode("csw:ElementName",ElementName[i],node);}}else{this.writeNode("csw:ElementSetName",options.ElementSetName||{value:'summary'},node);}
61678 if(options.Constraint){this.writeNode("csw:Constraint",options.Constraint,node);}
61679 return node;},"ElementName":function(options){var node=this.createElementNSPlus("csw:ElementName",{value:options.value});return node;},"ElementSetName":function(options){var node=this.createElementNSPlus("csw:ElementSetName",{attributes:{typeNames:options.typeNames},value:options.value});return node;},"Constraint":function(options){var node=this.createElementNSPlus("csw:Constraint",{attributes:{version:options.version}});if(options.Filter){var format=new OpenLayers.Format.Filter({version:options.version});node.appendChild(format.write(options.Filter));}else if(options.CqlText){var child=this.createElementNSPlus("CqlText",{value:options.CqlText.value});node.appendChild(child);}
61680 return node;}}},CLASS_NAME:"OpenLayers.Format.CSWGetRecords.v2_0_2"});OpenLayers.Format.SLD.v1=OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0,{namespaces:{sld:"http://www.opengis.net/sld",ogc:"http://www.opengis.net/ogc",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"sld",schemaLocation:null,multipleSymbolizers:false,featureTypeCounter:null,defaultSymbolizer:{fillColor:"#808080",fillOpacity:1,strokeColor:"#000000",strokeOpacity:1,strokeWidth:1,strokeDashstyle:"solid",pointRadius:3,graphicName:"square"},initialize:function(options){OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this,[options]);},read:function(data,options){options=OpenLayers.Util.applyDefaults(options,this.options);var sld={namedLayers:options.namedLayersAsArray===true?[]:{}};this.readChildNodes(data,sld);return sld;},readers:OpenLayers.Util.applyDefaults({"sld":{"StyledLayerDescriptor":function(node,sld){sld.version=node.getAttribute("version");this.readChildNodes(node,sld);},"Name":function(node,obj){obj.name=this.getChildValue(node);},"Title":function(node,obj){obj.title=this.getChildValue(node);},"Abstract":function(node,obj){obj.description=this.getChildValue(node);},"NamedLayer":function(node,sld){var layer={userStyles:[],namedStyles:[]};this.readChildNodes(node,layer);for(var i=0,len=layer.userStyles.length;i<len;++i){layer.userStyles[i].layerName=layer.name;}
61681 if(sld.namedLayers instanceof Array){sld.namedLayers.push(layer);}else{sld.namedLayers[layer.name]=layer;}},"NamedStyle":function(node,layer){layer.namedStyles.push(this.getChildName(node.firstChild));},"UserStyle":function(node,layer){var obj={defaultsPerSymbolizer:true,rules:[]};this.featureTypeCounter=-1;this.readChildNodes(node,obj);var style;if(this.multipleSymbolizers){delete obj.defaultsPerSymbolizer;style=new OpenLayers.Style2(obj);}else{style=new OpenLayers.Style(this.defaultSymbolizer,obj);}
61682 layer.userStyles.push(style);},"IsDefault":function(node,style){if(this.getChildValue(node)=="1"){style.isDefault=true;}},"FeatureTypeStyle":function(node,style){++this.featureTypeCounter;var obj={rules:this.multipleSymbolizers?style.rules:[]};this.readChildNodes(node,obj);if(!this.multipleSymbolizers){style.rules=obj.rules;}},"Rule":function(node,obj){var config;if(this.multipleSymbolizers){config={symbolizers:[]};}
61683 var rule=new OpenLayers.Rule(config);this.readChildNodes(node,rule);obj.rules.push(rule);},"ElseFilter":function(node,rule){rule.elseFilter=true;},"MinScaleDenominator":function(node,rule){rule.minScaleDenominator=parseFloat(this.getChildValue(node));},"MaxScaleDenominator":function(node,rule){rule.maxScaleDenominator=parseFloat(this.getChildValue(node));},"TextSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Text(config));}else{rule.symbolizer["Text"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Text"]);}},"Label":function(node,symbolizer){var obj={};this.readChildNodes(node,obj);if(obj.property){symbolizer.label="${"+obj.property+"}";}else{var value=this.readOgcExpression(node);if(value){symbolizer.label=value;}}},"Font":function(node,symbolizer){this.readChildNodes(node,symbolizer);},"Halo":function(node,symbolizer){var obj={};this.readChildNodes(node,obj);symbolizer.haloRadius=obj.haloRadius;symbolizer.haloColor=obj.fillColor;symbolizer.haloOpacity=obj.fillOpacity;},"Radius":function(node,symbolizer){var radius=this.readOgcExpression(node);if(radius!=null){symbolizer.haloRadius=radius;}},"RasterSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Raster(config));}else{rule.symbolizer["Raster"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Raster"]);}},"Geometry":function(node,obj){obj.geometry={};this.readChildNodes(node,obj.geometry);},"ColorMap":function(node,symbolizer){symbolizer.colorMap=[];this.readChildNodes(node,symbolizer.colorMap);},"ColorMapEntry":function(node,colorMap){var q=node.getAttribute("quantity");var o=node.getAttribute("opacity");colorMap.push({color:node.getAttribute("color"),quantity:q!==null?parseFloat(q):undefined,label:node.getAttribute("label")||undefined,opacity:o!==null?parseFloat(o):undefined});},"LineSymbolizer":function(node,rule){var config={};this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Line(config));}else{rule.symbolizer["Line"]=OpenLayers.Util.applyDefaults(config,rule.symbolizer["Line"]);}},"PolygonSymbolizer":function(node,rule){var config={fill:false,stroke:false};if(!this.multipleSymbolizers){config=rule.symbolizer["Polygon"]||config;}
61684 this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Polygon(config));}else{rule.symbolizer["Polygon"]=config;}},"PointSymbolizer":function(node,rule){var config={fill:false,stroke:false,graphic:false};if(!this.multipleSymbolizers){config=rule.symbolizer["Point"]||config;}
61685 this.readChildNodes(node,config);if(this.multipleSymbolizers){config.zIndex=this.featureTypeCounter;rule.symbolizers.push(new OpenLayers.Symbolizer.Point(config));}else{rule.symbolizer["Point"]=config;}},"Stroke":function(node,symbolizer){symbolizer.stroke=true;this.readChildNodes(node,symbolizer);},"Fill":function(node,symbolizer){symbolizer.fill=true;this.readChildNodes(node,symbolizer);},"CssParameter":function(node,symbolizer){var cssProperty=node.getAttribute("name");var symProperty=this.cssMap[cssProperty];if(symProperty){var value=this.readOgcExpression(node);if(value){symbolizer[symProperty]=value;}}},"Graphic":function(node,symbolizer){symbolizer.graphic=true;var graphic={};this.readChildNodes(node,graphic);var properties=["stroke","strokeColor","strokeWidth","strokeOpacity","strokeLinecap","fill","fillColor","fillOpacity","graphicName","rotation","graphicFormat"];var prop,value;for(var i=0,len=properties.length;i<len;++i){prop=properties[i];value=graphic[prop];if(value!=undefined){symbolizer[prop]=value;}}
61686 if(graphic.opacity!=undefined){symbolizer.graphicOpacity=graphic.opacity;}
61687 if(graphic.size!=undefined){symbolizer.pointRadius=graphic.size/2;}
61688 if(graphic.href!=undefined){symbolizer.externalGraphic=graphic.href;}
61689 if(graphic.rotation!=undefined){symbolizer.rotation=graphic.rotation;}},"ExternalGraphic":function(node,graphic){this.readChildNodes(node,graphic);},"Mark":function(node,graphic){this.readChildNodes(node,graphic);},"WellKnownName":function(node,graphic){graphic.graphicName=this.getChildValue(node);},"Opacity":function(node,obj){var opacity=this.readOgcExpression(node);if(opacity){obj.opacity=opacity;}},"Size":function(node,obj){var size=this.readOgcExpression(node);if(size){obj.size=size;}},"Rotation":function(node,obj){var rotation=this.readOgcExpression(node);if(rotation){obj.rotation=rotation;}},"OnlineResource":function(node,obj){obj.href=this.getAttributeNS(node,this.namespaces.xlink,"href");},"Format":function(node,graphic){graphic.graphicFormat=this.getChildValue(node);}}},OpenLayers.Format.Filter.v1_0_0.prototype.readers),cssMap:{"stroke":"strokeColor","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","stroke-linecap":"strokeLinecap","stroke-dasharray":"strokeDashstyle","fill":"fillColor","fill-opacity":"fillOpacity","font-family":"fontFamily","font-size":"fontSize","font-weight":"fontWeight","font-style":"fontStyle"},getCssProperty:function(sym){var css=null;for(var prop in this.cssMap){if(this.cssMap[prop]==sym){css=prop;break;}}
61690 return css;},getGraphicFormat:function(href){var format,regex;for(var key in this.graphicFormats){if(this.graphicFormats[key].test(href)){format=key;break;}}
61691 return format||this.defautlGraphicFormat;},defaultGraphicFormat:"image/png",graphicFormats:{"image/jpeg":/\.jpe?g$/i,"image/gif":/\.gif$/i,"image/png":/\.png$/i},write:function(sld){return this.writers.sld.StyledLayerDescriptor.apply(this,[sld]);},writers:OpenLayers.Util.applyDefaults({"sld":{"StyledLayerDescriptor":function(sld){var root=this.createElementNSPlus("sld:StyledLayerDescriptor",{attributes:{"version":this.VERSION,"xsi:schemaLocation":this.schemaLocation}});root.setAttribute("xmlns:ogc",this.namespaces.ogc);root.setAttribute("xmlns:gml",this.namespaces.gml);if(sld.name){this.writeNode("Name",sld.name,root);}
61692 if(sld.title){this.writeNode("Title",sld.title,root);}
61693 if(sld.description){this.writeNode("Abstract",sld.description,root);}
61694 if(sld.namedLayers instanceof Array){for(var i=0,len=sld.namedLayers.length;i<len;++i){this.writeNode("NamedLayer",sld.namedLayers[i],root);}}else{for(var name in sld.namedLayers){this.writeNode("NamedLayer",sld.namedLayers[name],root);}}
61695 return root;},"Name":function(name){return this.createElementNSPlus("sld:Name",{value:name});},"Title":function(title){return this.createElementNSPlus("sld:Title",{value:title});},"Abstract":function(description){return this.createElementNSPlus("sld:Abstract",{value:description});},"NamedLayer":function(layer){var node=this.createElementNSPlus("sld:NamedLayer");this.writeNode("Name",layer.name,node);if(layer.namedStyles){for(var i=0,len=layer.namedStyles.length;i<len;++i){this.writeNode("NamedStyle",layer.namedStyles[i],node);}}
61696 if(layer.userStyles){for(var i=0,len=layer.userStyles.length;i<len;++i){this.writeNode("UserStyle",layer.userStyles[i],node);}}
61697 return node;},"NamedStyle":function(name){var node=this.createElementNSPlus("sld:NamedStyle");this.writeNode("Name",name,node);return node;},"UserStyle":function(style){var node=this.createElementNSPlus("sld:UserStyle");if(style.name){this.writeNode("Name",style.name,node);}
61698 if(style.title){this.writeNode("Title",style.title,node);}
61699 if(style.description){this.writeNode("Abstract",style.description,node);}
61700 if(style.isDefault){this.writeNode("IsDefault",style.isDefault,node);}
61701 if(this.multipleSymbolizers&&style.rules){var rulesByZ={0:[]};var zValues=[0];var rule,ruleMap,symbolizer,zIndex,clone;for(var i=0,ii=style.rules.length;i<ii;++i){rule=style.rules[i];if(rule.symbolizers){ruleMap={};for(var j=0,jj=rule.symbolizers.length;j<jj;++j){symbolizer=rule.symbolizers[j];zIndex=symbolizer.zIndex;if(!(zIndex in ruleMap)){clone=rule.clone();clone.symbolizers=[];ruleMap[zIndex]=clone;}
61702 ruleMap[zIndex].symbolizers.push(symbolizer.clone());}
61703 for(zIndex in ruleMap){if(!(zIndex in rulesByZ)){zValues.push(zIndex);rulesByZ[zIndex]=[];}
61704 rulesByZ[zIndex].push(ruleMap[zIndex]);}}else{rulesByZ[0].push(rule.clone());}}
61705 zValues.sort();var rules;for(var i=0,ii=zValues.length;i<ii;++i){rules=rulesByZ[zValues[i]];if(rules.length>0){clone=style.clone();clone.rules=rulesByZ[zValues[i]];this.writeNode("FeatureTypeStyle",clone,node);}}}else{this.writeNode("FeatureTypeStyle",style,node);}
61706 return node;},"IsDefault":function(bool){return this.createElementNSPlus("sld:IsDefault",{value:(bool)?"1":"0"});},"FeatureTypeStyle":function(style){var node=this.createElementNSPlus("sld:FeatureTypeStyle");for(var i=0,len=style.rules.length;i<len;++i){this.writeNode("Rule",style.rules[i],node);}
61707 return node;},"Rule":function(rule){var node=this.createElementNSPlus("sld:Rule");if(rule.name){this.writeNode("Name",rule.name,node);}
61708 if(rule.title){this.writeNode("Title",rule.title,node);}
61709 if(rule.description){this.writeNode("Abstract",rule.description,node);}
61710 if(rule.elseFilter){this.writeNode("ElseFilter",null,node);}else if(rule.filter){this.writeNode("ogc:Filter",rule.filter,node);}
61711 if(rule.minScaleDenominator!=undefined){this.writeNode("MinScaleDenominator",rule.minScaleDenominator,node);}
61712 if(rule.maxScaleDenominator!=undefined){this.writeNode("MaxScaleDenominator",rule.maxScaleDenominator,node);}
61713 var type,symbolizer;if(this.multipleSymbolizers&&rule.symbolizers){var symbolizer;for(var i=0,ii=rule.symbolizers.length;i<ii;++i){symbolizer=rule.symbolizers[i];type=symbolizer.CLASS_NAME.split(".").pop();this.writeNode(type+"Symbolizer",symbolizer,node);}}else{var types=OpenLayers.Style.SYMBOLIZER_PREFIXES;for(var i=0,len=types.length;i<len;++i){type=types[i];symbolizer=rule.symbolizer[type];if(symbolizer){this.writeNode(type+"Symbolizer",symbolizer,node);}}}
61714 return node;},"ElseFilter":function(){return this.createElementNSPlus("sld:ElseFilter");},"MinScaleDenominator":function(scale){return this.createElementNSPlus("sld:MinScaleDenominator",{value:scale});},"MaxScaleDenominator":function(scale){return this.createElementNSPlus("sld:MaxScaleDenominator",{value:scale});},"LineSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:LineSymbolizer");this.writeNode("Stroke",symbolizer,node);return node;},"Stroke":function(symbolizer){var node=this.createElementNSPlus("sld:Stroke");if(symbolizer.strokeColor!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeColor"},node);}
61715 if(symbolizer.strokeOpacity!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeOpacity"},node);}
61716 if(symbolizer.strokeWidth!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeWidth"},node);}
61717 if(symbolizer.strokeDashstyle!=undefined&&symbolizer.strokeDashstyle!=="solid"){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeDashstyle"},node);}
61718 if(symbolizer.strokeLinecap!=undefined){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"strokeLinecap"},node);}
61719 return node;},"CssParameter":function(obj){return this.createElementNSPlus("sld:CssParameter",{attributes:{name:this.getCssProperty(obj.key)},value:obj.symbolizer[obj.key]});},"TextSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:TextSymbolizer");if(symbolizer.label!=null){this.writeNode("Label",symbolizer.label,node);}
61720 if(symbolizer.fontFamily!=null||symbolizer.fontSize!=null||symbolizer.fontWeight!=null||symbolizer.fontStyle!=null){this.writeNode("Font",symbolizer,node);}
61721 if(symbolizer.haloRadius!=null||symbolizer.haloColor!=null||symbolizer.haloOpacity!=null){this.writeNode("Halo",symbolizer,node);}
61722 if(symbolizer.fillColor!=null||symbolizer.fillOpacity!=null){this.writeNode("Fill",symbolizer,node);}
61723 return node;},"Font":function(symbolizer){var node=this.createElementNSPlus("sld:Font");if(symbolizer.fontFamily){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontFamily"},node);}
61724 if(symbolizer.fontSize){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontSize"},node);}
61725 if(symbolizer.fontWeight){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontWeight"},node);}
61726 if(symbolizer.fontStyle){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fontStyle"},node);}
61727 return node;},"Label":function(label){var node=this.createElementNSPlus("sld:Label");var tokens=label.split("${");node.appendChild(this.createTextNode(tokens[0]));var item,last;for(var i=1,len=tokens.length;i<len;i++){item=tokens[i];last=item.indexOf("}");if(last>0){this.writeNode("ogc:PropertyName",{property:item.substring(0,last)},node);node.appendChild(this.createTextNode(item.substring(++last)));}else{node.appendChild(this.createTextNode("${"+item));}}
61728 return node;},"Halo":function(symbolizer){var node=this.createElementNSPlus("sld:Halo");if(symbolizer.haloRadius){this.writeNode("Radius",symbolizer.haloRadius,node);}
61729 if(symbolizer.haloColor||symbolizer.haloOpacity){this.writeNode("Fill",{fillColor:symbolizer.haloColor,fillOpacity:symbolizer.haloOpacity},node);}
61730 return node;},"Radius":function(value){return this.createElementNSPlus("sld:Radius",{value:value});},"RasterSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:RasterSymbolizer");if(symbolizer.geometry){this.writeNode("Geometry",symbolizer.geometry,node);}
61731 if(symbolizer.opacity){this.writeNode("Opacity",symbolizer.opacity,node);}
61732 if(symbolizer.colorMap){this.writeNode("ColorMap",symbolizer.colorMap,node);}
61733 return node;},"Geometry":function(geometry){var node=this.createElementNSPlus("sld:Geometry");if(geometry.property){this.writeNode("ogc:PropertyName",geometry,node);}
61734 return node;},"ColorMap":function(colorMap){var node=this.createElementNSPlus("sld:ColorMap");for(var i=0,len=colorMap.length;i<len;++i){this.writeNode("ColorMapEntry",colorMap[i],node);}
61735 return node;},"ColorMapEntry":function(colorMapEntry){var node=this.createElementNSPlus("sld:ColorMapEntry");var a=colorMapEntry;node.setAttribute("color",a.color);a.opacity!==undefined&&node.setAttribute("opacity",parseFloat(a.opacity));a.quantity!==undefined&&node.setAttribute("quantity",parseFloat(a.quantity));a.label!==undefined&&node.setAttribute("label",a.label);return node;},"PolygonSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:PolygonSymbolizer");if(symbolizer.fill!==false){this.writeNode("Fill",symbolizer,node);}
61736 if(symbolizer.stroke!==false){this.writeNode("Stroke",symbolizer,node);}
61737 return node;},"Fill":function(symbolizer){var node=this.createElementNSPlus("sld:Fill");if(symbolizer.fillColor){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fillColor"},node);}
61738 if(symbolizer.fillOpacity!=null){this.writeNode("CssParameter",{symbolizer:symbolizer,key:"fillOpacity"},node);}
61739 return node;},"PointSymbolizer":function(symbolizer){var node=this.createElementNSPlus("sld:PointSymbolizer");this.writeNode("Graphic",symbolizer,node);return node;},"Graphic":function(symbolizer){var node=this.createElementNSPlus("sld:Graphic");if(symbolizer.externalGraphic!=undefined){this.writeNode("ExternalGraphic",symbolizer,node);}else{this.writeNode("Mark",symbolizer,node);}
61740 if(symbolizer.graphicOpacity!=undefined){this.writeNode("Opacity",symbolizer.graphicOpacity,node);}
61741 if(symbolizer.pointRadius!=undefined){this.writeNode("Size",symbolizer.pointRadius*2,node);}
61742 if(symbolizer.rotation!=undefined){this.writeNode("Rotation",symbolizer.rotation,node);}
61743 return node;},"ExternalGraphic":function(symbolizer){var node=this.createElementNSPlus("sld:ExternalGraphic");this.writeNode("OnlineResource",symbolizer.externalGraphic,node);var format=symbolizer.graphicFormat||this.getGraphicFormat(symbolizer.externalGraphic);this.writeNode("Format",format,node);return node;},"Mark":function(symbolizer){var node=this.createElementNSPlus("sld:Mark");if(symbolizer.graphicName){this.writeNode("WellKnownName",symbolizer.graphicName,node);}
61744 if(symbolizer.fill!==false){this.writeNode("Fill",symbolizer,node);}
61745 if(symbolizer.stroke!==false){this.writeNode("Stroke",symbolizer,node);}
61746 return node;},"WellKnownName":function(name){return this.createElementNSPlus("sld:WellKnownName",{value:name});},"Opacity":function(value){return this.createElementNSPlus("sld:Opacity",{value:value});},"Size":function(value){return this.createElementNSPlus("sld:Size",{value:value});},"Rotation":function(value){return this.createElementNSPlus("sld:Rotation",{value:value});},"OnlineResource":function(href){return this.createElementNSPlus("sld:OnlineResource",{attributes:{"xlink:type":"simple","xlink:href":href}});},"Format":function(format){return this.createElementNSPlus("sld:Format",{value:format});}}},OpenLayers.Format.Filter.v1_0_0.prototype.writers),CLASS_NAME:"OpenLayers.Format.SLD.v1"});OpenLayers.Format.WFST.v1_0_0=OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0,OpenLayers.Format.WFST.v1,{version:"1.0.0",srsNameInQuery:false,schemaLocations:{"wfs":"http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"},initialize:function(options){OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this,[options]);OpenLayers.Format.WFST.v1.prototype.initialize.apply(this,[options]);},readers:{"wfs":OpenLayers.Util.applyDefaults({"WFS_TransactionResponse":function(node,obj){obj.insertIds=[];obj.success=false;this.readChildNodes(node,obj);},"InsertResult":function(node,container){var obj={fids:[]};this.readChildNodes(node,obj);container.insertIds.push(obj.fids[0]);},"TransactionResult":function(node,obj){this.readChildNodes(node,obj);},"Status":function(node,obj){this.readChildNodes(node,obj);},"SUCCESS":function(node,obj){obj.success=true;}},OpenLayers.Format.WFST.v1.prototype.readers["wfs"]),"gml":OpenLayers.Format.GML.v2.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.readers["feature"],"ogc":OpenLayers.Format.Filter.v1_0_0.prototype.readers["ogc"]},writers:{"wfs":OpenLayers.Util.applyDefaults({"Query":function(options){options=OpenLayers.Util.extend({featureNS:this.featureNS,featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName,srsNameInQuery:this.srsNameInQuery},options);var node=this.createElementNSPlus("wfs:Query",{attributes:{typeName:(options.featureNS?options.featurePrefix+":":"")+
61747 options.featureType}});if(options.srsNameInQuery&&options.srsName){node.setAttribute("srsName",options.srsName);}
61748 if(options.featureNS){node.setAttribute("xmlns:"+options.featurePrefix,options.featureNS);}
61749 if(options.propertyNames){for(var i=0,len=options.propertyNames.length;i<len;i++){this.writeNode("ogc:PropertyName",{property:options.propertyNames[i]},node);}}
61750 if(options.filter){this.setFilterProperty(options.filter);this.writeNode("ogc:Filter",options.filter,node);}
61751 return node;}},OpenLayers.Format.WFST.v1.prototype.writers["wfs"]),"gml":OpenLayers.Format.GML.v2.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v2.prototype.writers["feature"],"ogc":OpenLayers.Format.Filter.v1_0_0.prototype.writers["ogc"]},CLASS_NAME:"OpenLayers.Format.WFST.v1_0_0"});OpenLayers.Format.WFST.v1_1_0=OpenLayers.Class(OpenLayers.Format.Filter.v1_1_0,OpenLayers.Format.WFST.v1,{version:"1.1.0",schemaLocations:{"wfs":"http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"},initialize:function(options){OpenLayers.Format.Filter.v1_1_0.prototype.initialize.apply(this,[options]);OpenLayers.Format.WFST.v1.prototype.initialize.apply(this,[options]);},readers:{"wfs":OpenLayers.Util.applyDefaults({"FeatureCollection":function(node,obj){obj.numberOfFeatures=parseInt(node.getAttribute("numberOfFeatures"));OpenLayers.Format.WFST.v1.prototype.readers["wfs"]["FeatureCollection"].apply(this,arguments);},"TransactionResponse":function(node,obj){obj.insertIds=[];obj.success=false;this.readChildNodes(node,obj);},"TransactionSummary":function(node,obj){obj.success=true;},"InsertResults":function(node,obj){this.readChildNodes(node,obj);},"Feature":function(node,container){var obj={fids:[]};this.readChildNodes(node,obj);container.insertIds.push(obj.fids[0]);}},OpenLayers.Format.WFST.v1.prototype.readers["wfs"]),"gml":OpenLayers.Format.GML.v3.prototype.readers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.readers["feature"],"ogc":OpenLayers.Format.Filter.v1_1_0.prototype.readers["ogc"]},writers:{"wfs":OpenLayers.Util.applyDefaults({"GetFeature":function(options){var node=OpenLayers.Format.WFST.v1.prototype.writers["wfs"]["GetFeature"].apply(this,arguments);options&&options.resultType&&this.setAttributes(node,{resultType:options.resultType});return node;},"Query":function(options){options=OpenLayers.Util.extend({featureNS:this.featureNS,featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName},options);var node=this.createElementNSPlus("wfs:Query",{attributes:{typeName:(options.featureNS?options.featurePrefix+":":"")+
61752 options.featureType,srsName:options.srsName}});if(options.featureNS){node.setAttribute("xmlns:"+options.featurePrefix,options.featureNS);}
61753 if(options.propertyNames){for(var i=0,len=options.propertyNames.length;i<len;i++){this.writeNode("wfs:PropertyName",{property:options.propertyNames[i]},node);}}
61754 if(options.filter){this.setFilterProperty(options.filter);this.writeNode("ogc:Filter",options.filter,node);}
61755 return node;},"PropertyName":function(obj){return this.createElementNSPlus("wfs:PropertyName",{value:obj.property});}},OpenLayers.Format.WFST.v1.prototype.writers["wfs"]),"gml":OpenLayers.Format.GML.v3.prototype.writers["gml"],"feature":OpenLayers.Format.GML.v3.prototype.writers["feature"],"ogc":OpenLayers.Format.Filter.v1_1_0.prototype.writers["ogc"]},CLASS_NAME:"OpenLayers.Format.WFST.v1_1_0"});OpenLayers.Protocol.SOS.v1_0_0=OpenLayers.Class(OpenLayers.Protocol,{fois:null,formatOptions:null,initialize:function(options){OpenLayers.Protocol.prototype.initialize.apply(this,[options]);if(!options.format){this.format=new OpenLayers.Format.SOSGetFeatureOfInterest(this.formatOptions);}},destroy:function(){if(this.options&&!this.options.format){this.format.destroy();}
61756 this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this);},read:function(options){options=OpenLayers.Util.extend({},options);OpenLayers.Util.applyDefaults(options,this.options||{});var response=new OpenLayers.Protocol.Response({requestType:"read"});var format=this.format;var data=OpenLayers.Format.XML.prototype.write.apply(format,[format.writeNode("sos:GetFeatureOfInterest",{fois:this.fois})]);response.priv=OpenLayers.Request.POST({url:options.url,callback:this.createCallback(this.handleRead,response,options),data:data});return response;},handleRead:function(response,options){if(options.callback){var request=response.priv;if(request.status>=200&&request.status<300){response.features=this.parseFeatures(request);response.code=OpenLayers.Protocol.Response.SUCCESS;}else{response.code=OpenLayers.Protocol.Response.FAILURE;}
61757 options.callback.call(options.scope,response);}},parseFeatures:function(request){var doc=request.responseXML;if(!doc||!doc.documentElement){doc=request.responseText;}
61758 if(!doc||doc.length<=0){return null;}
61759 return this.format.read(doc);},CLASS_NAME:"OpenLayers.Protocol.SOS.v1_0_0"});OpenLayers.Format.SLD.v1_0_0=OpenLayers.Class(OpenLayers.Format.SLD.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd",initialize:function(options){OpenLayers.Format.SLD.v1.prototype.initialize.apply(this,[options]);},CLASS_NAME:"OpenLayers.Format.SLD.v1_0_0"});OpenLayers.Protocol.WFS.v1_0_0=OpenLayers.Class(OpenLayers.Protocol.WFS.v1,{version:"1.0.0",CLASS_NAME:"OpenLayers.Protocol.WFS.v1_0_0"});OpenLayers.Protocol.WFS.v1_1_0=OpenLayers.Class(OpenLayers.Protocol.WFS.v1,{version:"1.1.0",CLASS_NAME:"OpenLayers.Protocol.WFS.v1_1_0"});OpenLayers.Format.OWSContext.v0_3_1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{owc:"http://www.opengis.net/ows-context",gml:"http://www.opengis.net/gml",kml:"http://www.opengis.net/kml/2.2",ogc:"http://www.opengis.net/ogc",ows:"http://www.opengis.net/ows",sld:"http://www.opengis.net/sld",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},VERSION:"0.3.1",schemaLocation:"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd",defaultPrefix:"owc",extractAttributes:true,xy:true,regExes:{trimSpace:(/^\s*|\s*$/g),removeSpace:(/\s*/g),splitSpace:(/\s+/),trimComma:(/\s*,\s*/g)},featureNS:"http://mapserver.gis.umn.edu/mapserver",featureType:'vector',geometryName:'geometry',nestingLayerLookup:null,initialize:function(options){OpenLayers.Format.XML.prototype.initialize.apply(this,[options]);OpenLayers.Format.GML.v2.prototype.setGeometryTypes.call(this);},setNestingPath:function(l){if(l.layersContext){for(var i=0,len=l.layersContext.length;i<len;i++){var layerContext=l.layersContext[i];var nPath=[];var nTitle=l.title||"";if(l.metadata&&l.metadata.nestingPath){nPath=l.metadata.nestingPath.slice();}
61760 if(nTitle!=""){nPath.push(nTitle);}
61761 layerContext.metadata.nestingPath=nPath;if(layerContext.layersContext){this.setNestingPath(layerContext);}}}},decomposeNestingPath:function(nPath){var a=[];if(nPath instanceof Array){while(nPath.length>0){a.push(nPath.slice());nPath.pop();}
61762 a.reverse();}
61763 return a;},read:function(data){if(typeof data=="string"){data=OpenLayers.Format.XML.prototype.read.apply(this,[data]);}
61764 if(data&&data.nodeType==9){data=data.documentElement;}
61765 var context={};this.readNode(data,context);this.setNestingPath({layersContext:context.layersContext});var layers=[];this.processLayer(layers,context);delete context.layersContext;context.layersContext=layers;return context;},processLayer:function(layerArray,layer){if(layer.layersContext){for(var i=0,len=layer.layersContext.length;i<len;i++){var l=layer.layersContext[i];layerArray.push(l);if(l.layersContext){this.processLayer(layerArray,l);}}}},write:function(context,options){var name="OWSContext";this.nestingLayerLookup={};options=options||{};OpenLayers.Util.applyDefaults(options,context);var root=this.writeNode(name,options);this.nestingLayerLookup=null;this.setAttributeNS(root,this.namespaces["xsi"],"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[root]);},readers:{"kml":{"Document":function(node,obj){obj.features=new OpenLayers.Format.KML({kmlns:this.namespaces.kml,extractStyles:true}).read(node);}},"owc":{"OWSContext":function(node,obj){this.readChildNodes(node,obj);},"General":function(node,obj){this.readChildNodes(node,obj);},"ResourceList":function(node,obj){this.readChildNodes(node,obj);},"Layer":function(node,obj){var layerContext={metadata:{},visibility:(node.getAttribute("hidden")!="1"),queryable:(node.getAttribute("queryable")=="1"),opacity:((node.getAttribute("opacity")!=null)?parseFloat(node.getAttribute("opacity")):null),name:node.getAttribute("name"),categoryLayer:(node.getAttribute("name")==null),formats:[],styles:[]};if(!obj.layersContext){obj.layersContext=[];}
61766 obj.layersContext.push(layerContext);this.readChildNodes(node,layerContext);},"InlineGeometry":function(node,obj){obj.features=[];var elements=this.getElementsByTagNameNS(node,this.namespaces.gml,"featureMember");var el;if(elements.length>=1){el=elements[0];}
61767 if(el&&el.firstChild){var featurenode=(el.firstChild.nextSibling)?el.firstChild.nextSibling:el.firstChild;this.setNamespace("feature",featurenode.namespaceURI);this.featureType=featurenode.localName||featurenode.nodeName.split(":").pop();this.readChildNodes(node,obj);}},"Server":function(node,obj){if((!obj.service&&!obj.version)||(obj.service!=OpenLayers.Format.Context.serviceTypes.WMS)){obj.service=node.getAttribute("service");obj.version=node.getAttribute("version");this.readChildNodes(node,obj);}},"Name":function(node,obj){obj.name=this.getChildValue(node);this.readChildNodes(node,obj);},"Title":function(node,obj){obj.title=this.getChildValue(node);this.readChildNodes(node,obj);},"StyleList":function(node,obj){this.readChildNodes(node,obj.styles);},"Style":function(node,obj){var style={};obj.push(style);this.readChildNodes(node,style);},"LegendURL":function(node,obj){var legend={};obj.legend=legend;this.readChildNodes(node,legend);},"OnlineResource":function(node,obj){obj.url=this.getAttributeNS(node,this.namespaces.xlink,"href");this.readChildNodes(node,obj);}},"ows":OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows,"gml":OpenLayers.Format.GML.v2.prototype.readers.gml,"sld":OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld,"feature":OpenLayers.Format.GML.v2.prototype.readers.feature},writers:{"owc":{"OWSContext":function(options){var node=this.createElementNSPlus("OWSContext",{attributes:{version:this.VERSION,id:options.id||OpenLayers.Util.createUniqueID("OpenLayers_OWSContext_")}});this.writeNode("General",options,node);this.writeNode("ResourceList",options,node);return node;},"General":function(options){var node=this.createElementNSPlus("General");this.writeNode("ows:BoundingBox",options,node);this.writeNode("ows:Title",options.title||'OpenLayers OWSContext',node);return node;},"ResourceList":function(options){var node=this.createElementNSPlus("ResourceList");for(var i=0,len=options.layers.length;i<len;i++){var layer=options.layers[i];var decomposedPath=this.decomposeNestingPath(layer.metadata.nestingPath);this.writeNode("_Layer",{layer:layer,subPaths:decomposedPath},node);}
61768 return node;},"Server":function(options){var node=this.createElementNSPlus("Server",{attributes:{version:options.version,service:options.service}});this.writeNode("OnlineResource",options,node);return node;},"OnlineResource":function(options){var node=this.createElementNSPlus("OnlineResource",{attributes:{"xlink:href":options.url}});return node;},"InlineGeometry":function(layer){var node=this.createElementNSPlus("InlineGeometry");this.writeNode("gml:boundedBy",layer.getDataExtent(),node);for(var i=0,len=layer.features.length;i<len;i++){this.writeNode("gml:featureMember",layer.features[i],node);}
61769 return node;},"StyleList":function(styles){var node=this.createElementNSPlus("StyleList");for(var i=0,len=styles.length;i<len;i++){this.writeNode("Style",styles[i],node);}
61770 return node;},"Style":function(style){var node=this.createElementNSPlus("Style");this.writeNode("Name",style,node);this.writeNode("Title",style,node);this.writeNode("LegendURL",style,node);return node;},"Name":function(obj){var node=this.createElementNSPlus("Name",{value:obj.name});return node;},"Title":function(obj){var node=this.createElementNSPlus("Title",{value:obj.title});return node;},"LegendURL":function(style){var node=this.createElementNSPlus("LegendURL");this.writeNode("OnlineResource",style.legend,node);return node;},"_WMS":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:layer.params.LAYERS,queryable:layer.queryable?"1":"0",hidden:layer.visibility?"0":"1",opacity:layer.opacity?layer.opacity:null}});this.writeNode("ows:Title",layer.name,node);this.writeNode("ows:OutputFormat",layer.params.FORMAT,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WMS,version:layer.params.VERSION,url:layer.url},node);if(layer.metadata.styles&&layer.metadata.styles.length>0){this.writeNode("StyleList",layer.metadata.styles,node);}
61771 return node;},"_Layer":function(options){var layer,subPaths,node,title;layer=options.layer;subPaths=options.subPaths;node=null;title=null;if(subPaths.length>0){var path=subPaths[0].join("/");var index=path.lastIndexOf("/");node=this.nestingLayerLookup[path];title=(index>0)?path.substring(index+1,path.length):path;if(!node){node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",title,node);this.nestingLayerLookup[path]=node;}
61772 options.subPaths.shift();this.writeNode("_Layer",options,node);return node;}else{if(layer instanceof OpenLayers.Layer.WMS){node=this.writeNode("_WMS",layer);}else if(layer instanceof OpenLayers.Layer.Vector){if(layer.protocol instanceof OpenLayers.Protocol.WFS.v1){node=this.writeNode("_WFS",layer);}else if(layer.protocol instanceof OpenLayers.Protocol.HTTP){if(layer.protocol.format instanceof OpenLayers.Format.GML){layer.protocol.format.version="2.1.2";node=this.writeNode("_GML",layer);}else if(layer.protocol.format instanceof OpenLayers.Format.KML){layer.protocol.format.version="2.2";node=this.writeNode("_KML",layer);}}else{this.setNamespace("feature",this.featureNS);node=this.writeNode("_InlineGeometry",layer);}}
61773 if(layer.options.maxScale){this.writeNode("sld:MinScaleDenominator",layer.options.maxScale,node);}
61774 if(layer.options.minScale){this.writeNode("sld:MaxScaleDenominator",layer.options.minScale,node);}
61775 this.nestingLayerLookup[layer.name]=node;return node;}},"_WFS":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:layer.protocol.featurePrefix+":"+layer.protocol.featureType,hidden:layer.visibility?"0":"1"}});this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WFS,version:layer.protocol.version,url:layer.protocol.url},node);return node;},"_InlineGeometry":function(layer){var node=this.createElementNSPlus("Layer",{attributes:{name:this.featureType,hidden:layer.visibility?"0":"1"}});this.writeNode("ows:Title",layer.name,node);this.writeNode("InlineGeometry",layer,node);return node;},"_GML":function(layer){var node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.GML,url:layer.protocol.url,version:layer.protocol.format.version},node);return node;},"_KML":function(layer){var node=this.createElementNSPlus("Layer");this.writeNode("ows:Title",layer.name,node);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.KML,version:layer.protocol.format.version,url:layer.protocol.url},node);return node;}},"gml":OpenLayers.Util.applyDefaults({"boundedBy":function(bounds){var node=this.createElementNSPlus("gml:boundedBy");this.writeNode("gml:Box",bounds,node);return node;}},OpenLayers.Format.GML.v2.prototype.writers.gml),"ows":OpenLayers.Format.OWSCommon.v1_0_0.prototype.writers.ows,"sld":OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld,"feature":OpenLayers.Format.GML.v2.prototype.writers.feature},CLASS_NAME:"OpenLayers.Format.OWSContext.v0_3_1"});
61776 (function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,d=e.filter,g=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,_=Object.keys,j=i.bind,w=function(n){return n instanceof w?n:this instanceof w?(this._wrapped=n,void 0):new w(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=w),exports._=w):n._=w,w.VERSION="1.4.4";var A=w.each=w.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(w.has(n,a)&&t.call(e,n[a],a,n)===r)return};w.map=w.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e[e.length]=t.call(r,n,u,i)}),e)};var O="Reduce of empty array with no initial value";w.reduce=w.foldl=w.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=w.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},w.reduceRight=w.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=w.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=w.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},w.find=w.detect=function(n,t,r){var e;return E(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},w.filter=w.select=function(n,t,r){var e=[];return null==n?e:d&&n.filter===d?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&(e[e.length]=n)}),e)},w.reject=function(n,t,r){return w.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},w.every=w.all=function(n,t,e){t||(t=w.identity);var u=!0;return null==n?u:g&&n.every===g?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var E=w.some=w.any=function(n,t,e){t||(t=w.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};w.contains=w.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:E(n,function(n){return n===t})},w.invoke=function(n,t){var r=o.call(arguments,2),e=w.isFunction(t);return w.map(n,function(n){return(e?t:n[t]).apply(n,r)})},w.pluck=function(n,t){return w.map(n,function(n){return n[t]})},w.where=function(n,t,r){return w.isEmpty(t)?r?null:[]:w[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},w.findWhere=function(n,t){return w.where(n,t,!0)},w.max=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.max.apply(Math,n);if(!t&&w.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>=e.computed&&(e={value:n,computed:a})}),e.value},w.min=function(n,t,r){if(!t&&w.isArray(n)&&n[0]===+n[0]&&65535>n.length)return Math.min.apply(Math,n);if(!t&&w.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;e.computed>a&&(e={value:n,computed:a})}),e.value},w.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=w.random(r++),e[r-1]=e[t],e[t]=n}),e};var k=function(n){return w.isFunction(n)?n:function(t){return t[n]}};w.sortBy=function(n,t,r){var e=k(t);return w.pluck(w.map(n,function(n,t,u){return{value:n,index:t,criteria:e.call(r,n,t,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index<t.index?-1:1}),"value")};var F=function(n,t,r,e){var u={},i=k(t||w.identity);return A(n,function(t,a){var o=i.call(r,t,a,n);e(u,o,t)}),u};w.groupBy=function(n,t,r){return F(n,t,r,function(n,t,r){(w.has(n,t)?n[t]:n[t]=[]).push(r)})},w.countBy=function(n,t,r){return F(n,t,r,function(n,t){w.has(n,t)||(n[t]=0),n[t]++})},w.sortedIndex=function(n,t,r,e){r=null==r?w.identity:k(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;u>r.call(e,n[o])?i=o+1:a=o}return i},w.toArray=function(n){return n?w.isArray(n)?o.call(n):n.length===+n.length?w.map(n,w.identity):w.values(n):[]},w.size=function(n){return null==n?0:n.length===+n.length?n.length:w.keys(n).length},w.first=w.head=w.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:o.call(n,0,t)},w.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},w.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},w.rest=w.tail=w.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},w.compact=function(n){return w.filter(n,w.identity)};var R=function(n,t,r){return A(n,function(n){w.isArray(n)?t?a.apply(r,n):R(n,t,r):r.push(n)}),r};w.flatten=function(n,t){return R(n,t,[])},w.without=function(n){return w.difference(n,o.call(arguments,1))},w.uniq=w.unique=function(n,t,r,e){w.isFunction(t)&&(e=r,r=t,t=!1);var u=r?w.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:w.contains(a,r))||(a.push(r),i.push(n[e]))}),i},w.union=function(){return w.uniq(c.apply(e,arguments))},w.intersection=function(n){var t=o.call(arguments,1);return w.filter(w.uniq(n),function(n){return w.every(t,function(t){return w.indexOf(t,n)>=0})})},w.difference=function(n){var t=c.apply(e,o.call(arguments,1));return w.filter(n,function(n){return!w.contains(t,n)})},w.zip=function(){for(var n=o.call(arguments),t=w.max(w.pluck(n,"length")),r=Array(t),e=0;t>e;e++)r[e]=w.pluck(n,""+e);return r},w.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},w.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=w.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},w.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},w.range=function(n,t,r){1>=arguments.length&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=Array(e);e>u;)i[u++]=n,n+=r;return i},w.bind=function(n,t){if(n.bind===j&&j)return j.apply(n,o.call(arguments,1));var r=o.call(arguments,2);return function(){return n.apply(t,r.concat(o.call(arguments)))}},w.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},w.bindAll=function(n){var t=o.call(arguments,1);return 0===t.length&&(t=w.functions(n)),A(t,function(t){n[t]=w.bind(n[t],n)}),n},w.memoize=function(n,t){var r={};return t||(t=w.identity),function(){var e=t.apply(this,arguments);return w.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},w.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},w.defer=function(n){return w.delay.apply(w,[n,1].concat(o.call(arguments,1)))},w.throttle=function(n,t){var r,e,u,i,a=0,o=function(){a=new Date,u=null,i=n.apply(r,e)};return function(){var c=new Date,l=t-(c-a);return r=this,e=arguments,0>=l?(clearTimeout(u),u=null,a=c,i=n.apply(r,e)):u||(u=setTimeout(o,l)),i}},w.debounce=function(n,t,r){var e,u;return function(){var i=this,a=arguments,o=function(){e=null,r||(u=n.apply(i,a))},c=r&&!e;return clearTimeout(e),e=setTimeout(o,t),c&&(u=n.apply(i,a)),u}},w.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},w.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},w.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},w.after=function(n,t){return 0>=n?t():function(){return 1>--n?t.apply(this,arguments):void 0}},w.keys=_||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)w.has(n,r)&&(t[t.length]=r);return t},w.values=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push(n[r]);return t},w.pairs=function(n){var t=[];for(var r in n)w.has(n,r)&&t.push([r,n[r]]);return t},w.invert=function(n){var t={};for(var r in n)w.has(n,r)&&(t[n[r]]=r);return t},w.functions=w.methods=function(n){var t=[];for(var r in n)w.isFunction(n[r])&&t.push(r);return t.sort()},w.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},w.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},w.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)w.contains(r,u)||(t[u]=n[u]);return t},w.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)null==n[r]&&(n[r]=t[r])}),n},w.clone=function(n){return w.isObject(n)?w.isArray(n)?n.slice():w.extend({},n):n},w.tap=function(n,t){return t(n),n};var I=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof w&&(n=n._wrapped),t instanceof w&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==t+"";case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;r.push(n),e.push(t);var a=0,o=!0;if("[object Array]"==u){if(a=n.length,o=a==t.length)for(;a--&&(o=I(n[a],t[a],r,e)););}else{var c=n.constructor,f=t.constructor;if(c!==f&&!(w.isFunction(c)&&c instanceof c&&w.isFunction(f)&&f instanceof f))return!1;for(var s in n)if(w.has(n,s)&&(a++,!(o=w.has(t,s)&&I(n[s],t[s],r,e))))break;if(o){for(s in t)if(w.has(t,s)&&!a--)break;o=!a}}return r.pop(),e.pop(),o};w.isEqual=function(n,t){return I(n,t,[],[])},w.isEmpty=function(n){if(null==n)return!0;if(w.isArray(n)||w.isString(n))return 0===n.length;for(var t in n)if(w.has(n,t))return!1;return!0},w.isElement=function(n){return!(!n||1!==n.nodeType)},w.isArray=x||function(n){return"[object Array]"==l.call(n)},w.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){w["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),w.isArguments(arguments)||(w.isArguments=function(n){return!(!n||!w.has(n,"callee"))}),"function"!=typeof/./&&(w.isFunction=function(n){return"function"==typeof n}),w.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},w.isNaN=function(n){return w.isNumber(n)&&n!=+n},w.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},w.isNull=function(n){return null===n},w.isUndefined=function(n){return n===void 0},w.has=function(n,t){return f.call(n,t)},w.noConflict=function(){return n._=t,this},w.identity=function(n){return n},w.times=function(n,t,r){for(var e=Array(n),u=0;n>u;u++)e[u]=t.call(r,u);return e},w.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var M={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","/":"&#x2F;"}};M.unescape=w.invert(M.escape);var S={escape:RegExp("["+w.keys(M.escape).join("")+"]","g"),unescape:RegExp("("+w.keys(M.unescape).join("|")+")","g")};w.each(["escape","unescape"],function(n){w[n]=function(t){return null==t?"":(""+t).replace(S[n],function(t){return M[n][t]})}}),w.result=function(n,t){if(null==n)return null;var r=n[t];return w.isFunction(r)?r.call(n):r},w.mixin=function(n){A(w.functions(n),function(t){var r=w[t]=n[t];w.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),D.call(this,r.apply(w,n))}})};var N=0;w.uniqueId=function(n){var t=++N+"";return n?n+t:t},w.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/(.)^/,q={"'":"'","\\":"\\","\r":"r","\n":"n","        ":"t","\u2028":"u2028","\u2029":"u2029"},B=/\\|'|\r|\n|\t|\u2028|\u2029/g;w.template=function(n,t,r){var e;r=w.defaults({},r,w.templateSettings);var u=RegExp([(r.escape||T).source,(r.interpolate||T).source,(r.evaluate||T).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(B,function(n){return"\\"+q[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,w);var c=function(n){return e.call(this,n,w)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},w.chain=function(n){return w(n).chain()};var D=function(n){return this._chain?w(n).chain():n};w.mixin(w),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];w.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],D.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];w.prototype[n]=function(){return D.call(this,t.apply(this._wrapped,arguments))}}),w.extend(w.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);/*global setImmediate: false, setTimeout: false, console: false */
61777 (function () {
61778
61779     var async = {};
61780
61781     // global on the server, window in the browser
61782     var root, previous_async;
61783
61784     root = this;
61785     if (root != null) {
61786       previous_async = root.async;
61787     }
61788
61789     async.noConflict = function () {
61790         root.async = previous_async;
61791         return async;
61792     };
61793
61794     function only_once(fn) {
61795         var called = false;
61796         return function() {
61797             if (called) throw new Error("Callback was already called.");
61798             called = true;
61799             fn.apply(root, arguments);
61800         }
61801     }
61802
61803     //// cross-browser compatiblity functions ////
61804
61805     var _each = function (arr, iterator) {
61806         if (arr.forEach) {
61807             return arr.forEach(iterator);
61808         }
61809         for (var i = 0; i < arr.length; i += 1) {
61810             iterator(arr[i], i, arr);
61811         }
61812     };
61813
61814     var _map = function (arr, iterator) {
61815         if (arr.map) {
61816             return arr.map(iterator);
61817         }
61818         var results = [];
61819         _each(arr, function (x, i, a) {
61820             results.push(iterator(x, i, a));
61821         });
61822         return results;
61823     };
61824
61825     var _reduce = function (arr, iterator, memo) {
61826         if (arr.reduce) {
61827             return arr.reduce(iterator, memo);
61828         }
61829         _each(arr, function (x, i, a) {
61830             memo = iterator(memo, x, i, a);
61831         });
61832         return memo;
61833     };
61834
61835     var _keys = function (obj) {
61836         if (Object.keys) {
61837             return Object.keys(obj);
61838         }
61839         var keys = [];
61840         for (var k in obj) {
61841             if (obj.hasOwnProperty(k)) {
61842                 keys.push(k);
61843             }
61844         }
61845         return keys;
61846     };
61847
61848     //// exported async module functions ////
61849
61850     //// nextTick implementation with browser-compatible fallback ////
61851     if (typeof process === 'undefined' || !(process.nextTick)) {
61852         if (typeof setImmediate === 'function') {
61853             async.nextTick = function (fn) {
61854                 // not a direct alias for IE10 compatibility
61855                 setImmediate(fn);
61856             };
61857             async.setImmediate = async.nextTick;
61858         }
61859         else {
61860             async.nextTick = function (fn) {
61861                 setTimeout(fn, 0);
61862             };
61863             async.setImmediate = async.nextTick;
61864         }
61865     }
61866     else {
61867         async.nextTick = process.nextTick;
61868         if (typeof setImmediate !== 'undefined') {
61869             async.setImmediate = setImmediate;
61870         }
61871         else {
61872             async.setImmediate = async.nextTick;
61873         }
61874     }
61875
61876     async.each = function (arr, iterator, callback) {
61877         callback = callback || function () {};
61878         if (!arr.length) {
61879             return callback();
61880         }
61881         var completed = 0;
61882         _each(arr, function (x) {
61883             iterator(x, only_once(function (err) {
61884                 if (err) {
61885                     callback(err);
61886                     callback = function () {};
61887                 }
61888                 else {
61889                     completed += 1;
61890                     if (completed >= arr.length) {
61891                         callback(null);
61892                     }
61893                 }
61894             }));
61895         });
61896     };
61897     async.forEach = async.each;
61898
61899     async.eachSeries = function (arr, iterator, callback) {
61900         callback = callback || function () {};
61901         if (!arr.length) {
61902             return callback();
61903         }
61904         var completed = 0;
61905         var iterate = function () {
61906             iterator(arr[completed], function (err) {
61907                 if (err) {
61908                     callback(err);
61909                     callback = function () {};
61910                 }
61911                 else {
61912                     completed += 1;
61913                     if (completed >= arr.length) {
61914                         callback(null);
61915                     }
61916                     else {
61917                         iterate();
61918                     }
61919                 }
61920             });
61921         };
61922         iterate();
61923     };
61924     async.forEachSeries = async.eachSeries;
61925
61926     async.eachLimit = function (arr, limit, iterator, callback) {
61927         var fn = _eachLimit(limit);
61928         fn.apply(null, [arr, iterator, callback]);
61929     };
61930     async.forEachLimit = async.eachLimit;
61931
61932     var _eachLimit = function (limit) {
61933
61934         return function (arr, iterator, callback) {
61935             callback = callback || function () {};
61936             if (!arr.length || limit <= 0) {
61937                 return callback();
61938             }
61939             var completed = 0;
61940             var started = 0;
61941             var running = 0;
61942
61943             (function replenish () {
61944                 if (completed >= arr.length) {
61945                     return callback();
61946                 }
61947
61948                 while (running < limit && started < arr.length) {
61949                     started += 1;
61950                     running += 1;
61951                     iterator(arr[started - 1], function (err) {
61952                         if (err) {
61953                             callback(err);
61954                             callback = function () {};
61955                         }
61956                         else {
61957                             completed += 1;
61958                             running -= 1;
61959                             if (completed >= arr.length) {
61960                                 callback();
61961                             }
61962                             else {
61963                                 replenish();
61964                             }
61965                         }
61966                     });
61967                 }
61968             })();
61969         };
61970     };
61971
61972
61973     var doParallel = function (fn) {
61974         return function () {
61975             var args = Array.prototype.slice.call(arguments);
61976             return fn.apply(null, [async.each].concat(args));
61977         };
61978     };
61979     var doParallelLimit = function(limit, fn) {
61980         return function () {
61981             var args = Array.prototype.slice.call(arguments);
61982             return fn.apply(null, [_eachLimit(limit)].concat(args));
61983         };
61984     };
61985     var doSeries = function (fn) {
61986         return function () {
61987             var args = Array.prototype.slice.call(arguments);
61988             return fn.apply(null, [async.eachSeries].concat(args));
61989         };
61990     };
61991
61992
61993     var _asyncMap = function (eachfn, arr, iterator, callback) {
61994         var results = [];
61995         arr = _map(arr, function (x, i) {
61996             return {index: i, value: x};
61997         });
61998         eachfn(arr, function (x, callback) {
61999             iterator(x.value, function (err, v) {
62000                 results[x.index] = v;
62001                 callback(err);
62002             });
62003         }, function (err) {
62004             callback(err, results);
62005         });
62006     };
62007     async.map = doParallel(_asyncMap);
62008     async.mapSeries = doSeries(_asyncMap);
62009     async.mapLimit = function (arr, limit, iterator, callback) {
62010         return _mapLimit(limit)(arr, iterator, callback);
62011     };
62012
62013     var _mapLimit = function(limit) {
62014         return doParallelLimit(limit, _asyncMap);
62015     };
62016
62017     // reduce only has a series version, as doing reduce in parallel won't
62018     // work in many situations.
62019     async.reduce = function (arr, memo, iterator, callback) {
62020         async.eachSeries(arr, function (x, callback) {
62021             iterator(memo, x, function (err, v) {
62022                 memo = v;
62023                 callback(err);
62024             });
62025         }, function (err) {
62026             callback(err, memo);
62027         });
62028     };
62029     // inject alias
62030     async.inject = async.reduce;
62031     // foldl alias
62032     async.foldl = async.reduce;
62033
62034     async.reduceRight = function (arr, memo, iterator, callback) {
62035         var reversed = _map(arr, function (x) {
62036             return x;
62037         }).reverse();
62038         async.reduce(reversed, memo, iterator, callback);
62039     };
62040     // foldr alias
62041     async.foldr = async.reduceRight;
62042
62043     var _filter = function (eachfn, arr, iterator, callback) {
62044         var results = [];
62045         arr = _map(arr, function (x, i) {
62046             return {index: i, value: x};
62047         });
62048         eachfn(arr, function (x, callback) {
62049             iterator(x.value, function (v) {
62050                 if (v) {
62051                     results.push(x);
62052                 }
62053                 callback();
62054             });
62055         }, function (err) {
62056             callback(_map(results.sort(function (a, b) {
62057                 return a.index - b.index;
62058             }), function (x) {
62059                 return x.value;
62060             }));
62061         });
62062     };
62063     async.filter = doParallel(_filter);
62064     async.filterSeries = doSeries(_filter);
62065     // select alias
62066     async.select = async.filter;
62067     async.selectSeries = async.filterSeries;
62068
62069     var _reject = function (eachfn, arr, iterator, callback) {
62070         var results = [];
62071         arr = _map(arr, function (x, i) {
62072             return {index: i, value: x};
62073         });
62074         eachfn(arr, function (x, callback) {
62075             iterator(x.value, function (v) {
62076                 if (!v) {
62077                     results.push(x);
62078                 }
62079                 callback();
62080             });
62081         }, function (err) {
62082             callback(_map(results.sort(function (a, b) {
62083                 return a.index - b.index;
62084             }), function (x) {
62085                 return x.value;
62086             }));
62087         });
62088     };
62089     async.reject = doParallel(_reject);
62090     async.rejectSeries = doSeries(_reject);
62091
62092     var _detect = function (eachfn, arr, iterator, main_callback) {
62093         eachfn(arr, function (x, callback) {
62094             iterator(x, function (result) {
62095                 if (result) {
62096                     main_callback(x);
62097                     main_callback = function () {};
62098                 }
62099                 else {
62100                     callback();
62101                 }
62102             });
62103         }, function (err) {
62104             main_callback();
62105         });
62106     };
62107     async.detect = doParallel(_detect);
62108     async.detectSeries = doSeries(_detect);
62109
62110     async.some = function (arr, iterator, main_callback) {
62111         async.each(arr, function (x, callback) {
62112             iterator(x, function (v) {
62113                 if (v) {
62114                     main_callback(true);
62115                     main_callback = function () {};
62116                 }
62117                 callback();
62118             });
62119         }, function (err) {
62120             main_callback(false);
62121         });
62122     };
62123     // any alias
62124     async.any = async.some;
62125
62126     async.every = function (arr, iterator, main_callback) {
62127         async.each(arr, function (x, callback) {
62128             iterator(x, function (v) {
62129                 if (!v) {
62130                     main_callback(false);
62131                     main_callback = function () {};
62132                 }
62133                 callback();
62134             });
62135         }, function (err) {
62136             main_callback(true);
62137         });
62138     };
62139     // all alias
62140     async.all = async.every;
62141
62142     async.sortBy = function (arr, iterator, callback) {
62143         async.map(arr, function (x, callback) {
62144             iterator(x, function (err, criteria) {
62145                 if (err) {
62146                     callback(err);
62147                 }
62148                 else {
62149                     callback(null, {value: x, criteria: criteria});
62150                 }
62151             });
62152         }, function (err, results) {
62153             if (err) {
62154                 return callback(err);
62155             }
62156             else {
62157                 var fn = function (left, right) {
62158                     var a = left.criteria, b = right.criteria;
62159                     return a < b ? -1 : a > b ? 1 : 0;
62160                 };
62161                 callback(null, _map(results.sort(fn), function (x) {
62162                     return x.value;
62163                 }));
62164             }
62165         });
62166     };
62167
62168     async.auto = function (tasks, callback) {
62169         callback = callback || function () {};
62170         var keys = _keys(tasks);
62171         if (!keys.length) {
62172             return callback(null);
62173         }
62174
62175         var results = {};
62176
62177         var listeners = [];
62178         var addListener = function (fn) {
62179             listeners.unshift(fn);
62180         };
62181         var removeListener = function (fn) {
62182             for (var i = 0; i < listeners.length; i += 1) {
62183                 if (listeners[i] === fn) {
62184                     listeners.splice(i, 1);
62185                     return;
62186                 }
62187             }
62188         };
62189         var taskComplete = function () {
62190             _each(listeners.slice(0), function (fn) {
62191                 fn();
62192             });
62193         };
62194
62195         addListener(function () {
62196             if (_keys(results).length === keys.length) {
62197                 callback(null, results);
62198                 callback = function () {};
62199             }
62200         });
62201
62202         _each(keys, function (k) {
62203             var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
62204             var taskCallback = function (err) {
62205                 var args = Array.prototype.slice.call(arguments, 1);
62206                 if (args.length <= 1) {
62207                     args = args[0];
62208                 }
62209                 if (err) {
62210                     var safeResults = {};
62211                     _each(_keys(results), function(rkey) {
62212                         safeResults[rkey] = results[rkey];
62213                     });
62214                     safeResults[k] = args;
62215                     callback(err, safeResults);
62216                     // stop subsequent errors hitting callback multiple times
62217                     callback = function () {};
62218                 }
62219                 else {
62220                     results[k] = args;
62221                     async.setImmediate(taskComplete);
62222                 }
62223             };
62224             var requires = task.slice(0, Math.abs(task.length - 1)) || [];
62225             var ready = function () {
62226                 return _reduce(requires, function (a, x) {
62227                     return (a && results.hasOwnProperty(x));
62228                 }, true) && !results.hasOwnProperty(k);
62229             };
62230             if (ready()) {
62231                 task[task.length - 1](taskCallback, results);
62232             }
62233             else {
62234                 var listener = function () {
62235                     if (ready()) {
62236                         removeListener(listener);
62237                         task[task.length - 1](taskCallback, results);
62238                     }
62239                 };
62240                 addListener(listener);
62241             }
62242         });
62243     };
62244
62245     async.waterfall = function (tasks, callback) {
62246         callback = callback || function () {};
62247         if (tasks.constructor !== Array) {
62248           var err = new Error('First argument to waterfall must be an array of functions');
62249           return callback(err);
62250         }
62251         if (!tasks.length) {
62252             return callback();
62253         }
62254         var wrapIterator = function (iterator) {
62255             return function (err) {
62256                 if (err) {
62257                     callback.apply(null, arguments);
62258                     callback = function () {};
62259                 }
62260                 else {
62261                     var args = Array.prototype.slice.call(arguments, 1);
62262                     var next = iterator.next();
62263                     if (next) {
62264                         args.push(wrapIterator(next));
62265                     }
62266                     else {
62267                         args.push(callback);
62268                     }
62269                     async.setImmediate(function () {
62270                         iterator.apply(null, args);
62271                     });
62272                 }
62273             };
62274         };
62275         wrapIterator(async.iterator(tasks))();
62276     };
62277
62278     var _parallel = function(eachfn, tasks, callback) {
62279         callback = callback || function () {};
62280         if (tasks.constructor === Array) {
62281             eachfn.map(tasks, function (fn, callback) {
62282                 if (fn) {
62283                     fn(function (err) {
62284                         var args = Array.prototype.slice.call(arguments, 1);
62285                         if (args.length <= 1) {
62286                             args = args[0];
62287                         }
62288                         callback.call(null, err, args);
62289                     });
62290                 }
62291             }, callback);
62292         }
62293         else {
62294             var results = {};
62295             eachfn.each(_keys(tasks), function (k, callback) {
62296                 tasks[k](function (err) {
62297                     var args = Array.prototype.slice.call(arguments, 1);
62298                     if (args.length <= 1) {
62299                         args = args[0];
62300                     }
62301                     results[k] = args;
62302                     callback(err);
62303                 });
62304             }, function (err) {
62305                 callback(err, results);
62306             });
62307         }
62308     };
62309
62310     async.parallel = function (tasks, callback) {
62311         _parallel({ map: async.map, each: async.each }, tasks, callback);
62312     };
62313
62314     async.parallelLimit = function(tasks, limit, callback) {
62315         _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
62316     };
62317
62318     async.series = function (tasks, callback) {
62319         callback = callback || function () {};
62320         if (tasks.constructor === Array) {
62321             async.mapSeries(tasks, function (fn, callback) {
62322                 if (fn) {
62323                     fn(function (err) {
62324                         var args = Array.prototype.slice.call(arguments, 1);
62325                         if (args.length <= 1) {
62326                             args = args[0];
62327                         }
62328                         callback.call(null, err, args);
62329                     });
62330                 }
62331             }, callback);
62332         }
62333         else {
62334             var results = {};
62335             async.eachSeries(_keys(tasks), function (k, callback) {
62336                 tasks[k](function (err) {
62337                     var args = Array.prototype.slice.call(arguments, 1);
62338                     if (args.length <= 1) {
62339                         args = args[0];
62340                     }
62341                     results[k] = args;
62342                     callback(err);
62343                 });
62344             }, function (err) {
62345                 callback(err, results);
62346             });
62347         }
62348     };
62349
62350     async.iterator = function (tasks) {
62351         var makeCallback = function (index) {
62352             var fn = function () {
62353                 if (tasks.length) {
62354                     tasks[index].apply(null, arguments);
62355                 }
62356                 return fn.next();
62357             };
62358             fn.next = function () {
62359                 return (index < tasks.length - 1) ? makeCallback(index + 1): null;
62360             };
62361             return fn;
62362         };
62363         return makeCallback(0);
62364     };
62365
62366     async.apply = function (fn) {
62367         var args = Array.prototype.slice.call(arguments, 1);
62368         return function () {
62369             return fn.apply(
62370                 null, args.concat(Array.prototype.slice.call(arguments))
62371             );
62372         };
62373     };
62374
62375     var _concat = function (eachfn, arr, fn, callback) {
62376         var r = [];
62377         eachfn(arr, function (x, cb) {
62378             fn(x, function (err, y) {
62379                 r = r.concat(y || []);
62380                 cb(err);
62381             });
62382         }, function (err) {
62383             callback(err, r);
62384         });
62385     };
62386     async.concat = doParallel(_concat);
62387     async.concatSeries = doSeries(_concat);
62388
62389     async.whilst = function (test, iterator, callback) {
62390         if (test()) {
62391             iterator(function (err) {
62392                 if (err) {
62393                     return callback(err);
62394                 }
62395                 async.whilst(test, iterator, callback);
62396             });
62397         }
62398         else {
62399             callback();
62400         }
62401     };
62402
62403     async.doWhilst = function (iterator, test, callback) {
62404         iterator(function (err) {
62405             if (err) {
62406                 return callback(err);
62407             }
62408             if (test()) {
62409                 async.doWhilst(iterator, test, callback);
62410             }
62411             else {
62412                 callback();
62413             }
62414         });
62415     };
62416
62417     async.until = function (test, iterator, callback) {
62418         if (!test()) {
62419             iterator(function (err) {
62420                 if (err) {
62421                     return callback(err);
62422                 }
62423                 async.until(test, iterator, callback);
62424             });
62425         }
62426         else {
62427             callback();
62428         }
62429     };
62430
62431     async.doUntil = function (iterator, test, callback) {
62432         iterator(function (err) {
62433             if (err) {
62434                 return callback(err);
62435             }
62436             if (!test()) {
62437                 async.doUntil(iterator, test, callback);
62438             }
62439             else {
62440                 callback();
62441             }
62442         });
62443     };
62444
62445     async.queue = function (worker, concurrency) {
62446         if (concurrency === undefined) {
62447             concurrency = 1;
62448         }
62449         function _insert(q, data, pos, callback) {
62450           if(data.constructor !== Array) {
62451               data = [data];
62452           }
62453           _each(data, function(task) {
62454               var item = {
62455                   data: task,
62456                   callback: typeof callback === 'function' ? callback : null
62457               };
62458
62459               if (pos) {
62460                 q.tasks.unshift(item);
62461               } else {
62462                 q.tasks.push(item);
62463               }
62464
62465               if (q.saturated && q.tasks.length === concurrency) {
62466                   q.saturated();
62467               }
62468               async.setImmediate(q.process);
62469           });
62470         }
62471
62472         var workers = 0;
62473         var q = {
62474             tasks: [],
62475             concurrency: concurrency,
62476             saturated: null,
62477             empty: null,
62478             drain: null,
62479             push: function (data, callback) {
62480               _insert(q, data, false, callback);
62481             },
62482             unshift: function (data, callback) {
62483               _insert(q, data, true, callback);
62484             },
62485             process: function () {
62486                 if (workers < q.concurrency && q.tasks.length) {
62487                     var task = q.tasks.shift();
62488                     if (q.empty && q.tasks.length === 0) {
62489                         q.empty();
62490                     }
62491                     workers += 1;
62492                     var next = function () {
62493                         workers -= 1;
62494                         if (task.callback) {
62495                             task.callback.apply(task, arguments);
62496                         }
62497                         if (q.drain && q.tasks.length + workers === 0) {
62498                             q.drain();
62499                         }
62500                         q.process();
62501                     };
62502                     var cb = only_once(next);
62503                     worker(task.data, cb);
62504                 }
62505             },
62506             length: function () {
62507                 return q.tasks.length;
62508             },
62509             running: function () {
62510                 return workers;
62511             }
62512         };
62513         return q;
62514     };
62515
62516     async.cargo = function (worker, payload) {
62517         var working     = false,
62518             tasks       = [];
62519
62520         var cargo = {
62521             tasks: tasks,
62522             payload: payload,
62523             saturated: null,
62524             empty: null,
62525             drain: null,
62526             push: function (data, callback) {
62527                 if(data.constructor !== Array) {
62528                     data = [data];
62529                 }
62530                 _each(data, function(task) {
62531                     tasks.push({
62532                         data: task,
62533                         callback: typeof callback === 'function' ? callback : null
62534                     });
62535                     if (cargo.saturated && tasks.length === payload) {
62536                         cargo.saturated();
62537                     }
62538                 });
62539                 async.setImmediate(cargo.process);
62540             },
62541             process: function process() {
62542                 if (working) return;
62543                 if (tasks.length === 0) {
62544                     if(cargo.drain) cargo.drain();
62545                     return;
62546                 }
62547
62548                 var ts = typeof payload === 'number'
62549                             ? tasks.splice(0, payload)
62550                             : tasks.splice(0);
62551
62552                 var ds = _map(ts, function (task) {
62553                     return task.data;
62554                 });
62555
62556                 if(cargo.empty) cargo.empty();
62557                 working = true;
62558                 worker(ds, function () {
62559                     working = false;
62560
62561                     var args = arguments;
62562                     _each(ts, function (data) {
62563                         if (data.callback) {
62564                             data.callback.apply(null, args);
62565                         }
62566                     });
62567
62568                     process();
62569                 });
62570             },
62571             length: function () {
62572                 return tasks.length;
62573             },
62574             running: function () {
62575                 return working;
62576             }
62577         };
62578         return cargo;
62579     };
62580
62581     var _console_fn = function (name) {
62582         return function (fn) {
62583             var args = Array.prototype.slice.call(arguments, 1);
62584             fn.apply(null, args.concat([function (err) {
62585                 var args = Array.prototype.slice.call(arguments, 1);
62586                 if (typeof console !== 'undefined') {
62587                     if (err) {
62588                         if (console.error) {
62589                             console.error(err);
62590                         }
62591                     }
62592                     else if (console[name]) {
62593                         _each(args, function (x) {
62594                             console[name](x);
62595                         });
62596                     }
62597                 }
62598             }]));
62599         };
62600     };
62601     async.log = _console_fn('log');
62602     async.dir = _console_fn('dir');
62603     /*async.info = _console_fn('info');
62604     async.warn = _console_fn('warn');
62605     async.error = _console_fn('error');*/
62606
62607     async.memoize = function (fn, hasher) {
62608         var memo = {};
62609         var queues = {};
62610         hasher = hasher || function (x) {
62611             return x;
62612         };
62613         var memoized = function () {
62614             var args = Array.prototype.slice.call(arguments);
62615             var callback = args.pop();
62616             var key = hasher.apply(null, args);
62617             if (key in memo) {
62618                 callback.apply(null, memo[key]);
62619             }
62620             else if (key in queues) {
62621                 queues[key].push(callback);
62622             }
62623             else {
62624                 queues[key] = [callback];
62625                 fn.apply(null, args.concat([function () {
62626                     memo[key] = arguments;
62627                     var q = queues[key];
62628                     delete queues[key];
62629                     for (var i = 0, l = q.length; i < l; i++) {
62630                       q[i].apply(null, arguments);
62631                     }
62632                 }]));
62633             }
62634         };
62635         memoized.memo = memo;
62636         memoized.unmemoized = fn;
62637         return memoized;
62638     };
62639
62640     async.unmemoize = function (fn) {
62641       return function () {
62642         return (fn.unmemoized || fn).apply(null, arguments);
62643       };
62644     };
62645
62646     async.times = function (count, iterator, callback) {
62647         var counter = [];
62648         for (var i = 0; i < count; i++) {
62649             counter.push(i);
62650         }
62651         return async.map(counter, iterator, callback);
62652     };
62653
62654     async.timesSeries = function (count, iterator, callback) {
62655         var counter = [];
62656         for (var i = 0; i < count; i++) {
62657             counter.push(i);
62658         }
62659         return async.mapSeries(counter, iterator, callback);
62660     };
62661
62662     async.compose = function (/* functions... */) {
62663         var fns = Array.prototype.reverse.call(arguments);
62664         return function () {
62665             var that = this;
62666             var args = Array.prototype.slice.call(arguments);
62667             var callback = args.pop();
62668             async.reduce(fns, args, function (newargs, fn, cb) {
62669                 fn.apply(that, newargs.concat([function () {
62670                     var err = arguments[0];
62671                     var nextargs = Array.prototype.slice.call(arguments, 1);
62672                     cb(err, nextargs);
62673                 }]))
62674             },
62675             function (err, results) {
62676                 callback.apply(that, [err].concat(results));
62677             });
62678         };
62679     };
62680
62681     var _applyEach = function (eachfn, fns /*args...*/) {
62682         var go = function () {
62683             var that = this;
62684             var args = Array.prototype.slice.call(arguments);
62685             var callback = args.pop();
62686             return eachfn(fns, function (fn, cb) {
62687                 fn.apply(that, args.concat([cb]));
62688             },
62689             callback);
62690         };
62691         if (arguments.length > 2) {
62692             var args = Array.prototype.slice.call(arguments, 2);
62693             return go.apply(this, args);
62694         }
62695         else {
62696             return go;
62697         }
62698     };
62699     async.applyEach = doParallel(_applyEach);
62700     async.applyEachSeries = doSeries(_applyEach);
62701
62702     async.forever = function (fn, callback) {
62703         function next(err) {
62704             if (err) {
62705                 if (callback) {
62706                     return callback(err);
62707                 }
62708                 throw err;
62709             }
62710             fn(next);
62711         }
62712         next();
62713     };
62714
62715     root.async = async;
62716
62717 }());
62718 (function() {
62719
62720     var redblack = {};
62721     var root = this;
62722     var orig = root.redblack;
62723
62724     if (typeof module !== 'undefined' && module.exports) {
62725         module.exports = redblack;
62726     } else {
62727         root.redblack = redblack;
62728     }
62729
62730     redblack.VERSION = '0.1.2';
62731
62732     redblack.noConflict = function() {
62733         root.redblack = orig;
62734         return redblack;
62735     };
62736
62737     redblack.tree = function() {
62738         return new Tree();
62739     };
62740
62741     var BLACK = redblack.BLACK = 'black';
62742     var RED = redblack.RED = 'red';
62743
62744     // Node
62745     // ---------------
62746
62747     function Node(key, value) {
62748         this.key = key;
62749         this.value = value;
62750         this.color = RED;
62751         this.left = null;
62752         this.right = null;
62753         this.parent = null;
62754     };
62755
62756     Node.prototype.grandparent = function() {
62757         if (this.parent === null) return null;
62758         return this.parent.parent;
62759     };
62760
62761     Node.prototype.sibling = function() {
62762         if (this.parent === null) return null;
62763         return this === this.parent.left ? this.parent.right : this.parent.left;
62764     };
62765
62766     Node.prototype.uncle = function() {
62767         if (this.parent === null) return null;
62768         return this.parent.sibling();
62769     };
62770
62771     // Cursor
62772     // ---------------
62773
62774     function Cursor(tree, start, end) {
62775         this.tree = tree;
62776         this.start = start;
62777         this.end = end;
62778
62779         var self = this;
62780         this.walk = function walk(node, iterator) {
62781             if (node === null) return;
62782
62783             if (start !== undefined && node.key < start) {
62784                 walk(node.right, iterator);
62785             } else if (end !== undefined && node.key > end) {
62786                 walk(node.left, iterator);
62787             } else {
62788                 walk(node.left, iterator);
62789                 iterator(node.value, node.key, self.tree);
62790                 walk(node.right, iterator);
62791             }
62792         };
62793     };
62794
62795     Cursor.prototype.forEach = function(iterator) {
62796         this.walk(this.tree.root, iterator);
62797     };
62798
62799     Cursor.prototype.map = function(iterator) {
62800         var results = [];
62801
62802         this.forEach(function(value, key, tree) {
62803             results.push(iterator(value, key, tree));
62804         });
62805
62806         return results;
62807     };
62808
62809     // Tree
62810     // ---------------
62811
62812     function Tree() {
62813         this.root = null;
62814         this.balancer = new Balancer(this);
62815     };
62816
62817     Tree.prototype.get = function(key) {
62818         var node = find(this.root, key);
62819         return node === null ? null : node.value;
62820     };
62821
62822     Tree.prototype.insert = function(key, value) {
62823         var newNode = new Node(key, value);
62824
62825         if (this.root === null) {
62826             this.root = newNode;
62827         } else {
62828             var node = this.root;
62829
62830             while (true) {
62831                 if (key < node.key) {
62832                     if (node.left === null) {
62833                         node.left = newNode;
62834                         break;
62835                     } else {
62836                         node = node.left;
62837                     }
62838                 } else if (key > node.key) {
62839                     if (node.right === null) {
62840                         node.right = newNode;
62841                         break;
62842                     } else {
62843                         node = node.right;
62844                     }
62845                 } else {
62846                     node.value = value;
62847                     return;
62848                 }
62849             }
62850
62851             newNode.parent = node;
62852         }
62853
62854         this.balancer.inserted(newNode);
62855     };
62856
62857     Tree.prototype.delete = function(key) {
62858         var node = find(this.root, key);
62859         if (node === null) return;
62860
62861         if (node.left !== null && node.right !== null) {
62862             var pred = node.left;
62863             while (pred.right !== null) pred = pred.right;
62864
62865             node.key = pred.key;
62866             node.value = pred.value;
62867             node = pred;
62868         }
62869
62870         var child = (node.right === null) ? node.left : node.right;
62871         if (nodeColor(node) === BLACK) {
62872             node.color = nodeColor(child);
62873             this.balancer.deleted(node);
62874         }
62875
62876         this.balancer.replaceNode(node, child);
62877
62878         if (nodeColor(this.root) === RED) {
62879             this.root.color = BLACK;
62880         }
62881     };
62882
62883     Tree.prototype.range = function(start, end) {
62884         return new Cursor(this, start, end);
62885     };
62886
62887     // Proxy cursor methods
62888     for (var method in Cursor.prototype) {
62889         if (Cursor.prototype.hasOwnProperty(method)) {
62890             var func = Cursor.prototype[method];
62891             Tree.prototype[method] = function() {
62892                 var cursor = new Cursor(this);
62893                 return func.apply(cursor, arguments);
62894             };
62895         }
62896     }
62897
62898     // Balancer
62899     // ---------------
62900
62901     function Balancer(tree) {
62902         this.tree = tree;
62903     };
62904
62905     Balancer.prototype.inserted = function(node) {
62906         this.insertCase1(node);
62907     };
62908
62909     Balancer.prototype.deleted = function(node) {
62910         this.deleteCase1(node);
62911     };
62912
62913     Balancer.prototype.replaceNode = function(original, replacement) {
62914         if (original.parent === null) {
62915             this.tree.root = replacement;
62916         } else {
62917             if (original === original.parent.left) {
62918                 original.parent.left = replacement;
62919             } else {
62920                 original.parent.right = replacement;
62921             }
62922         }
62923
62924         if (replacement !== null) {
62925             replacement.parent = original.parent;
62926         }
62927     };
62928
62929     Balancer.prototype.rotateLeft = function(node) {
62930         var right = node.right;
62931         this.replaceNode(node, right);
62932
62933         // Update pointers
62934         node.right = right.left;
62935         if (right.left !== null) right.left.parent = node;
62936         right.left = node;
62937         node.parent = right;
62938     };
62939
62940     Balancer.prototype.rotateRight = function(node) {
62941         var left = node.left;
62942         this.replaceNode(node, left);
62943
62944         // Update pointers
62945         node.left = left.right;
62946         if (left.right !== null) left.right.parent = node;
62947         left.right = node;
62948         node.parent = left;
62949     };
62950
62951     Balancer.prototype.insertCase1 = function(node) {
62952         if (node.parent === null) {
62953             node.color = BLACK;
62954         } else {
62955             this.insertCase2(node);
62956         }
62957     };
62958
62959     Balancer.prototype.insertCase2 = function(node) {
62960         if (nodeColor(node.parent) === BLACK) {
62961             return;
62962         } else {
62963             this.insertCase3(node);
62964         }
62965     };
62966
62967     Balancer.prototype.insertCase3 = function(node) {
62968         var uncle = node.uncle();
62969         var grandparent = node.grandparent();
62970
62971         if (uncle !== null && nodeColor(uncle) === RED) {
62972             node.parent.color = BLACK;
62973             uncle.color = BLACK;
62974             grandparent.color = RED;
62975             this.insertCase1(grandparent);
62976         } else {
62977             this.insertCase4(node);
62978         }
62979     };
62980
62981     Balancer.prototype.insertCase4 = function(node) {
62982         var grandparent = node.grandparent();
62983
62984         if (node === node.parent.right && node.parent === grandparent.left) {
62985             this.rotateLeft(node.parent);
62986             node = node.left;
62987         } else if (node === node.parent.left && node.parent === grandparent.right) {
62988             this.rotateRight(node.parent);
62989             node = node.right;
62990         }
62991
62992         this.insertCase5(node);
62993     };
62994
62995     Balancer.prototype.insertCase5 = function(node) {
62996         var grandparent = node.grandparent();
62997
62998         node.parent.color = BLACK;
62999         grandparent.color = RED;
63000
63001         if (node === node.parent.left && node.parent === grandparent.left) {
63002             this.rotateRight(grandparent);
63003         } else if (node === node.parent.right && node.parent === grandparent.right) {
63004             this.rotateLeft(grandparent);
63005         }
63006     };
63007
63008     Balancer.prototype.deleteCase1 = function(node) {
63009         if (node.parent !== null) this.deleteCase2(node);
63010     };
63011
63012     Balancer.prototype.deleteCase2 = function(node) {
63013         var sibling = node.sibling();
63014
63015         if (nodeColor(sibling) === RED) {
63016             node.parent.color = RED;
63017             sibling.color = BLACK;
63018             if (node === node.parent.left) {
63019                 this.rotateLeft(node.parent);
63020             } else {
63021                 this.rotateRight(node.parent);
63022             }
63023         }
63024
63025         this.deleteCase3(node);
63026     };
63027
63028     Balancer.prototype.deleteCase3 = function(node) {
63029         var sibling = node.sibling();
63030
63031         if (nodeColor(node.parent) === BLACK &&
63032             nodeColor(sibling) === BLACK &&
63033             nodeColor(sibling.left) === BLACK &&
63034             nodeColor(sibling.right) === BLACK) {
63035
63036             sibling.color = RED;
63037             this.deleteCase1(node.parent);
63038         } else {
63039             this.deleteCase4(node);
63040         }
63041     };
63042
63043     Balancer.prototype.deleteCase4 = function(node) {
63044         var sibling = node.sibling();
63045
63046         if (nodeColor(node.parent) === RED &&
63047             nodeColor(sibling) === BLACK &&
63048             nodeColor(sibling.left) === BLACK &&
63049             nodeColor(sibling.right) === BLACK) {
63050
63051             sibling.color = RED;
63052             node.parent.color = BLACK;
63053         } else {
63054             this.deleteCase5(node);
63055         }
63056     };
63057
63058     Balancer.prototype.deleteCase5 = function(node) {
63059         var sibling = node.sibling();
63060
63061         if (node === node.parent.left &&
63062             nodeColor(sibling) === BLACK &&
63063             nodeColor(sibling.left) === RED &&
63064             nodeColor(sibling.right) === BLACK) {
63065
63066             sibling.color = RED;
63067             sibling.left.color = BLACK;
63068             this.rotateRight(sibling);
63069         } else if (node === node.parent.right &&
63070             nodeColor(sibling) === BLACK &&
63071             nodeColor(sibling.right) === RED &&
63072             nodeColor(sibling.left) === BLACK) {
63073
63074             sibling.color = RED;
63075             sibling.right.color = BLACK;
63076             this.rotateLeft(sibling);
63077         }
63078
63079         this.deleteCase6(node);
63080     };
63081
63082     Balancer.prototype.deleteCase6 = function(node) {
63083         var sibling = node.sibling();
63084
63085         sibling.color = nodeColor(node.parent);
63086         node.parent.color = BLACK;
63087
63088         if (node === node.parent.left) {
63089             sibling.right.color = BLACK;
63090             this.rotateLeft(node.parent);
63091         } else {
63092             sibling.left.color = BLACK;
63093             this.rotateRight(node.parent);
63094         }
63095     };
63096
63097     // Helpers
63098     // ---------------
63099
63100     function nodeColor(node) {
63101         return node === null ? BLACK : node.color;
63102     };
63103
63104     function find(node, key) {
63105         while (node !== null) {
63106             if (key === node.key) {
63107                 return node;
63108             } else if (key < node.key) {
63109                 node = node.left;
63110             } else if (key > node.key) {
63111                 node = node.right;
63112             }
63113         }
63114
63115         return node;
63116     };
63117
63118 })();
63119 define.unordered = true;define('ripple/db', function (require, exports, module) {
63120 /*
63121  *  Copyright 2011 Research In Motion Limited.
63122  *
63123  * Licensed under the Apache License, Version 2.0 (the "License");
63124  * you may not use this file except in compliance with the License.
63125  * You may obtain a copy of the License at
63126  *
63127  * http://www.apache.org/licenses/LICENSE-2.0
63128  *
63129  * Unless required by applicable law or agreed to in writing, software
63130  * distributed under the License is distributed on an "AS IS" BASIS,
63131  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63132  * See the License for the specific language governing permissions and
63133  * limitations under the License.
63134  */
63135 var _self,
63136     _db,
63137     utils = require('ripple/utils'),
63138     constants = require('ripple/constants'),
63139     event = require('ripple/event'),
63140     _cache = {};
63141
63142 function _validateAndSetPrefix(prefix) {
63143     if (prefix) {
63144         utils.validateArgumentType(prefix, "string");
63145     }
63146
63147     return prefix || constants.COMMON.PREFIX;
63148 }
63149
63150 function _createKey(key, prefix) {
63151     return _validateAndSetPrefix(prefix) + key;
63152 }
63153
63154 function _createItem(key, value, prefix) {
63155     return {
63156         id: _createKey(key, prefix),
63157         key: key,
63158         value: value,
63159         prefix: _validateAndSetPrefix(prefix)
63160     };
63161 }
63162
63163 function _save(key, value, prefix, callback) {
63164     var item = _createItem(key, value, prefix);
63165     _cache[item.id] = item;
63166
63167     _db.transaction(function (tx) {
63168         tx.executeSql('REPLACE INTO persistence (id, key, value, prefix) VALUES (?, ?, ?, ?)', [item.id, item.key, item.value, item.prefix], function () {
63169             return callback && callback();
63170         });
63171     });
63172 }
63173
63174 function _retrieve(key, prefix) {
63175     var item = _cache[_createKey(key, prefix)];
63176     return item ? item.value : undefined;
63177 }
63178
63179 function _retrieveAll(prefix, callback) {
63180     var result = {};
63181
63182     if (prefix) {
63183         utils.forEach(_cache, function (value, key) {
63184             if (value.prefix === prefix) {
63185                 result[value.key] = value.value;
63186             }
63187         });
63188     }
63189
63190     callback.apply(null, [result]);
63191 }
63192
63193 function _remove(key, prefix, callback) {
63194     delete _cache[_createKey(key, prefix)];
63195
63196     _db.transaction(function (tx) {
63197         tx.executeSql('DELETE FROM persistence WHERE key = ? AND prefix = ?', [key, _validateAndSetPrefix(prefix)], function () {
63198             return callback && callback();
63199         });
63200     });
63201 }
63202
63203 function _removeAll(prefix, callback) {
63204     utils.forEach(_cache, function (value, key) {
63205         if (!prefix || key.indexOf(prefix) === 0) {
63206             delete _cache[key];
63207         }
63208     });
63209
63210     _db.transaction(function (tx) {
63211         if (prefix) {
63212             tx.executeSql('DELETE FROM persistence WHERE prefix = ?', [prefix], function () {
63213                 return callback && callback();
63214             });
63215         } else {
63216             tx.executeSql('DELETE FROM persistence', [], function () {
63217                 return callback && callback();
63218             });
63219         }
63220     });
63221 }
63222
63223 _self = {
63224     save: function (key, value, prefix, callback) {
63225         _save(key, value, prefix, callback);
63226         event.trigger("StorageUpdatedEvent");
63227     },
63228
63229     saveObject: function (key, obj, prefix, callback) {
63230         _save(key, JSON.stringify(obj), prefix, callback);
63231         event.trigger("StorageUpdatedEvent");
63232     },
63233
63234     retrieve: function (key, prefix) {
63235         return _retrieve(key, prefix);
63236     },
63237
63238     retrieveObject: function (key, prefix) {
63239         var retrievedValue = _retrieve(key, prefix);
63240         return retrievedValue ? JSON.parse(retrievedValue) : retrievedValue;
63241     },
63242
63243     retrieveAll: function (prefix, callback) {
63244         return _retrieveAll(prefix, callback);
63245     },
63246
63247     remove: function (key, prefix, callback) {
63248         event.trigger("StorageUpdatedEvent");
63249         _remove(key, prefix, callback);
63250     },
63251
63252     removeAll: function (prefix, callback) {
63253         _removeAll(prefix, callback);
63254         event.trigger("StorageUpdatedEvent");
63255     },
63256
63257     initialize: function (previous, baton) {
63258         baton.take();
63259
63260         _db = openDatabase('tinyHippos', '1.0', 'tiny Hippos persistence', 2 * 1024 * 1024);
63261         _db.transaction(function (tx) {
63262             tx.executeSql('CREATE TABLE IF NOT EXISTS persistence (id unique, key, value, prefix)');
63263
63264             tx.executeSql('SELECT id, key, value, prefix FROM persistence', [], function (tx, results) {
63265                 var len = results.rows.length, i, item;
63266
63267                 for (i = 0; i < len; i++) {
63268                     item = results.rows.item(i);
63269                     _cache[item.id] = item;
63270                 }
63271
63272                 baton.pass();
63273             });
63274         });
63275     }
63276 };
63277
63278 module.exports = _self;
63279
63280 });
63281 define('ripple/fileSystem', function (require, exports, module) {
63282 /*
63283  *  Copyright 2011 Research In Motion Limited.
63284  *
63285  * Licensed under the Apache License, Version 2.0 (the "License");
63286  * you may not use this file except in compliance with the License.
63287  * You may obtain a copy of the License at
63288  *
63289  * http://www.apache.org/licenses/LICENSE-2.0
63290  *
63291  * Unless required by applicable law or agreed to in writing, software
63292  * distributed under the License is distributed on an "AS IS" BASIS,
63293  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63294  * See the License for the specific language governing permissions and
63295  * limitations under the License.
63296  */
63297 var constants = require('ripple/constants'),
63298     db = require('ripple/db'),
63299     exception = require('ripple/exception'),
63300     event = require('ripple/event'),
63301     _console = require('ripple/console'),
63302     utils = require('ripple/utils'),
63303     _fileSystemPaths = {
63304         "photos": { "uri": "" },
63305         "videos": { "uri": "" },
63306         "music": { "uri": "" },
63307         "downloads": { "uri": "" },
63308         "widgethome": { "uri": "" }
63309     },
63310     _fileSystemRegex = {
63311         "photos": { "virtualPathRegex": /^\/virtual\/photos\//i },
63312         "videos": { "virtualPathRegex": /^\/virtual\/videos\//i },
63313         "music": { "virtualPathRegex": /^\/virtual\/music\//i },
63314         "downloads": { "virtualPathRegex": /^\/virtual\/downloads\//i },
63315         "widgethome": { "virtualPathRegex": /^\/virtual\/widgethome\//i }
63316     },
63317     _overrides = {};
63318
63319 module.exports = {
63320     initialize: function () {
63321         _fileSystemPaths = db.retrieveObject(constants.FILESYSTEM.PERSISTENCE_KEY) || _fileSystemPaths;
63322         _fileSystemPaths.widgethome.uri = window.location.protocol + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/') + 1);
63323     },
63324
63325     getURI: function getURI(origURI) {
63326         var newURI = origURI,
63327             found = false;
63328
63329         if (_overrides[origURI]) {
63330             return _overrides[origURI];
63331         }
63332
63333         utils.forEach(_fileSystemPaths, function (value, key) {
63334             if (found) {
63335                 return;
63336             }
63337
63338             var uri = value.uri.replace(/\/$/, "");
63339             if (origURI.match(_fileSystemRegex[key].virtualPathRegex)) {
63340                 newURI = origURI.replace(_fileSystemRegex[key].virtualPathRegex, uri + "/");
63341                 found = true;
63342             }
63343         });
63344
63345         return newURI;
63346     },
63347
63348     exists: function (path) {
63349         try {
63350             var scrubbedUri = this.getURI(path),
63351                 xhr = new XMLHttpRequest();
63352
63353             xhr.open("GET", scrubbedUri, false);
63354             xhr.send();
63355
63356             //HACK: this should return maybe for 403
63357             return xhr.status !== 404;
63358         }
63359         catch (e) {
63360             exception.handle(e);
63361             _console.log("failed to check if [" + path + "] exists");
63362             return false;
63363         }
63364     },
63365
63366
63367     getFileSystemPaths: function getFileSystemPaths() {
63368         return utils.copy(_fileSystemPaths);
63369     },
63370
63371     updateFileSystemPaths: function updateFileSystemPaths(filePathsObject) {
63372         _fileSystemPaths = utils.copy(filePathsObject);
63373         _fileSystemPaths.widgethome.uri = window.location.protocol + "//" + window.location.host + window.location.pathname;
63374         db.saveObject(constants.FILESYSTEM.PERSISTENCE_KEY, filePathsObject);
63375     },
63376
63377     override : function (from, to) {
63378         _overrides[from] = to;
63379     }
63380 };
63381
63382 });
63383 define('ripple/notifications', function (require, exports, module) {
63384 /*
63385  *  Copyright 2011 Research In Motion Limited.
63386  *
63387  * Licensed under the Apache License, Version 2.0 (the "License");
63388  * you may not use this file except in compliance with the License.
63389  * You may obtain a copy of the License at
63390  *
63391  * http://www.apache.org/licenses/LICENSE-2.0
63392  *
63393  * Unless required by applicable law or agreed to in writing, software
63394  * distributed under the License is distributed on an "AS IS" BASIS,
63395  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63396  * See the License for the specific language governing permissions and
63397  * limitations under the License.
63398  */
63399 var constants = require('ripple/constants'),
63400     exception = require('ripple/exception'),
63401     utils = require('ripple/utils'),
63402     event = require('ripple/event');
63403
63404 function _validateAndInitNType(nType) {
63405     nType = nType || "normal";
63406
63407     if (nType !== "normal" && nType !== "error") {
63408         exception.raise(exception.types.NotificationType, "Unknown Notification Type == " + nType + ",when dealing with Console notification.");
63409     }
63410
63411     return nType;
63412 }
63413
63414 function _processNotification(nType, stateType, message) {
63415     nType = _validateAndInitNType(nType);
63416     message = message || "";
63417
63418     var display,
63419         displayText,
63420         className,
63421         notificationIcon,
63422         box = document.getElementById(constants.NOTIFICATIONS.MAIN_CONTAINER_CLASS),
63423         msgBox = document.getElementById(constants.NOTIFICATIONS.MESSAGE_TEXT_CONTAINER_CLASS);
63424
63425     className = "ui-widget";
63426
63427     switch (stateType) {
63428
63429     case constants.NOTIFICATIONS.STATE_TYPES.CLOSE:
63430         display = "display: none;"; //need to do this better.
63431         displayText = "";
63432         break;
63433
63434     case constants.NOTIFICATIONS.STATE_TYPES.OPEN:
63435         display = "display: block;"; //need to do this better.
63436         displayText = message;
63437         if (nType === "error") {
63438             displayText = "Oh Snap!\n\n" + displayText;
63439             className += " ui-state-error ui-corner-all";
63440             notificationIcon = '<span class="ui-icon ui-icon-alert" style="float: left; margin-right: .3em;"></span>';
63441         }
63442         else {
63443             className += " ui-state-highlight ui-corner-all";
63444             notificationIcon = '<span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>';
63445         }
63446         break;
63447
63448     default:
63449         exception.raise(exception.types.NotificationStateType, "Unknown StateType == " + stateType.toString());
63450     }
63451
63452     msgBox.innerHTML = notificationIcon + displayText;
63453     box.setAttribute("class", className);
63454     box.setAttribute("style", display);
63455
63456 }
63457
63458 module.exports = {
63459     openNotification: function (nType, msg) {
63460         _processNotification(nType, constants.NOTIFICATIONS.STATE_TYPES.OPEN, msg);
63461     },
63462
63463     closeNotification: function (nType) {
63464         _processNotification(nType, constants.NOTIFICATIONS.STATE_TYPES.CLOSE);
63465     }
63466 };
63467
63468 });
63469 define('ripple/exception', function (require, exports, module) {
63470 /*
63471  *  Copyright 2011 Research In Motion Limited.
63472  *
63473  * Licensed under the Apache License, Version 2.0 (the "License");
63474  * you may not use this file except in compliance with the License.
63475  * You may obtain a copy of the License at
63476  *
63477  * http://www.apache.org/licenses/LICENSE-2.0
63478  *
63479  * Unless required by applicable law or agreed to in writing, software
63480  * distributed under the License is distributed on an "AS IS" BASIS,
63481  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63482  * See the License for the specific language governing permissions and
63483  * limitations under the License.
63484  */
63485 var _console = require('ripple/console');
63486
63487 function _getStack(depth) {
63488     var caller,
63489         stack = "",
63490         count = 0;
63491
63492     try {
63493         caller = arguments.callee.caller.arguments.callee.caller;
63494
63495         while (count <= depth && caller) {
63496             stack += "function: " + caller.toString().match(/function\s?(.*)\{/)[1] + "\n";
63497             caller = caller.arguments.callee.caller;
63498             count++;
63499         }
63500     } catch (e) {
63501         stack = "failed to determine stack trace (" + (e.name || e.type) + " :: " + e.message + ")";
63502     }
63503
63504     return stack;
63505 }
63506
63507 module.exports = {
63508
63509     types: {
63510         Application: "Application",
63511         ArgumentLength: "ArgumentLength",
63512         ArgumentType: "ArgumentType",
63513         Argument: "Argument",
63514         NotificationType: "NotificationType",
63515         NotificationStateType: "NotificationStateType",
63516         DomObjectNotFound: "DomObjectNotFound",
63517         LayoutType: "LayoutType",
63518         OrientationType: "OrientationType",
63519         DeviceNotFound: "DeviceNotFound",
63520         tinyHipposMaskedException: "tinyHipposMaskedException",
63521         Geo: "Geo",
63522         Accelerometer: "Accelerometer",
63523         MethodNotImplemented: "MethodNotImplemented",
63524         InvalidState: "InvalidState",
63525         ApplicationState: "ApplicationState"
63526     },
63527
63528     handle: function handle(exception, reThrow) {
63529         reThrow = reThrow || false;
63530
63531         var eMsg = exception.message || "exception caught!",
63532         msg = eMsg + "\n\n" + (exception.stack || "*no stack provided*") + "\n\n";
63533
63534         _console.error(msg);
63535
63536         if (reThrow) {
63537             throw exception;
63538         }
63539     },
63540
63541     raise: function raise(exceptionType, message, customExceptionObject) {
63542         var obj = customExceptionObject || {
63543                 type: "",
63544                 message: "",
63545
63546                 toString: function () {
63547                     var result = this.name + ': "' + this.message + '"';
63548
63549                     if (this.stack) {
63550                         result += "\n" + this.stack;
63551                     }
63552                     return result;
63553                 }
63554             };
63555
63556         message = message || "";
63557
63558         obj.name = exceptionType;
63559         obj.type = exceptionType;
63560         // TODO: include the exception objects original message if exists
63561         obj.message = message;
63562         obj.stack = _getStack(5);
63563
63564         throw obj;
63565     },
63566
63567     throwMaskedException: function throwMaskedException(exceptionType, message, customExceptionObject) {
63568         try {
63569             this.raise.apply(this, arguments);
63570         } catch (e) {
63571             this.handle(e);
63572         }
63573         this.raise(this.types.tinyHipposMaskedException, "tinyhippos terminated your script due to exception");
63574     }
63575
63576 };
63577
63578 });
63579 define('ripple/widgetConfig', function (require, exports, module) {
63580 /*
63581  *  Copyright 2011 Research In Motion Limited.
63582  *
63583  * Licensed under the Apache License, Version 2.0 (the "License");
63584  * you may not use this file except in compliance with the License.
63585  * You may obtain a copy of the License at
63586  *
63587  * http://www.apache.org/licenses/LICENSE-2.0
63588  *
63589  * Unless required by applicable law or agreed to in writing, software
63590  * distributed under the License is distributed on an "AS IS" BASIS,
63591  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63592  * See the License for the specific language governing permissions and
63593  * limitations under the License.
63594  */
63595 var exception = require('ripple/exception'),
63596     event = require('ripple/event'),
63597     app = require('ripple/app'),
63598     _console = require('ripple/console'),
63599     utils = require('ripple/utils'),
63600     platform = require('ripple/platform'),
63601     _validationResult = {
63602         valid: false,
63603         message: "",
63604         value: null
63605     },
63606     _configValidationResults = null;
63607
63608 function _failNodeValidation(schemaNode, message, value, node) {
63609     var validationResult = utils.copy(_validationResult);
63610
63611     if (!schemaNode.validationResult) {
63612         schemaNode.validationResult = [];
63613     }
63614     validationResult.valid = false;
63615     if (value) {
63616         validationResult.value = value;
63617     }
63618     else {
63619         delete(validationResult.value);
63620     }
63621     validationResult.message = schemaNode.nodeName + message;
63622     validationResult.node = node;
63623
63624     schemaNode.validationResult.push(validationResult);
63625 }
63626
63627 function _createEmptyNodeValidation(node) {
63628
63629     var validationResult = utils.copy(_validationResult),
63630         attributeValidationResult, attribute;
63631
63632     if (!node.validationResult) {
63633         node.validationResult = [];
63634     }
63635
63636     validationResult.value = "";
63637     delete(validationResult.valid);
63638     delete(validationResult.message);
63639
63640     if (node.attributes) {
63641         for (attribute in node.attributes) {
63642             if (node.attributes.hasOwnProperty(attribute)) {
63643                 if (!validationResult.attributes) {
63644                     validationResult.attributes = {};
63645                 }
63646
63647                 attributeValidationResult = utils.copy(_validationResult);
63648
63649                 attributeValidationResult.attributeName = node.attributes[attribute].attributeName;
63650                 delete(attributeValidationResult.value);
63651                 delete(attributeValidationResult.valid);
63652                 delete(attributeValidationResult.message);
63653
63654                 validationResult.attributes[attributeValidationResult.attributeName] = attributeValidationResult;
63655             }
63656         }
63657     }
63658
63659     node.validationResult.push(validationResult);
63660 }
63661
63662 function _validateValue(valueToTest, schemaNode) {
63663     var failMessage = "",
63664         nodeValue,
63665         numbers,
63666         numberRangeIndex,
63667         numberRange,
63668         range1,
63669         range2;
63670
63671     switch (schemaNode.type) {
63672     case "string":
63673         if (typeof valueToTest !== "string") {
63674             failMessage = " value was expected to be of type string but was typeof: " + typeof(valueToTest);
63675         }
63676         break;
63677     case "number":
63678         nodeValue = parseFloat(valueToTest);
63679         if (isNaN(nodeValue)) {
63680             failMessage = " value was expected to be of type number but was typeof: " + typeof(valueToTest);
63681         }
63682         break;
63683     case "integer":
63684         nodeValue = parseInt(valueToTest, 10);
63685         if (isNaN(nodeValue)) {
63686             failMessage = " value was expected to be of type number but was typeof: " + typeof(valueToTest);
63687         }
63688         break;
63689     case "boolean":
63690         if (valueToTest !== "false" && valueToTest !== "true") {
63691             failMessage = " value was expected to be of type boolean (i.e. 'true' or 'false' but was: " + valueToTest;
63692         }
63693         break;
63694     case "list":
63695         if (!utils.arrayContains(schemaNode.listValues, valueToTest)) {
63696             failMessage = " value is not recognized as being valid, it was:<br/><br/><span class=\"ui-text-fail\">" + valueToTest +
63697                     "</span><br/><br/>Valid values are:<p class=\"ui-text-pass\">" + schemaNode.listValues.join(" <br/> ") + "</p>";
63698         }
63699         break;
63700     case "listBoolean":
63701     case "listDefault":
63702         if (!utils.arrayContains(schemaNode.listValues, valueToTest)) {
63703             failMessage = " value is not recognized as being valid, it was:<br/><br/><span class=\"ui-text-fail\">" + valueToTest +
63704                     "</span><br/><br/>The framework will assume the value to be:<p class=\"ui-text-pass\">" + schemaNode.defaultValue + "</p>";
63705         }
63706         break;
63707     case "listNumbers":
63708         numbers = valueToTest.split(",");
63709
63710         for (numberRangeIndex = 0; numberRangeIndex < numbers.length; numberRangeIndex++) {
63711             numberRange = valueToTest.split("-");
63712             if (numberRange.length > 1) {
63713                 range1 = parseInt(numberRange[0], 10);
63714                 range2 = parseInt(numberRange[1], 10);
63715                 if (isNaN(range1) || isNaN(range2)) {
63716                     failMessage = " range values where not recognized as being valid, they was: " + range1 +
63717                             " and " + range2 + " :: valid values should be of type 'integer'";
63718                     break;
63719                 }
63720             }
63721             else if (numberRange.length === 1) {
63722                 range1 = parseInt(numberRange[0], 10);
63723                 if (isNaN(range1)) {
63724                     failMessage = " value was not recognized as being valid, it was: " + range1 +
63725                             " :: valid values should be of type 'integer'";
63726                     break;
63727                 }
63728             }
63729         }
63730         break;
63731     case "regex":
63732         if (!valueToTest.match(schemaNode.regex)) {
63733             failMessage = " value does not match expected format. Value should pass this regular expression validation: " + schemaNode.regex;
63734         }
63735         break;
63736     case "iso-language":
63737         break;
63738     default:
63739         exception.raise(exception.types.Application, "Schema node with value type of: " + schemaNode.type + " is not known");
63740     }
63741
63742     return failMessage;
63743 }
63744
63745 function _passNodeValidation(schemaNode, value, node) {
63746     var validationResult = utils.copy(_validationResult);
63747
63748     if (!schemaNode.validationResult) {
63749         schemaNode.validationResult = [];
63750     }
63751     validationResult.valid = true;
63752     validationResult.node = node;
63753     if (value) {
63754         validationResult.value = value;
63755     }
63756     else {
63757         delete(validationResult.value);
63758     }
63759     delete(validationResult.message);
63760
63761     schemaNode.validationResult.push(validationResult);
63762 }
63763
63764 function _validateNodeValue(schemaNode, node) {
63765     var failMessage,
63766         valueToTest = node && node.nodeValue ? node.nodeValue.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : null;
63767
63768     if (schemaNode.type && valueToTest) {
63769
63770         failMessage = _validateValue(valueToTest, schemaNode);
63771
63772         if (failMessage !== "") {
63773             _failNodeValidation(schemaNode, failMessage, valueToTest, node);
63774             return;
63775         }
63776     }
63777     _passNodeValidation(schemaNode, valueToTest, node);
63778 }
63779
63780 function _failNodeAttributeValidation(node, attribute, message, value) {
63781     var nodeValidationResult = node.validationResult ? node.validationResult.pop() : utils.copy(_validationResult),
63782         attributeValidationResult = utils.copy(_validationResult);
63783
63784     if (!nodeValidationResult.attributes) {
63785         nodeValidationResult.attributes = {};
63786     }
63787
63788     nodeValidationResult.valid = false;
63789     nodeValidationResult.message = "One or more attributes failed validation";
63790
63791     attributeValidationResult.attributeName = attribute.attributeName;
63792     attributeValidationResult.valid = false;
63793     if (value) {
63794         attributeValidationResult.value = value;
63795     }
63796     else {
63797         delete(attributeValidationResult.value);
63798     }
63799     attributeValidationResult.message = node.nodeName + "." + attribute.attributeName + message;
63800
63801     nodeValidationResult.attributes[attribute.attributeName] = attributeValidationResult;
63802     node.validationResult.push(nodeValidationResult);
63803 }
63804
63805 function _passNodeAttributeValidation(node, attribute, value) {
63806     var nodeValidationResult = node.validationResult ? node.validationResult.pop() : utils.copy(_validationResult),
63807         attributeValidationResult = utils.copy(_validationResult);
63808
63809     if (!nodeValidationResult.attributes) {
63810         nodeValidationResult.attributes = {};
63811     }
63812
63813     attributeValidationResult.attributeName = attribute.attributeName;
63814     attributeValidationResult.valid = true;
63815     if (value) {
63816         attributeValidationResult.value = value;
63817     }
63818     else {
63819         delete(attributeValidationResult.value);
63820     }
63821     delete(attributeValidationResult.message);
63822
63823     nodeValidationResult.attributes[attribute.attributeName] = attributeValidationResult;
63824     node.validationResult.push(nodeValidationResult);
63825 }
63826
63827 function _validateNodeAttributeValue(schemaNode, schemaNodeAttribute, attribute) {
63828     var failMessage,
63829         valueToTest = attribute ? attribute.value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : null;
63830
63831     if (schemaNodeAttribute.type && valueToTest) {
63832
63833         failMessage = _validateValue(valueToTest, schemaNodeAttribute);
63834
63835         if (failMessage !== "") {
63836             _failNodeAttributeValidation(schemaNode, schemaNodeAttribute, failMessage, valueToTest);
63837             return;
63838         }
63839     }
63840     _passNodeAttributeValidation(schemaNode, schemaNodeAttribute, valueToTest);
63841 }
63842
63843 function _validateNodeAttributes(schemaNode, node, children) {
63844
63845     var siblings = utils.filter(children, function (child) {
63846             return child !== node;
63847         }),
63848         attributeConverter = function (attribute) {
63849             var _self = {
63850                 toValue: function (n) {
63851                     var obj = _self.toNode(n);
63852                     return obj ? obj.value : null;
63853                 },
63854                 toNode: function (n) {
63855                     return n.attributes.getNamedItem(attribute.attributeName);
63856                 }
63857             };
63858
63859             return _self;
63860         };
63861
63862     utils.forEach(schemaNode.attributes, function (attribute) {
63863
63864         var convert = attributeConverter(attribute),
63865             dupe = false;
63866
63867         if (attribute.unique) {
63868             // this means we need to check and see if there are other node with the same name
63869             // and ensure that they have a different value for this attributes, if not... fail
63870
63871             dupe = siblings.some(function (sibling) {
63872                 return convert.toValue(sibling) === convert.toValue(node);
63873             });
63874
63875             if (dupe) {
63876                 _failNodeAttributeValidation(schemaNode,
63877                         attribute,
63878                         " node is allowed to appear multiple times, however it must be unique based on this attribute and in this case another node with an identical attribute vale was found",
63879                         convert.toValue(node));
63880                 return;
63881             }
63882         }
63883
63884         if (attribute.required && !convert.toValue(node)) {
63885             _failNodeAttributeValidation(schemaNode, attribute, " attribute was expected but not found", null);
63886         }
63887         else {
63888             _validateNodeAttributeValue(schemaNode, attribute, convert.toNode(node));
63889         }
63890     });
63891 }
63892
63893
63894 function _validateNode(schemaNode, parentNode) {
63895     var children = utils.filter(parentNode.childNodes, function (child) {
63896         return child && child.nodeName === schemaNode.nodeName;
63897     });
63898
63899     if (children.length === 0) {
63900         if (schemaNode.required) {
63901             _failNodeValidation(schemaNode, " node expected, but not found", null, null);
63902         }
63903     }
63904
63905     utils.forEach(children, function (child) {
63906         if (schemaNode.occurrence !== 0 && schemaNode.occurrence < children.length) {
63907             _failNodeValidation(schemaNode, " node: more then " + schemaNode.occurrence + " node(s) found", null, child);
63908         }
63909         else {
63910             _validateNodeValue(schemaNode, child.childNodes[0] || child);
63911
63912             _validateNodeAttributes(schemaNode, child, children);
63913         }
63914
63915         utils.forEach(schemaNode.children, function (schema) {
63916             _validateNode(schema, child);
63917         });
63918     });
63919 }
63920
63921 function _validateAgainstSchemaNode(configSchema, configXML) {
63922     var results = utils.copy(configSchema);
63923     try {
63924         _validateNode(results[configSchema.rootElement], configXML);
63925     }
63926     catch (e) {
63927         exception.handle(e, true);
63928     }
63929
63930     return results;
63931 }
63932
63933 function _validate(configXML) {
63934     // traverse the config schema JSON object
63935     // TODO: update to get platform.getPlatformConfigSpec().schema
63936     return _validateAgainstSchemaNode(platform.current().config.schema, configXML);
63937 }
63938
63939 function _process(results) {
63940     // Check to make sure that widget is the correct version (i.e. config.xml needs to match selected platform)
63941     var validVersion = app.validateVersion(results);
63942
63943     if (!validVersion) {
63944         _console.warn("Your application does not appear to match" +
63945                 " the platform you have selected. The version number in your configuration might not " +
63946                 "match the selected platform version or your configuration file has errors in it.");
63947     }
63948
63949     // save widget info
63950     app.saveInfo(results);
63951     event.trigger("WidgetInformationUpdated");
63952
63953     // Check for readonly preferences (WAC only?)
63954
63955     if (app.getInfo().preferences !== {}) {
63956         event.trigger("StorageUpdatedEvent");
63957     }
63958 }
63959
63960 function _xmlToJson(xml) {
63961     var obj = {};
63962
63963     if (xml.nodeType === 1) { // element
63964         if (xml.attributes.length > 0) {
63965             obj["@attributes"] = {};
63966             utils.forEach(xml.attributes, function (attribute) {
63967                 obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
63968             });
63969         }
63970     } 
63971     else if (xml.nodeType === 3) { // text node
63972         obj = xml.nodeValue;
63973     }
63974
63975     if (xml.hasChildNodes && xml.hasChildNodes()) {
63976         utils.forEach(xml.childNodes, function (child) {
63977             if (!child.nodeName) {
63978                 return;
63979             }
63980             if (!obj[child.nodeName]) {
63981                 obj[child.nodeName] = [];
63982             }
63983             obj[child.nodeName].push(_xmlToJson(child));
63984         });
63985     }
63986
63987     return obj;
63988 }
63989
63990 module.exports = {
63991
63992     validate: function (configXML) {
63993         utils.validateNumberOfArguments(1, 1, arguments.length);
63994         return _validate(configXML);
63995     },
63996
63997     initialize: function (previous, baton) {
63998         var xmlHttp = new XMLHttpRequest(),
63999             config = platform.current().config,
64000             fileName = config ? config.fileName : null,
64001             results;
64002
64003         if (!fileName) {
64004             return;
64005         }
64006
64007         try {
64008             xmlHttp.open("GET", utils.appLocation() + fileName, false);
64009             xmlHttp.send();
64010             if (xmlHttp.responseXML) {
64011                 results = _validate(xmlHttp.responseXML);
64012                 results.rawJSON = _xmlToJson(xmlHttp.responseXML);
64013                 _process(results);
64014                 _configValidationResults = results;
64015             }
64016             else {
64017                 _process();
64018                 _configValidationResults = null;
64019                 require('ripple/ui/plugins/widgetConfig').initialize();
64020             }
64021         }
64022         catch (e) {
64023             exception.handle(e);
64024         }
64025     },
64026
64027     getValidationResults: function () {
64028         return _configValidationResults;
64029     }
64030 };
64031
64032 });
64033 define('ripple/devices/PalmPre', function (require, exports, module) {
64034 /*
64035  *  Copyright 2011 Research In Motion Limited.
64036  *
64037  * Licensed under the Apache License, Version 2.0 (the "License");
64038  * you may not use this file except in compliance with the License.
64039  * You may obtain a copy of the License at
64040  *
64041  * http://www.apache.org/licenses/LICENSE-2.0
64042  *
64043  * Unless required by applicable law or agreed to in writing, software
64044  * distributed under the License is distributed on an "AS IS" BASIS,
64045  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64046  * See the License for the specific language governing permissions and
64047  * limitations under the License.
64048  */
64049 module.exports = {
64050     "id": "PalmPre",
64051     "name": "Palm Pre",
64052     "manufacturer": "Palm",
64053     "model": "Pre",
64054     "osName": "WebOS",
64055     "osVersion": "1.x",
64056
64057     "screen": {
64058         "width": 320,
64059         "height": 480
64060     },
64061     "viewPort": {
64062         "portrait": {
64063             "width": 320,
64064             "height": 480,
64065             "paddingTop": 0,
64066             "paddingLeft": 0
64067         },
64068         "landscape": {
64069             "width": 480,
64070             "height": 320,
64071             "paddingTop": 0,
64072             "paddingLeft": 0
64073         }
64074     },
64075
64076     "ppi": 186.09,
64077     "userAgent": "Mozilla/5.0 (webOS/1.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/1.0",
64078     "platforms": ["web", "phonegap"],
64079
64080     "notes": {
64081         "1": "<a href=\"http://www.palm.com/us/products/phones/pre/#tab2\" target=\"_blank\">Specs</a>"
64082     }
64083 };
64084
64085 });
64086 define('ripple/devices/Bold9900', function (require, exports, module) {
64087 /*
64088  *  Copyright 2011 Research In Motion Limited.
64089  *
64090  * Licensed under the Apache License, Version 2.0 (the "License");
64091  * you may not use this file except in compliance with the License.
64092  * You may obtain a copy of the License at
64093  *
64094  * http://www.apache.org/licenses/LICENSE-2.0
64095  *
64096  * Unless required by applicable law or agreed to in writing, software
64097  * distributed under the License is distributed on an "AS IS" BASIS,
64098  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64099  * See the License for the specific language governing permissions and
64100  * limitations under the License.
64101  */
64102 module.exports = {
64103
64104     "id": "Bold9900",
64105     "name": "BlackBerry Bold 9900",
64106     "model": "9900",
64107     "osName": "BlackBerry OS",
64108     "uuid": "42",
64109     "osVersion": "7",
64110     "manufacturer": "Research In Motion",
64111
64112     "skin": "Bold9900",
64113
64114     "capabilities": [
64115         "input.touch",
64116         "location.gps",
64117         "location.maps",
64118         "media.audio.capture",
64119         "media.video.capture",
64120         "media.recording",
64121         "storage.memorycard",
64122         "network.bluetooth",
64123         "network.wlan",
64124         "network.3gpp"
64125     ],
64126
64127     "screen": {
64128         "width": 640,
64129         "height": 480
64130     },
64131     "viewPort": {
64132         "portrait": {
64133             "width": 640,
64134             "height": 480,
64135             "paddingTop": 0,
64136             "paddingLeft": 0
64137         }
64138     },
64139
64140     "ppi": 287.00,
64141     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.141 Mobile Safari/534.1",
64142     "platforms": ["web", "phonegap", "webworks.handset", "cordova"]
64143 };
64144
64145 });
64146 define('ripple/devices/NexusS', function (require, exports, module) {
64147 /*
64148  *  Copyright 2011 Research In Motion Limited.
64149  *
64150  * Licensed under the Apache License, Version 2.0 (the "License");
64151  * you may not use this file except in compliance with the License.
64152  * You may obtain a copy of the License at
64153  *
64154  * http://www.apache.org/licenses/LICENSE-2.0
64155  *
64156  * Unless required by applicable law or agreed to in writing, software
64157  * distributed under the License is distributed on an "AS IS" BASIS,
64158  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64159  * See the License for the specific language governing permissions and
64160  * limitations under the License.
64161  */
64162 module.exports = {
64163     "id" : "NexusS",
64164     "name": "Nexus S",
64165     "manufacturer": "Samsung",
64166     "model": "Nexux S",
64167     "osName": "Android",
64168     "uuid" : "F54E13F1-C1B7-4212-BFA8-AB3C9C3F088F",
64169     "osVersion": "2.3.x",
64170
64171     "screen": {
64172         "width": 480,
64173         "height": 800
64174     },
64175     "viewPort": {
64176         "portrait": {
64177             "width": 480,
64178             "height": 800,
64179             "paddingTop": 0,
64180             "paddingLeft": 0
64181         },
64182         "landscape": {
64183             "width": 800,
64184             "height": 480,
64185             "paddingTop": 0,
64186             "paddingLeft": 0
64187         }
64188     },
64189
64190     "ppi": 235,
64191     "userAgent": "Mozilla/5.0 (Linux; U; Android 2.3.2; en-us; Nexus S Build/GRH78C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1",
64192     "platforms": ["web", "phonegap", "cordova"],
64193
64194     "notes": {
64195         "1": "<a href=\"http://www.google.com/nexus/#/tech-specs\" target=\"_blank\">Specs</a>"
64196     }
64197
64198 };
64199
64200 });
64201 define('ripple/devices/Playbook', function (require, exports, module) {
64202 /*
64203  *  Copyright 2011 Research In Motion Limited.
64204  *
64205  * Licensed under the Apache License, Version 2.0 (the "License");
64206  * you may not use this file except in compliance with the License.
64207  * You may obtain a copy of the License at
64208  *
64209  * http://www.apache.org/licenses/LICENSE-2.0
64210  *
64211  * Unless required by applicable law or agreed to in writing, software
64212  * distributed under the License is distributed on an "AS IS" BASIS,
64213  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64214  * See the License for the specific language governing permissions and
64215  * limitations under the License.
64216  */
64217 module.exports = {
64218
64219     "id": "Playbook",
64220     "name": "BlackBerry Playbook",
64221     "model": "100669958",
64222     "osName": "BlackBerry PlayBook OS",
64223     "uuid": "42",
64224     "osVersion": "BlackBerry PlayBook OS",
64225     "manufacturer": "Research In Motion",
64226
64227     "skin": "Playbook",
64228
64229     "capabilities": [
64230         "input.touch",
64231         "location.gps",
64232         "media.audio.capture",
64233         "media.video.capture",
64234         "media.recording",
64235         "network.bluetooth",
64236         "network.wlan"
64237     ],
64238
64239     "screen": {
64240         "width": 1024,
64241         "height": 600
64242     },
64243     "viewPort": {
64244         "portrait": {
64245             "width": 1024,
64246             "height": 600,
64247             "paddingTop": 0,
64248             "paddingLeft": 0
64249         },
64250         "landscape": {
64251             "width": 600,
64252             "height": 1024,
64253             "paddingTop": 0,
64254             "paddingLeft": 0
64255         }
64256     },
64257
64258     "defaultOrientation": "landscape",
64259
64260     "ppi": 169.55,
64261     "userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+",
64262     "platforms": ["web", "webworks.tablet", "phonegap", "cordova"]
64263 };
64264
64265 });
64266 define('ripple/devices/tizen-WVGA', function (require, exports, module) {
64267 /*
64268  *  Copyright 2011 Research In Motion Limited.
64269  *
64270  * Licensed under the Apache License, Version 2.0 (the "License");
64271  * you may not use this file except in compliance with the License.
64272  * You may obtain a copy of the License at
64273  *
64274  * http://www.apache.org/licenses/LICENSE-2.0
64275  *
64276  * Unless required by applicable law or agreed to in writing, software
64277  * distributed under the License is distributed on an "AS IS" BASIS,
64278  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64279  * See the License for the specific language governing permissions and
64280  * limitations under the License.
64281  */
64282 module.exports = {
64283     "id": "tizen-WVGA",
64284     "name": "Tizen WVGA (480x800)",
64285     "osName": "Generic",
64286     "osVersion": "Generic",
64287     "manufacturer": "Tizen",
64288     "model": "Generic",
64289     "uuid": "42",
64290
64291     "screen": {
64292         "width": 480,
64293         "height": 800
64294     },
64295     "viewPort": {
64296         "portrait": {
64297             "width": 320,
64298             "height": 534,
64299             "paddingTop": 0,
64300             "paddingLeft": 0
64301         },
64302         "landscape": {
64303             "width": 534,
64304             "height": 320,
64305             "paddingTop": 0,
64306             "paddingLeft": 0
64307         }
64308     },
64309
64310     "ppi": 316,
64311     "browser": ["Generic"],
64312     "platforms": ["web", "phonegap", "tizen", "cordova"],
64313     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
64314 };
64315
64316 });
64317 define('ripple/devices/Pearl9100', function (require, exports, module) {
64318 /*
64319  *  Copyright 2011 Research In Motion Limited.
64320  *
64321  * Licensed under the Apache License, Version 2.0 (the "License");
64322  * you may not use this file except in compliance with the License.
64323  * You may obtain a copy of the License at
64324  *
64325  * http://www.apache.org/licenses/LICENSE-2.0
64326  *
64327  * Unless required by applicable law or agreed to in writing, software
64328  * distributed under the License is distributed on an "AS IS" BASIS,
64329  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64330  * See the License for the specific language governing permissions and
64331  * limitations under the License.
64332  */
64333 module.exports = {
64334
64335     "id": "Pearl9100",
64336     "name": "BlackBerry Pearl 9100",
64337     "model": "9100",
64338     "osName": "BlackBerry OS",
64339     "uuid": "42",
64340     "osVersion": "6",
64341     "manufacturer": "Research In Motion",
64342
64343     "skin": "Pearl9100",
64344
64345     "capabilities": [
64346         "input.keyboard.issuretype",
64347         "location.gps",
64348         "location.maps",
64349         "media.audio.capture",
64350         "media.video.capture",
64351         "media.recording",
64352         "storage.memorycard",
64353         "network.bluetooth",
64354         "network.wlan",
64355         "network.3gpp"
64356     ],
64357
64358     "screen": {
64359         "width": 360,
64360         "height": 400
64361     },
64362     "viewPort": {
64363         "portrait": {
64364             "width": 360,
64365             "height": 400,
64366             "paddingTop": 0,
64367             "paddingLeft": 0
64368         }
64369     },
64370
64371     "ppi": 239,
64372     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9100; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
64373     "platforms": ["web", "phonegap", "webworks.handset"]
64374 };
64375
64376 });
64377 define('ripple/devices/iPhone3', function (require, exports, module) {
64378 /*
64379  *  Copyright 2011 Research In Motion Limited.
64380  *
64381  * Licensed under the Apache License, Version 2.0 (the "License");
64382  * you may not use this file except in compliance with the License.
64383  * You may obtain a copy of the License at
64384  *
64385  * http://www.apache.org/licenses/LICENSE-2.0
64386  *
64387  * Unless required by applicable law or agreed to in writing, software
64388  * distributed under the License is distributed on an "AS IS" BASIS,
64389  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64390  * See the License for the specific language governing permissions and
64391  * limitations under the License.
64392  */
64393 module.exports = {
64394
64395     "id": "iPhone3",
64396     "name": "iPhone 3G/3Gs/4/4s",
64397     "model": "3G",
64398     "osName": "iPhone",
64399     "osVersion": "3",
64400     "uuid": "e0101010d38bde8e6740011221af335301010333",
64401     "manufacturer": "Apple",
64402
64403     "screen": {
64404         "width": 320,
64405         "height": 480
64406     },
64407     "viewPort": {
64408         "portrait": {
64409             "width": 320,
64410             "height": 480,
64411             "paddingTop": 0,
64412             "paddingLeft": 0
64413         },
64414         "landscape": {
64415             "width": 480,
64416             "height": 320,
64417             "paddingTop": 0,
64418             "paddingLeft": 0
64419         }
64420     },
64421
64422     "ppi": 164.8,
64423     "userAgent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3",
64424     "platforms": ["web", "phonegap", "cordova"]
64425 };
64426
64427 });
64428 define('ripple/devices/HD', function (require, exports, module) {
64429 /*
64430  *  Copyright 2012 Intel Corporation
64431  *
64432  * Licensed under the Apache License, Version 2.0 (the "License");
64433  * you may not use this file except in compliance with the License.
64434  * You may obtain a copy of the License at
64435  *
64436  * http://www.apache.org/licenses/LICENSE-2.0
64437  *
64438  * Unless required by applicable law or agreed to in writing, software
64439  * distributed under the License is distributed on an "AS IS" BASIS,
64440  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64441  * See the License for the specific language governing permissions and
64442  * limitations under the License.
64443  */
64444
64445 module.exports = {
64446     "id": "HD",
64447     "name": "HD (720x1280)",
64448     "osName": "Generic",
64449     "osVersion": "Generic",
64450     "manufacturer": "Generic",
64451     "model": "Generic",
64452     "uuid": "42",
64453     "firmware": "Generic",
64454
64455     "screen": {
64456         "width": 720,
64457         "height": 1280
64458     },
64459     "viewPort": {
64460         "portrait": {
64461             "width": 720,
64462             "height": 1280,
64463             "paddingTop": 0,
64464             "paddingLeft": 0
64465         },
64466         "landscape": {
64467             "width": 1280,
64468             "height": 720,
64469             "paddingTop": 0,
64470             "paddingLeft": 0
64471         }
64472     },
64473
64474     "ppi": 316,
64475     "browser": ["Generic"],
64476     "platforms": ["wac", "web", "phonegap", "tizen", "cordova"],
64477     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
64478 };
64479
64480 });
64481 define('ripple/devices/Tattoo', function (require, exports, module) {
64482 /*
64483  *  Copyright 2011 Research In Motion Limited.
64484  *
64485  * Licensed under the Apache License, Version 2.0 (the "License");
64486  * you may not use this file except in compliance with the License.
64487  * You may obtain a copy of the License at
64488  *
64489  * http://www.apache.org/licenses/LICENSE-2.0
64490  *
64491  * Unless required by applicable law or agreed to in writing, software
64492  * distributed under the License is distributed on an "AS IS" BASIS,
64493  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64494  * See the License for the specific language governing permissions and
64495  * limitations under the License.
64496  */
64497 module.exports = {
64498     "id": "Tattoo",
64499     "name": "HTC Tattoo",
64500     "manufacturer": "HTC",
64501     "model": "Tattoo",
64502     "osVersion": "1.6",
64503     "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
64504     "osName": "Android",
64505
64506     "screen": {
64507         "width": 240,
64508         "height": 320
64509     },
64510     "viewPort": {
64511         "portrait": {
64512             "width": 240,
64513             "height": 320,
64514             "paddingTop": 0,
64515             "paddingLeft": 0
64516         }
64517     },
64518
64519     "ppi": 142.9,
64520     "userAgent": "Mozilla/5.0 (Linux; U; Android 1.6; en-us; HTC_TATTOO_A3288 Build/DRC79) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1",
64521     "platforms": ["web", "phonegap"]
64522 };
64523
64524 });
64525 define('ripple/devices/custom', function (require, exports, module) {
64526 /*
64527  *  Copyright 2012 Intel Corporation
64528  *
64529  * Licensed under the Apache License, Version 2.0 (the "License");
64530  * you may not use this file except in compliance with the License.
64531  * You may obtain a copy of the License at
64532  *
64533  * http://www.apache.org/licenses/LICENSE-2.0
64534  *
64535  * Unless required by applicable law or agreed to in writing, software
64536  * distributed under the License is distributed on an "AS IS" BASIS,
64537  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64538  * See the License for the specific language governing permissions and
64539  * limitations under the License.
64540  */
64541
64542 module.exports = {
64543     "id": "CUSTOM",
64544     "name": "Custom",
64545     "osName": "Generic",
64546     "osVersion": "Generic",
64547     "manufacturer": "Generic",
64548     "model": "Generic",
64549     "uuid": "42",
64550     "firmware": "Generic",
64551
64552     "screen": {
64553         "width": 600,
64554         "height": 800
64555     },
64556     "viewPort": {
64557         "portrait": {
64558             "width": 600,
64559             "height": 800,
64560             "paddingTop": 0,
64561             "paddingLeft": 0
64562         },
64563         "landscape": {
64564             "width": 600,
64565             "height": 800,
64566             "paddingTop": 0,
64567             "paddingLeft": 0
64568         }
64569     },
64570
64571     "ppi": 316,
64572     "browser": ["Generic"],
64573     "platforms": [],
64574     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
64575 };
64576
64577 });
64578 define('ripple/devices/Torch9860-9850', function (require, exports, module) {
64579 /*
64580  *  Copyright 2011 Research In Motion Limited.
64581  *
64582  * Licensed under the Apache License, Version 2.0 (the "License");
64583  * you may not use this file except in compliance with the License.
64584  * You may obtain a copy of the License at
64585  *
64586  * http://www.apache.org/licenses/LICENSE-2.0
64587  *
64588  * Unless required by applicable law or agreed to in writing, software
64589  * distributed under the License is distributed on an "AS IS" BASIS,
64590  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64591  * See the License for the specific language governing permissions and
64592  * limitations under the License.
64593  */
64594 module.exports = {
64595
64596     "id": "Torch9860-9850",
64597     "name": "BlackBerry Torch 9860/9850",
64598     "model": "9860-9850",
64599     "osName": "BlackBerry OS",
64600     "uuid": "42",
64601     "osVersion": "7",
64602     "manufacturer": "Research In Motion",
64603
64604     "skin": "Torch9860-9850",
64605
64606     "capabilities": [
64607         "input.touch",
64608         "location.gps",
64609         "location.maps",
64610         "media.audio.capture",
64611         "media.video.capture",
64612         "media.recording",
64613         "storage.memorycard",
64614         "network.bluetooth",
64615         "network.wlan",
64616         "network.3gpp"
64617     ],
64618
64619     "screen": {
64620         "width": 480,
64621         "height": 800
64622     },
64623     "viewPort": {
64624         "portrait": {
64625             "width": 480,
64626             "height": 800,
64627             "paddingTop": 0,
64628             "paddingLeft": 0
64629         },
64630         "landscape": {
64631             "width": 800,
64632             "height": 480,
64633             "paddingTop": 0,
64634             "paddingLeft": 0
64635         }
64636     },
64637
64638     "ppi": 253,
64639     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9860; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
64640     "platforms": ["web", "phonegap", "webworks.handset"]
64641 };
64642
64643 });
64644 define('ripple/devices/WVGA', function (require, exports, module) {
64645 /*
64646  *  Copyright 2011 Research In Motion Limited.
64647  *
64648  * Licensed under the Apache License, Version 2.0 (the "License");
64649  * you may not use this file except in compliance with the License.
64650  * You may obtain a copy of the License at
64651  *
64652  * http://www.apache.org/licenses/LICENSE-2.0
64653  *
64654  * Unless required by applicable law or agreed to in writing, software
64655  * distributed under the License is distributed on an "AS IS" BASIS,
64656  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64657  * See the License for the specific language governing permissions and
64658  * limitations under the License.
64659  */
64660 module.exports = {
64661     "id": "WVGA",
64662     "name": "WVGA (480x800)",
64663     "osName": "Generic",
64664     "osVersion": "Generic",
64665     "manufacturer": "Generic",
64666     "model": "Generic",
64667     "uuid": "42",
64668
64669     "screen": {
64670         "width": 480,
64671         "height": 800
64672     },
64673     "viewPort": {
64674         "portrait": {
64675             "width": 480,
64676             "height": 800,
64677             "paddingTop": 0,
64678             "paddingLeft": 0
64679         },
64680         "landscape": {
64681             "width": 800,
64682             "height": 480,
64683             "paddingTop": 0,
64684             "paddingLeft": 0
64685         }
64686     },
64687
64688     "ppi": 316,
64689     "browser": ["Generic"],
64690     "platforms": ["web", "phonegap", "tizen", "cordova"],
64691     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
64692 };
64693
64694 });
64695 define('ripple/devices/tizen-HD', function (require, exports, module) {
64696 /*
64697  *  Copyright 2012 Intel Corporation
64698  *
64699  * Licensed under the Apache License, Version 2.0 (the "License");
64700  * you may not use this file except in compliance with the License.
64701  * You may obtain a copy of the License at
64702  *
64703  * http://www.apache.org/licenses/LICENSE-2.0
64704  *
64705  * Unless required by applicable law or agreed to in writing, software
64706  * distributed under the License is distributed on an "AS IS" BASIS,
64707  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64708  * See the License for the specific language governing permissions and
64709  * limitations under the License.
64710  */
64711
64712 module.exports = {
64713     "id": "tizen-HD",
64714     "name": "Tizen HD (720x1280)",
64715     "osName": "Generic",
64716     "osVersion": "Generic",
64717     "manufacturer": "Tizen",
64718     "model": "Generic",
64719     "uuid": "42",
64720     "firmware": "Generic",
64721
64722     "screen": {
64723         "width": 720,
64724         "height": 1280
64725     },
64726     "viewPort": {
64727         "portrait": {
64728             "width": 360,
64729             "height": 640,
64730             "paddingTop": 0,
64731             "paddingLeft": 0
64732         },
64733         "landscape": {
64734             "width": 640,
64735             "height": 360,
64736             "paddingTop": 0,
64737             "paddingLeft": 0
64738         }
64739     },
64740
64741     "ppi": 316,
64742     "browser": ["Generic"],
64743     "platforms": ["wac", "web", "phonegap", "tizen", "cordova"],
64744     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
64745 };
64746
64747 });
64748 define('ripple/devices/iPad', function (require, exports, module) {
64749 /*
64750  *  Copyright 2011 Research In Motion Limited.
64751  *
64752  * Licensed under the Apache License, Version 2.0 (the "License");
64753  * you may not use this file except in compliance with the License.
64754  * You may obtain a copy of the License at
64755  *
64756  * http://www.apache.org/licenses/LICENSE-2.0
64757  *
64758  * Unless required by applicable law or agreed to in writing, software
64759  * distributed under the License is distributed on an "AS IS" BASIS,
64760  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64761  * See the License for the specific language governing permissions and
64762  * limitations under the License.
64763  */
64764 module.exports = {
64765
64766     "id": "iPad",
64767     "name": "iPad",
64768     "model": "iPad",
64769     "osName": "iOS",
64770     "uuid": "e0101010d38bde8e6740011221af335301010333",
64771     "osVersion": "1.6",
64772     "manufacturer": "Apple",
64773
64774     "screen": {
64775         "width": 768,
64776         "height": 1024
64777     },
64778     "viewPort": {
64779         "portrait": {
64780             "width": 768,
64781             "height": 1024,
64782             "paddingTop": 0,
64783             "paddingLeft": 0
64784         },
64785         "landscape": {
64786             "width": 1024,
64787             "height": 768,
64788             "paddingTop": 0,
64789             "paddingLeft": 0
64790         }
64791     },
64792
64793     "ppi": 132,
64794     "userAgent": "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10",
64795     "platforms": ["web", "phonegap", "cordova"],
64796
64797     "notes": {
64798         "1": "<a href=\"http://www.apple.com/ipad/specs/\" target=\"_blank\">Specs</a>"
64799     }
64800 };
64801
64802 });
64803 define('ripple/devices/NokiaN97', function (require, exports, module) {
64804 /*
64805  *  Copyright 2011 Research In Motion Limited.
64806  *
64807  * Licensed under the Apache License, Version 2.0 (the "License");
64808  * you may not use this file except in compliance with the License.
64809  * You may obtain a copy of the License at
64810  *
64811  * http://www.apache.org/licenses/LICENSE-2.0
64812  *
64813  * Unless required by applicable law or agreed to in writing, software
64814  * distributed under the License is distributed on an "AS IS" BASIS,
64815  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64816  * See the License for the specific language governing permissions and
64817  * limitations under the License.
64818  */
64819 module.exports = {
64820     "id": "NokiaN97",
64821     "name": "Nokia N97/5800 (touch)",
64822     "manufacturer": "Nokia",
64823     "model": "N97",
64824     "osName": "S60",
64825     "osVersion": "v5",
64826     "uuid": "42",
64827
64828     "screen": {
64829         "width": 360,
64830         "height": 640
64831     },
64832     "viewPort": {
64833         "portrait": {
64834             "width": 360,
64835             "height": 640,
64836             "paddingTop": 0,
64837             "paddingLeft": 0
64838         },
64839         "landscape": {
64840             "width": 640,
64841             "height": 360,
64842             "paddingTop": 0,
64843             "paddingLeft": 0
64844         }
64845     },
64846
64847     "ppi": 232,
64848     "userAgent": "?",
64849     "platforms": ["web", "phonegap"]
64850 };
64851
64852 });
64853 define('ripple/devices/Style9670', function (require, exports, module) {
64854 /*
64855  *  Copyright 2011 Research In Motion Limited.
64856  *
64857  * Licensed under the Apache License, Version 2.0 (the "License");
64858  * you may not use this file except in compliance with the License.
64859  * You may obtain a copy of the License at
64860  *
64861  * http://www.apache.org/licenses/LICENSE-2.0
64862  *
64863  * Unless required by applicable law or agreed to in writing, software
64864  * distributed under the License is distributed on an "AS IS" BASIS,
64865  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64866  * See the License for the specific language governing permissions and
64867  * limitations under the License.
64868  */
64869 module.exports = {
64870
64871     "id": "Style9670",
64872     "name": "BlackBerry Style 9670",
64873     "model": "9670",
64874     "osName": "BlackBerry OS",
64875     "uuid": "42",
64876     "osVersion": "6",
64877     "manufacturer": "Research In Motion",
64878
64879     "skin": "Style9670",
64880
64881     "capabilities": [
64882         "location.gps",
64883         "location.maps",
64884         "media.audio.capture",
64885         "media.video.capture",
64886         "media.recording",
64887         "storage.memorycard",
64888         "network.bluetooth",
64889         "network.wlan",
64890         "network.3gpp"
64891     ],
64892
64893     "screen": {
64894         "width": 360,
64895         "height": 400
64896     },
64897     "viewPort": {
64898         "portrait": {
64899             "width": 360,
64900             "height": 400,
64901             "paddingTop": 0,
64902             "paddingLeft": 0
64903         }
64904     },
64905
64906     "ppi": 200,
64907     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9670; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
64908     "platforms": ["web", "phonegap", "webworks.handset"]
64909 };
64910
64911 });
64912 define('ripple/devices/Nexus', function (require, exports, module) {
64913 /*
64914  *  Copyright 2011 Research In Motion Limited.
64915  *
64916  * Licensed under the Apache License, Version 2.0 (the "License");
64917  * you may not use this file except in compliance with the License.
64918  * You may obtain a copy of the License at
64919  *
64920  * http://www.apache.org/licenses/LICENSE-2.0
64921  *
64922  * Unless required by applicable law or agreed to in writing, software
64923  * distributed under the License is distributed on an "AS IS" BASIS,
64924  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64925  * See the License for the specific language governing permissions and
64926  * limitations under the License.
64927  */
64928 module.exports = {
64929     "id": "Nexus",
64930     "name": "Nexus One",
64931     "manufacturer": "HTC",
64932     "model": "Nexux One",
64933     "osName": "Android",
64934     "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
64935     "osVersion": "2.x.x",
64936
64937     "screen": {
64938         "width": 480,
64939         "height": 800
64940     },
64941     "viewPort": {
64942         "portrait": {
64943             "width": 480,
64944             "height": 800,
64945             "paddingTop": 0,
64946             "paddingLeft": 0
64947         },
64948         "landscape": {
64949             "width": 800,
64950             "height": 480,
64951             "paddingTop": 0,
64952             "paddingLeft": 0
64953         }
64954     },
64955
64956     "ppi": 252.15,
64957     "userAgent": "Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
64958     "platforms": ["web", "phonegap"],
64959
64960     "notes": {
64961         "1": "<a href=\"http://www.google.com/phone/static/en_US-nexusone_tech_specs.html\" target=\"_blank\">Specs</a>"
64962     }
64963 };
64964
64965 });
64966 define('ripple/devices/HVGA', function (require, exports, module) {
64967 /*
64968  *  Copyright 2011 Research In Motion Limited.
64969  *
64970  * Licensed under the Apache License, Version 2.0 (the "License");
64971  * you may not use this file except in compliance with the License.
64972  * You may obtain a copy of the License at
64973  *
64974  * http://www.apache.org/licenses/LICENSE-2.0
64975  *
64976  * Unless required by applicable law or agreed to in writing, software
64977  * distributed under the License is distributed on an "AS IS" BASIS,
64978  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64979  * See the License for the specific language governing permissions and
64980  * limitations under the License.
64981  */
64982 module.exports = {
64983     "group": "Generic Devices",
64984
64985     "id": "HVGA",
64986     "name": "HVGA (320x480)",
64987     "osName": "Generic",
64988     "osVersion": "Generic",
64989     "manufacturer": "Generic",
64990     "model": "Generic",
64991     "uuid": "42",
64992
64993     "screen": {
64994         "width": 320,
64995         "height": 480
64996     },
64997     "viewPort": {
64998         "portrait": {
64999             "width": 320,
65000             "height": 480,
65001             "paddingTop": 0,
65002             "paddingLeft": 0
65003         },
65004         "landscape": {
65005             "width": 480,
65006             "height": 320,
65007             "paddingTop": 0,
65008             "paddingLeft": 0
65009         }
65010     },
65011
65012     "ppi": 316,
65013     "platforms": ["wac", "web", "phonegap", "tizen", "cordova"],
65014     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65015 };
65016
65017 });
65018 define('ripple/devices/QVGA', function (require, exports, module) {
65019 /*
65020  *  Copyright 2011 Research In Motion Limited.
65021  *
65022  * Licensed under the Apache License, Version 2.0 (the "License");
65023  * you may not use this file except in compliance with the License.
65024  * You may obtain a copy of the License at
65025  *
65026  * http://www.apache.org/licenses/LICENSE-2.0
65027  *
65028  * Unless required by applicable law or agreed to in writing, software
65029  * distributed under the License is distributed on an "AS IS" BASIS,
65030  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65031  * See the License for the specific language governing permissions and
65032  * limitations under the License.
65033  */
65034 module.exports = {
65035     "id": "QVGA",
65036     "name": "Generic - QVGA (240X320)",
65037     "osName": "Generic",
65038     "osVersion": "Generic",
65039     "manufacturer": "Generic",
65040     "model": "Generic",
65041     "uuid": "42",
65042
65043     "screen": {
65044         "width": 240,
65045         "height": 320
65046     },
65047     "viewPort": {
65048         "portrait": {
65049             "width": 240,
65050             "height": 320,
65051             "paddingTop": 0,
65052             "paddingLeft": 0
65053         },
65054         "landscape": {
65055             "width": 320,
65056             "height": 240,
65057             "paddingTop": 0,
65058             "paddingLeft": 0
65059         }
65060     },
65061
65062     "ppi": 96,
65063     "platforms": ["web", "phonegap", "cordova", "tizen"],
65064     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65065 };
65066
65067 });
65068 define('ripple/devices/HPPre3', function (require, exports, module) {
65069 /*
65070  *  Copyright 2011 Research In Motion Limited.
65071  *
65072  * Licensed under the Apache License, Version 2.0 (the "License");
65073  * you may not use this file except in compliance with the License.
65074  * You may obtain a copy of the License at
65075  *
65076  * http://www.apache.org/licenses/LICENSE-2.0
65077  *
65078  * Unless required by applicable law or agreed to in writing, software
65079  * distributed under the License is distributed on an "AS IS" BASIS,
65080  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65081  * See the License for the specific language governing permissions and
65082  * limitations under the License.
65083  */
65084 module.exports = {
65085     "id": "HPPre3",
65086     "name": "HP Pre 3",
65087     "manufacturer": "HP",
65088     "model": "Pre",
65089     "osName": "WebOS",
65090     "osVersion": "2.x",
65091
65092     "screen": {
65093         "width": 480,
65094         "height": 800
65095     },
65096     "viewPort": {
65097         "portrait": {
65098             "width": 480,
65099             "height": 800,
65100             "paddingTop": 0,
65101             "paddingLeft": 0
65102         },
65103         "landscape": {
65104             "width": 800,
65105             "height": 480,
65106             "paddingTop": 0,
65107             "paddingLeft": 0
65108         }
65109     },
65110
65111     "ppi": 260,
65112     // TODO :: not exactly the correct userAgent webkit version is probably different
65113     "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
65114     "platforms": ["web", "phonegap"],
65115
65116     "notes": {
65117         "1": "<a href=\"http://www.palm.com/us/products/phones/pre3/index.html\" target=\"_blank\">Specs</a>"
65118     }
65119 };
65120
65121 });
65122 define('ripple/devices/Curve9300', function (require, exports, module) {
65123 /*
65124  *  Copyright 2011 Research In Motion Limited.
65125  *
65126  * Licensed under the Apache License, Version 2.0 (the "License");
65127  * you may not use this file except in compliance with the License.
65128  * You may obtain a copy of the License at
65129  *
65130  * http://www.apache.org/licenses/LICENSE-2.0
65131  *
65132  * Unless required by applicable law or agreed to in writing, software
65133  * distributed under the License is distributed on an "AS IS" BASIS,
65134  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65135  * See the License for the specific language governing permissions and
65136  * limitations under the License.
65137  */
65138 module.exports = {
65139
65140     "id": "Curve9300",
65141     "name": "BlackBerry Curve 9300",
65142     "model": "9300",
65143     "osName": "BlackBerry OS",
65144     "uuid": "42",
65145     "osVersion": "6",
65146     "manufacturer": "Research In Motion",
65147
65148     "skin": "Curve9300",
65149
65150     "capabilities": [
65151         "location.gps",
65152         "location.maps",
65153         "media.audio.capture",
65154         "media.video.capture",
65155         "media.recording",
65156         "storage.memorycard",
65157         "network.bluetooth",
65158         "network.wlan",
65159         "network.3gpp"
65160     ],
65161
65162     "screen": {
65163         "width": 320,
65164         "height": 240
65165     },
65166     "viewPort": {
65167         "portrait": {
65168             "width": 320,
65169             "height": 240,
65170             "paddingTop": 0,
65171             "paddingLeft": 0
65172         }
65173     },
65174
65175     "ppi": 163,
65176     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9300; en) AppleWebKit/534.3+ (KHTML, like Gecko) Version/6.0.0.286 Mobile Safari/534.3+",
65177     "platforms": ["web", "phonegap", "webworks.handset"]
65178 };
65179
65180 });
65181 define('ripple/devices/Bold9700', function (require, exports, module) {
65182 /*
65183  *  Copyright 2011 Research In Motion Limited.
65184  *
65185  * Licensed under the Apache License, Version 2.0 (the "License");
65186  * you may not use this file except in compliance with the License.
65187  * You may obtain a copy of the License at
65188  *
65189  * http://www.apache.org/licenses/LICENSE-2.0
65190  *
65191  * Unless required by applicable law or agreed to in writing, software
65192  * distributed under the License is distributed on an "AS IS" BASIS,
65193  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65194  * See the License for the specific language governing permissions and
65195  * limitations under the License.
65196  */
65197 module.exports = {
65198
65199     "id": "Bold9700",
65200     "name": "BlackBerry Bold 9700",
65201     "model": "9700",
65202     "osName": "BlackBerry OS",
65203     "uuid": "42",
65204     "osVersion": "6",
65205     "manufacturer": "Research In Motion",
65206
65207     "skin": "Bold9700",
65208
65209     "capabilities": [
65210         "location.gps",
65211         "location.maps",
65212         "media.audio.capture",
65213         "media.video.capture",
65214         "media.recording",
65215         "storage.memorycard",
65216         "network.bluetooth",
65217         "network.wlan",
65218         "network.3gpp"
65219     ],
65220
65221     "screen": {
65222         "width": 480,
65223         "height": 360
65224     },
65225     "viewPort": {
65226         "portrait": {
65227             "width": 480,
65228             "height": 360,
65229             "paddingTop": 0,
65230             "paddingLeft": 0
65231         }
65232     },
65233
65234     "ppi": 245.00,
65235     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9700; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1",
65236     "platforms": ["web", "phonegap", "webworks.handset", "cordova"]
65237 };
65238
65239 });
65240 define('ripple/devices/G1', function (require, exports, module) {
65241 /*
65242  *  Copyright 2011 Research In Motion Limited.
65243  *
65244  * Licensed under the Apache License, Version 2.0 (the "License");
65245  * you may not use this file except in compliance with the License.
65246  * You may obtain a copy of the License at
65247  *
65248  * http://www.apache.org/licenses/LICENSE-2.0
65249  *
65250  * Unless required by applicable law or agreed to in writing, software
65251  * distributed under the License is distributed on an "AS IS" BASIS,
65252  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65253  * See the License for the specific language governing permissions and
65254  * limitations under the License.
65255  */
65256 module.exports = {
65257
65258     "id": "G1",
65259     "name": "HTC G1",
65260     "model": "G1",
65261     "osName": "Android",
65262     "osVersion": "1.6",
65263     "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
65264     "manufacturer": "HTC",
65265
65266     "screen": {
65267         "width": 320,
65268         "height": 480
65269     },
65270     "viewPort": {
65271         "portrait": {
65272             "width": 320,
65273             "height": 480,
65274             "paddingTop": 0,
65275             "paddingLeft": 0
65276         },
65277         "landscape": {
65278             "width": 480,
65279             "height": 320,
65280             "paddingTop": 0,
65281             "paddingLeft": 0
65282         }
65283     },
65284
65285     "ppi": 180.28,
65286     "platforms": ["web", "phonegap"],
65287     "userAgent": "Mozilla/5.0 (Linux; U; Android 1.0; en-us; dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2",
65288
65289     "notes": {
65290         "1": "<a href=\"http://www.htc.com/www/product/g1/specification.html\" target=\"_blank\">Specs</a>"
65291     }
65292 };
65293
65294 });
65295 define('ripple/devices/NexusGalaxy', function (require, exports, module) {
65296 /*
65297  *  Copyright 2011 Research In Motion Limited.
65298  *
65299  * Licensed under the Apache License, Version 2.0 (the "License");
65300  * you may not use this file except in compliance with the License.
65301  * You may obtain a copy of the License at
65302  *
65303  * http://www.apache.org/licenses/LICENSE-2.0
65304  *
65305  * Unless required by applicable law or agreed to in writing, software
65306  * distributed under the License is distributed on an "AS IS" BASIS,
65307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65308  * See the License for the specific language governing permissions and
65309  * limitations under the License.
65310  */
65311 module.exports = {
65312     "id" : "NexusGalaxy",
65313     "name": "Nexus (Galaxy)",
65314     "manufacturer": "Samsung",
65315     "model": "Galaxy Nexus (generic)",
65316     "osName": "Android",
65317     "uuid" : "3D0AD03B-8B46-431A-BEF5-FF01B96BA990",
65318     "osVersion": "4.x.x",
65319
65320     "screen": {
65321         "width": 720,
65322         "height": 1280
65323     },
65324     "viewPort": {
65325         "portrait": {
65326             "width": 720,
65327             "height": 1280,
65328             "paddingTop": 0,
65329             "paddingLeft": 0
65330         },
65331         "landscape": {
65332             "width": 1280,
65333             "height": 720,
65334             "paddingTop": 0,
65335             "paddingLeft": 0
65336         }
65337     },
65338
65339     "ppi": 315,
65340     "userAgent": "Mozilla/5.0 (Linux; Android 4.0.1; Galaxy Nexus Build/ITL41F) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19",
65341     "platforms": ["web", "phonegap", "cordova"],
65342
65343     "notes": {
65344         "1": "<a href=\"http://www.google.com/nexus/#/tech-specs\" target=\"_blank\">Specs</a>"
65345     }
65346
65347 };
65348
65349 });
65350 define('ripple/devices/Torch9810', function (require, exports, module) {
65351 /*
65352  *  Copyright 2011 Research In Motion Limited.
65353  *
65354  * Licensed under the Apache License, Version 2.0 (the "License");
65355  * you may not use this file except in compliance with the License.
65356  * You may obtain a copy of the License at
65357  *
65358  * http://www.apache.org/licenses/LICENSE-2.0
65359  *
65360  * Unless required by applicable law or agreed to in writing, software
65361  * distributed under the License is distributed on an "AS IS" BASIS,
65362  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65363  * See the License for the specific language governing permissions and
65364  * limitations under the License.
65365  */
65366 module.exports = {
65367
65368     "id": "Torch9810",
65369     "name": "BlackBerry Torch 9810",
65370     "model": "9810",
65371     "osName": "BlackBerry OS",
65372     "uuid": "42",
65373     "osVersion": "7",
65374     "manufacturer": "Research In Motion",
65375
65376     "skin": "Torch9810",
65377
65378     "capabilities": [
65379         "input.touch",
65380         "location.gps",
65381         "location.maps",
65382         "media.audio.capture",
65383         "media.video.capture",
65384         "media.recording",
65385         "storage.memorycard",
65386         "network.bluetooth",
65387         "network.wlan",
65388         "network.3gpp"
65389     ],
65390
65391     "screen": {
65392         "width": 480,
65393         "height": 640
65394     },
65395     "viewPort": {
65396         "portrait": {
65397             "width": 480,
65398             "height": 640,
65399             "paddingTop": 0,
65400             "paddingLeft": 0
65401         },
65402         "landscape": {
65403             "width": 640,
65404             "height": 480,
65405             "paddingTop": 0,
65406             "paddingLeft": 0
65407         }
65408     },
65409
65410     "ppi": 253,
65411     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9810; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
65412     "platforms": ["web", "phonegap", "webworks.handset"]
65413 };
65414
65415 });
65416 define('ripple/devices/PalmPre2', function (require, exports, module) {
65417 /*
65418  *  Copyright 2011 Research In Motion Limited.
65419  *
65420  * Licensed under the Apache License, Version 2.0 (the "License");
65421  * you may not use this file except in compliance with the License.
65422  * You may obtain a copy of the License at
65423  *
65424  * http://www.apache.org/licenses/LICENSE-2.0
65425  *
65426  * Unless required by applicable law or agreed to in writing, software
65427  * distributed under the License is distributed on an "AS IS" BASIS,
65428  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65429  * See the License for the specific language governing permissions and
65430  * limitations under the License.
65431  */
65432 module.exports = {
65433     "id": "PalmPre2",
65434     "name": "Palm Pre 2",
65435     "manufacturer": "Palm",
65436     "model": "Pre",
65437     "osName": "WebOS",
65438     "osVersion": "2.x",
65439
65440     "screen": {
65441         "width": 320,
65442         "height": 480
65443     },
65444     "viewPort": {
65445         "portrait": {
65446             "width": 320,
65447             "height": 480,
65448             "paddingTop": 0,
65449             "paddingLeft": 0
65450         },
65451         "landscape": {
65452             "width": 480,
65453             "height": 320,
65454             "paddingTop": 0,
65455             "paddingLeft": 0
65456         }
65457     },
65458
65459     "ppi": 186.09,
65460     // TODO :: not exactly the correct userAgent webkit version is probably different
65461     "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
65462     "platforms": ["web", "phonegap"],
65463
65464     "notes": {
65465         "1": "<a href=\"http://www.palm.com/us/products/phones/pre2/#tab2\" target=\"_blank\">Specs</a>"
65466     }
65467 };
65468
65469 });
65470 define('ripple/devices/Curve9350-9360-9370', function (require, exports, module) {
65471 /*
65472  *  Copyright 2011 Research In Motion Limited.
65473  *
65474  * Licensed under the Apache License, Version 2.0 (the "License");
65475  * you may not use this file except in compliance with the License.
65476  * You may obtain a copy of the License at
65477  *
65478  * http://www.apache.org/licenses/LICENSE-2.0
65479  *
65480  * Unless required by applicable law or agreed to in writing, software
65481  * distributed under the License is distributed on an "AS IS" BASIS,
65482  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65483  * See the License for the specific language governing permissions and
65484  * limitations under the License.
65485  */
65486 module.exports = {
65487
65488     "id": "Curve9350-9360-9370",
65489     "name": "BlackBerry Curve 9350/9360/9370",
65490     "model": "9350-9360-9370",
65491     "osName": "BlackBerry OS",
65492     "uuid": "42",
65493     "osVersion": "7",
65494     "manufacturer": "Research In Motion",
65495
65496     "skin": "Curve9350-9360-9370",
65497
65498     "capabilities": [
65499         "location.gps",
65500         "location.maps",
65501         "media.audio.capture",
65502         "media.video.capture",
65503         "media.recording",
65504         "storage.memorycard",
65505         "network.bluetooth",
65506         "network.wlan",
65507         "network.3gpp"
65508     ],
65509
65510     "screen": {
65511         "width": 480,
65512         "height": 360
65513     },
65514     "viewPort": {
65515         "portrait": {
65516             "width": 480,
65517             "height": 360,
65518             "paddingTop": 0,
65519             "paddingLeft": 0
65520         }
65521     },
65522
65523     "ppi": 246.00,
65524     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9350; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/7.0.0.0 Mobile Safari/534.1",
65525     "platforms": ["web", "phonegap", "webworks.handset"]
65526 };
65527
65528 });
65529 define('ripple/devices/Colt', function (require, exports, module) {
65530 /*
65531  *  Copyright 2011 Research In Motion Limited.
65532  *
65533  * Licensed under the Apache License, Version 2.0 (the "License");
65534  * you may not use this file except in compliance with the License.
65535  * You may obtain a copy of the License at
65536  *
65537  * http://www.apache.org/licenses/LICENSE-2.0
65538  *
65539  * Unless required by applicable law or agreed to in writing, software
65540  * distributed under the License is distributed on an "AS IS" BASIS,
65541  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65542  * See the License for the specific language governing permissions and
65543  * limitations under the License.
65544  */
65545 module.exports = {
65546
65547     "id": "Colt",
65548     "name": "BlackBerry 10 Dev Alpha",
65549     "model": "Colt",
65550     "osName": "BlackBerry",
65551     "uuid": "42",
65552     "osVersion": "10.0.6.99",
65553     "manufacturer": "Research In Motion",
65554     "hardwareId": "0x8500240a",
65555
65556     "skin": "Colt",
65557
65558     "capabilities": [
65559         "input.touch",
65560         "location.gps",
65561         "media.audio.capture",
65562         "media.video.capture",
65563         "media.recording",
65564         "network.bluetooth",
65565         "network.wlan"
65566     ],
65567
65568     "screen": {
65569         "width": 768,
65570         "height": 1280
65571     },
65572     "viewPort": {
65573         "portrait": {
65574             "width": 768,
65575             "height": 1280,
65576             "paddingTop": 0,
65577             "paddingLeft": 0
65578         },
65579         "landscape": {
65580             "width": 1280,
65581             "height": 768,
65582             "paddingTop": 0,
65583             "paddingLeft": 0
65584         }
65585     },
65586
65587     "defaultOrientation": "portrait",
65588
65589     "ppi": 355,
65590     "userAgent": "Mozilla/5.0 (BlackBerry) AppleWebKit/536.2+ (KHTML, like Gecko) Version/10.0.4.182 Mobile Safari/536.2+",
65591     "platforms": ["web", "webworks.bb10", "cordova"]
65592 };
65593
65594 });
65595 define('ripple/devices/Nexus7', function (require, exports, module) {
65596 /*
65597  *  Copyright 2011 Research In Motion Limited.
65598  *
65599  * Licensed under the Apache License, Version 2.0 (the "License");
65600  * you may not use this file except in compliance with the License.
65601  * You may obtain a copy of the License at
65602  *
65603  * http://www.apache.org/licenses/LICENSE-2.0
65604  *
65605  * Unless required by applicable law or agreed to in writing, software
65606  * distributed under the License is distributed on an "AS IS" BASIS,
65607  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65608  * See the License for the specific language governing permissions and
65609  * limitations under the License.
65610  */
65611 module.exports = {
65612     "id" : "Nexus7",
65613     "name": "Nexus 7 (Tablet)",
65614     "manufacturer": "Asus",
65615     "model": "Nexus 7 8/16 GB",
65616     "osName": "Android",
65617     "uuid" : "903802EA-1786-4175-B0F1-1FDF87813CAA",
65618     "osVersion": "4.x.x",
65619
65620     "screen": {
65621         "width": 800,
65622         "height": 1280
65623     },
65624     "viewPort": {
65625         "portrait": {
65626             "width": 800,
65627             "height": 1280,
65628             "paddingTop": 0,
65629             "paddingLeft": 0
65630         },
65631         "landscape": {
65632             "width": 1280,
65633             "height": 800,
65634             "paddingTop": 0,
65635             "paddingLeft": 0
65636         }
65637     },
65638
65639     "ppi": 215,
65640     "userAgent": "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166  Safari/535.19",
65641     "platforms": ["web", "phonegap", "cordova"],
65642
65643     "notes": {
65644         "1": "<a href=\"http://www.google.com/nexus/#/7/specs\" target=\"_blank\">Specs</a>"
65645     }
65646
65647 };
65648
65649 });
65650 define('ripple/devices/Legend', function (require, exports, module) {
65651 /*
65652  *  Copyright 2011 Research In Motion Limited.
65653  *
65654  * Licensed under the Apache License, Version 2.0 (the "License");
65655  * you may not use this file except in compliance with the License.
65656  * You may obtain a copy of the License at
65657  *
65658  * http://www.apache.org/licenses/LICENSE-2.0
65659  *
65660  * Unless required by applicable law or agreed to in writing, software
65661  * distributed under the License is distributed on an "AS IS" BASIS,
65662  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65663  * See the License for the specific language governing permissions and
65664  * limitations under the License.
65665  */
65666 module.exports = {
65667     "id": "Legend",
65668     "name": "HTC Legend",
65669     "osName": "Android",
65670     "osVersion": "1.6",
65671     "manufacturer": "HTC",
65672     "model": "Legend",
65673     "uuid": "6F196F23-FD0D-4F62-B27B-730147FCC5A3",
65674
65675     "screen": {
65676         "width": 320,
65677         "height": 480
65678     },
65679     "viewPort": {
65680         "portrait": {
65681             "width": 320,
65682             "height": 480,
65683             "paddingTop": 0,
65684             "paddingLeft": 0
65685         },
65686         "landscape": {
65687             "width": 480,
65688             "height": 320,
65689             "paddingTop": 0,
65690             "paddingLeft": 0
65691         }
65692     },
65693
65694     "ppi": 180.3,
65695     "userAgent": "Mozilla/5.0 (Linux; U; Android 2.1; fr-fr; HTC Legend 1.32.163.1 Build/ERD79) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17",
65696     "platforms": ["web", "phonegap"]
65697 };
65698
65699 });
65700 define('ripple/devices/Torch9800', function (require, exports, module) {
65701 /*
65702  *  Copyright 2011 Research In Motion Limited.
65703  *
65704  * Licensed under the Apache License, Version 2.0 (the "License");
65705  * you may not use this file except in compliance with the License.
65706  * You may obtain a copy of the License at
65707  *
65708  * http://www.apache.org/licenses/LICENSE-2.0
65709  *
65710  * Unless required by applicable law or agreed to in writing, software
65711  * distributed under the License is distributed on an "AS IS" BASIS,
65712  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65713  * See the License for the specific language governing permissions and
65714  * limitations under the License.
65715  */
65716 module.exports = {
65717
65718     "id": "Torch9800",
65719     "name": "BlackBerry Torch 9800",
65720     "model": "9800",
65721     "osName": "BlackBerry OS",
65722     "uuid": "42",
65723     "osVersion": "6",
65724     "manufacturer": "Research In Motion",
65725
65726     "skin": "Torch9800",
65727
65728     "capabilities": [
65729         "input.touch",
65730         "location.gps",
65731         "location.maps",
65732         "media.audio.capture",
65733         "media.video.capture",
65734         "media.recording",
65735         "storage.memorycard",
65736         "network.bluetooth",
65737         "network.wlan",
65738         "network.3gpp"
65739     ],
65740
65741     "screen": {
65742         "width": 360,
65743         "height": 480
65744     },
65745     "viewPort": {
65746         "portrait": {
65747             "width": 360,
65748             "height": 480,
65749             "paddingTop": 0,
65750             "paddingLeft": 0
65751         },
65752         "landscape": {
65753             "width": 480,
65754             "height": 360,
65755             "paddingTop": 0,
65756             "paddingLeft": 0
65757         }
65758     },
65759
65760     "ppi": 188.68,
65761     "userAgent": "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, Like Gecko) Version/6.0.0.141 Mobile Safari/534.1",
65762     "platforms": ["web", "phonegap", "webworks.handset"]
65763 };
65764
65765 });
65766 define('ripple/devices/HPVeer', function (require, exports, module) {
65767 /*
65768  *  Copyright 2011 Research In Motion Limited.
65769  *
65770  * Licensed under the Apache License, Version 2.0 (the "License");
65771  * you may not use this file except in compliance with the License.
65772  * You may obtain a copy of the License at
65773  *
65774  * http://www.apache.org/licenses/LICENSE-2.0
65775  *
65776  * Unless required by applicable law or agreed to in writing, software
65777  * distributed under the License is distributed on an "AS IS" BASIS,
65778  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65779  * See the License for the specific language governing permissions and
65780  * limitations under the License.
65781  */
65782 module.exports = {
65783     "id": "HPVeer",
65784     "name": "HP Veer",
65785     "manufacturer": "HP",
65786     "model": "Veer",
65787     "osName": "WebOS",
65788     "osVersion": "2.x",
65789
65790     "screen": {
65791         "width": 320,
65792         "height": 400
65793     },
65794     "viewPort": {
65795         "portrait": {
65796             "width": 320,
65797             "height": 400,
65798             "paddingTop": 0,
65799             "paddingLeft": 0
65800         },
65801         "landscape": {
65802             "width": 400,
65803             "height": 320,
65804             "paddingTop": 0,
65805             "paddingLeft": 0
65806         }
65807     },
65808
65809     "ppi": 197,
65810     // TODO :: not exactly the correct userAgent webkit version is probably different
65811     "userAgent": "Mozilla/5.0 (webOS/2.0; U; en-US) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/1.0 Safari/525.27.1 Pre/2.0",
65812     "platforms": ["web", "phonegap"],
65813
65814     "notes": {
65815         "1": "<a href=\"http://www.palm.com/us/products/phones/veer/index.html\" target=\"_blank\">Specs</a>"
65816     }
65817 };
65818
65819 });
65820 define('ripple/devices/WQVGA', function (require, exports, module) {
65821 /*
65822  *  Copyright 2011 Research In Motion Limited.
65823  *
65824  * Licensed under the Apache License, Version 2.0 (the "License");
65825  * you may not use this file except in compliance with the License.
65826  * You may obtain a copy of the License at
65827  *
65828  * http://www.apache.org/licenses/LICENSE-2.0
65829  *
65830  * Unless required by applicable law or agreed to in writing, software
65831  * distributed under the License is distributed on an "AS IS" BASIS,
65832  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65833  * See the License for the specific language governing permissions and
65834  * limitations under the License.
65835  */
65836 module.exports = {
65837     "id": "WQVGA",
65838     "name": "Generic - WQVGA (240x480)",
65839     "osName": "Generic",
65840     "osVersion": "Generic",
65841     "manufacturer": "Generic",
65842     "model": "Generic",
65843     "uuid": "42",
65844
65845     "screen": {
65846         "width": 240,
65847         "height": 480
65848     },
65849     "viewPort": {
65850         "portrait": {
65851             "width": 240,
65852             "height": 480,
65853             "paddingTop": 0,
65854             "paddingLeft": 0
65855         },
65856         "landscape": {
65857             "width": 480,
65858             "height": 240,
65859             "paddingTop": 0,
65860             "paddingLeft": 0
65861         }
65862     },
65863
65864     "ppi": 96,
65865     "browser": ["Generic"],
65866     "platforms": ["web", "phonegap", "tizen"],
65867     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65868 };
65869
65870 });
65871 define('ripple/devices/WSVGA', function (require, exports, module) {
65872 /*
65873  *  Copyright 2011 Research In Motion Limited.
65874  *
65875  * Licensed under the Apache License, Version 2.0 (the "License");
65876  * you may not use this file except in compliance with the License.
65877  * You may obtain a copy of the License at
65878  *
65879  * http://www.apache.org/licenses/LICENSE-2.0
65880  *
65881  * Unless required by applicable law or agreed to in writing, software
65882  * distributed under the License is distributed on an "AS IS" BASIS,
65883  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65884  * See the License for the specific language governing permissions and
65885  * limitations under the License.
65886  */
65887 module.exports = {
65888     "id": "WSVGA",
65889     "name": "WSVGA (600x1024)",
65890     "osName": "Generic",
65891     "osVersion": "Generic",
65892     "manufacturer": "Generic",
65893     "model": "Generic",
65894     "uuid": "42",
65895     "firmware": "Generic",
65896
65897     "screen": {
65898         "width": 600,
65899         "height": 1024
65900     },
65901     "viewPort": {
65902         "portrait": {
65903             "width": 600,
65904             "height": 1024,
65905             "paddingTop": 0,
65906             "paddingLeft": 0
65907         },
65908         "landscape": {
65909             "width": 1024,
65910             "height": 600,
65911             "paddingTop": 0,
65912             "paddingLeft": 0
65913         }
65914     },
65915
65916     "ppi": 316,
65917     "browser": ["Generic"],
65918     "platforms": ["wac", "web", "phonegap", "tizen", "cordova"],
65919     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65920 };
65921
65922 });
65923 define('ripple/devices/FWVGA', function (require, exports, module) {
65924 /*
65925  *  Copyright 2011 Research In Motion Limited.
65926  *
65927  * Licensed under the Apache License, Version 2.0 (the "License");
65928  * you may not use this file except in compliance with the License.
65929  * You may obtain a copy of the License at
65930  *
65931  * http://www.apache.org/licenses/LICENSE-2.0
65932  *
65933  * Unless required by applicable law or agreed to in writing, software
65934  * distributed under the License is distributed on an "AS IS" BASIS,
65935  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65936  * See the License for the specific language governing permissions and
65937  * limitations under the License.
65938  */
65939 module.exports = {
65940     "group": "Generic Devices",
65941
65942     "id": "FWVGA",
65943     "name": "Generic - FWVGA (480x854)",
65944     "osName": "Generic",
65945     "osVersion": "Generic",
65946     "manufacturer": "Generic",
65947     "model": "Generic",
65948     "uuid": "42",
65949
65950     "screen": {
65951         "width": 480,
65952         "height": 854
65953     },
65954     "viewPort": {
65955         "portrait": {
65956             "width": 480,
65957             "height": 854,
65958             "paddingTop": 0,
65959             "paddingLeft": 0
65960         },
65961         "landscape": {
65962             "width": 854,
65963             "height": 480,
65964             "paddingTop": 0,
65965             "paddingLeft": 0
65966         }
65967     },
65968
65969     "ppi": 96,
65970     "platforms": ["web", "phonegap", "cordova"],
65971     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
65972 };
65973
65974 });
65975 define('ripple/devices/NokiaN8', function (require, exports, module) {
65976 /*
65977  *  Copyright 2011 Research In Motion Limited.
65978  *
65979  * Licensed under the Apache License, Version 2.0 (the "License");
65980  * you may not use this file except in compliance with the License.
65981  * You may obtain a copy of the License at
65982  *
65983  * http://www.apache.org/licenses/LICENSE-2.0
65984  *
65985  * Unless required by applicable law or agreed to in writing, software
65986  * distributed under the License is distributed on an "AS IS" BASIS,
65987  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65988  * See the License for the specific language governing permissions and
65989  * limitations under the License.
65990  */
65991 module.exports = {
65992
65993     "id": "NokiaN8",
65994     "name": "Nokia N8",
65995     "model": "N8",
65996     "osName": "SymbianOS",
65997     "uuid": "42",
65998     "osVersion": "3",
65999     "manufacturer": "Nokia",
66000
66001     "screen": {
66002         "width": 360,
66003         "height": 640
66004     },
66005     "viewPort": {
66006         "portrait": {
66007             "width": 360,
66008             "height": 640,
66009             "paddingTop": 0,
66010             "paddingLeft": 0
66011         },
66012         "landscape": {
66013             "width": 640,
66014             "height": 360,
66015             "paddingTop": 0,
66016             "paddingLeft": 0
66017         }
66018     },
66019
66020     "ppi": 209.8,
66021     "userAgent": "(Symbian/3; S60/5.2 Mozilla/5.0; NokiaN8-00/10.0.000; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.2",
66022     "platforms": ["web", "phonegap"],
66023
66024     "notes": {
66025         "1": "<a href=\"http://www.forum.nokia.com/Devices/Device_specifications/N8-00/\" target=\"_blank\">Specs</a>"
66026     }
66027 };
66028
66029 });
66030 define('ripple/devices/Wave', function (require, exports, module) {
66031 /*
66032  *  Copyright 2011 Research In Motion Limited.
66033  *
66034  * Licensed under the Apache License, Version 2.0 (the "License");
66035  * you may not use this file except in compliance with the License.
66036  * You may obtain a copy of the License at
66037  *
66038  * http://www.apache.org/licenses/LICENSE-2.0
66039  *
66040  * Unless required by applicable law or agreed to in writing, software
66041  * distributed under the License is distributed on an "AS IS" BASIS,
66042  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66043  * See the License for the specific language governing permissions and
66044  * limitations under the License.
66045  */
66046 module.exports = {
66047     "id": "Wave",
66048     "name": "Samsung Wave",
66049     "manufacturer": "Samsung",
66050     "model": "Wave",
66051     "osName": "Bada",
66052     "osVersion": "n/a",
66053
66054     "screen": {
66055         "width": 480,
66056         "height": 800
66057     },
66058     "viewPort": {
66059         "portrait": {
66060             "width": 480,
66061             "height": 800,
66062             "paddingTop": 0,
66063             "paddingLeft": 0
66064         },
66065         "landscape": {
66066             "width": 800,
66067             "height": 480,
66068             "paddingTop": 0,
66069             "paddingLeft": 0
66070         }
66071     },
66072
66073     "ppi": 283,
66074     "userAgent": "?",
66075     "platforms": ["web"]
66076 };
66077
66078 });
66079 define('ripple/devices/IVI-HD', function (require, exports, module) {
66080 /*
66081  *  Copyright 2012 Intel Corporation
66082  *
66083  * Licensed under the Apache License, Version 2.0 (the "License");
66084  * you may not use this file except in compliance with the License.
66085  * You may obtain a copy of the License at
66086  *
66087  * http://www.apache.org/licenses/LICENSE-2.0
66088  *
66089  * Unless required by applicable law or agreed to in writing, software
66090  * distributed under the License is distributed on an "AS IS" BASIS,
66091  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66092  * See the License for the specific language governing permissions and
66093  * limitations under the License.
66094  */
66095
66096 module.exports = {
66097     "id": "IVI-HD",
66098     "name": "IVI HD (800x480)",
66099     "osName": "Generic",
66100     "osVersion": "Generic",
66101     "manufacturer": "Tizen",
66102     "model": "Generic",
66103     "uuid": "42",
66104     "firmware": "Generic",
66105
66106     "screen": {
66107         "width": 800,
66108         "height": 480
66109     },
66110     "viewPort": {
66111         "portrait": {
66112             "width": 1024,
66113             "height": 640,
66114             "paddingTop": 0,
66115             "paddingLeft": 0
66116         },
66117         "landscape": {
66118             "width": 640,
66119             "height": 1024,
66120             "paddingTop": 0,
66121             "paddingLeft": 0
66122         }
66123     },
66124
66125     "ppi": 316,
66126     "browser": ["Generic"],
66127     "platforms": ["ivi"],
66128     "userAgent": "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.7 Safari/533.2"
66129 };
66130
66131 });
66132 define('ripple/event', function (require, exports, module) {
66133 /*
66134  *  Copyright 2011 Research In Motion Limited.
66135  *
66136  * Licensed under the Apache License, Version 2.0 (the "License");
66137  * you may not use this file except in compliance with the License.
66138  * You may obtain a copy of the License at
66139  *
66140  * http://www.apache.org/licenses/LICENSE-2.0
66141  *
66142  * Unless required by applicable law or agreed to in writing, software
66143  * distributed under the License is distributed on an "AS IS" BASIS,
66144  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66145  * See the License for the specific language governing permissions and
66146  * limitations under the License.
66147  */
66148 var utils = require('ripple/utils'),
66149     exception = require('ripple/exception'),
66150     _listeners = {};
66151
66152 function _on(eventType, listener, scope, once) {
66153     if (!eventType) {
66154         throw "eventType must be truthy";
66155     }
66156     _listeners[eventType] = _listeners[eventType] || [];
66157     _listeners[eventType].push({
66158         func: listener,
66159         scope: scope,
66160         once: !!once
66161     });
66162 }
66163
66164 function _deleteEventHandler(eventType, listenerFunc, scope) {
66165     var i, listeners;
66166
66167     if (!eventType) {
66168         throw "eventType must be truthy";
66169     }
66170
66171     listeners = _listeners[eventType];
66172
66173     // only delete once
66174     for (i = 0; i < listeners.length; i++) {
66175         if (listeners[i].func === listenerFunc) {
66176             listeners.splice(i, 1);
66177             break;
66178         }
66179     }
66180 }
66181
66182 function _trigger(listener, args, sync) {
66183     try {
66184         if (sync) {
66185             listener.func.apply(listener.scope, args);
66186         }
66187         else {
66188             setTimeout(function () {
66189                 listener.func.apply(listener.scope, args);
66190             }, 1);
66191         }
66192     }
66193     catch (e) {
66194         exception.handle(e);
66195     }
66196 }
66197
66198 module.exports = {
66199     on: function (eventType, listener, scope) {
66200         _on(eventType, listener, scope, false);
66201     },
66202
66203     once: function (eventType, listener, scope) {
66204         _on(eventType, listener, scope, true);
66205     },
66206
66207     trigger: function (eventType, args, sync) {
66208         args = args || [];
66209         sync = sync || false;
66210
66211         var listeners = _listeners[eventType];
66212
66213         if (listeners) {
66214             listeners.forEach(function (listener) {
66215                 _trigger(listener, args, sync);
66216             });
66217
66218             _listeners[eventType] = listeners.filter(function (listener) {
66219                 return !listener.once;
66220             });
66221         }
66222     },
66223
66224     eventHasSubscriber: function (eventType) {
66225         return !!_listeners[eventType];
66226     },
66227
66228     getEventSubscribers: function (eventType) {
66229         return utils.copy(_listeners[eventType]) || [];
66230     },
66231
66232     clear: function (eventType) {
66233         if (eventType) {
66234             delete _listeners[eventType];
66235         }
66236     },
66237
66238     deleteEventHandler: function (eventType, listener, scope) {
66239         _deleteEventHandler(eventType, listener, scope);
66240     }
66241 };
66242
66243 });
66244 define('ripple/devices', function (require, exports, module) {
66245 /*
66246  *  Copyright 2011 Research In Motion Limited.
66247  *
66248  * Licensed under the Apache License, Version 2.0 (the "License");
66249  * you may not use this file except in compliance with the License.
66250  * You may obtain a copy of the License at
66251  *
66252  * http://www.apache.org/licenses/LICENSE-2.0
66253  *
66254  * Unless required by applicable law or agreed to in writing, software
66255  * distributed under the License is distributed on an "AS IS" BASIS,
66256  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66257  * See the License for the specific language governing permissions and
66258  * limitations under the License.
66259  */
66260 var _self,
66261     db = require('ripple/db'),
66262     utils = require('ripple/utils'),
66263     platform = require('ripple/platform'),
66264     event = require('ripple/event'),
66265     _devices = {};
66266
66267 event.on("HardwareKeyDefault", function (key) {
66268     if (key === 0 || key === "0") { //back button key
66269         require('ripple/emulatorBridge').window().history.back();
66270     }
66271 });
66272
66273 _self = module.exports = {
66274     initialize: function () {
66275         _devices = [
66276 /* 
66277            "Bold9700",
66278             "Bold9900",
66279             "Colt",
66280             "Curve9300",
66281             "Curve9350-9360-9370",
66282             "FWVGA",
66283             "G1",
66284 */          "IVI-HD",
66285             "tizen-WVGA",
66286 /*
66287             "HPPre3",
66288             "HPVeer",
66289 */
66290 //            "HVGA",
66291 /*
66292             "iPad",
66293             "iPhone3",
66294             "Legend",
66295             "Nexus",
66296             "NexusS",
66297             "NexusGalaxy",
66298             "Nexus7",
66299             "NokiaN8",
66300             "NokiaN97",
66301             "PalmPre",
66302             "PalmPre2",
66303             "Pearl9100",
66304             "Playbook",
66305             "QVGA",
66306             "Style9670",
66307             "Tattoo",
66308             "Torch9800",
66309             "Torch9810",
66310             "Torch9860-9850",
66311             "Wave",
66312             "WQVGA",
66313 */
66314 //            "WSVGA",
66315             "WVGA",
66316             "HD",
66317             "tizen-HD",
66318             "custom"
66319         ].reduce(function (hash, deviceID) {
66320             hash[deviceID] = require('ripple/devices/' + deviceID);
66321             return hash;
66322         }, {});
66323
66324         var current = this.getCurrentDevice();
66325         require('ripple/bus').send('userAgent', current.userAgent);
66326     },
66327
66328     getCurrentDevice: function () {
66329         var deviceId = db.retrieve("device-key"),
66330             device = this.getDevice(deviceId),
66331             platformId = platform.current().id,
66332             does = function (device) {
66333                 return {
66334                     include: function (platformId) {
66335                         return device.platforms.some(function (id) {
66336                             return platformId === id;
66337                         });
66338                     }
66339                 };
66340             };
66341
66342         if (deviceId !== "custom" && (!device || !does(device).include(platformId))) {
66343             deviceId = utils.reduce(_devices, function (current, device, id) {
66344                 return does(device).include(platformId) ? id : current;
66345             });
66346             device = this.getDevice(deviceId);
66347         }
66348
66349         return device;
66350     },
66351
66352     getDevice: function (deviceId) {
66353         var device, width, height, viewportWidth, viewportHeight, layout, viewportTag, ratio;
66354
66355         device = _devices[deviceId] ? utils.copy(_devices[deviceId]) : null;
66356         width = db.retrieve("custom_width") || 600;
66357         height = db.retrieve("custom_height") || 800;
66358         viewportTag = db.retrieveObject("viewportTag");
66359         layout = db.retrieve("layout") || "portrait" ;
66360
66361         if (deviceId === undefined)
66362             return null;
66363         width =  parseInt(width, 10);
66364         height =  parseInt(height, 10);
66365
66366         if (viewportTag !== undefined) {
66367             if (viewportTag['width'] !== undefined) {
66368                 if (viewportTag['width'] === "device-width") {
66369                     viewportWidth = device.viewPort[layout].width;
66370                 } else if (viewportTag['width'] === "device-height") {
66371                     viewportWidth = device.viewPort[layout].height;
66372                 }
66373                 else {
66374                     viewportWidth = parseInt(viewportTag['width'], 10);
66375                     if (isNaN(viewportWidth)) {
66376                         viewportWidth = device.viewPort[layout].width;
66377                     }
66378                 }
66379                 db.saveObject("viewport_width", viewportWidth);
66380
66381                 if (layout === "portrait") {
66382                     if (deviceId !== "custom") {
66383                         ratio = device.screen.height / device.screen.width;
66384                     } else {
66385                         ratio = height / width;
66386                     }
66387                     viewportHeight = viewportWidth * ratio;
66388                     db.saveObject("viewport_height", viewportHeight);
66389                 } else {
66390                     if (deviceId !== "custom") {
66391                         ratio = device.screen.width / device.screen.height;
66392                     } else {
66393                         ratio = width / height;
66394                     }
66395                     viewportHeight = viewportWidth * ratio;
66396                     db.saveObject("viewport_height", viewportHeight);
66397                 }
66398             } else if(viewportTag['height'] !== undefined) {
66399                 if (viewportTag['height'] === "device-height") {
66400                     viewportHeight = device.viewPort[layout].height;
66401                 } else if (viewportTag['height'] === "device-width") {
66402                     viewportHeight = device.viewPort[layout].width;
66403                 }
66404                 else {
66405                     viewportHeight = parseInt(viewportTag['height'], 10);
66406                     if (isNaN(viewportHeight)) {
66407                         viewportHeight = device.viewPort[layout].height;
66408                     }
66409                 }
66410                 db.saveObject("viewport_height", viewportHeight);
66411
66412                 if (layout === "portrait") {
66413                     if (deviceId !== "custom") {
66414                         ratio = device.screen.height / device.screen.width;
66415                     } else {
66416                         ratio = height / width;
66417                     }
66418                     viewportWidth = viewportHeight / ratio;
66419                     db.saveObject("viewport_width", viewportWidth);
66420                 } else {
66421                     if (deviceId !== "custom") {
66422                         ratio = device.screen.width / device.screen.height;
66423                     } else {
66424                         ratio = width / height;
66425                     }
66426                     viewportWidth = viewportHeight / ratio;
66427                     db.saveObject("viewport_width", viewportWidth);
66428                 }
66429             }
66430         }
66431
66432         if (viewportWidth === undefined) {
66433             if (deviceId === "custom") {
66434                 viewportWidth = width;
66435             } else {
66436                 viewportWidth = device.viewPort[layout].width;
66437             }
66438         }
66439
66440         if (viewportHeight === undefined) {
66441             if (deviceId === "custom") {
66442                 viewportHeight = height;
66443             } else {
66444                 viewportHeight = device.viewPort[layout].height;
66445             }
66446         }
66447
66448         $('#resolution-custom-width').val(width);
66449         $('#resolution-custom-height').val(height);
66450
66451         if (deviceId === "custom") {
66452             device.screen.width = width;
66453             device.screen.height = height;
66454             $('input:radio[name="resolution-type"][value="custom"]').click();
66455         }
66456
66457         if (layout === "portrait") {
66458             device.viewPort.portrait.width = viewportWidth;
66459             device.viewPort.portrait.height = viewportHeight;
66460             device.viewPort.landscape.width = viewportHeight;
66461             device.viewPort.landscape.height = viewportWidth;
66462         } else {
66463             device.viewPort.portrait.width = viewportHeight;
66464             device.viewPort.portrait.height = viewportWidth;
66465             device.viewPort.landscape.width = viewportWidth;
66466             device.viewPort.landscape.height = viewportHeight;
66467         }
66468         return device;
66469     },
66470
66471     getDevicesForPlatform: function (platformId) {
66472         return utils.filter(_devices, function (device) {
66473             return device.platforms.indexOf(platformId) > -1;
66474         });
66475     }
66476 };
66477
66478 });
66479 define('ripple/dbfs', function (require, exports, module) {
66480 /*
66481  *  Copyright 2011 Research In Motion Limited.
66482  *
66483  * Licensed under the Apache License, Version 2.0 (the "License");
66484  * you may not use this file except in compliance with the License.
66485  * You may obtain a copy of the License at
66486  *
66487  * http://www.apache.org/licenses/LICENSE-2.0
66488  *
66489  * Unless required by applicable law or agreed to in writing, software
66490  * distributed under the License is distributed on an "AS IS" BASIS,
66491  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66492  * See the License for the specific language governing permissions and
66493  * limitations under the License.
66494  */
66495 var db = require('ripple/db'),
66496     utils = require('ripple/utils'),
66497     event = require('ripple/event'),
66498     _cache = {},
66499     _self;
66500
66501 function _get(path) {
66502     return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
66503         return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
66504     }, _cache);
66505 }
66506
66507 function _getInfo(path) {
66508     var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
66509         name = parent.splice(parent.length - 1, 1).join(""),
66510         ext = name.split(".");
66511
66512     return {
66513         name: name,
66514         extension: ext.length > 1 ? ext[ext.length - 1] : "",
66515         hidden: (name.length > 0 && name[0] === ".") || false,
66516         parent: parent.join("/") || "/"
66517     };
66518 }
66519
66520 function _set(path, obj) {
66521     var parent = _cache,
66522         tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
66523         child = tokens.splice(tokens.length - 1, 1).join("");
66524
66525     tokens.forEach(function (token) {
66526         parent = parent.children[token];
66527     });
66528
66529     parent.children = parent.children || {};
66530     obj.properties = obj.properties || {};
66531     parent.children[child] = obj;
66532 }
66533
66534 function _delete(path) {
66535     var parent = _cache,
66536         tokens = path.replace(/^\//, '').split("/"),
66537         child = tokens.splice(tokens.length - 1, 1).join("");
66538
66539     tokens.forEach(function (token) {
66540         parent = parent.children[token];
66541     });
66542
66543     delete parent.children[child];
66544 }
66545
66546 function _save() {
66547     db.saveObject("db-filesystem", _cache);
66548 }
66549
66550 _self = {
66551
66552     initialize: function (prev, baton) {
66553         _cache = db.retrieveObject("db-filesystem") || {};
66554         event.trigger("FileSystemInitialized", null, true);
66555     },
66556
66557     ls: function (path, success, error) {
66558         try {
66559             var dir = _get(path),
66560                 items = [];
66561
66562             if (dir) {
66563                 utils.forEach(dir.children, function (item) {
66564                     if (!item.isDirectory) {
66565                         item.file = function (callback) {
66566                             callback({});
66567                         };
66568                     }
66569                     items.push(item);
66570                 });
66571             }
66572             else {
66573                 items = {};
66574             }
66575
66576             success(utils.copy(items));
66577         }
66578         catch (e) {
66579             e.code = 1;
66580             error(e);
66581         }
66582     },
66583
66584     rm: function (path, success, error, options) {
66585         _delete(path);
66586         _save();
66587         success();
66588     },
66589
66590     rmdir: function (path, success, error, options) {
66591         _delete(path);
66592         _save();
66593         success();
66594     },
66595
66596     mkdir: function (path, success, error) {
66597         var entry = _get(path),
66598             info = _getInfo(path);
66599
66600         if (!entry) {
66601             _set(path, {
66602                 name: info.name,
66603                 isDirectory: true,
66604                 fullPath: path
66605             });
66606             entry = _get(path);
66607         }
66608         
66609         _save();
66610         if (entry) {
66611             success(utils.copy(entry));
66612         }
66613         else {
66614             error({code: 1});
66615         }
66616     },
66617
66618     mv: function (from, to, success, error) {
66619         try {
66620             var fromEntry = _get(from),
66621                 toInfo = _getInfo(to);
66622
66623             fromEntry.fullPath = to;
66624             fromEntry.name = toInfo.name;
66625
66626             _set(to, fromEntry);
66627             _delete(from);
66628             _save();
66629             success(utils.copy(_get(to)));
66630         }
66631         catch (e) {
66632             e.code = 1;
66633             error(e);
66634         }
66635     },
66636
66637     touch: function (path, success, error) {
66638         if (!_get(path)) {
66639             _set(path, {
66640                 fullPath: path
66641             });
66642         }
66643         _save();
66644         success(utils.copy(_get(path)));
66645     },
66646
66647     cp: function (from, to, success, error) {
66648         try {
66649             var fromEntry = _get(from);
66650             fromEntry.fullPath = to;
66651             _set(to, fromEntry);
66652             _save();
66653             success(utils.copy(_get(to)));
66654         }
66655         catch (e) {
66656             e.code = 1;
66657             error(e);
66658         }
66659     },
66660
66661     stat: function (path, success, error) {
66662         var entry = _get(path);
66663         success(utils.copy(entry));
66664     },
66665
66666     write: function (path, contents, success, error, options) {
66667         var info = _getInfo(path);
66668
66669         _set(path, {
66670             lastModifiedDate: new Date(),
66671             name: info.name,
66672             fullPath: path,
66673             isDirectory: false,
66674             properties: {
66675                 type: "",
66676                 size: contents.size
66677             },
66678             data: contents,
66679             file: function (callback) {
66680                 callback({});
66681             }
66682         });
66683
66684         success(utils.copy(_get(path)));
66685     },
66686
66687     read: function (path, success, error) {
66688         var entry = _get(path);
66689
66690         if (entry) {
66691             success(utils.copy(entry.data));
66692         }
66693         else {
66694             error({code: 1});
66695         }
66696     }
66697 };
66698
66699 module.exports = _self;
66700
66701 });
66702 define('ripple/deviceMotionEmulator', function (require, exports, module) {
66703 /*
66704  *  Copyright 2011 Research In Motion Limited.
66705  *
66706  * Licensed under the Apache License, Version 2.0 (the "License");
66707  * you may not use this file except in compliance with the License.
66708  * You may obtain a copy of the License at
66709  *
66710  * http://www.apache.org/licenses/LICENSE-2.0
66711  *
66712  * Unless required by applicable law or agreed to in writing, software
66713  * distributed under the License is distributed on an "AS IS" BASIS,
66714  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66715  * See the License for the specific language governing permissions and
66716  * limitations under the License.
66717  */
66718
66719 var event = require('ripple/event'),
66720     platform = require('ripple/platform'),
66721     INTERVAL = 60000,
66722     _self;
66723
66724 function _bind(name, win) {
66725     var callback = null;
66726
66727     win.__defineGetter__(name, function () {
66728         return callback;
66729     });
66730
66731     win.__defineSetter__(name, function (cb) {
66732         callback = cb;
66733     });
66734
66735     return {
66736         get: function () {
66737             return callback;
66738         },
66739         set: function (value) {
66740             callback = value;
66741         },
66742         exec: function (arg) {
66743             return callback && callback(arg);
66744         },
66745         unbind: function (cb) {
66746             callback = cb === callback ? null : callback;
66747         }
66748     };
66749 }
66750
66751 _self = {
66752     init: function (win, doc) {
66753         var widgetWindow = win,
66754             _motion,
66755             _orientation,
66756             _calibration,
66757             add = widgetWindow.addEventListener,
66758             remove = widgetWindow.removeEventListener;
66759
66760         //Hang events off window (these are used to check for API existence by developer)
66761         widgetWindow.DeviceMotionEvent = function DeviceMotionEvent() {};
66762         widgetWindow.DeviceOrientationEvent = function DeviceOrientationEvent() {};
66763
66764         _motion = _bind("ondevicemotion", widgetWindow);
66765         _orientation = _bind("ondeviceorientation", widgetWindow);
66766         _calibration = _bind("oncompassneedscalibration", widgetWindow);
66767
66768         widgetWindow.addEventListener = function (e, callback, useCapture) {
66769             switch (e) {
66770             case "deviceorientation":
66771                 _orientation.set(callback);
66772                 event.trigger("DeviceOrientationEventAddedEvent");
66773                 break;
66774             case "devicemotion":
66775                 _motion.set(callback);
66776                 event.trigger("DeviceMotionEventAddedEvent");
66777                 break;
66778             case "compassneedscalibration":
66779                 _calibration.set(callback);
66780                 break;
66781
66782             default:
66783                 add.apply(widgetWindow, arguments);
66784                 break;
66785             }
66786         };
66787
66788         widgetWindow.removeEventListener = function (event, callback) {
66789             _motion.unbind(callback);
66790             _orientation.unbind(callback);
66791             _calibration.unbind(callback);
66792             remove.apply(widgetWindow, arguments);
66793         };
66794
66795         event.on("DeviceMotionEvent", function (motion) {
66796             var _motionEvent, DeviceMotionEvent;
66797
66798             if (platform.current().DeviceMotionEvent) {
66799                 DeviceMotionEvent = platform.current().DeviceMotionEvent;
66800                 if (typeof DeviceMotionEvent !== "function")
66801                     return;
66802
66803                 _motionEvent = new DeviceMotionEvent();
66804                 _motionEvent.initAccelerometerEvent("devicemotion", true, false, motion.acceleration, motion.accelerationIncludingGravity, 
66805                                                     motion.rotationRate, INTERVAL);    
66806             }
66807             else {
66808                 _motionEvent = {
66809                     acceleration: motion.acceleration,
66810                     accelerationIncludingGravity: motion.accelerationIncludingGravity,
66811                     rotationRate: motion.rotationRate
66812                 };
66813             }
66814
66815             _motion.exec(_motionEvent);
66816         });
66817
66818         event.on("DeviceOrientationEvent", function (motion) {
66819             var _orientationEvent, DeviceOrientationEvent;
66820
66821             if (platform.current().DeviceOrientationEvent) {
66822                 DeviceOrientationEvent = platform.current().DeviceOrientationEvent;
66823                 if (typeof DeviceOrientationEvent !== "function")
66824                     return;
66825
66826                 _orientationEvent = new DeviceOrientationEvent();        
66827                 _orientationEvent.initDeviceOrientationEvent("deviceorientation", true, false, motion.orientation.alpha, 
66828                                                               motion.orientation.beta, motion.orientation.gamma, true);
66829             }
66830             else {
66831                 _orientationEvent = motion.orientation;
66832             }
66833
66834             _orientation.exec(_orientationEvent);
66835         });
66836     }
66837 };
66838
66839 module.exports = _self;
66840
66841 });
66842 define('ripple/platform', function (require, exports, module) {
66843 /*
66844  *  Copyright 2011 Research In Motion Limited.
66845  *
66846  * Licensed under the Apache License, Version 2.0 (the "License");
66847  * you may not use this file except in compliance with the License.
66848  * You may obtain a copy of the License at
66849  *
66850  * http://www.apache.org/licenses/LICENSE-2.0
66851  *
66852  * Unless required by applicable law or agreed to in writing, software
66853  * distributed under the License is distributed on an "AS IS" BASIS,
66854  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66855  * See the License for the specific language governing permissions and
66856  * limitations under the License.
66857  */
66858 var _current,
66859     db = require('ripple/db'),
66860     utils = require('ripple/utils'),
66861     _console = require('ripple/console'),
66862     app = require('ripple/app'),
66863     event = require('ripple/event'),
66864     spec = require('ripple/platform/spec'),
66865     _self;
66866
66867 function _getRequestedPlatform() {
66868     var requestedPlatform = null,
66869         enableRippleArg = utils.queryString().enableripple,
66870         platform;
66871
66872     if (enableRippleArg) {
66873         enableRippleArg = enableRippleArg.split('-');
66874         platform = spec.get(enableRippleArg[0], enableRippleArg[1]);
66875         if (platform) {
66876             requestedPlatform = { name: platform.id, version: platform.version };
66877         }
66878     }
66879
66880     return requestedPlatform;
66881 }
66882
66883 function _validatePlatform(platform, defaultPlatform) {
66884     if (!platform ||
66885         !spec[platform.name] ||
66886         !spec[platform.name][platform.version] ||
66887         (spec[platform.name][platform.version] && !spec[platform.name][platform.version].objects)) {
66888         return defaultPlatform;
66889     }
66890     return platform;
66891 }
66892
66893 function _getPlatform() {
66894     return require('ripple/platform/' + _current.name + "/" + _current.version + "/spec");
66895 }
66896
66897 function _getCurrentPlatform() {
66898     var uriParams, platform = {};
66899
66900     uriParams = utils.getURIParams(document.documentURI);
66901     if (uriParams && uriParams.platform) {
66902         var platformName = uriParams.platform.split("-")[0], platformVersion;
66903
66904         if (platformName === "mobile" || platformName === "tizen") {
66905             platformName = "tizen";
66906             platformVersion = "2.0";
66907         }
66908         else {
66909             platformName = "ivi";
66910             platformVersion = "3.0";
66911         }
66912         platform.name = platformName;
66913         platform.version = platformVersion;
66914
66915         return platform;
66916     }
66917
66918     return undefined;
66919 }
66920
66921 _self = {
66922     initialize: function () {
66923         var firstAvailablePlatform = utils.map(this.getList(), function (platform) {
66924             return utils.map(platform, function (details, version) {
66925                 return {name: details.id, version: version};
66926             })[0];
66927         })[0];
66928
66929         _current = _getRequestedPlatform() || _getCurrentPlatform() ||
66930                 db.retrieveObject("api-key") || firstAvailablePlatform;
66931         _current = _validatePlatform(_current, firstAvailablePlatform);
66932
66933         db.saveObject("api-key", _current);
66934
66935         _console.prefix = _current.name;
66936     },
66937
66938     getList: function () {
66939         var platformList = {};
66940         utils.forEach(spec, function (platform, platformKey) {
66941             utils.forEach(platform, function (version, versionKey) {
66942                 platformList[platformKey] = platformList[platformKey] || {};
66943                 platformList[platformKey][versionKey] = {
66944                     "id": version.id,
66945                     "name": version.name,
66946                     "type": version.type,
66947                     "text": require('ripple/platform/' + platformKey + "/" + versionKey + "/spec").version
66948                 };
66949             });
66950         });
66951
66952         return platformList;
66953     },
66954
66955     getPersistencePrefix: function (id) {
66956         return _getPlatform().persistencePrefix + (id || app.getInfo().id) + "-";
66957     },
66958
66959     current: function () {
66960         return _getPlatform();
66961     },
66962
66963     changeEnvironment: function (platform, deviceId, callback) {
66964         var save = jWorkflow.order(function (prev, baton) {
66965                 baton.take();
66966                 db.saveObject("api-key", platform, null, baton.pass);
66967             }).andThen(function (prev, baton) {
66968                 baton.take();
66969                 db.save("device-key", deviceId, null, baton.pass);
66970             }).andThen(function (prev, baton) {
66971                 //remove the persisted value for the layout
66972                 baton.take();
66973                 db.save("layout", null, null, baton.pass);
66974             }).andThen(function () {
66975                 event.trigger("PlatformChangedEvent", [], true);
66976                 _console.prefix = null;
66977                 _console.log("Emulator :: loading platform " + platform.name);
66978             });
66979
66980         save.start(callback);
66981     }
66982 };
66983
66984 module.exports = _self;
66985
66986 });
66987 define('ripple/hwKeyEmulator', function (require, exports, module) {
66988 /*
66989  *  Copyright 2011 Research In Motion Limited.
66990  *
66991  * Licensed under the Apache License, Version 2.0 (the "License");
66992  * you may not use this file except in compliance with the License.
66993  * You may obtain a copy of the License at
66994  *
66995  * http://www.apache.org/licenses/LICENSE-2.0
66996  *
66997  * Unless required by applicable law or agreed to in writing, software
66998  * distributed under the License is distributed on an "AS IS" BASIS,
66999  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67000  * See the License for the specific language governing permissions and
67001  * limitations under the License.
67002  */
67003
67004 var event = require('ripple/event'),
67005    _self;
67006
67007 function _HWKeyEvent(keyName) {
67008     var doc = document.getElementById('document').contentDocument,
67009     event;
67010
67011     event = doc.createEvent('Event');
67012     event.initEvent("tizenhwkey", true, false);
67013     event.__defineGetter__("keyName", function () {
67014         return keyName;
67015     });
67016     doc.dispatchEvent(event);
67017 }
67018
67019
67020 _self = {
67021     init: function (win, doc) {
67022         event.clear("tizenhwkeyEvent");
67023         event.on("tizenhwkeyEvent", function (keyName) {
67024             _HWKeyEvent(keyName);
67025         });
67026     }
67027 };
67028
67029 module.exports = _self;
67030
67031 });
67032 define('ripple/emulatorBridge', function (require, exports, module) {
67033 /*
67034  *  Copyright 2011 Research In Motion Limited.
67035  *
67036  * Licensed under the Apache License, Version 2.0 (the "License");
67037  * you may not use this file except in compliance with the License.
67038  * You may obtain a copy of the License at
67039  *
67040  * http://www.apache.org/licenses/LICENSE-2.0
67041  *
67042  * Unless required by applicable law or agreed to in writing, software
67043  * distributed under the License is distributed on an "AS IS" BASIS,
67044  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67045  * See the License for the specific language governing permissions and
67046  * limitations under the License.
67047  */
67048 var platform = require('ripple/platform'),
67049     builder = require('ripple/platform/builder'),
67050     utils = require('ripple/utils'),
67051     _xhr, _win, _doc;
67052
67053 function _getEmulatedViewportStyle(attr) {
67054     var vp = document.getElementById("viewport-container");
67055     return vp["client" + attr];
67056 }
67057
67058 function _getEmulatedDeviceStyle(attr) {
67059     var vp = document.getElementById("device-container"), value;
67060     value = vp.style[attr].replace(/\s/g, '');
67061     value = value.split("px")[0] - 4;
67062     return (value);
67063 }
67064
67065 function _screenAvailWidth() {
67066     return _getEmulatedDeviceStyle("width");
67067 }
67068
67069 function _screenAvailHeight() {
67070     return _getEmulatedDeviceStyle("height");
67071 }
67072
67073 function _screenWidth() {
67074     return _getEmulatedDeviceStyle("width");
67075 }
67076
67077 function _screenHeight() {
67078     return _getEmulatedDeviceStyle("height");
67079 }
67080
67081 function _window_innerWidth() {
67082     return _getEmulatedViewportStyle("Width");
67083 }
67084
67085 function _window_innerHeight() {
67086     return _getEmulatedViewportStyle("Height");
67087 }
67088
67089 function _marshalScreen(win) {
67090     utils.forEach({
67091         "availWidth": _screenAvailWidth,
67092         "availHeight": _screenAvailHeight,
67093         "width": _screenWidth,
67094         "height": _screenHeight
67095     }, function (mappedFunc, prop) {
67096         win.screen.__defineGetter__(prop, mappedFunc);
67097     });
67098
67099     utils.forEach({
67100         "innerWidth": _window_innerWidth,
67101         "innerHeight": _window_innerHeight
67102     }, function (mappedFunc, prop) {
67103         win.__defineGetter__(prop, mappedFunc);
67104     });
67105 }
67106
67107 module.exports = {
67108     link: function  (win, doc) {
67109         // Only cache the device window and route onmessage to it
67110         if (win.parent.parent === win.parent &&
67111                 win.frameElement.getAttribute('id') === 'document') {
67112             _win = win;
67113             _doc = doc;
67114             _xhr = win.XMLHttpRequest;
67115
67116             window.onmessage = function (e) {
67117                 if (typeof win.onmessage === 'function') {
67118                     win.onmessage(e);
67119                 }
67120             };
67121         }
67122
67123         require('ripple/widgetConfig').initialize();
67124
67125         var marshal = function (obj, key) {
67126                 window[key] = win[key] = obj;
67127             },
67128             currentPlatform = platform.current(),
67129             sandbox = {};
67130
67131         marshal(window.tinyHippos, "tinyHippos");
67132         marshal(window.XMLHttpRequest, "XMLHttpRequest");
67133         marshal(window.Date, "Date");
67134
67135         if (currentPlatform.initialize) {
67136             currentPlatform.initialize(win);
67137         }
67138
67139         builder.build(platform.current().objects).into(sandbox);
67140         utils.forEach(sandbox, marshal);
67141
67142         _marshalScreen(win);
67143         _marshalScreen(window);
67144     },
67145
67146     document: function () {
67147         return _doc;
67148     },
67149
67150     window: function () {
67151         return _win;
67152     },
67153
67154     xhr: function () {
67155         return _xhr;
67156     }
67157 };
67158
67159 });
67160 define('ripple/documentEventListener', function (require, exports, module) {
67161 /*
67162  *  Copyright 2012 Intel Corporation.
67163  *
67164  * Licensed under the Apache License, Version 2.0 (the "License");
67165  * you may not use this file except in compliance with the License.
67166  * You may obtain a copy of the License at
67167  *
67168  * http://www.apache.org/licenses/LICENSE-2.0
67169  *
67170  * Unless required by applicable law or agreed to in writing, software
67171  * distributed under the License is distributed on an "AS IS" BASIS,
67172  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67173  * See the License for the specific language governing permissions and
67174  * limitations under the License.
67175  */
67176
67177 var event = require('ripple/event'),
67178     constants = require('ripple/constants'),
67179     deviceSettings = require('ripple/deviceSettings'),
67180     ui = require('ripple/ui'),
67181     _self,
67182     _ComWinShow = false;
67183
67184 function _bind(name, win) {
67185     var _listeners = [];
67186
67187     return {
67188         add: function (callback, useCapture) {
67189             // ignore non-function
67190             if (typeof callback === "function") {
67191                 // ignore useCapture as we could not handle it
67192                 if (!useCapture) {
67193                     if (!_listeners.some(function (listener) {
67194                         return (listener === callback);
67195                     })) {
67196                         _listeners.push(callback);
67197                     }
67198                 }
67199             }
67200         },
67201         exec: function (arg) {
67202             _listeners.forEach(function (listener) {
67203                 listener.apply(win, arg);
67204             });
67205         },
67206         remove: function (callback, useCapture) {
67207             // ignore non-function
67208             if (typeof callback === "function") {
67209                 // ignore useCapture as we do not add them into _listeners
67210                 if (!useCapture) {
67211                     _listeners = _listeners.filter(function (listener) {
67212                         return (listener !== callback);
67213                     });
67214                 }
67215             }
67216         }
67217     };
67218 }
67219
67220 function _isComWinSHow() {
67221     return _ComWinShow;
67222 }
67223
67224 _self = {
67225     mask: function (frame, doc) {
67226         /* 
67227          * The current issue is that "document.addEventListener(visibilitychange, function(){...})" 
67228          * does not work if it is invoked in the document.DOMContentLoaded listeners, for example, at 
67229          * JQuery(document).ready function.
67230
67231          * The reason is that window.DOMContentLoaded is fired after the document.DOMContentLoaded. 
67232          * Currently we have not found a proper event to override the document.addEventListener. 
67233          * The beforeload is fine for window.addEventListener, while does not work for document.addEventListener 
67234          * because the contentDocument will be reset after loading. 
67235          */
67236         frame.addEventListener("DOMContentLoaded", function () {
67237             var widgetDocument = doc,
67238                 _pageVisibility,
67239                 add = widgetDocument.addEventListener,
67240                 remove = widgetDocument.removeEventListener;
67241
67242             widgetDocument.PAGE_HIDDEN  = "hidden";
67243             widgetDocument.PAGE_VISIBLE = "visible";
67244             widgetDocument.PAGE_PREVIEW = "preview";
67245
67246             function _lockScreen(on) {
67247                 var hidden = on;
67248
67249                 if (on) {
67250                     ui.showOverlay("lock-screen-window", function (background) {});
67251                 } else {
67252                     ui.hideOverlay("lock-screen-window", function (background) {});
67253                 }
67254
67255                 event.trigger("visibilitychange", [hidden]);
67256             }
67257
67258             function _isLockScreenOn() {
67259                 return deviceSettings.retrieve("Config.lockScreen");
67260             }
67261
67262             _lockScreen(_isLockScreenOn());
67263
67264             _pageVisibility = _bind("visibilitychange", frame.contentWindow);
67265
67266             widgetDocument.addEventListener = function (event, callback, useCapture) {
67267                 switch (event) {
67268                 case "visibilitychange":
67269                     _pageVisibility.add(callback, useCapture);
67270                     break;
67271
67272                 default:
67273                     add.apply(widgetDocument, arguments);
67274                     break;
67275                 }
67276             };
67277
67278             widgetDocument.removeEventListener = function (event, callback, useCapture) {
67279                 _pageVisibility.remove(callback, useCapture);
67280                 remove.apply(widgetDocument, arguments);
67281             };
67282
67283             event.on("LockScreenChanged", function (on) {
67284                 if (_isComWinSHow() === false) {
67285                     _lockScreen(on);
67286                 }
67287                 else {
67288                     if (on === true) {
67289                         ui.hideOverlay("communication-window");
67290                         _lockScreen(on);
67291                     }
67292                     else {
67293                         _lockScreen(on);
67294                         ui.showOverlay("communication-window");
67295                     }
67296                 }
67297             });
67298
67299             event.on("CommWinShow", function (status) {
67300                 _ComWinShow = status;
67301                 if (_isLockScreenOn() === true) {
67302                     if (status === false) {
67303                         _lockScreen(true);
67304                     }
67305                     else {
67306                         jQuery("#lock-screen-window").hide();
67307                     }
67308                 }
67309             });
67310
67311             event.on("visibilitychange", function (hidden) {
67312                 widgetDocument.hidden = hidden;
67313                 widgetDocument.visibilityState = hidden ? widgetDocument.PAGE_HIDDEN : widgetDocument.PAGE_VISIBLE;
67314                 _pageVisibility.exec();
67315             });
67316         });
67317     }
67318 };
67319
67320 module.exports = _self;
67321
67322 });
67323 define('ripple/honeypot', function (require, exports, module) {
67324 /*
67325  *  Copyright 2011 Research In Motion Limited.
67326  *
67327  * Licensed under the Apache License, Version 2.0 (the "License");
67328  * you may not use this file except in compliance with the License.
67329  * You may obtain a copy of the License at
67330  *
67331  * http://www.apache.org/licenses/LICENSE-2.0
67332  *
67333  * Unless required by applicable law or agreed to in writing, software
67334  * distributed under the License is distributed on an "AS IS" BASIS,
67335  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67336  * See the License for the specific language governing permissions and
67337  * limitations under the License.
67338  */
67339
67340 var noop = function () {};
67341
67342 module.exports = {
67343     monitor: function (context, target) {
67344
67345         var setup = function (get, set) {
67346             set = set || noop;
67347
67348             context.__defineGetter__(target, noop);
67349             context.__defineSetter__(target, function (value) {
67350                 context.__defineGetter__(target, get);
67351                 set(value);
67352             });
67353         };
67354
67355         return {
67356             andReturn: function (value) {
67357                 setup(function () {
67358                     return value;
67359                 });
67360             },
67361             andRun: function (get, set) {
67362                 setup(get, set);
67363             }
67364         };
67365     }
67366 };
67367
67368 });
67369 define('ripple/bootstrap', function (require, exports, module) {
67370 /*
67371  *  Copyright 2011 Research In Motion Limited.
67372  *
67373  * Licensed under the Apache License, Version 2.0 (the "License");
67374  * you may not use this file except in compliance with the License.
67375  * You may obtain a copy of the License at
67376  *
67377  * http://www.apache.org/licenses/LICENSE-2.0
67378  *
67379  * Unless required by applicable law or agreed to in writing, software
67380  * distributed under the License is distributed on an "AS IS" BASIS,
67381  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67382  * See the License for the specific language governing permissions and
67383  * limitations under the License.
67384  */
67385 var _bound,
67386     _console = require('ripple/console'),
67387     utils = require('ripple/utils'),
67388     ui = require('ripple/ui'),
67389     db = require('ripple/db'),
67390     _CURRENT_URL = "current-url",
67391     resizer = require('ripple/resizer'),
67392     platform = require('ripple/platform');
67393
67394 var _srcChangedObserver = new WebKitMutationObserver(function (mutations) {
67395             utils.forEach(mutations, function (mutation) {
67396                 _bindObjectsToFrame(mutation.target);
67397             });
67398         });
67399
67400 function _observeIframeAdded(doc) {
67401     doc._iframeAddedObserver.observe(doc, {childList: true, subtree: true});
67402 }
67403
67404 function _bindObjects(win, doc) {
67405     if (!win.tinyHippos) {
67406         require('ripple/emulatorBridge').link(win, doc);
67407         /// require('ripple/platform/tizen/2.0/touchEvent').mask(win, doc);
67408         require('ripple/touchEventEmulator').mask(win, doc);
67409         require('ripple/hwKeyEmulator').init(win, doc);
67410         require('ripple/documentEventListener').mask(win, doc);
67411         require('ripple/deviceMotionEmulator').init(win, doc);
67412         require('ripple/resizer').init(win, doc);
67413         win.addEventListener("DOMContentLoaded", function () {
67414             var iframes =  $(this.document).find("iframe");
67415             // Observe iframe added event so that we can bind objects to newly added iframes
67416             if (!this.document._iframeAddedObserver) {
67417                 this.document._iframeAddedObserver = new WebKitMutationObserver(function (mutations) {
67418                     utils.forEach(mutations, function (mutation) {
67419                         for (var i in mutation.addedNodes) {
67420                             var node = mutation.addedNodes[i];
67421                             if (node.tagName && (node.tagName.toUpperCase() === "IFRAME")) {
67422                                 _bindObjectsToFrame(node);
67423                             }
67424                         }
67425                     });
67426                 });
67427                 _observeIframeAdded(this.document);
67428             }
67429             iframes.each(function () {
67430                 _bindObjectsToFrame(this);
67431             });
67432
67433         });
67434         win.frameElement._bound = true;
67435     }
67436 }
67437
67438 function _beforeLoad() {
67439     this._bound = false;
67440     _bindObjects(this.contentWindow, this.contentDocument);
67441     this._intervalId = window.setInterval(function () {
67442         if (this._bound) {
67443             window.clearInterval(this._intervalId);
67444         } else {
67445             _bindObjects(this.contentWindow, this.contentDocument);
67446         }
67447     }.bind(this), 1);
67448 }
67449
67450 function _bindObjectsToFrame(frame) {
67451     _srcChangedObserver.observe(frame, {attributes: true, attributeFilter: ["src"]});
67452     frame.addEventListener("beforeload", _beforeLoad);
67453     // beforeload event of an iframe will not be triggered unless we detach and
67454     // then attach the iframe to the dom tree
67455     var parentNode = frame.parentNode;
67456     var nextNode = frame.nextNode;
67457     if (parentNode) {
67458         // Disable iframe added observer to avoid infinite loop of binding objects
67459         if (frame.ownerDocument && frame.ownerDocument._iframeAddedObserver) {
67460             frame.ownerDocument._iframeAddedObserver.disconnect();
67461         }
67462         parentNode.removeChild(frame);
67463         if (nextNode)
67464             nextNode.insertBefore(frame);
67465         else
67466             parentNode.appendChild(frame);
67467
67468         if (frame.ownerDocument && frame.ownerDocument._iframeAddedObserver) {
67469             _observeIframeAdded(frame.ownerDocument);
67470         }
67471     }
67472 }
67473
67474 function _createFrame(src) {
67475     var frame = document.createElement("iframe");
67476     frame.setAttribute("id", "document");
67477     frame.src = src;
67478
67479     if (ui.registered("omnibar")) {
67480         _bindObjectsToFrame(frame);
67481     }
67482
67483     return frame;
67484 }
67485
67486 function _cleanBody() {
67487     require('ripple/utils').forEach(document.body.children, function (child) {
67488         if (child && child.id && !child.id.match(/ui|tooltip|bus/)) {
67489             document.body.removeChild(child);
67490         }
67491
67492         document.body.removeAttribute("style");
67493         document.body.removeAttribute("id");
67494         document.body.removeAttribute("class");
67495     });
67496 }
67497
67498 function reload() {
67499     window.tinyHipposReload = true;
67500     location.reload();
67501 }
67502
67503 function _post(src) {
67504     var event = require('ripple/event'),
67505         frame = _createFrame(src);
67506
67507     _console.log("Initialization Finished (Make it so.)");
67508
67509     frame.onload = function () {
67510         var bootLoader = document.querySelector("#emulator-booting"),
67511             id,
67512             iframe = document.getElementById('document'),
67513             viewportTagFound = false,
67514             viewportTagContent = {},
67515             viewportTagStr = "",
67516             tagProperties = [],
67517             propertyKey ="",
67518             propertyValue = "",
67519             curViewPortWidth = "",
67520             curViewPortHeight = "",
67521             layout = db.retrieve("layout") || "portrait",
67522             preLayout = "";
67523
67524         if (bootLoader) {
67525             document.querySelector("#ui").removeChild(bootLoader);
67526         }
67527
67528         // Workaround to enforce the content of iframe to rerender when scrolling
67529         document.getElementById('document').contentWindow.onscroll = function() {
67530             jQuery("#device-maskmask").show();
67531             setTimeout(function() {
67532                 jQuery("#device-maskmask").hide();
67533             }, 50);
67534         }
67535
67536         event.trigger("TinyHipposLoaded");
67537         _cleanBody();
67538         id = window.setInterval(_cleanBody, 20);
67539
67540         window.setTimeout(function () {
67541             window.clearInterval(id);
67542         }, 1200);
67543
67544         // Clean data for different app
67545         if (db.retrieve("current-url") !== db.retrieve("previous-url")) {
67546             db.remove("viewport_width");
67547             db.remove("viewport_height");
67548             db.remove("viewportTag");
67549             db.remove("prelayout");
67550         }
67551
67552         curViewPortWidth = db.retrieve("viewport_width");
67553         curViewPortHeight = db.retrieve("viewport_height");
67554         preLayout = db.retrieve("prelayout") || "portrait";
67555         db.save("previous-url", db.retrieve("current-url"));
67556
67557         if (iframe.contentDocument.getElementsByName('viewport')[0] !== undefined) {
67558             viewportTagStr = iframe.contentDocument.getElementsByName('viewport')[0].getAttribute("content");
67559             viewportTagStr = viewportTagStr.replace(/\s/g, '');
67560             tagProperties = viewportTagStr.split(",");
67561
67562             for (var i in tagProperties) {
67563                 propertyKey = tagProperties[i].split("=")[0];
67564                 propertyValue = tagProperties[i].split("=")[1];
67565                 viewportTagContent[propertyKey] = propertyValue;
67566             }
67567             viewportTagFound = true;
67568         }
67569
67570         // if viewport tag found (width, height)
67571         if (viewportTagFound && ((viewportTagContent['width'] !== undefined) || (viewportTagContent['height'] !== undefined))) {
67572             if ((viewportTagContent['width'] !== undefined)) {
67573                 if (curViewPortWidth !== viewportTagContent['width']) {
67574                     db.saveObject("viewportTag", viewportTagContent);
67575                     if (layout !== preLayout) {
67576                         db.save("prelayout", layout);
67577                         resizer.changeLayoutType(layout);
67578                         event.trigger("LayoutChanged", [layout], true);
67579                         frame.contentWindow.location.reload(); // get the updated screenAvailWidth, screenWidth....
67580                     } else {
67581                         resizer.changeLayoutType(layout);
67582                     }
67583                 }
67584             } else {
67585                 if (curViewPortHeight !== viewportTagContent['height']) {
67586                     db.saveObject("viewportTag", viewportTagContent);
67587                     if (layout !== preLayout) {
67588                         db.save("prelayout", layout);
67589                         resizer.changeLayoutType(layout);
67590                         event.trigger("LayoutChanged", [layout], true);
67591                         frame.contentWindow.location.reload(); // get the updated screenAvailWidth, screenWidth....
67592                     } else {
67593                         resizer.changeLayoutType(layout);
67594                     }
67595                 }
67596             }
67597         } else {
67598             // Set layout to portrait if no viewport tag detected
67599             resizer.changeLayoutType('portrait');
67600             event.trigger("LayoutChanged", ['portrait'], true);
67601         }
67602
67603         if (ui.registered("omnibar")) {
67604             //reset the onload function so that when navigating we can destroy
67605             //the iframe and create a new one so we can reinject the platform by
67606             //calling post again.
67607             frame.onload = function () {
67608                 var url = frame.contentWindow.location.href;
67609                 document.getElementById("viewport-container").removeChild(frame);
67610                 event.trigger("FrameHistoryChange", [url]);
67611                 _console.log("-----------------------------------------------------------");
67612                 _console.log("Pay no attention to that man behind the curtain.");
67613                 _console.log("Environment Warning up again (Set main batteries to auto-fire cycle)");
67614                 _post(url);
67615             };
67616         }
67617     };
67618
67619     // append frame
67620     document.getElementById("viewport-container").appendChild(frame);
67621
67622     delete tinyHippos.boot;
67623 }
67624
67625 function _bootstrap() {
67626     // TODO: figure this out for web and ext
67627     //_console.log("-----------------------------------------------------------");
67628     //_console.log("There be dragons above here!");
67629     _console.log("Web Simulator :: Environment Warming Up (Tea. Earl Gray. Hot.)");
67630
67631     window.tinyHippos = require('ripple');
67632
67633     tinyHippos.boot(function () {
67634         var uri = ui.registered('omnibar') ?
67635                 db.retrieve(_CURRENT_URL) || "about:blank" :
67636                 document.documentURI.replace(/enableripple=[^&]*[&]?/i, "").replace(/[\?&]*$/, "");
67637
67638         _post(uri);
67639         delete tinyHippos.boot;
67640     });
67641 }
67642
67643 module.exports = {
67644     bootstrap: _bootstrap,
67645     inject: function (frameWindow, frameDocument) {
67646         _bindObjects(frameWindow, frameDocument);
67647     }
67648 };
67649
67650 });
67651 define('ripple/appcache', function (require, exports, module) {
67652 /*
67653  *  Copyright 2011 Research In Motion Limited.
67654  *
67655  * Licensed under the Apache License, Version 2.0 (the "License");
67656  * you may not use this file except in compliance with the License.
67657  * You may obtain a copy of the License at
67658  *
67659  * http://www.apache.org/licenses/LICENSE-2.0
67660  *
67661  * Unless required by applicable law or agreed to in writing, software
67662  * distributed under the License is distributed on an "AS IS" BASIS,
67663  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67664  * See the License for the specific language governing permissions and
67665  * limitations under the License.
67666  */
67667 module.exports = {
67668     initialize: function () {
67669         window.addEventListener('load', function (e) {
67670             window.applicationCache.addEventListener('updateready', function (e) {
67671                 if (window.applicationCache.status === window.applicationCache.UPDATEREADY) {
67672                     window.applicationCache.swapCache();
67673                     window.location.reload();
67674                 }
67675             }, false);
67676         }, false);
67677     }
67678 };
67679
67680 });
67681 define('ripple/app', function (require, exports, module) {
67682 /*
67683  *  Copyright 2011 Research In Motion Limited.
67684  *
67685  * Licensed under the Apache License, Version 2.0 (the "License");
67686  * you may not use this file except in compliance with the License.
67687  * You may obtain a copy of the License at
67688  *
67689  * http://www.apache.org/licenses/LICENSE-2.0
67690  *
67691  * Unless required by applicable law or agreed to in writing, software
67692  * distributed under the License is distributed on an "AS IS" BASIS,
67693  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67694  * See the License for the specific language governing permissions and
67695  * limitations under the License.
67696  */
67697 var _data = {},
67698     utils = require('ripple/utils'),
67699     _self;
67700
67701 _self = {
67702     setInfo: function (info) {
67703         if (!info) {
67704             _data = {};
67705         }
67706         _data = info;
67707     },
67708
67709     getInfo: function () {
67710         return utils.copy(_data);
67711     },
67712
67713     isPreferenceReadOnly: function (key) {
67714         return (_data.preferences &&
67715                 _data.preferences[key] &&
67716                 _data.preferences[key].readonly &&
67717                 _data.preferences[key].readonly === true);
67718     },
67719
67720     validateVersion: function (configValidationObject) {
67721         // TODO: WTF figure this out, platform is empty object when require at require time
67722         // could be that the new platform _getBuilder code dies when called, beforre it is initialized
67723         var spec = require('ripple/platform').current();
67724         if (typeof spec.config.validateVersion === "function" && configValidationObject) {
67725             return spec.config.validateVersion(configValidationObject);
67726         }
67727
67728         return true;
67729     },
67730
67731     saveInfo: function (configValidationObject) {
67732         var spec = require('ripple/platform').current(),
67733             info = null;
67734         if (typeof spec.config.extractInfo === "function") {
67735             info = spec.config.extractInfo(configValidationObject);
67736         }
67737
67738         if (info) {
67739             _self.setInfo(info);
67740         }
67741     }
67742
67743 };
67744
67745 module.exports = _self;
67746
67747 });
67748 define('ripple/deviceSettings', function (require, exports, module) {
67749 /*
67750  *  Copyright 2011 Research In Motion Limited.
67751  *
67752  * Licensed under the Apache License, Version 2.0 (the "License");
67753  * you may not use this file except in compliance with the License.
67754  * You may obtain a copy of the License at
67755  *
67756  * http://www.apache.org/licenses/LICENSE-2.0
67757  *
67758  * Unless required by applicable law or agreed to in writing, software
67759  * distributed under the License is distributed on an "AS IS" BASIS,
67760  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67761  * See the License for the specific language governing permissions and
67762  * limitations under the License.
67763  */
67764 /* DeviceSettings
67765  *  A per object store for a platform's settings.
67766  *  For example, RadioInfo object in WAC has isRadioEnabled that can be true/false
67767  *  setting => {key: {key1: "test"}}
67768  */
67769 var _PERSISTENCE_KEY = "devicesettings",
67770     db = require('ripple/db'),
67771     platform = require('ripple/platform'),
67772     _currentDeviceSettings = {},
67773     _self;
67774
67775 function _default(key) {
67776     var keys = key.split("."),
67777         defaults = platform.current().device;
67778     if (keys.length === 1)
67779         return defaults[key];
67780     return keys.length === 2 &&
67781            defaults[keys[0]] &&
67782            defaults[keys[0]][keys[1]] &&
67783            defaults[keys[0]][keys[1]].control ?
67784            defaults[keys[0]][keys[1]].control.value : undefined;
67785 }
67786
67787 _self = {
67788     initialize: function () {
67789         // TODO: remove deprecated DeviceSettings from persisted ones.
67790         _currentDeviceSettings = db.retrieveObject(_PERSISTENCE_KEY) || {};
67791     },
67792     register: function (key, obj) {
67793         _currentDeviceSettings[key] = obj;
67794     },
67795
67796     persist: function (key, obj) {
67797         if (key) {
67798             _currentDeviceSettings[key] = obj;
67799         }
67800         db.saveObject(_PERSISTENCE_KEY, _currentDeviceSettings);
67801     },
67802
67803     retrieve: function (key) {
67804         return _currentDeviceSettings.hasOwnProperty(key) ?
67805                _currentDeviceSettings[key] : _default(key);
67806     },
67807
67808     retrieveAsInt: function (key) {
67809         return parseInt(_self.retrieve(key), 10);
67810     },
67811
67812     retrieveAsBoolean: function (key) {
67813         return !!_self.retrieve(key);
67814     }
67815 };
67816
67817 module.exports = _self;
67818
67819 });
67820 define('ripple/touchEventEmulator', function (require, exports, module) {
67821 /*
67822  *  Copyright 2011 Research In Motion Limited.
67823  *
67824  * Licensed under the Apache License, Version 2.0 (the "License");
67825  * you may not use this file except in compliance with the License.
67826  * You may obtain a copy of the License at
67827  *
67828  * http://www.apache.org/licenses/LICENSE-2.0
67829  *
67830  * Unless required by applicable law or agreed to in writing, software
67831  * distributed under the License is distributed on an "AS IS" BASIS,
67832  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67833  * See the License for the specific language governing permissions and
67834  * limitations under the License.
67835  */
67836 var emulatorBridge = require('ripple/emulatorBridge'),
67837     utils = require('ripple/utils'),
67838     _isMouseDown, self;
67839
67840 // NOTE: missing view, detail, touches, targetTouches, scale and rotation
67841 function _initTouchEvent(type, canBubble, cancelable, eventData) {
67842     var touchEvent = emulatorBridge.document().createEvent("Event");
67843     touchEvent.initEvent(type, canBubble, cancelable);
67844     utils.mixin(eventData, touchEvent);
67845     return touchEvent;
67846 }
67847
67848 function _raiseTouchEvent(mouseEvent) {
67849     var type = "",
67850         simulatedEvent,
67851         touchObj,
67852         eventData;
67853
67854     switch (mouseEvent.type) {
67855     case "mousedown":
67856         type = "touchstart";
67857         _isMouseDown = true;
67858         break;
67859     case "mousemove":
67860         if (!_isMouseDown) {
67861             return;
67862         }
67863         type = "touchmove";
67864         break;
67865     case "mouseup":
67866         type = "touchend";
67867         _isMouseDown = false;
67868         break;
67869     default:
67870         return;
67871     }
67872
67873     touchObj = {
67874         clientX: mouseEvent.pageX,
67875         clientY: mouseEvent.pageY,
67876         identifier: "",
67877         pageX: mouseEvent.pageX,
67878         pageY: mouseEvent.pageY,
67879         screenX: mouseEvent.pageX,
67880         screenY: mouseEvent.pageY,
67881         target: mouseEvent.target
67882     };
67883
67884     eventData = {
67885         altKey: mouseEvent.altKey,
67886         ctrlKey: mouseEvent.ctrlKey,
67887         shiftKey: mouseEvent.shiftKey,
67888         metaKey: mouseEvent.metaKey,
67889         changedTouches: [touchObj],
67890         targetTouches: [touchObj],
67891         touches: [touchObj]
67892     };
67893
67894     utils.mixin(touchObj, eventData);
67895
67896     simulatedEvent = _initTouchEvent(type, true, true, eventData);
67897
67898     mouseEvent.target.dispatchEvent(simulatedEvent);
67899
67900     if (typeof mouseEvent.target["on" + type] === "function") {
67901         mouseEvent.target["on" + type].apply(mouseEvent.target, [simulatedEvent]);
67902     }
67903 }
67904
67905 function _marshalEvents(win, doc) {
67906     utils.forEach(["mousedown", "mousemove", "mouseup"],
67907         function (event) {
67908             doc.addEventListener(event, _raiseTouchEvent, true);
67909         });
67910
67911     //win.Node.prototype.ontouchstart = null;
67912     //win.Node.prototype.ontouchend = null;
67913     //win.Node.prototype.ontouchmove = null;
67914 }
67915
67916 self = module.exports = {
67917     mask: function (win, doc) {
67918         _marshalEvents(win, doc);
67919     }
67920 };
67921
67922 });
67923 define('ripple/constants', function (require, exports, module) {
67924 /*
67925  *  Copyright 2011 Research In Motion Limited.
67926  *
67927  * Licensed under the Apache License, Version 2.0 (the "License");
67928  * you may not use this file except in compliance with the License.
67929  * You may obtain a copy of the License at
67930  *
67931  * http://www.apache.org/licenses/LICENSE-2.0
67932  *
67933  * Unless required by applicable law or agreed to in writing, software
67934  * distributed under the License is distributed on an "AS IS" BASIS,
67935  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67936  * See the License for the specific language governing permissions and
67937  * limitations under the License.
67938  */
67939 module.exports = {
67940     "API_URL": "http://api.tinyhippos.com",
67941
67942     "RELEASE_VERSION": "simulator-release-version",
67943
67944     "SERVICES": {
67945         "GOOGLE_MAPS_URI": "http://maps.google.com/maps/api/staticmap?size=476x476&maptype=roadmap",
67946         "GOOGLE_MAPS_API_KEY": "ABQIAAAA-CaPZHXR-0Tzhui_h6gpjhSE_2rGlnYiB7L-ZGVwgaut5s7OYRSlBAaHCzBuZf2_23_vrCOfPxXHjA"
67947     },
67948
67949     "FS_SIZE": 1024 * 1024 * 10,
67950
67951     "COMMON":  {
67952         "APPLICATION_STATE": "ui-application-state-",
67953         "PREFIX": "tinyhippos-",
67954         "DEVICE_CONTAINER" : "device-container",
67955         "MENU_BUTTON" : "menu-button",
67956         "BACK_BUTTON" : "back-button",
67957         "HTML_CONTAINER" : "document",
67958         "INFO_SECTION": "information-sub-container",
67959         "ORIENTATION_SELECT_PORTRAIT_ID" : "layout-portrait",
67960         "ORIENTATION_SELECT_LANDSCAPE_ID" : "layout-landscape",
67961         "PLATFORM_SELECT_ID": "platform-select",
67962         "DEVICE_SELECT_ID": "device-select",
67963         "STORAGE_TABLE_BODY_CLASS": "preferences-list-body",
67964         "STORAGE_COUNT_CONTAINER_ID": "preferences-count",
67965         "GEO_MAP_CONTAINER_ID": "geo-map",
67966         "FILESYSTEM_UPDATE_BUTTON_ID_WITH_HASH": "#update-filesystem-button",
67967         "USER_AGENT_DEFAULT": "default",
67968         "APPLICATIONS_CONTAINER_ID": "widget-applications-content",
67969         "STORAGE_CLEAR_BUTTON_ID": "preferences-clear-button",
67970         "AJAX_LOADER_CONTAINER_CLASS": ".loader",
67971         "IRRELEVANT_CLASS": "irrelevant",
67972         "MULTIMEDIA_VOLUME_SLIDER_ID": "media-volume",
67973         "MULTIMEDIA_VOLUME_FIELD_ID": "media-volume-value",
67974         "MULTIMEDIA_AUDIO_STATE_FIELD_ID": "media-audio-state",
67975         "MULTIMEDIA_AUDIO_PLAYING_FIELD_ID": "multimedia-isaudioplaying",
67976         "MULTIMEDIA_AUDIO_PROGRESS_ID": "media-audio-progress",
67977         "MULTIMEDIA_AUDIO_FILE_FIELD_ID": "media-audio-file",
67978         "MULTIMEDIA_VIDEO_STATE_FIELD_ID": "media-video-state",
67979         "MULTIMEDIA_VIDEO_PLAYING_FIELD_ID": "multimedia-isvideoplaying",
67980         "MULTIMEDIA_VIDEO_PROGRESS_ID": "media-video-progress",
67981         "MULTIMEDIA_VIDEO_FILE_FIELD_ID": "media-video-file",
67982         "EXTENSION_URL_CONTAINER": "extension-url",
67983         "SECURITY_LEVEL": "security-level"
67984     },
67985     "LAUNCHING_HISTORY": "application-launching-history",
67986
67987     "FILESYSTEM": {
67988         "PERSISTENCE_KEY": "filesystem",
67989         "INPUT_PREFIX_ID": "#panel-filesystem-"
67990     },
67991
67992     "PLATFORM":  {
67993         "DEFAULT": {
67994             "name": "tizen",
67995             "version": "1.0"
67996         }
67997     },
67998
67999     "DEVICE":  {
68000         "SAVED_KEY": "device-key"
68001     },
68002
68003     "BATTERY":  {
68004         "TIME": "charging-time",
68005         "VOLUME": "battery-volume",
68006         "CHARGING": "is-charging"
68007     },
68008
68009     "TOUCHEVENT":  {
68010         "OPTION": "touch_option",
68011         "ALTKEY": "touch_altKey",
68012         "METAKEY": "touch_metaKey",
68013         "CTRLKEY": "touch_ctrlKey",
68014         "SHIFTKEY": "touch_shiftKey",
68015         "CANVAS": "touch_canvas"
68016     },
68017
68018     "ENCAPSULATOR":  {
68019         "DEFAULT_HEIGHT": 684,
68020         "DEFAULT_WIDTH": 480,
68021         "LAYOUT": "layout",
68022         "DISPLAY_LAYOUT": {
68023             "LANDSCAPE": "landscape",
68024             "PORTRAIT": "portrait"
68025         },
68026         "ZOOMING": "screen-zooming"
68027     },
68028
68029     "GEO":  {
68030         "OPTIONS" : {
68031             "LATITUDE" : "geo-latitude",
68032             "LONGITUDE" : "geo-longitude",
68033             "ALTITUDE" : "geo-altitude",
68034             "CELL_ID" : "geo-cellid",
68035             "ACCURACY" : "geo-accuracy",
68036             "ALTITUDE_ACCURACY" : "geo-altitudeaccuracy",
68037             "HEADING" : "geo-heading",
68038             "SPEED" : "geo-speed",
68039             "TIME_STAMP" : "geo-timestamp",
68040             "DELAY" : "geo-delay",
68041             "DELAY_LABEL" : "geo-delay-label",
68042             "HEADING_LABEL" : "geo-heading-label",
68043             "HEADING_MAP_LABEL" : "geo-map-direction-label",
68044             "IMAGE" : "geo-map-img",
68045             "MAP_CONTAINER" : "geo-map-container",
68046             "TIMEOUT" : "geo-timeout",
68047             "GPXFILE": "geo-gpxfile",
68048             "GPXGO": "geo-gpx-go",
68049             "GPXMULTIPLIER": "geo-gpxmultiplier-select",
68050             "GPXREPLAYSTATUS": "geo-gpxreplaystatus"
68051         },
68052         "MAP_ZOOM_MAX": 18,
68053         "MAP_ZOOM_MIN": 0,
68054         "MAP_ZOOM_LEVEL_CONTAINER": "geo-map-zoomlevel-value",
68055         "MAP_ZOOM_KEY": "geo-map-zoom-key",
68056         "GPXGO_LABELS": {
68057
68058             "GO": "Go",
68059             "STOP": "Stop"
68060         }
68061     },
68062
68063     "PUSH": {
68064         "OPTIONS" : {
68065             "PAYLOAD" : "push-text"
68066         }
68067     },
68068
68069     "TELEPHONY": {
68070         "CALL_LIST_KEY": "telephony-call-list-key"
68071     },
68072
68073     "PIM": {
68074         "ADDRESS_LIST_KEY": "pim-address-list-key",
68075         "CALENDAR_LIST_KEY": "pim-calendar-list-key"
68076     },
68077
68078     "CAMERA": {
68079         "WINDOW_ANIMATION": "images/tizen-wave.gif",
68080         "WARNING_TEXT": "The runtime simulated saving the camera file to {file}. If you need to access this file in your application, please copy a file to the saved location"
68081     },
68082
68083     "AUDIOPLAYER" : {
68084         "WARNING_TEXT": "The runtime simulated saving the audio file to {file}. If you need to access this file in your application, please copy a file to the saved location"
68085     },
68086
68087     "API_APPLICATION": {
68088         "NO_APPLICATIONS_MESSAGE": "No applications available for your platform"
68089     },
68090
68091     "NOTIFICATIONS":  {
68092         "MESSAGE_CONTAINER_CLASS": "notification-message-div",
68093         "MAIN_CONTAINER_CLASS": "panel-notification",
68094         "CLOSE_BUTTON_CLASS": "panel-notification-closebtn",
68095         "MESSAGE_TEXT_CONTAINER_CLASS": "panel-notification-text",
68096         "CSS_PREFIX": "panel-notification-",
68097         "STATE_TYPES": {
68098             "OPEN": 1,
68099             "CLOSE": 2
68100         }
68101     },
68102
68103     "CSS_PREFIX":  {
68104         "IRRELEVANT" : "irrelevant"
68105     },
68106
68107     "STORAGE":  {
68108         "PAIR_DELIMETER" : ",",
68109         "KEY_VALUE_DELIMETER" : "|"
68110     },
68111
68112     "REGEX":  {
68113         "GEO" : /^geo-/,
68114         "URL": /^((https?|ftp|gopher|telnet|file|notes|ms-help):((\/\/)|(\\\\))+[\w\d:#@%\/;$()~_?\+-=\\\.&]*)$/,
68115         //"Email": /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/
68116         "EMAIL": /^([^@\s]+)@((?:[\-a-z0-9]+\.)+[a-z]{2,})$/,
68117         "WC3_DTF": /^((\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)|(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)|(\d{4})-(\d\d)-(\d\d)|(\d{4})-(\d\d)|(\d\d\d\d))$/,
68118         "LOCAL_URI": /^https?:\/\/(127\.0\.0\.1|localhost)|^file:\/\//,
68119         "EXTERNAL_URI": /(?:(?:[a-zA-Z0-9\/;\?&=:\-_\$\+!\*'\(\|\\~\[\]#%\.](?!www))+(?:\.[Cc]om|\.[Ee]du|\.[gG]ov|\.[Ii]nt|\.[Mm]il|\.[Nn]et|\.[Oo]rg|\.[Bb]iz|\.[Ii]nfo|\.[Nn]ame|\.[Pp]ro|\.[Aa]ero|\.[cC]oop|\.[mM]useum|\.[Cc]at|\.[Jj]obs|\.[Tt]ravel|\.[Aa]rpa|\.[Mm]obi|\.[Aa]c|\.[Aa]d|\.[aA]e|\.[aA]f|\.[aA]g|\.[aA]i|\.[aA]l|\.[aA]m|\.[aA]n|\.[aA]o|\.[aA]q|\.[aA]r|\.[aA]s|\.[aA]t|\.[aA]u|\.[aA]w|\.[aA]z|\.[aA]x|\.[bB]a|\.[bB]b|\.[bB]d|\.[bB]e|\.[bB]f|\.[bB]g|\.[bB]h|\.[bB]i|\.[bB]j|\.[bB]m|\.[bB]n|\.[bB]o|\.[bB]r|\.[bB]s|\.[bB]t|\.[bB]v|\.[bB]w|\.[bB]y|\.[bB]z|\.[cC]a|\.[cC]c|\.[cC]d|\.[cC]f|\.[cC]g|\.[cC]h|\.[cC]i|\.[cC]k|\.[cC]l|\.[cC]m|\.[cC]n|\.[cC]o|\.[cC]r|\.[cC]s|\.[cC]u|\.[cC]v|\.[cC]x|\.[cC]y|\.[cC]z|\.[dD]e|\.[dD]j|\.[dD]k|\.[dD]m|\.[dD]o|\.[dD]z|\.[eE]c|\.[eE]e|\.[eE]g|\.[eE]h|\.[eE]r|\.[eE]s|\.[eE]t|\.[eE]u|\.[fF]i|\.[fF]j|\.[fF]k|\.[fF]m|\.[fF]o|\.[fF]r|\.[gG]a|\.[gG]b|\.[gG]d|\.[gG]e|\.[gG]f|\.[gG]g|\.[gG]h|\.[gG]i|\.[gG]l|\.[gG]m|\.[gG]n|\.[gG]p|\.[gG]q|\.[gG]r|\.[gG]s|\.[gG]t|\.[gG]u|\.[gG]w|\.[gG]y|\.[hH]k|\.[hH]m|\.[hH]n|\.[hH]r|\.[hH]t^[ml]?|\.[hH]u|\.[iI]d|\.[iI]e|\.[iI]l|\.[iI]m|\.[iI]n|\.[iI]o|\.[iI]q|\.[iI]r|\.[iI]s|\.[iI]t|\.[jJ]e|\.[jJ]m|\.[jJ]o|\.[jJ]p|\.[kK]e|\.[kK]g|\.[kK]h|\.[kK]i|\.[kK]m|\.[kK]n|\.[kK]p|\.[kK]r|\.[kK]w|\.[kK]y|\.[kK]z|\.[lL]a|\.[lL]b|\.[lL]c|\.[lL]i|\.[lL]k|\.[lL]r|\.[lL]s|\.[lL]t|\.[lL]u|\.[lL]v|\.[lL]y|\.[mM]a|\.[mM]c|\.[mM]d|\.[mM]g|\.[mM]h|\.[mM]k|\.[mM]l|\.[mM]m|\.[mM]n|\.[mM]o|\.[mM]p|\.[mM]q|\.[mM]r|\.[mM]s|\.[mM]t|\.[mM]u|\.[mM]v|\.[mM]w|\.[mM]x|\.[mM]y|\.[mM]z|\.[nN]a|\.[nN]c|\.[nN]e|\.[nN]f|\.[nN]g|\.[nN]i|\.[nN]l|\.[nN]o|\.[nN]p|\.[nN]r|\.[nN]u|\.[nN]z|\.[oO]m|\.[pP]a|\.[pP]e|\.[pP]f|\.[pP]g|\.[pP]h|\.[pP]k|\.[pP]l|\.[pP]m|\.[pP]n|\.[pP]r|\.[pP]s|\.[pP]t|\.[pP]w|\.[pP]y|\.[qP]a|\.[rR]e|\.[rR]o|\.[rR]u|\.[rR]w|\.[sS]a|\.[sS]b|\.[sS]c|\.[sS]d|\.[sS]e|\.[sS]g|\.[sS]h|\.[Ss]i|\.[sS]j|\.[sS]k|\.[sS]l|\.[sS]m|\.[sS]n|\.[sS]o|\.[sS]r|\.[sS]t|\.[sS]v[^c]|\.[sS]y|\.[sS]z|\.[tT]c|\.[tT]d|\.[tT]f|\.[tT]g|\.[tT]h|\.[tT]j|\.[tT]k|\.[tT]l|\.[tT]m|\.[tT]n|\.[tT]o|\.[tT]p|\.[tT]r|\.[tT]t|\.[tT]v|\.[tT]w|\.[tT]z|\.[uU]a|\.[uU]g|\.[uU]k|\.[uU]m|\.[uU]s|\.[uU]y|\.[uU]z|\.[vV]a|\.[vV]c|\.[vV]e|\.[vV]g|\.[vV]i|\.[vV]n|\.[vV]u|\.[wW]f|\.[wW]s|\.[yY]e|\.[yY]t|\.[yY]u|\.[zZ]a|\.[zZ]m|\.[zZ]w))/
68120     },
68121
68122     "CONFIG": {
68123         "SUCCESS_CSS": {
68124             "true": "ui-text-pass",
68125             "false": "ui-text-fail",
68126             "missing": "ui-text-missing"
68127         }
68128     },
68129
68130     "SETTINGS": {
68131         "TOOLTIPS_TOGGLE_DIV": "#settings-toggletooltips",
68132         "TOOLTIPS_KEY": "tool-tips-key"
68133     },
68134
68135     "PANEL": {
68136         "PANEL_CONFIG_ENABLE": "panel-config-enable"
68137     },
68138
68139     "UI": {
68140         "JQUERY_UI_BUTTON_CLASSES": "ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only",
68141         "JQUERY_UI_INPUT_CLASSES": "ui-state-default ui-corner-all",
68142         "PANEL_TABLE_CLASS": "panel-table",
68143         "RIGHT_RANGE_LABEL_CLASS": "range-label",
68144         "LEFT_RANGE_LABEL_CLASS": "range-label-left",
68145         "TEXT_LABEL_CLASS": "ui-text-label",
68146         "SCREEN_PPI": 96
68147     },
68148
68149     "MULTIMEDIA": {
68150         "AUDIO_STATES": {
68151             "OPENED": "opened",
68152             "STOPPED": "stopped",
68153             "PAUSED": "paused",
68154             "PLAYING": "playing",
68155             "COMPLETED": "completed"
68156         }
68157     },
68158
68159     "LANG": {
68160         "ISO6392_LIST": ["abk", "ace", "ach", "ada", "ady", "aar", "afh", "afr", "afa", "ain", "aka", "akk", "alb/sqi", "gsw", "ale", "alg", "tut", "amh", "anp", "apa", "ara", "arg", "arp", "arw", "arm/hye", "rup", "art", "asm", "ast", "ath", "aus", "map", "ava", "ave", "awa", "aym", "aze", "ban", "bat", "bal", "bam", "bai", "bad", "bnt", "bas", "bak", "baq/eus", "btk", "bej", "bel", "bem", "ben", "ber", "bho", "bih", "bik", "byn", "bin", "bis", "zbl", "nob", "bos", "bra", "bre", "bug", "bul", "bua", "bur/mya", "cad", "spa", "cat", "cau", "ceb", "cel", "cai", "khm", "chg", "cmc", "cha", "che", "chr", "nya", "chy", "chb", "chi/zho", "chn", "chp", "cho", "zha", "chu", "chk", "chv", "nwc", "syc", "rar", "cop", "cor", "cos", "cre", "mus", "crp", "cpe", "cpf", "cpp", "crh", "hrv", "cus", "cze/ces", "dak", "dan", "dar", "del", "div", "zza", "din", "doi", "dgr", "dra", "dua", "dut/nld", "dum", "dyu", "dzo", "frs", "efi", "egy", "eka", "elx", "eng", "enm", "ang", "myv", "epo", "est", "ewe", "ewo", "fan", "fat", "fao", "fij", "fil", "fin", "fiu", "fon", "fre/fra", "frm", "fro", "fur", "ful", "gaa", "gla", "car", "glg", "lug", "gay", "gba", "gez", "geo/kat", "ger/deu", "nds", "gmh", "goh", "gem", "kik", "gil", "gon", "gor", "got", "grb", "grc", "gre/ell", "kal", "grn", "guj", "gwi", "hai", "hat", "hau", "haw", "heb", "her", "hil", "him", "hin", "hmo", "hit", "hmn", "hun", "hup", "iba", "ice/isl", "ido", "ibo", "ijo", "ilo", "arc", "smn", "inc", "ine", "ind", "inh", "ina", "ile", "iku", "ipk", "ira", "gle", "mga", "sga", "iro", "ita", "jpn", "jav", "kac", "jrb", "jpr", "kbd", "kab", "xal", "kam", "kan", "kau", "pam", "kaa", "krc", "krl", "kar", "kas", "csb", "kaw", "kaz", "kha", "khi", "kho", "kmb", "kin", "kir", "tlh", "kom", "kon", "kok", "kor", "kos", "kpe", "kro", "kua", "kum", "kur", "kru", "kut", "lad", "lah", "lam", "day", "lao", "lat", "lav", "ltz", "lez", "lim", "lin", "lit", "jbo", "dsb", "loz", "lub", "lua", "lui", "smj", "lun", "luo", "lus", "mac/mkd", "mad", "mag", "mai", "mak", "mlg", "may/msa", "mal", "mlt", "mnc", "mdr", "man", "mni", "mno", "glv", "mao/mri", "arn", "mar", "chm", "mah", "mwr", "mas", "myn", "men", "mic", "min", "mwl", "moh", "mdf", "rum/ron", "mkh", "lol", "mon", "mos", "mul", "mun", "nqo", "nah", "nau", "nav", "nde", "nbl", "ndo", "nap", "new", "nep", "nia", "nic", "ssa", "niu", "zxx", "nog", "non", "nai", "frr", "sme", "nso", "nor", "nno", "nub", "iii", "nym", "nyn", "nyo", "nzi", "oci", "pro", "oji", "ori", "orm", "osa", "oss", "oto", "pal", "pau", "pli", "pag", "pan", "pap", "paa", "pus", "per/fas", "peo", "phi", "phn", "pon", "pol", "por", "pra", "que", "raj", "rap", "qaa-qtz", "roa", "roh", "rom", "run", "rus", "sal", "sam", "smi", "smo", "sad", "sag", "san", "sat", "srd", "sas", "sco", "sel", "sem", "srp", "srr", "shn", "sna", "scn", "sid", "sgn", "bla", "snd", "sin", "sit", "sio", "sms", "den", "sla", "slo/slk", "slv", "sog", "som", "son", "snk", "wen", "sot", "sai", "alt", "sma", "srn", "suk", "sux", "sun", "sus", "swa", "ssw", "swe", "syr", "tgl", "tah", "tai", "tgk", "tmh", "tam", "tat", "tel", "ter", "tet", "tha", "tib/bod", "tig", "tir", "tem", "tiv", "tli", "tpi", "tkl", "tog", "ton", "tsi", "tso", "tsn", "tum", "tup", "tur", "ota", "tuk", "tvl", "tyv", "twi", "udm", "uga", "uig", "ukr", "umb", "mis", "und", "hsb", "urd", "uzb", "vai", "ven", "vie", "vol", "vot", "wak", "wln", "war", "was", "wel/cym", "fry", "wal", "wol", "xho", "sah", "yao", "yap", "yid", "yor", "ypk", "znd", "zap", "zen", "zul", "zun"]
68161     },
68162
68163     "XHR": {
68164         "PROXY_DISABLED_BUTTON": "settings-xhrproxy-disabled"
68165     },
68166
68167     "PLATFORMS": {
68168         "WAC": {
68169             "APPLICATIONS": [
68170                 "ALARM",
68171                 "BROWSER",
68172                 "CALCULATOR",
68173                 "CALENDAR",
68174                 "CAMERA",
68175                 "CONTACTS",
68176                 "FILES",
68177                 "GAMES",
68178                 "MAIL",
68179                 "MEDIAPLAYER",
68180                 "MESSAGING",
68181                 "PHONECALL",
68182                 "PICTURES",
68183                 "PROG_MANAGER",
68184                 "SETTINGS",
68185                 "TASKS",
68186                 "WIDGET_MANAGER"
68187             ],
68188             "DEVICE": {
68189                 "WIDGET_ENGINE_NAME": "Generic",
68190                 "WIDGET_ENGINE_PROVIDER": "tinyHippos",
68191                 "WIDGET_ENGINE_VERSION": "x.x"
68192             }
68193         }
68194     },
68195
68196     "POWER_RESOURCE": {
68197         "SCREEN": {
68198             "NAME": "SCREEN",
68199             "STATE": {
68200                 "SCREEN_OFF": {
68201                     "NAME": "SCREEN_OFF",
68202                     "MIN": 0,
68203                     "MAX": 0,
68204                     "VALUE": 0
68205                 },
68206                 "SCREEN_DIM": {
68207                     "NAME": "SCREEN_DIM",
68208                     "MIN": 0,
68209                     "MAX": 0.2,
68210                     "VALUE": 0.15
68211                 },
68212                 "SCREEN_NORMAL": {
68213                     "NAME": "SCREEN_NORMAL",
68214                     "MIN": 0.2,
68215                     "MAX": 1,
68216                     "VALUE": 0.8
68217                 },
68218                 "SCREEN_BRIGHT": {
68219                     "NAME": "SCREEN_BRIGHT",
68220                     "MIN": 1,
68221                     "MAX": 1,
68222                     "VALUE": 1
68223                 }
68224             }
68225         },
68226         "CPU": {
68227             "NAME": "CPU",
68228             "STATE": {
68229                 "CPU_AWAKE": {
68230                     "NAME": "CPU_AWAKE",
68231                     "DEFAULT_VALUE" : 0.5
68232                 }
68233             }
68234         }
68235     }
68236 };
68237
68238 });
68239 define('ripple/ui/plugins/tooltip', function (require, exports, module) {
68240 /*
68241  *  Copyright 2011 Research In Motion Limited.
68242  *
68243  * Licensed under the Apache License, Version 2.0 (the "License");
68244  * you may not use this file except in compliance with the License.
68245  * You may obtain a copy of the License at
68246  *
68247  * http://www.apache.org/licenses/LICENSE-2.0
68248  *
68249  * Unless required by applicable law or agreed to in writing, software
68250  * distributed under the License is distributed on an "AS IS" BASIS,
68251  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68252  * See the License for the specific language governing permissions and
68253  * limitations under the License.
68254  */
68255 var utils = require('ripple/utils'),
68256     _options = {
68257         track: true,
68258         delay: 0,
68259         showURL: false,
68260         fade: 250,
68261         extraClass: "ui-state-highlight ui-corner-all"
68262     };
68263
68264 module.exports = {
68265     create: function (element, message) {
68266         var options = utils.copy(_options);
68267
68268         options.bodyHandler = function () {
68269             return message;
68270         };
68271
68272         return jQuery(element).tooltip(options);
68273     },
68274
68275     toggle: function () {
68276         jQuery.tooltip.block();
68277         return this.isOff();
68278     },
68279
68280     isOff: function () {
68281         return jQuery.tooltip.blocked;
68282     }
68283 };
68284
68285 });
68286 define('ripple/ui/plugins/call', function (require, exports, module) {
68287 /*
68288  *  Copyright 2012 Intel Corporation
68289  *
68290  * Licensed under the Apache License, Version 2.0 (the "License");
68291  * you may not use this file except in compliance with the License.
68292  * You may obtain a copy of the License at
68293  *
68294  * http://www.apache.org/licenses/LICENSE-2.0
68295  *
68296  * Unless required by applicable law or agreed to in writing, software
68297  * distributed under the License is distributed on an "AS IS" BASIS,
68298  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68299  * See the License for the specific language governing permissions and
68300  * limitations under the License.
68301  */
68302 var event = require('ripple/event'),
68303     utils = require('ripple/utils'),
68304     db = require('ripple/db'),
68305     _exception = {
68306         "unknown":           "Unknown",
68307         "network":           "Network",
68308         "unreachable":       "Unreachable",
68309         "no-answer":         "No Answer",
68310         "bad-number":        "Bad Number",
68311         "number-not-in-use": "Number Not In Use",
68312         "media":             "Media",
68313         "no-sim":            "No Sim Card",
68314         "account-down":      "Account Down",
68315         "credit-down":       "Credit Down",
68316         "barred":            "Barred",
68317         "network-busy":      "Network Busy",
68318         "network-down":      "Network Down"
68319     },
68320     _status = {
68321         IDLE:       0,
68322         DIALED:     1,
68323         PLACED:     2,
68324         INPROGRESS: 3,
68325     },
68326     _statusInfo = [
68327         "Waiting...;Waiting",                                   // IDLE
68328         "Calling... ;Incomming call from simulator",               // DIALED
68329         "Incomming call from ;Calling simulator",                // PLACED
68330         "In conversation with ;In conversation with simulator"   // INPROGRESS
68331     ],
68332     _data = {
68333         status: _status.IDLE,
68334         isInException: false,
68335         isAutoAccept: false,
68336         autoAcceptTimerId: null,
68337         conversationStartTime: null
68338     },
68339     _contactMap = {
68340         "861012345678": "Guest"
68341     },
68342     _CONTACT_KEY = "tizen1-contact",
68343     _RECORDING_KEY = "tizen1-call-recording",
68344     _RECORDING_PATH = "music/",
68345     _record = {},
68346     _conversationSeconds = 0,
68347     _conversationTimer,
68348     _callingEffectTimer;
68349
68350 function _initContacts() {
68351     var data = db.retrieveObject(_CONTACT_KEY),
68352         contactsSelect = document.getElementById("call-local-phone-number"),
68353         displayName = null, number = null, index = 0, i;
68354         
68355     contactsSelect.innerHTML = "";
68356
68357     utils.forEach(data, function (addrBook) {
68358         utils.forEach(addrBook._contacts, function (contact) {
68359             if (contact.name && contact.name && contact.phoneNumbers &&
68360                 contact.phoneNumbers.length > 0) {
68361                 displayName = contact.name.firstName + ' ' + contact.name.lastName;
68362                 number = contact.phoneNumbers[0].number;
68363                 _contactMap[number] = displayName;
68364
68365                 contactsSelect.appendChild(utils.createElement("option", {
68366                     "innerText": displayName + ':' + number,
68367                     "value": index
68368                 }));
68369                 index++;
68370             }
68371         });
68372     });
68373
68374     if (displayName === null && number === null) {
68375         for (i in _contactMap) {
68376             displayName = _contactMap[i];
68377             number = i;
68378             contactsSelect.appendChild(utils.createElement("option", {
68379                 "innerText": displayName + ':' + number,
68380                 "value": index
68381             }));
68382         }
68383     }
68384 }
68385
68386 function _initEventWatchers() {
68387     event.on("DialerLaunched", function (remoteParty) {
68388         var localContact = document.getElementById("call-local-phone-number");
68389
68390         if (_data.status !== _status.IDLE) {
68391             return;
68392         }
68393
68394         localContact.appendChild(utils.createElement("option", {
68395             "innerText": remoteParty.displayName,
68396             "value": remoteParty.remoteParty,
68397             "selected": "selected"
68398         }));
68399         _localCall();
68400     });
68401 }
68402
68403 function _initExceptionTypes() {
68404     utils.forEach(_exception, function (value, key) {
68405         document.getElementById("call-exception-type").appendChild(utils.createElement("option", {
68406             "innerText": value,
68407             "value": key
68408         }));
68409     });
68410 }
68411
68412 function _initRecord() {
68413     var localPartString = jQuery("#call-local-phone-number option:selected").text() || "",
68414         localPartStringList = localPartString.split(":"),
68415         displayName;
68416
68417     if (localPartStringList.length > 1) {
68418         displayName = localPartStringList[0];
68419     }
68420     else {
68421         displayName = localPartString;
68422     }
68423
68424     _record = {};
68425     _record.serviceId = (new Date()).getTime() || 0;
68426     _record.callParticipants = [{
68427         id: localPartString + ':' + displayName,
68428         displayName: displayName,
68429         contactRef: null
68430     }];
68431     _record.forwardedFrom = null;
68432     _record.startTime = new Date();
68433     _record.recording = [];
68434 }
68435
68436
68437 function updateConvTime() {
68438     var timeObj = new Date(1970, 0, 1),
68439     timeString;
68440
68441     timeObj.setSeconds(_conversationSeconds);
68442     timeString = timeObj.toTimeString().substr(0, 8);
68443     jQuery("#ConvTimeString").text(timeString);
68444     jQuery("#ConvTimeString2").text(timeString);
68445     _conversationSeconds = _conversationSeconds + 1;
68446 }
68447
68448
68449 function CallingEffect() {
68450     var color = jQuery("#callingString").css('color');
68451     if (color === "rgb(255, 255, 255)") {
68452         jQuery("#callingString").css('color', "black");
68453         jQuery("#callingString2").css('color', "black");
68454     }
68455     else {
68456         jQuery("#callingString").css('color', "white");
68457         jQuery("#callingString2").css('color', "white");
68458     }
68459 }
68460
68461
68462 function _transferStatus() {
68463     var statusStringList = _statusInfo[_data.status].split(";"),
68464         localPartString = jQuery("#call-local-phone-number option:selected").text() || "",
68465         localPartStringList = localPartString.split(":"),
68466         localNumber = localPartStringList[0],
68467         localName = _contactMap[localNumber] || localNumber;
68468     jQuery("#status-text").show();
68469     jQuery("#remote-status-text").show();
68470     jQuery("#call-status").show();
68471     jQuery("#remote-call-status").show();
68472     jQuery("#remotePartyName").html(localName);
68473     jQuery("#call-local-call").show();
68474     window.clearInterval(_callingEffectTimer);
68475
68476     switch (_data.status) {
68477     case _status.DIALED:      // local call
68478         jQuery("#call-remote-text").html("Accept");
68479         jQuery("#end-remote-text").html("Reject");
68480         jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
68481                         "<span id='callingString' style='font-size: 14px;'>&nbsp;" + statusStringList[0] + 
68482                         "</span><br><br><br><button id='call-local-end-d' class='ui-corner-all' style='padding:2px;" +
68483                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
68484         jQuery("#call-local-end-d").bind("click", _localEnd);
68485         jQuery("#remote-call-status").html("<span style='font-size: 20px;'>Simulator Bot</span><br>" + 
68486                         "<span id='callingString2' style='font-size: 12px;'>&nbsp;Incoming call...</span>" +
68487                         "<br><br><br><button id='call-remote-decline-d' class='ui-corner-all' style='padding:2px;" +
68488                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:48%;'>Decline</button>&nbsp;&nbsp;" +
68489                         "<button id='call-remote-answer-d' class='ui-corner-all' style='padding:2px; border-width:1px; background-color:green; color:white; font-size:14px; font-weight:bold; width:48%;'>Answer</button>");
68490         jQuery("#call-remote-answer-d").bind("click", _remoteCall);
68491         jQuery("#call-remote-decline-d").bind("click", _remoteEnd);
68492         _callingEffectTimer = window.setInterval(CallingEffect, 800);
68493         break;
68494     case _status.PLACED:      // Remote Call
68495         jQuery("#call-local-text").html("Accept");
68496         jQuery("#end-local-text").html("Reject");
68497         jQuery("#call-status").html(statusStringList[0] + localName);
68498         jQuery("#remote-call-status").html(statusStringList[1]);
68499         jQuery("#remote-call-status").html("<span style='font-size: 22px;'>Simulator Bot</span><br>" + 
68500                         "<span id='callingString' style='font-size: 14px;'>&nbsp;Calling..." + 
68501                         "</span><br><br><br><button id='call-remote-end-d' class='ui-corner-all' style='padding:2px;" +
68502                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
68503         jQuery("#call-remote-end-d").bind("click", _remoteEnd);
68504         jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
68505                         "<span id='callingString2' style='font-size: 14px;'>&nbsp;Incoming call...</span>" +
68506                         "<br><br><br><button id='call-local-decline-d' class='ui-corner-all' style='padding:2px;" +
68507                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:48%;'>Decline</button>&nbsp;&nbsp;" +
68508                         "<button id='call-local-answer-d' class='ui-corner-all' style='padding:2px; border-width:1px;" +
68509                         " background-color:green; color:white; font-size:14px; font-weight:bold; width:48%;'>Answer</button>");
68510         jQuery("#call-local-answer-d").bind("click", _localCall);
68511         jQuery("#call-local-decline-d").bind("click", _localEnd);
68512         _callingEffectTimer = window.setInterval(CallingEffect, 800);
68513         break;
68514     case _status.INPROGRESS:
68515         jQuery("#call-status").html("<span style='font-size: 22px;'>" + localName + "</span><br>" + 
68516                         "<span id='ConvTimeString' style='font-size: 14px;'>" + "00:00:00" + 
68517                         "</span><br><br><br><button id='call-local-end-d-c' class='ui-corner-all' style='padding:2px;" +
68518                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
68519         jQuery("#remote-call-status").html("<span style='font-size: 22px;'>Simulator Robot</span><br>" + 
68520                         "<span id='ConvTimeString2' style='font-size: 14px;'>" + "00:00:00" + 
68521                         "</span><br><br><br><button id='call-remote-end-d-c' class='ui-corner-all' style='padding:2px;" +
68522                         " border-width:1px; background-color:red; color:white; font-size:14px; font-weight:bold; width:100%;'>End call</button>");
68523         jQuery("#call-local-end-d-c").bind("click", _localEnd);
68524         jQuery("#call-remote-end-d-c").bind("click", _remoteEnd);
68525         _conversationTimer = window.setInterval(updateConvTime, 1000);
68526         jQuery("#call-remote-text").html("Call");
68527         jQuery("#end-remote-text").html("End");
68528         jQuery("#call-local-text").html("Call");
68529         jQuery("#end-local-text").html("End");
68530         break;
68531     default:
68532         jQuery("#call-status").html(statusStringList[0]);
68533         jQuery("#call-status").html("default");
68534         jQuery("#remote-call-status").html(statusStringList[1]);
68535         jQuery("#remote-call-status").html("default");
68536         jQuery("#call-remote-text").html("Call");
68537         jQuery("#end-remote-text").html("End");
68538         jQuery("#call-local-text").html("Call");
68539         jQuery("#end-local-text").html("End");
68540         return;
68541     }
68542 }
68543
68544 function _startCall() {
68545     _data.conversationStartTime = new Date();
68546     event.trigger("CallInProgress", [true]);
68547     _data.status = _status.INPROGRESS;
68548     //_transferStatus();
68549 }
68550
68551 function _endCall(callEndReason) {
68552     if (_data.autoAcceptTimerId) {
68553         var path = _RECORDING_PATH + _record.serviceId + ".mp3";
68554
68555         _record.recording.push(path);
68556         db.saveObject(_RECORDING_KEY, path);
68557
68558         clearTimeout(_data.autoAcceptTimerId);
68559         _data.autoAcceptTimerId = null;
68560     }
68561
68562     _record.duration = _data.conversationStartTime ? ((new Date()) - _data.conversationStartTime) : 0;
68563     _data.conversationStartTime = null;
68564     
68565     _record.endReason = callEndReason;
68566
68567     if (_data.status === _status.PLACED) {
68568         _record.direction = "missed-new";
68569     }
68570
68571     event.trigger("CallRecorded", [_record]);
68572     event.trigger("CallInProgress", [false]);
68573
68574     _data.status = _status.IDLE;
68575     _transferStatus();
68576     _record = {};
68577
68578     _conversationSeconds = 0;
68579     window.clearInterval(_conversationTimer);
68580     jQuery("#call-status").hide();
68581     jQuery("#remote-call-status").hide();
68582
68583     jQuery("#status-text").hide();
68584     jQuery("#remote-status-text").hide();
68585 }
68586
68587 function _localCall() {
68588     if (_data.isInException) {
68589         return;
68590     }
68591
68592     switch (_data.status) {
68593     case _status.IDLE:    //local call
68594         _data.status = _status.DIALED;
68595         _initRecord();
68596         _record.direction = "dialed";
68597         break;
68598     case _status.PLACED:
68599         _data.status = _status.INPROGRESS;
68600         _record.direction = "received";
68601         if (_data.autoAcceptTimerId) {
68602             clearTimeout(_data.autoAcceptTimerId);
68603             _data.autoAcceptTimerId = null;
68604         }
68605         _startCall();
68606         break;
68607     default:
68608         return;
68609     }
68610
68611     _transferStatus();
68612
68613     if (_data.isInException) {
68614         _endCall(document.getElementById("call-exception-type").value);
68615     }
68616 }
68617
68618 function _localEnd() {
68619     switch (_data.status) {
68620     case _status.DIALED:     // Local Cancel
68621     case _status.INPROGRESS: // Local End
68622         _endCall("local");
68623         break;
68624     case _status.PLACED:
68625         _record.direction = "missed-new";
68626         _endCall("local");
68627         break;
68628     default:
68629         return;
68630     }
68631 }
68632
68633 function _remoteCall() {
68634     if (_data.isInException) {
68635         return;
68636     }
68637
68638     switch (_data.status) {
68639     case _status.IDLE:      // Remote Call
68640         _data.status = _status.PLACED; 
68641         _initRecord();
68642         if (_data.isAutoAccept) {
68643             _data.autoAcceptTimerId = setTimeout(_localCall, 2000);
68644         }
68645         break;
68646     case _status.DIALED:    // Remote Answer
68647         _startCall();
68648         break;
68649     default:
68650         return;
68651     }
68652
68653     _transferStatus();
68654
68655     if (_data.isInException) {
68656         _endCall(document.getElementById("call-exception-type").value);
68657     }
68658 }
68659
68660 function _remoteEnd() {
68661     switch (_data.status) {
68662     case _status.DIALED:     // Remote Reject
68663         _endCall("rejected");
68664         break;
68665     case _status.INPROGRESS: // Remote End
68666         _endCall("remote");
68667         break;
68668     case _status.PLACED:    // Remote Cancel
68669         _record.direction = "missed-new";
68670         _endCall("remote");
68671         break;
68672     default:
68673         return;
68674     }
68675 }
68676
68677 function _leaveMessage() {
68678     if (!this.checked && _data.autoAcceptTimerId) {
68679         clearTimeout(_data.autoAcceptTimerId);
68680         _data.autoAcceptTimerId = null;
68681     }
68682     _data.isAutoAccept = this.checked;
68683 }
68684
68685 function _exceptionStatus() {
68686     _data.isInException = this.checked;
68687     if (_data.isInException && (_data.status !== _status.IDLE)) {
68688         if (_data.status === _status.RECEIVED) {   // Remote Cancel
68689             _record.direction = "missed-new";
68690             _record.duration = 0;
68691         }
68692         _endCall(document.getElementById("call-exception-type").value);
68693     }
68694 }
68695
68696
68697 function _updateRemotePartyName() {
68698     jQuery("#remotePartyName").text(jQuery("#call-local-phone-number option:selected").text());
68699 }
68700
68701
68702 module.exports = {
68703     panel: {
68704         domId: "call-container",
68705         collapsed: true,
68706         pane: "left",
68707         titleName: "Call",
68708         display: true
68709     },
68710     initialize: function () {
68711         jQuery("#call-local-call").bind("click", _localCall);
68712         jQuery("#call-local-end").bind("click", _localEnd);
68713         jQuery("#call-remote-call").bind("click", _remoteCall);
68714         jQuery("#call-remote-end").bind("click", _remoteEnd);
68715         jQuery("#recording-status").bind("click", _leaveMessage);
68716         jQuery("#call-exception-status").bind("click", _exceptionStatus);
68717         jQuery("#call-exception-type").bind("click", null);
68718
68719         _initEventWatchers();
68720         _initContacts();
68721         jQuery("#remotePartyName").text(jQuery("#call-local-phone-number option:selected").text());
68722         jQuery("#call-local-phone-number").bind("change", _updateRemotePartyName);
68723         _initExceptionTypes();
68724     }
68725 };
68726
68727 });
68728 define('ripple/ui/plugins/omnibar', function (require, exports, module) {
68729 /*
68730  *  Copyright 2011 Research In Motion Limited.
68731  *
68732  * Licensed under the Apache License, Version 2.0 (the "License");
68733  * you may not use this file except in compliance with the License.
68734  * You may obtain a copy of the License at
68735  *
68736  * http://www.apache.org/licenses/LICENSE-2.0
68737  *
68738  * Unless required by applicable law or agreed to in writing, software
68739  * distributed under the License is distributed on an "AS IS" BASIS,
68740  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68741  * See the License for the specific language governing permissions and
68742  * limitations under the License.
68743  */
68744 var emulatorBridge = require('ripple/emulatorBridge'),
68745     platform = require('ripple/platform'),
68746     db = require('ripple/db'),
68747     utils = require('ripple/utils'),
68748     devices = require('ripple/devices'),
68749     constants = require('ripple/constants'),
68750     _event = require('ripple/event'),
68751     tooltip = require('ripple/ui/plugins/tooltip'),
68752     histories = [];
68753
68754 function _omnibar() {
68755     return document.querySelector(".omni-bar input");
68756 }
68757
68758 function _persist(url) {
68759     db.save("current-url", url);
68760 }
68761
68762 function _persistRoot(url) {
68763     db.save("root-url", url);
68764 }
68765
68766 function _currentURL() {
68767     return db.retrieve("current-url") || "about:blank";
68768 }
68769
68770 function _rootURL() {
68771     return db.retrieve("root-url") || "about:blank";
68772 }
68773
68774 function _reload() {
68775     _event.trigger("ApplicationLoad", null);
68776     emulatorBridge.window().location.reload();
68777 }
68778
68779 function _loadApplication() {
68780     var omnibar = _omnibar(),
68781             xhr;
68782     if (omnibar.value.trim() !== "") {
68783         if (_currentURL().match(/^file:/) && omnibar.value.match(/^file:/)) { // Use ajax to know whether that file exists
68784             xhr = new XMLHttpRequest();
68785             xhr.onreadystatechange = function () {
68786                 if (xhr.readyState === 4) {
68787                     if (xhr.responseText !== '') {
68788                         _persist(omnibar.value);
68789                         _persistRoot(omnibar.value);
68790                         emulatorBridge.window().location.assign(omnibar.value);
68791                     } else {
68792                         alert("File doesn't exist!");
68793                         return;
68794                     }
68795                 }
68796             };
68797             xhr.open('GET', omnibar.value, true);
68798             xhr.send(null);
68799         } else {
68800             omnibar.value = omnibar.value.indexOf("://") < 0 ? "http://" + omnibar.value : omnibar.value;
68801             _persist(omnibar.value);
68802             _persistRoot(omnibar.value);
68803             emulatorBridge.window().location.assign(omnibar.value);
68804         }
68805         _addHistory(omnibar.value);
68806     }
68807     _event.trigger("ApplicationLoad", null);
68808 }
68809
68810 function _hideHistory() {
68811     $("#app-launching-history").hide("slide", {direction: "up"}, "fast");
68812     $("#overlayBackground-transparent").hide();
68813 }
68814
68815 function _makeHistoryItems() {
68816     histories = db.retrieveObject(constants.LAUNCHING_HISTORY);
68817     if (histories === undefined) {
68818         histories = [];
68819     }
68820     $("#app-launching-history").empty();
68821     histories.reverse();
68822     histories.forEach(function (item) {
68823         $("#app-launching-history").append('<div class="app-launching-history-item">' + item + '</div>');
68824     });
68825
68826     if (histories.length === 0) {
68827         $("#app-launching-history").append('<div class="app-launching-history-item-empty">History empty</div>');
68828     }
68829
68830     $(".app-launching-history-item").unbind('click');
68831     $(".app-launching-history-item").bind("click", function () {
68832         $(".omni-bar input").val(histories[$(this).index()]);
68833         _loadApplication();
68834         _hideHistory();
68835     });
68836 }
68837
68838
68839 function _showHistory() {
68840     _makeHistoryItems();
68841     $("#app-launching-history").css("width", $(".omni-bar input").width() + 20);
68842     $("#app-launching-history").show("slide", {direction: "up"}, "fast");
68843     $(window).bind('resize', function () {
68844         $("#app-launching-history").css("width", $(".omni-bar input").width() + 20);
68845         $("#overlayBackground-transparent").css("width", $(window).width());
68846         $("#overlayBackground-transparent").css("height", $(window).height());
68847     });
68848
68849     $("#history-background-overlay").show();
68850     $("#overlayBackground-transparent").css("width", $(window).width());
68851     $("#overlayBackground-transparent").css("height", $(window).height());
68852     $("#overlayBackground-transparent").show();
68853     $("#overlayBackground-transparent").unbind('click');
68854     $("#overlayBackground-transparent").bind("click", function () {
68855         _hideHistory();
68856     });
68857 }
68858
68859
68860 function _addHistory(uri) {
68861     var i = 0, thehistories = db.retrieveObject(constants.LAUNCHING_HISTORY);
68862     if (thehistories !== undefined) {
68863         for (i; i < thehistories.length; i++) {
68864             if (uri === thehistories[i]) {
68865                 return;
68866             }
68867         }
68868         if (thehistories.length >= 20) {
68869             thehistories.reverse();
68870             thehistories.pop();
68871             thehistories.reverse();
68872         }
68873     } else {
68874         thehistories = [];
68875     }
68876     thehistories.push(uri);
68877     db.saveObject(constants.LAUNCHING_HISTORY, thehistories);
68878 }
68879
68880 _event.on("FrameHistoryChange", function (url) {
68881     _omnibar().value = url;
68882     _persist(url);
68883     _persistRoot(url);
68884 });
68885
68886 module.exports = {
68887     initialize: function () {
68888         var omnibar = _omnibar(), loc, tmp,
68889             url, filename, matching, deviceId,
68890             xhr, uriParams, platformName, platformVersion, newUrl;
68891
68892         jQuery(".logo, .beta, .left, .right, .left-panel-collapse, .right-panel-collapse").css({
68893             "marginTop": "35px"
68894         });
68895
68896         jQuery("#settings-xhr-proxy").parent().parent().hide();
68897
68898         $(".omni-bar").show();
68899
68900         uriParams = utils.getURIParams(document.documentURI);
68901         if (uriParams.url !== undefined) {
68902             url = uriParams.url;
68903             if (url.match(/^\.[\.]?/) !== null) {
68904                 loc = document.location;
68905                 filename = loc.pathname.replace(/^.*[\\\/]/, '');
68906                 matching = new RegExp(filename, "g");
68907                 tmp = loc.protocol + "//" + loc.hostname + loc.pathname.replace(matching, "") + url;
68908                 url = tmp;
68909             }
68910             _persist(url);
68911             _persistRoot(url);
68912             require('ripple/widgetConfig').initialize();
68913             require('ripple/ui/plugins/widgetConfig').initialize();
68914         }
68915
68916         omnibar.value = _currentURL();
68917
68918         omnibar.addEventListener("keydown", function (event) {
68919             if (event.keyCode === '13' || event.keyCode === 13 || event.keyCode === '0' || event.keyCode === 0) { // enter or return
68920                 if (omnibar.value.trim() !== "") {
68921                     if (_currentURL().match(/^file:/) && omnibar.value.match(/^file:/)) { // Use ajax to know whether that file exists
68922                         xhr = new XMLHttpRequest();
68923                         xhr.onreadystatechange = function () {
68924                             if (xhr.readyState === 4) {
68925                                 if (xhr.responseText !== '') {
68926                                     _persist(omnibar.value);
68927                                     _persistRoot(omnibar.value);
68928                                     emulatorBridge.window().location.assign(omnibar.value);
68929                                 } else {
68930                                     alert("File doesn't exist!");
68931                                     return;
68932                                 }
68933                             }
68934                         };
68935                         xhr.open('GET', omnibar.value, true);
68936                         xhr.send(null);
68937                     } else {
68938                         //default the protocal if not provided
68939                         omnibar.value = omnibar.value.indexOf("://") < 0 ? "http://" + omnibar.value : omnibar.value;
68940                         _persist(omnibar.value);
68941                         _persistRoot(omnibar.value);
68942                         emulatorBridge.window().location.assign(omnibar.value);
68943                     }
68944                     _event.trigger("ApplicationLoad", null);
68945                     _addHistory(omnibar.value);
68946                 }
68947             }
68948         });
68949
68950         window.addEventListener("keydown", function (event) {
68951             var hasMetaOrAltPressed = (event.metaKey || event.ctrlKey),
68952                 key = parseInt(event.keyCode, 10);
68953
68954             if (key === 82 && hasMetaOrAltPressed) { // cmd/ctrl + r
68955                 event.preventDefault();
68956                 _reload();
68957             }
68958
68959             if (key === 116) { // F5
68960                 event.preventDefault();
68961                 _reload();
68962             }
68963         });
68964
68965         document.getElementById("history-reload").addEventListener("click", _reload);
68966         $("#options-button-history").bind("click", function () {
68967             _showHistory();
68968         });
68969         tooltip.create("#history-reload", "Reload Application");
68970         tooltip.create("#options-button-history", "History");
68971         tooltip.create("#options-button-config-window", "Configuration");
68972         tooltip.create("#options-button-panels", "Panel Settings");
68973         tooltip.create("#options-button-about", "About");
68974     },
68975     currentURL: function () {
68976         return _currentURL();
68977     },
68978     rootURL: function () {
68979         return _rootURL();
68980     }
68981 };
68982
68983 });
68984 define('ripple/ui/plugins/fileSystem', function (require, exports, module) {
68985 /*
68986  *  Copyright 2011 Research In Motion Limited.
68987  *
68988  * Licensed under the Apache License, Version 2.0 (the "License");
68989  * you may not use this file except in compliance with the License.
68990  * You may obtain a copy of the License at
68991  *
68992  * http://www.apache.org/licenses/LICENSE-2.0
68993  *
68994  * Unless required by applicable law or agreed to in writing, software
68995  * distributed under the License is distributed on an "AS IS" BASIS,
68996  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68997  * See the License for the specific language governing permissions and
68998  * limitations under the License.
68999  */
69000 var utils = require('ripple/utils'),
69001     constants = require('ripple/constants'),
69002     fileSystem = require('ripple/fileSystem'),
69003     fileSystemPaths = fileSystem.getFileSystemPaths();
69004
69005 module.exports = {
69006     panel: {
69007         domId: "filsystem-container",
69008         collapsed: true,
69009         pane: "left"
69010     },
69011     initialize: function () {
69012         var fileSystemPaths = fileSystem.getFileSystemPaths();
69013
69014         utils.forEach(fileSystemPaths, function (value, key) {
69015             utils.bindAutoSaveEvent(jQuery(constants.FILESYSTEM.INPUT_PREFIX_ID + key).val(value.uri), function () {
69016                 value.uri = jQuery(constants.FILESYSTEM.INPUT_PREFIX_ID + key).val();
69017                 fileSystem.updateFileSystemPaths(fileSystemPaths);
69018             });
69019         });
69020     }
69021 };
69022
69023 });
69024 define('ripple/ui/plugins/notifications', function (require, exports, module) {
69025 /*
69026  *  Copyright 2011 Research In Motion Limited.
69027  *
69028  * Licensed under the Apache License, Version 2.0 (the "License");
69029  * you may not use this file except in compliance with the License.
69030  * You may obtain a copy of the License at
69031  *
69032  * http://www.apache.org/licenses/LICENSE-2.0
69033  *
69034  * Unless required by applicable law or agreed to in writing, software
69035  * distributed under the License is distributed on an "AS IS" BASIS,
69036  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69037  * See the License for the specific language governing permissions and
69038  * limitations under the License.
69039  */
69040
69041 var db = require('ripple/db'),
69042     utils = require('ripple/utils'),
69043     event = require('ripple/event'),
69044     _notificationUIStack,
69045     _notificationTemplate = "";
69046
69047 function _remove(id) {
69048     delete _notificationUIStack[id];
69049     db.saveObject("posted-notifications", _notificationUIStack);
69050     event.trigger("refreshNotificationStack", [], true);
69051     _render();
69052 }
69053
69054 function _removeAll() {
69055     _notificationUIStack = {};
69056     db.saveObject("posted-notifications", _notificationUIStack);
69057     event.trigger("refreshNotificationStack", [], true);
69058     $("#notification-box").empty();
69059     $("#notification-box").append('<div style="color:#666666;">(Empty notification.)</div>');
69060     $("#remove-all-notifications-btn").hide();
69061 }
69062
69063 function _render() {
69064     var notificationHTML = "",
69065         htmlContent = "";
69066
69067     utils.forEach(_notificationUIStack, function (item) {
69068         notificationHTML = _notificationTemplate.replace(/#id/g, item.id)
69069             .replace(/#title/g, item.title)
69070             .replace(/#content/, item.content ? item.content : "")
69071             .replace(/#type/, item.type)
69072             .replace(/#statusType/, item.statusType)
69073             .replace(/#postedTime/, item.postedTime)
69074             .replace(/#iconPath/, item.iconPath ? item.iconPath : "")
69075             .replace(/#subIconPath/, item.subIconPath ? item.subIconPath : "")
69076             .replace(/#number/, item.number ? item.number : "")
69077             .replace(/#detailInfo/, item.detailInfo ? item.detailInfo.join() : "")
69078             .replace(/#backgroundImagePath/, item.backgroundImagePath ? item.backgroundImagePath : "")
69079             .replace(/#thumbnails/, item.thumbnails ? item.thumbnails.join() : "")
69080             .replace(/#soundPath/, item.soundPath ? item.soundPath : "")
69081             .replace(/#vibration/, item.vibration !== undefined ? (item.vibration === true ? "true" : "false") : "")
69082             .replace(/#appControl/, item.appControl ? item.appControl : "")
69083             .replace(/#appId/, item.appId ? item.appId : "")
69084             .replace(/#progressType/g, item.progressType ? item.progressType: "")
69085             .replace(/#progressValue/, (item.statusType === "PROGRESS" && item.progressType === "PERCENTAGE" && item.progressValue) ? item.progressValue.toString() + "%" : "")
69086             .replace(/#progressBarValue/, (item.statusType === "PROGRESS" && item.progressType === "PERCENTAGE" && item.progressValue) ? item.progressValue : 0)
69087             .replace(/#progress2Value/, (item.statusType === "PROGRESS" && item.progressType === "BYTE" && item.progressValue) ? item.progressValue.toString() + " byte(s)" : "")
69088             .replace(/#displayBar/g, (item.statusType !== "PROGRESS" || item.progressType !== "PERCENTAGE") ? "none" : "")
69089             .replace(/#display2Bar/g, (item.statusType !== "PROGRESS" || item.progressType !== "BYTE") ? "none" : "");
69090         htmlContent += notificationHTML;
69091     });
69092
69093     $("#notification-box").accordion("destroy");
69094     $("#notification-box").html(htmlContent).accordion({
69095         active : false,
69096         collapsible : true,
69097         autoHeight : false
69098     });
69099
69100     $("#notification-box .progress-bar").each(function (index, item) {
69101         $(item).width(this.id);
69102     });
69103     if (utils.count(_notificationUIStack) !== 0) {
69104         $("#remove-all-notifications-btn").show();
69105     } else {
69106         $("#remove-all-notifications-btn").hide();
69107     }
69108     $("." + "remove-notification-btn").bind("click", function () {
69109         _remove(this.id);
69110     });
69111 }
69112
69113 module.exports = {
69114     panel: {
69115         domId: "notification-container",
69116         collapsed: true,
69117         pane: "left",
69118         titleName: "Notification",
69119         display: true
69120     },
69121     initialize: function () {
69122         _notificationTemplate = $("#notification-template").html();
69123         $("#notification-box").empty();
69124         _notificationUIStack = db.retrieveObject("posted-notifications") || {};
69125         if (utils.count(_notificationUIStack) === 0) {
69126             $("#notification-box").append('<div style="color:#666666;">(Empty notification.)</div>');
69127         }
69128         else
69129             _render();
69130         $("#remove-all-notifications-btn").bind("click", _removeAll);
69131
69132         event.on("refreshNotificationUI", function () {
69133             _notificationUIStack = db.retrieveObject("posted-notifications");
69134             _render();
69135         });
69136     }
69137 };
69138
69139 });
69140 define('ripple/ui/plugins/messaging', function (require, exports, module) {
69141 /*
69142  *  Copyright 2011 Research In Motion Limited.
69143  *
69144  * Licensed under the Apache License, Version 2.0 (the "License");
69145  * you may not use this file except in compliance with the License.
69146  * You may obtain a copy of the License at
69147  *
69148  * http://www.apache.org/licenses/LICENSE-2.0
69149  *
69150  * Unless required by applicable law or agreed to in writing, software
69151  * distributed under the License is distributed on an "AS IS" BASIS,
69152  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69153  * See the License for the specific language governing permissions and
69154  * limitations under the License.
69155  */
69156 var event = require('ripple/event'),
69157     utils = require('ripple/utils'),
69158     _type = {
69159         sms: "SMS",
69160         mms: "MMS",
69161         email: "E-mail"
69162     },
69163     _filename_suffix = 0,
69164     _attachments = [];
69165
69166 function _getAttachmentFileName() {
69167     return "attach" + _filename_suffix + ".txt";
69168 }
69169
69170 module.exports = {
69171     panel: {
69172         domId: "messaging-container",
69173         collapsed: true,
69174         pane: "left",
69175         titleName: "Messaging",
69176         display: true
69177     },
69178     initialize: function () {
69179         document.getElementById("messaging-send")
69180             .addEventListener("click", function () {
69181                 var number = document.getElementById("messaging-sms-number").value,
69182                     text = document.getElementById("messaging-text").value,
69183                     type = document.getElementById("messaging-type").value,
69184                     message = {
69185                         type: type,
69186                         body: text,
69187                         from: number,
69188                         time: new Date(),
69189                         attachments: _attachments
69190                     };
69191
69192                 event.trigger("MessageReceived", [message]);
69193                 
69194                 _attachments = [];
69195 /* TODO: add back when attachment is finished
69196                 document.getElementById("messaging-attachments").innerHTML = "";
69197 */
69198                 _filename_suffix = 0;
69199             }, false);
69200
69201 /* TODO: add back when attachment is finished
69202         document.getElementById("messaging-attach")
69203             .addEventListener("click", function () {
69204                 var attachedFile, attachedFileCheckbox, attachedFileName;
69205                 if (_filename_suffix > 0)
69206                     return;
69207                 _attachments.push({filename: _getAttachmentFileName(), content: document.getElementById("messaging-attachment-content").value});
69208
69209                 attachedFile = document.getElementById("messaging-attachments").insertRow(0);
69210                 attachedFileName = attachedFile.insertCell(0);
69211                 attachedFileCheckbox = attachedFile.insertCell(1);
69212                 attachedFileName.innerHTML = _attachments[_filename_suffix].filename;
69213 //                attachedFileCheckbox.innerHTML = '<input type="checkbox" value="' + _filename_suffix + '">';
69214
69215                 document.getElementById("messaging-attachment-content").value = "";
69216                 _filename_suffix++;
69217             }, false);
69218
69219         document.getElementById("messaging-detach")
69220             .addEventListener("click", function () {
69221                 _attachments = [];
69222                 document.getElementById("messaging-attachments").innerHTML = "";
69223                 _filename_suffix = 0;
69224             }, false);
69225 */
69226         event.on("OutsideMessageReceived", function (message) {
69227             var numRecipients = 0,
69228                 i = 0,
69229                 recipients = [],
69230                 recipientsStatus = {},
69231                 strRecipients = document.getElementById("messaging-recipients").value;
69232
69233             recipientsStatus.id = message.id;
69234             recipientsStatus.msg = message.msg;
69235             for (i in message.to) {
69236                 recipientsStatus[message.to[i]] = true;
69237                 recipients.push(message.to[i]);
69238             }
69239             for (i in message.cc) {
69240                 recipientsStatus[message.cc[i]] = true;
69241                 recipients.push(message.cc[i]);
69242             }
69243             for (i in message.bcc) {
69244                 recipientsStatus[message.bcc[i]] = true;
69245                 recipients.push(message.bcc[i]);
69246             }
69247             numRecipients = recipients.length;
69248             strRecipients = recipients.join(",");
69249             event.trigger("MessageSent", [recipientsStatus]);
69250             document.getElementById("messaging-received").innerHTML = "" + numRecipients + " recipient(s)" + " delivered";
69251             document.getElementById("messaging-recipients").value = strRecipients;
69252             document.getElementById("received-message-box").value = message.body;
69253         });
69254         
69255         document.getElementById("messaging-clear")
69256             .addEventListener("click", function () {
69257                 document.getElementById("received-message-box").value = "";
69258                 document.getElementById("messaging-received").innerHTML = "";
69259             }, false);
69260         
69261         utils.forEach(_type, function (msgTypeText, msgType) {
69262             var typeNode = utils.createElement("option", {
69263                     "innerText": msgTypeText,
69264                     "value": msgType
69265                 });
69266
69267             document.getElementById("messaging-type").appendChild(typeNode);
69268         });
69269     }
69270 };
69271
69272 });
69273 define('ripple/ui/plugins/audioPlayer', function (require, exports, module) {
69274 /*
69275  *  Copyright 2011 Research In Motion Limited.
69276  *
69277  * Licensed under the Apache License, Version 2.0 (the "License");
69278  * you may not use this file except in compliance with the License.
69279  * You may obtain a copy of the License at
69280  *
69281  * http://www.apache.org/licenses/LICENSE-2.0
69282  *
69283  * Unless required by applicable law or agreed to in writing, software
69284  * distributed under the License is distributed on an "AS IS" BASIS,
69285  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69286  * See the License for the specific language governing permissions and
69287  * limitations under the License.
69288  */
69289 var event = require('ripple/event'),
69290     constants = require('ripple/constants'),
69291     audioObj = document.getElementById("multimedia-audio"),
69292     audioProgress = document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PROGRESS_ID);
69293
69294 module.exports = {
69295     initialize: function () {
69296         var audioObj = document.getElementById("multimedia-audio"),
69297             audioProgress = document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PROGRESS_ID);
69298
69299         if (audioObj) {
69300             event.on("MultimediaVolumeChanged", function (volume) {
69301                 audioObj.volume = parseFloat(volume / 10);
69302             });
69303
69304             audioObj.addEventListener("timeupdate", function () {
69305                 var s = parseInt(audioObj.currentTime % 60, 10),
69306                     m = parseInt((audioObj.currentTime / 60) % 60, 10);
69307
69308                 audioProgress.innerText = ((m > 9) ? m  : "0" + m) + ':' + ((s > 9) ? s  : "0" + s);
69309             }, false);
69310
69311             event.on("MultimediaAudioStateChanged", function (state) {
69312                 document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_STATE_FIELD_ID).innerText = state;
69313                 document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_FILE_FIELD_ID).innerText = audioObj.getAttribute("src");
69314             });
69315         }
69316     }
69317 };
69318
69319 });
69320 define('ripple/ui/plugins/settings', function (require, exports, module) {
69321 /*
69322  *  Copyright 2011 Research In Motion Limited.
69323  *
69324  * Licensed under the Apache License, Version 2.0 (the "License");
69325  * you may not use this file except in compliance with the License.
69326  * You may obtain a copy of the License at
69327  *
69328  * http://www.apache.org/licenses/LICENSE-2.0
69329  *
69330  * Unless required by applicable law or agreed to in writing, software
69331  * distributed under the License is distributed on an "AS IS" BASIS,
69332  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69333  * See the License for the specific language governing permissions and
69334  * limitations under the License.
69335  */
69336 var db = require('ripple/db'),
69337     constants = require('ripple/constants'),
69338     KEY = constants.XHR.PROXY_DISABLED_BUTTON; // TODO: one settings object for all
69339
69340 function _saveAndReload(key, value) {
69341     jWorkflow.order(function (prev, baton) {
69342         baton.take();
69343         db.save(key, value, null, baton.pass);
69344     }).start(function () {
69345         window.tinyHipposReload = true;
69346         location.reload();
69347     });
69348 }
69349
69350 function _initialize(prev, baton) {
69351     var select = document.getElementById("settings-xhr-proxy"),
69352         about = require('ripple/ui/plugins/about-dialog');
69353
69354     select.value = String(db.retrieve(KEY));
69355     select.addEventListener("change", function () {
69356         _saveAndReload(KEY, this.value);
69357     }, false);
69358     
69359     $("#options-menu-about").click(function () {
69360         about.show();
69361     });
69362     // TODO: reload here?
69363 }
69364
69365 module.exports = {
69366     panel: {
69367         domId: "settings-container",
69368         collapsed: true,
69369         pane: "right"
69370     },
69371     initialize: _initialize
69372 };
69373
69374 });
69375 define('ripple/ui/plugins/widgetConfig', function (require, exports, module) {
69376 /*
69377  *  Copyright 2011 Research In Motion Limited.
69378  *
69379  * Licensed under the Apache License, Version 2.0 (the "License");
69380  * you may not use this file except in compliance with the License.
69381  * You may obtain a copy of the License at
69382  *
69383  * http://www.apache.org/licenses/LICENSE-2.0
69384  *
69385  * Unless required by applicable law or agreed to in writing, software
69386  * distributed under the License is distributed on an "AS IS" BASIS,
69387  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69388  * See the License for the specific language governing permissions and
69389  * limitations under the License.
69390  */
69391 var constants = require('ripple/constants'),
69392     event = require('ripple/event'),
69393     utils = require('ripple/utils'),
69394     exception = require('ripple/exception'),
69395     tooltip = require('ripple/ui/plugins/tooltip'),
69396     platform = require('ripple/platform'),
69397     widgetConfig = require('ripple/widgetConfig');
69398
69399 function _buildConfigAccordionNode(node, accordionContainer, counter) {
69400     var nodeDiv, nodeTitleH3, nodeContentDiv, tableString, attribute, child, result,
69401         tableClass, nameClass, attributeNameClass, messageClass, nameId, messageId, attributeName, attributeValue, attributeMessage,
69402         helpText = {},
69403         nodeCounter = 0,
69404         attributeCounter = 0,
69405         moreNodes = node.validationResult,
69406         createTooltip = function (value, index) {
69407             tooltip.create("#" +  index, value);
69408         };
69409
69410     while (moreNodes) {
69411         result = node.validationResult[nodeCounter];
69412
69413         if (!result) {
69414             // this should never happen
69415             return;
69416         }
69417
69418         // the container of the entire accordion block
69419         nodeDiv = utils.createElement("div", {
69420             "id": "config-accordion-node-content-" + counter + "-" + nodeCounter,
69421             "class": "ui-corner-all"
69422         });
69423
69424         // the header bar of the accordion block
69425         nodeTitleH3 = utils.createElement("h3", {
69426             "id": "config-accordion-node-title-" + counter + "-" + nodeCounter,
69427             "class": "config-accordion-node-title"
69428         });
69429
69430         nodeTitleH3.appendChild(utils.createElement("a", {
69431             href: "#",
69432             innerText: node.nodeName,
69433             "class": constants.CONFIG.SUCCESS_CSS[(result.valid === undefined) ? "missing" : result.valid.toString()]
69434         }));
69435         nodeDiv.appendChild(nodeTitleH3);
69436
69437         if (node.helpText) {
69438             helpText[nodeTitleH3.id] = node.helpText;
69439         }
69440
69441         nodeContentDiv = utils.createElement("div");
69442
69443         // display node value (add tool tip if exists)
69444         if (node.type || (!node.type && result && result.value)) {
69445             nodeContentDiv.appendChild(utils.createElement("div", {
69446                 "id": "config-accordion-node-content-value-" + counter + "-" + nodeCounter,
69447                 "class": "config-accordion-node-content-value",
69448                 "innerHTML": "<span>Value:</span>" + (result.value || "")
69449             }));
69450
69451             if (node.helpValueText) {
69452                 helpText["config-accordion-node-content-value-" + counter + "-" + nodeCounter] = node.helpValueText;
69453             }
69454         }
69455
69456         // display node message if failed validation
69457         if (result && result.message) {
69458             nodeContentDiv.appendChild(utils.createElement("div", {
69459                 "id": "config-accordion-node-content-value-message-" + counter + "-" + nodeCounter,
69460                 "class": "config-accordion-node-content-value-message ui-text-fail",
69461                 "innerHTML": "<span>Message:</span>" + result.message
69462             }));
69463         }
69464
69465         // display node attributes with name, value, message if failed validation
69466         if (result.attributes) {
69467             nodeContentDiv.appendChild(utils.createElement("div", {
69468                 "id": "config-accordion-node-content-attributes-title-" + counter + "-" + nodeCounter,
69469                 "class": "config-accordion-node-content-attributes-title",
69470                 "innerHTML": "Attributes..."
69471             }));
69472
69473             tableClass = "preferences-table";
69474             nameClass = "config-attributes-name-value";
69475             attributeNameClass = "ui-text-label";
69476             messageClass = "config-attributes-message";
69477
69478             tableString = '<table class="' + tableClass + ' ui-widget-content">';
69479             for (attribute in result.attributes) {
69480                 if (result.attributes.hasOwnProperty(attribute)) {
69481                     nameId = "config-accordion-node-content-attributes-table-name-" + counter + "-" + nodeCounter + "-" + attributeCounter;
69482                     messageId = "config-accordion-node-content-attributes-table-message-" + counter + "-" + nodeCounter + "-" + attributeCounter;
69483                     attributeName = result.attributes[attribute].attributeName;
69484                     attributeValue = result.attributes[attribute].value || "&nbsp;";
69485                     attributeMessage = result.attributes[attribute].message || null;
69486
69487                     tableString += '<tr class="' + nameClass + '" id="' + nameId + '">' +
69488                             '<td class="' + attributeNameClass + '">' + attributeName + '</td>' +
69489                             '<td>' + attributeValue + '</td></tr>';
69490
69491                     if (node.attributes[attributeName].helpText) {
69492                         helpText[nameId] = node.attributes[attributeName].helpText;
69493                     }
69494
69495                     if (attributeMessage !== null) {
69496                         tableString += "<tr class=" + messageClass + " id=" + messageId + "><td colspan=\"2\">" +
69497                                 attributeMessage + "</td></tr>";
69498                     }
69499                     attributeCounter++;
69500                 }
69501             }
69502             tableString += "</table>";
69503
69504             nodeContentDiv.innerHTML += tableString;
69505         }
69506
69507
69508         nodeDiv.appendChild(nodeContentDiv);
69509         accordionContainer.appendChild(nodeDiv);
69510
69511         utils.forEach(helpText, createTooltip);
69512
69513         nodeCounter ++;
69514
69515         if (!node.validationResult[nodeCounter]) {
69516             nodeCounter = 0;
69517             moreNodes = false;
69518         }
69519     }
69520
69521     if (node.children) {
69522         for (child in node.children) {
69523             if (node.children.hasOwnProperty(child)) {
69524                 counter ++;
69525                 _buildConfigAccordionNode(node.children[child], accordionContainer, counter);
69526             }
69527         }
69528     }
69529 }
69530
69531 function _initializeConfigResultsView(results) {
69532     try {
69533         var rootNode,
69534             accordionContainer = document.getElementById("widget-config");
69535
69536         accordionContainer.innerHTML = "";
69537         if (!results) {
69538             accordionContainer.appendChild(utils.createElement("div", {
69539                 "class": "config-accordion-node-title " + constants.CONFIG.SUCCESS_CSS["false"],
69540                 "innerHTML": "Expected to find a configuration file for your application, but none is present. Please create" +
69541                         " a configuration file with the following name in the root directory of your application: " +
69542                         platform.current().fileName
69543             }));
69544             return;
69545         }
69546
69547         rootNode = results[results.rootElement];
69548
69549         _buildConfigAccordionNode(rootNode, accordionContainer, 0);
69550
69551         jQuery(function () {
69552             var stop = false;
69553             jQuery("#widget-config h3").click(function (event) {
69554                 if (stop) {
69555                     event.stopImmediatePropagation();
69556                     event.preventDefault();
69557                     stop = false;
69558                 }
69559             });
69560             jQuery("#widget-config").accordion("destroy").accordion({
69561                 header: "> div > h3",
69562                 autoHeight: false
69563             });
69564         });
69565     } catch (e) {
69566         exception.handle(e, true);
69567     }
69568 }
69569
69570 event.on("FrameHistoryChange", function () {
69571     module.exports.initialize();
69572 });
69573
69574 module.exports = {
69575     panel: {
69576         domId: "config-container",
69577         collapsed: true,
69578         pane: "right",
69579         titleName: "Application Configuration",
69580         display: true
69581     },
69582     initialize: function () {
69583         var results = widgetConfig.getValidationResults();
69584         _initializeConfigResultsView(results);
69585     }
69586 };
69587
69588 });
69589 define('ripple/ui/plugins/layout', function (require, exports, module) {
69590 /*
69591  *  Copyright 2011 Research In Motion Limited.
69592  *
69593  * Licensed under the Apache License, Version 2.0 (the "License");
69594  * you may not use this file except in compliance with the License.
69595  * You may obtain a copy of the License at
69596  *
69597  * http://www.apache.org/licenses/LICENSE-2.0
69598  *
69599  * Unless required by applicable law or agreed to in writing, software
69600  * distributed under the License is distributed on an "AS IS" BASIS,
69601  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69602  * See the License for the specific language governing permissions and
69603  * limitations under the License.
69604  */
69605 var constants = require('ripple/constants'),
69606     db = require('ripple/db'),
69607     resizer = require('ripple/resizer'),
69608     devices = require('ripple/devices'),
69609     event = require('ripple/event');
69610
69611 function _initializeLayout(prev, baton) {
69612     var layout = db.retrieve("layout"),
69613         orientation = db.retrieve("deviceOrientation") || "portrait",
69614         layoutLandscape = document.getElementById(constants.COMMON.ORIENTATION_SELECT_LANDSCAPE_ID),
69615         layoutPortrait = document.getElementById(constants.COMMON.ORIENTATION_SELECT_PORTRAIT_ID),
69616         currentDevice = devices.getCurrentDevice(),
69617         defaultOrientation =  currentDevice ? currentDevice.defaultOrientation : null,
69618         layoutTypeChanged = false;
69619
69620     jQuery("#" + constants.COMMON.ORIENTATION_SELECT_LANDSCAPE_ID).bind("click", function () {
69621         layoutLandscape.setAttribute("class", "layout-selected");
69622         layoutPortrait.setAttribute("class", "layout-not-selected");
69623         resizer.rotateDevice("landscape");
69624         event.trigger("OrientationChanged", ["landscape"], true);
69625     });
69626
69627     jQuery("#" + constants.COMMON.ORIENTATION_SELECT_PORTRAIT_ID).bind("click", function () {
69628         layoutLandscape.setAttribute("class", "layout-not-selected");
69629         layoutPortrait.setAttribute("class", "layout-selected");
69630         resizer.rotateDevice("portrait");
69631         event.trigger("OrientationChanged", ["portrait"], true);
69632     });
69633
69634     jQuery("#" + constants.COMMON.MENU_BUTTON).bind("click", function () {
69635         event.trigger("HardwareKey", [1]);
69636     });
69637
69638     jQuery("#" + constants.COMMON.BACK_BUTTON).bind("click", function () {
69639         event.trigger("HardwareKey", [0]);
69640     });
69641
69642     if (!layout) {
69643         layout = defaultOrientation || "portrait";
69644         layoutTypeChanged = true;
69645         resizer.changeLayoutType(layout);
69646     }
69647
69648     //Hide the orientation buttons that we don't need for this device
69649     if (!currentDevice.viewPort.landscape) {
69650         layoutLandscape.setAttribute("style", "display:none");
69651     }
69652
69653     if (!currentDevice.viewPort.portrait) {
69654         layoutPortrait.setAttribute("style", "display:none");
69655     }
69656
69657     if (layout && layout === "portrait") {
69658         layoutLandscape.setAttribute("class", "layout-not-selected");
69659         layoutPortrait.setAttribute("class", "layout-selected");
69660     }
69661     else if (layout && layout === "landscape") {
69662         layoutLandscape.setAttribute("class", "layout-selected");
69663         layoutPortrait.setAttribute("class", "layout-not-selected");
69664     }
69665
69666     if (!layoutTypeChanged) {
69667         resizer.resize(currentDevice);
69668     }
69669
69670     if (orientation === "portrait") {
69671         layoutLandscape.setAttribute("class", "layout-not-selected");
69672         layoutPortrait.setAttribute("class", "layout-selected");
69673     } else {
69674         layoutLandscape.setAttribute("class", "layout-selected");
69675         layoutPortrait.setAttribute("class", "layout-not-selected");
69676     }
69677     resizer.rotateDevice(orientation);
69678 }
69679
69680 module.exports = {
69681     initialize: _initializeLayout
69682 };
69683
69684 });
69685 define('ripple/ui/plugins/devices', function (require, exports, module) {
69686 /*
69687  *  Copyright 2011 Research In Motion Limited.
69688  *
69689  * Licensed under the Apache License, Version 2.0 (the "License");
69690  * you may not use this file except in compliance with the License.
69691  * You may obtain a copy of the License at
69692  *
69693  * http://www.apache.org/licenses/LICENSE-2.0
69694  *
69695  * Unless required by applicable law or agreed to in writing, software
69696  * distributed under the License is distributed on an "AS IS" BASIS,
69697  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69698  * See the License for the specific language governing permissions and
69699  * limitations under the License.
69700  */
69701 var constants = require('ripple/constants'),
69702     db = require('ripple/db'),
69703     resizer = require('ripple/resizer');
69704
69705 function _getTextZooming(zooming) {
69706     return zooming + '%';
69707 }
69708
69709 module.exports = {
69710     panel: {
69711         domId: "devices-container",
69712         collapsed: true,
69713         pane: "left",
69714         titleName: "Orientation and Zooming",
69715         display: true
69716     },
69717
69718     initialize: function () {
69719         var zooming = document.getElementById(constants.ENCAPSULATOR.ZOOMING);
69720         function updateZoomingValues() {
69721             var zoomingText, scaleFactor;
69722
69723             zoomingText = _getTextZooming(zooming.value);
69724             jQuery('#screen-zooming-label').html(zoomingText);
69725
69726             // Zooming device skin
69727             scaleFactor = zooming.value / 100;
69728             resizer.scaleDevice(scaleFactor);
69729         }
69730
69731         function initializeValues() {
69732             var zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING);
69733
69734             if (!zoomingValue) {
69735                 zoomingValue = 100;
69736             }
69737             jQuery("#" + constants.ENCAPSULATOR.ZOOMING).val(zoomingValue);
69738             updateZoomingValues();
69739         }
69740
69741         jQuery("#" + constants.ENCAPSULATOR.ZOOMING).bind("change", function () {
69742             updateZoomingValues();
69743             db.save(constants.ENCAPSULATOR.ZOOMING, zooming.value);
69744         });
69745
69746         initializeValues();
69747     }
69748 };
69749
69750
69751 });
69752 define('ripple/ui/plugins/storage', function (require, exports, module) {
69753 /*
69754  *  Copyright 2011 Research In Motion Limited.
69755  *
69756  * Licensed under the Apache License, Version 2.0 (the "License");
69757  * you may not use this file except in compliance with the License.
69758  * You may obtain a copy of the License at
69759  *
69760  * http://www.apache.org/licenses/LICENSE-2.0
69761  *
69762  * Unless required by applicable law or agreed to in writing, software
69763  * distributed under the License is distributed on an "AS IS" BASIS,
69764  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69765  * See the License for the specific language governing permissions and
69766  * limitations under the License.
69767  */
69768 var constants = require('ripple/constants'),
69769     event = require('ripple/event'),
69770     platform = require('ripple/platform'),
69771     utils = require('ripple/utils'),
69772     app = require('ripple/app'),
69773     db = require('ripple/db');
69774
69775 function _updatePreferencesView() {
69776     var node = document.getElementById(constants.COMMON.STORAGE_TABLE_BODY_CLASS),
69777         countTitle = document.getElementById(constants.COMMON.STORAGE_COUNT_CONTAINER_ID);
69778
69779     // TODO: convert to appendChild
69780     if (node) {
69781         db.retrieveAll(platform.getPersistencePrefix(), function (results) {
69782             var str = "",
69783                 counter = 0;
69784
69785             utils.forEach(results, function (value, key) {
69786                 // TODO: based of current platform
69787                 if (app.isPreferenceReadOnly(key)) {
69788                     str += '<tr class="ui-text-highlight">';
69789                 } else {
69790                     str += '<tr>';
69791                 }
69792                 str += '<td>' + key + '</td><td>' + value + "</td></tr>";
69793                 counter ++;
69794             });
69795
69796             node.innerHTML = str;
69797             countTitle.innerHTML = counter.toString();
69798
69799             if (counter === 0) {
69800                 jQuery("#" + constants.COMMON.STORAGE_CLEAR_BUTTON_ID).addClass(constants.CSS_PREFIX.IRRELEVANT);
69801             }
69802             else {
69803                 jQuery("#" + constants.COMMON.STORAGE_CLEAR_BUTTON_ID).removeClass(constants.CSS_PREFIX.IRRELEVANT);
69804             }
69805         });
69806     }
69807 }
69808
69809 module.exports = {
69810     panel: {
69811         domId: "preferences",
69812         collapsed: true,
69813         pane: "left"
69814     },
69815     initialize: function () {
69816         jQuery("#preferences-clear-button").bind("click", function () {
69817             db.removeAll(platform.getPersistencePrefix());
69818         });
69819
69820         event.on("StorageUpdatedEvent", function () {
69821             _updatePreferencesView();
69822         });
69823
69824         _updatePreferencesView();
69825     }
69826 };
69827
69828 });
69829 define('ripple/ui/plugins/messagePort', function (require, exports, module) {
69830 /*
69831  *  Copyright 2014 Intel Corporation.
69832  *
69833  * Licensed under the Apache License, Version 2.0 (the "License");
69834  * you may not use this file except in compliance with the License.
69835  * You may obtain a copy of the License at
69836  *
69837  * http://www.apache.org/licenses/LICENSE-2.0
69838  *
69839  * Unless required by applicable law or agreed to in writing, software
69840  * distributed under the License is distributed on an "AS IS" BASIS,
69841  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69842  * See the License for the specific language governing permissions and
69843  * limitations under the License.
69844  */
69845
69846 var db = require('ripple/db'),
69847     event = require('ripple/event'),
69848     exception = require('ripple/exception'),
69849     dbinit = require('ripple/platform/tizen/2.0/dbinit'),
69850     _messagePortGlobal = {
69851         localMessagePorts: {}
69852     },
69853     _db = null;
69854
69855 function _initMessagePortDatabase() {
69856     _db = dbinit.MessagePort;
69857
69858     db.saveObject("tizen-messageport", _db);
69859 }
69860
69861 function _initializeMessagePortPanel() {
69862     var stop = false;
69863
69864     _makeRemoteApplicationsHtml();
69865     _sendingRemoteMessage();
69866
69867     try {
69868         jQuery("#messagePort-remote-applications h3").click(function (event) {
69869             if (stop) {
69870                 event.stopImmediatePropagation();
69871                 event.preventDefault();
69872                 stop = true;
69873             }
69874         });
69875         jQuery("#messagePort-remote-applications").accordion("destroy").accordion({
69876             header: "> div > h3",
69877             active: false,
69878             collapsible: true,
69879             autoHeight: false
69880         });
69881     } catch (e) {
69882         exception.handle(e, true);
69883     }
69884 }
69885
69886 function _addLocalMessagePortOptions(messagePortName) {
69887     var htmlTemplate = '<option value="#messagePortName">#messagePortName</option>',
69888         option = '', appId, portSelector = [], sendSelector = [];
69889
69890     for (appId in _db) {
69891         portSelector.push("#" + appId + "-local-port");
69892         sendSelector.push("#" + appId + "-send");
69893     }
69894
69895     option += htmlTemplate.replace(/#messagePortName/g, messagePortName);
69896
69897     jQuery(portSelector.join(",")).append(option);
69898     jQuery(portSelector.join(",")).removeAttr("disabled");
69899     jQuery(sendSelector.join(",")).removeAttr("disabled");
69900 }
69901
69902 function _makeRemoteApplicationsHtml() {
69903     var htmlTemplate = jQuery("#messagePort-remote-template").html(),
69904         portHtmlTemplate = '<h3><span style="font-weight: bold;">#isTrustedIcon</span>&nbsp;#messagePortName</h3>' +
69905             '<div class="#portContainterAddr" style="border: 1px solid #DCDCDC; height: 10em; overflow: auto; border-radius: 8px;"></div>',
69906         optionTemplate = '<input id="#RemoteApplicationId-isTrusted" type="checkbox" value="true" #CHECKED disabled>' +
69907             '<label for="#RemoteApplicationId-isTrusted">Same as current application</label>',
69908         appId, appName, portName, abbr, isTrusted, html = '', portHtml,
69909         tabSelectors = [], portSelectors = [], certificate, option;
69910
69911     for (appId in _db) {
69912         appName = _db[appId].name;
69913         certificate= _db[appId].certificate;
69914
69915         portHtml = '';
69916         for (portName in _db[appId].ports) {
69917             isTrusted = _db[appId].ports[portName];
69918             abbr = portName.replace(/\s+/g, "");
69919
69920             portHtml += portHtmlTemplate.replace(/#messagePortName/g, portName)
69921                 .replace(/#RemoteApplicationId/g, appId)
69922                 .replace(/#isTrustedIcon/g, isTrusted ? "&#9417;" : "&#9711;")
69923                 .replace(/#portContainterAddr/g, abbr);
69924         }
69925
69926         tabSelectors.push("#" + appId + "-operations");
69927         portSelectors.push("#" + appId + "-local-port");
69928
69929         option = optionTemplate.replace(/#RemoteApplicationId/g, appId)
69930             .replace(/#CHECKED/g, certificate ? "checked" : "");
69931
69932         html += htmlTemplate.replace(/#RemoteApplicationId/g, appId)
69933             .replace(/#RemoteApplicationName/g, appName)
69934             .replace(/#RemoteApplicationPortHtml/g, portHtml)
69935             .replace(/#RemoteApplicationIsTrusted/g, option)
69936             .replace(/#80AC27/g, !certificate ? "#FF4500" : "#80AC27");
69937     }
69938
69939     jQuery("#messagePort-remote-applications").html(html);
69940
69941     jQuery(tabSelectors.join(",")).tabs();
69942     jQuery(portSelectors.join(",")).change(function () {
69943         var appId = this.id.replace("-local-port", "");
69944
69945         jQuery("#" + appId + "-access").hide();
69946     });
69947 }
69948
69949 function _sendingRemoteMessage() {
69950     var appId, sendSelector = [], clearSelector = [];
69951
69952     for (appId in _db) {
69953         sendSelector.push("#" + appId + "-send");
69954         clearSelector.push("#" + appId + "-clear");
69955     }
69956
69957     jQuery(sendSelector.join(",")).bind("click", function () {
69958         var appId = this.id.replace("-send", ""),
69959             key = jQuery("#" + appId + "-key").val(),
69960             value = jQuery("#" + appId + "-value").val(),
69961             data, remotePort, errorHtml,
69962             messagePortName = jQuery("#" + appId + "-local-port").val(),
69963             certificate = _db[appId].certificate;
69964
69965         if ((key.length === 0) || (value.length === 0))
69966             return;
69967
69968         data = [{
69969             key: key,
69970             value: value
69971         }];
69972         remotePort = {
69973             appId: appId,
69974             messagePortName: messagePortName,
69975             isTrusted: false
69976         };
69977         jQuery("#" + appId + "-key").val("");
69978         jQuery("#" + appId + "-value").val("");
69979
69980         if (!certificate && _messagePortGlobal.localMessagePorts[messagePortName]) {
69981             errorHtml = 'Access Denied: "' + messagePortName + '" is a trusted port ' +
69982                 'and the target application is signed with the different certification ' +
69983                 'from this application.';
69984             jQuery("#" + appId + "-access").html(errorHtml);
69985             jQuery("#" + appId + "-access").show();
69986             return;
69987         }
69988
69989         event.trigger("LocalMessagePortReceived", [data, remotePort, false]);
69990     });
69991
69992     jQuery(clearSelector.join(",")).bind("click", function () {
69993         var appId = this.id.replace("-clear", "");
69994
69995         jQuery("#" + appId + "-key").val("");
69996         jQuery("#" + appId + "-value").val("");
69997     });
69998 }
69999
70000 function _showRequestMessagePort(id, messagePortName, isTrusted, isRemote, appId) {
70001     var htmlTemplate, port, html, remoteKey;
70002
70003     htmlTemplate = '<h3><span style="font-weight: bold;">#isTrustedIcon</span>&nbsp;#messagePortName</h3>';
70004
70005     if (isRemote) {
70006         remoteKey = messagePortName + "&nbsp;(=>" + appId + ")";
70007         html = htmlTemplate.replace("#messagePortName", remoteKey)
70008             .replace("#isTrustedIcon", isTrusted ? "&#9417;" : "&#9711;");
70009     } else {
70010         remoteKey = messagePortName;
70011         html = htmlTemplate.replace("#messagePortName", remoteKey)
70012             .replace("#isTrustedIcon", isTrusted ? "&#9417;" : "&#9711;");
70013     }
70014
70015     if (port === undefined) {
70016         jQuery(id).append(html);
70017
70018         if (!isRemote) {
70019             _messagePortGlobal.localMessagePorts[messagePortName] = isTrusted;
70020             _addLocalMessagePortOptions(remoteKey);
70021         }
70022     }
70023 }
70024
70025 /**
70026  * receive sending message from current application and show content
70027  * @param remoteMessagePort
70028  * @param data
70029  * @param localMessagePort
70030  * @private
70031  */
70032 function _receiveMessage(remoteMessagePort, data, localMessagePort) {
70033     var htmlTemplate, header, footer, html = '', i, appId, messagePortName, selector,
70034         remotePort;
70035
70036     appId = remoteMessagePort.appId;
70037     messagePortName = remoteMessagePort.messagePortName;
70038
70039     selector = "#" + appId + "-receiving ." + messagePortName.replace(/\s+/g, "");
70040
70041     header = '<table class="preferences-table" style="border-bottom: 1px dashed #DCDCDC; width: 100%;">';
70042     htmlTemplate = '<tr><td><label class="ui-text-label">Key:</label></td><td>#Key</td></tr>' +
70043         '<tr><td><label class="ui-text-label">Value:</label></td><td>#Value</td></tr>';
70044     footer = '</table>';
70045
70046     for (i = 0; i < data.length; i++) {
70047         html += header +
70048             htmlTemplate.replace("#Key", data[i].key).replace("#Value", data[i].value) +
70049             footer;
70050     }
70051
70052     jQuery(selector).html(html);
70053
70054     if (!localMessagePort) return;
70055
70056     remotePort = {
70057         appId: appId,
70058         messagePortName: localMessagePort.messagePortName,
70059         isTrusted: localMessagePort.isTrusted
70060     };
70061
70062     event.trigger("LocalMessagePortReceived", [_db[appId]["reply"], remotePort, true]);
70063 }
70064
70065 //show requested local message port
70066 event.on("LocalMessagePortAdded", function (messagePortName, isTrusted) {
70067     _showRequestMessagePort("#current-app-local-port", messagePortName, isTrusted, false);
70068 });
70069
70070 //show requested remote message port
70071 event.on("RemoteMessagePortAdded", function (appId, messagePortName, isTrusted) {
70072     _showRequestMessagePort("#current-app-remote-port", messagePortName, isTrusted, true, appId);
70073 });
70074
70075 //show sending message content
70076 event.on("RemoteMessagePortSent", function (remoteMessagePort, data, localMessagePort) {
70077     _receiveMessage(remoteMessagePort, data, localMessagePort);
70078 });
70079
70080 module.exports = {
70081     panel: {
70082         domId: "messagePort-container",
70083         collapsed: true,
70084         pane: "left",
70085         titleName: "Message Port",
70086         display: true
70087     },
70088     initialize: function () {
70089         _initMessagePortDatabase();
70090         _initializeMessagePortPanel();
70091     }
70092 };
70093
70094 });
70095 define('ripple/ui/plugins/platform', function (require, exports, module) {
70096 /*
70097  *  Copyright 2011 Research In Motion Limited.
70098  *
70099  * Licensed under the Apache License, Version 2.0 (the "License");
70100  * you may not use this file except in compliance with the License.
70101  * You may obtain a copy of the License at
70102  *
70103  * http://www.apache.org/licenses/LICENSE-2.0
70104  *
70105  * Unless required by applicable law or agreed to in writing, software
70106  * distributed under the License is distributed on an "AS IS" BASIS,
70107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70108  * See the License for the specific language governing permissions and
70109  * limitations under the License.
70110  */
70111 var constants = require('ripple/constants'),
70112     utils = require('ripple/utils'),
70113     devices = require('ripple/devices'),
70114     platform = require('ripple/platform'),
70115     db = require('ripple/db');
70116
70117 function _updatePlatformDeviceSelect(platformID, currentDeviceKey) {
70118     var devicesSelect = document.getElementById(constants.COMMON.DEVICE_SELECT_ID),
70119         listOfSortedDevices = devices.getDevicesForPlatform(platformID)
70120                                         .sort(function (a, b) {
70121                                             return (a.screen.width * a.screen.height) < (b.screen.width * b.screen.height) ? -1 : ((a.screen.width * a.screen.height) > (b.screen.width * b.screen.height) ? 1 : 0);
70122                                         });
70123     db.remove("viewport_width");
70124     db.remove("viewport_height");
70125     db.remove("viewportTag");
70126
70127     devicesSelect.innerHTML = "";
70128     listOfSortedDevices.forEach(function (dev) {
70129         var deviceNode = utils.createElement("option", {
70130             "innerText": dev.name,
70131             "value": dev.id
70132         });
70133
70134         if (currentDeviceKey && deviceNode.value === currentDeviceKey) {
70135             deviceNode.selected = true;
70136         }
70137
70138         devicesSelect.appendChild(deviceNode);
70139     });
70140
70141     if (platformID === "ivi") {
70142         jQuery("#configuration-window-save-btn").hide();
70143         jQuery("#configuration-window-load-btn").hide();
70144
70145         jQuery("#item_container :nth-child(2)").hide();
70146         jQuery("#item_container :nth-child(3)").hide();
70147
70148         //jQuery("#hwkeys-panel").hide();
70149     }
70150     else {
70151         jQuery("#configuration-window-save-btn").show();
70152         jQuery("#configuration-window-load-btn").show();
70153
70154         jQuery("#item_container :nth-child(2)").show();
70155         jQuery("#item_container :nth-child(3)").show();
70156
70157         //jQuery("#hwkeys-panel").show();
70158     }
70159 }
70160
70161 function checkResolutionSize(evt) {
70162         var query_str, id_str, len;
70163         query_str = "#resolution-custom-" + evt.data.msg;
70164         id_str = "custom_" + evt.data.msg;
70165         len = jQuery(query_str).val();
70166         if (len >= 200 && len <= 2000) {
70167                 db.save(id_str, len);
70168         } else {
70169                 jQuery(query_str).val(db.retrieve(id_str));
70170         }
70171 }
70172
70173 module.exports = {
70174     initialize: function () {
70175         var currentPlatform = platform.current().id,
70176             currentVersion = platform.current().version,
70177             platformList = platform.getList(),
70178             platformSelect = document.getElementById(constants.COMMON.PLATFORM_SELECT_ID),
70179             versionSelect = document.getElementById("version-select"),
70180             currentDeviceKey = devices.getCurrentDevice().id,
70181             platformNode, versionNode;
70182
70183         jQuery("#platform-select").bind("change", function () {
70184             var newPlatform = jQuery(this).val(),
70185                 newDevice = jQuery("#device-select").val();
70186
70187             jQuery(versionSelect).children("option").remove();
70188             utils.forEach(platformList, function (platform) {
70189                 utils.forEach(platform, function (version, versionNumber) {
70190                     if (newPlatform === version.id) {
70191                         versionSelect.appendChild(utils.createElement("option", {
70192                             "innerText": version.text,
70193                             "value":  versionNumber
70194                         }));
70195                     }
70196                 });
70197             });
70198             _updatePlatformDeviceSelect(newPlatform, newDevice);
70199
70200         });
70201
70202         jQuery("#device-select").bind("focus", function () {
70203             $('input:radio[name="resolution-type"][value="predefined"]').click();
70204         });
70205         jQuery("#resolution-custom-width").bind("focus", function () {
70206             $('input:radio[name="resolution-type"][value="custom"]').click();
70207         });
70208         jQuery("#resolution-custom-height").bind("focus", function () {
70209             $('input:radio[name="resolution-type"][value="custom"]').click();
70210         });
70211         jQuery("#resolution-custom-width").bind("change", {msg: "width"}, checkResolutionSize);
70212         jQuery("#resolution-custom-height").bind("change", {msg: "height"}, checkResolutionSize);
70213
70214         utils.forEach(platformList, function (platform, platformKey) {
70215             platformNode = utils.createElement("option", {
70216                 "innerText": platformKey === "tizen" ? "mobile": platformKey,
70217                 "value":  platformKey
70218             });
70219
70220             utils.forEach(platform, function (version, versionNumber) {
70221                 versionNode = utils.createElement("option", {
70222                     "innerText": version.text,
70223                     "value":  versionNumber
70224                 });
70225
70226                 if (currentPlatform && version.id === currentPlatform) {
70227                     versionSelect.appendChild(versionNode);
70228                     if (currentVersion && currentVersion === versionNumber) {
70229                         platformNode.selected = true;
70230                         versionNode.selected = true;
70231                     }
70232                 }
70233             });
70234             platformSelect.appendChild(platformNode);
70235         });
70236
70237         _updatePlatformDeviceSelect(currentPlatform, currentDeviceKey);
70238     }
70239 };
70240
70241 });
70242 define('ripple/ui/plugins/geoView', function (require, exports, module) {
70243 /*
70244  *  Copyright 2011 Research In Motion Limited.
70245  *
70246  * Licensed under the Apache License, Version 2.0 (the "License");
70247  * you may not use this file except in compliance with the License.
70248  * You may obtain a copy of the License at
70249  *
70250  * http://www.apache.org/licenses/LICENSE-2.0
70251  *
70252  * Unless required by applicable law or agreed to in writing, software
70253  * distributed under the License is distributed on an "AS IS" BASIS,
70254  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70255  * See the License for the specific language governing permissions and
70256  * limitations under the License.
70257  */
70258 var constants = require('ripple/constants'),
70259     geo = require('ripple/geo'),
70260     db = require('ripple/db'),
70261     event = require('ripple/event'),
70262     utils = require('ripple/utils'),
70263     platform = require('ripple/platform'),
70264     markers,
70265     _gpsMapZoomLevel,
70266     _routePoints = [],
70267     _routes = [],
70268     _routeMarkers,
70269     _lineLayer,
70270     _drawLineTimeout,
70271     _playFrequency = 0,
70272     _originalNavigator = window.navigator,
70273     _locationSharing = false;
70274     _playState = {'play': false, 'replay': false};
70275
70276 function _initTimeZone() {
70277     var allTZ, dbTZ, node = jQuery("#time-locale-select"),
70278         timezone = require('ripple/platform/tizen/2.0/timezone_info'),
70279         alarms, time;
70280
70281     function triggerAlarm() {
70282         time = new Date();
70283         alarms = db.retrieveObject("tizen1.0-db-alarms");
70284         if (alarms !== null) {
70285             utils.forEach(alarms, function (obj) {
70286                 if (obj.id !== undefined) {
70287                     event.trigger("CheckAlarm", [obj.id]);
70288                 }
70289             });
70290         }
70291     }
70292     window.setInterval(triggerAlarm, 1000);
70293
70294     allTZ = timezone.getAllTimezone();
70295     utils.forEach(allTZ, function (tz) {
70296         node.append(utils.createElement("option", {
70297             "value": tz,
70298             "innerHTML": tz + " - " + timezone.getTimezoneAbbr(tz) + "(" + timezone.getTimezoneDiff(tz) + ")"
70299         }));
70300     });
70301     dbTZ = db.retrieve("tizen-timezone");
70302     if (timezone.isValidTimezone(dbTZ)) {
70303         node.val(dbTZ);
70304     } else {
70305         db.save("tizen-timezone", node.val());
70306     }
70307     node.bind("change", function () {
70308         db.save("tizen-timezone", node.val());
70309     });
70310 }
70311
70312 function _updateGpsMap() {
70313     var positionInfo = geo.getPositionInfo(),
70314         mapContainer = document.getElementById(constants.GEO.OPTIONS.MAP_CONTAINER);
70315
70316     if (mapContainer && jQuery(mapContainer).is(':visible')) {
70317         geo.map.setCenter(new OpenLayers.LonLat(positionInfo.longitude, positionInfo.latitude).transform(
70318             new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel, true);
70319     }
70320
70321     if (_lineLayer) {
70322         geo.map.removeLayer(_lineLayer);
70323         geo.map.addLayer(_lineLayer);
70324     }
70325 }
70326
70327 function _updateGpsMapZoom(goUp) {
70328     if (goUp && _gpsMapZoomLevel < constants.GEO.MAP_ZOOM_MAX) {
70329         _gpsMapZoomLevel++;
70330     }
70331     else if (!goUp && _gpsMapZoomLevel > constants.GEO.MAP_ZOOM_MIN) {
70332         _gpsMapZoomLevel--;
70333     }
70334
70335     _updateGpsMap();
70336     db.save(constants.GEO.MAP_ZOOM_KEY, _gpsMapZoomLevel);
70337 }
70338
70339 function _getTextHeading(heading) {
70340     if (heading >= 337.5 || (heading >= 0 && heading <= 22.5)) {
70341         return 'N';
70342     }
70343
70344     if (heading >= 22.5 && heading <= 67.5) {
70345         return 'NE';
70346     }
70347
70348     if (heading >= 67.5 && heading <= 112.5) {
70349         return 'E';
70350     }
70351     if (heading >= 112.5 && heading <= 157.5) {
70352         return 'SE';
70353     }
70354
70355     if (heading >= 157.5 && heading <= 202.5) {
70356         return 'S';
70357     }
70358
70359     if (heading >= 202.5 && heading <= 247.5) {
70360         return 'SW';
70361     }
70362
70363     if (heading >= 247.5 && heading <= 292.5) {
70364         return 'W';
70365     }
70366
70367     if (heading >= 292.5 && heading <= 337.5) {
70368         return 'NW';
70369     }
70370 }
70371
70372 function _updateRoutes() {
70373     var i, j, k, lon_step, lat_step;
70374     _routes = [];
70375
70376     for (i = 0; i < _routePoints.length - 1; i++) {
70377         lon_step = (_routePoints[i + 1].lonlat.lon - _routePoints[i].lonlat.lon) / 50;
70378         lat_step = (_routePoints[i + 1].lonlat.lat - _routePoints[i].lonlat.lat) / 50;
70379
70380         _routes.push(new OpenLayers.LonLat(_routePoints[i].lonlat.lon, _routePoints[i].lonlat.lat));
70381         for (j = 1, k = _routes.length; j < 50; j++, k++) {
70382             _routes.push(new OpenLayers.LonLat(_routes[k - 1].lon + lon_step, _routes[k - 1].lat + lat_step));
70383         }
70384     }
70385     _routes.push(new OpenLayers.LonLat(
70386         _routePoints[_routePoints.length - 1].lonlat.lon,
70387         _routePoints[_routePoints.length - 1].lonlat.lat)
70388     );
70389 }
70390
70391 function _drawLine(array) {
70392     var GEO_OPTIONS = constants.GEO.OPTIONS,
70393         latitude = document.getElementById(GEO_OPTIONS.LATITUDE),
70394         longitude = document.getElementById(GEO_OPTIONS.LONGITUDE),
70395         lonlat = new OpenLayers.LonLat(array[0].lon, array[0].lat).transform(
70396             new OpenLayers.Projection("EPSG:900913"),
70397             new OpenLayers.Projection("EPSG:4326")
70398         ),
70399         points = new Array(
70400             new OpenLayers.Geometry.Point(array[0].lon, array[0].lat),
70401             new OpenLayers.Geometry.Point(array[1].lon, array[1].lat)
70402         ),
70403         line = new OpenLayers.Geometry.LineString(points),
70404         style = {
70405             strokeColor: '#0000ff',
70406             strokeOpacity: 1,
70407             strokeWidth: 3
70408         },
70409         lineFeature = new OpenLayers.Feature.Vector(line, null, style);
70410
70411     if (!_lineLayer) {
70412         _lineLayer = new OpenLayers.Layer.Vector("Line Layer");
70413         geo.map.addLayer(_lineLayer);
70414     }
70415
70416     _lineLayer.addFeatures([lineFeature]);
70417     longitude.value = lonlat.lon;
70418     latitude.value = lonlat.lat;
70419
70420     if (_playFrequency % 10 === 0) {
70421         geo.map.panTo(new OpenLayers.LonLat(array[0].lon, array[0].lat), _gpsMapZoomLevel);
70422     }
70423     _playFrequency++;
70424 }
70425
70426 function clearRoute() {
70427     if (!_playState.play) {
70428         _routePoints.forEach(function (item) {
70429             _routeMarkers.removeMarker(item.marker);
70430         });
70431         _routePoints = [];
70432         _routes = [];
70433         _lineLayer.removeFeatures(_lineLayer.features);
70434     }
70435 }
70436
70437 function setRoute() {
70438     var clickHandler = new OpenLayers.Handler.Click(
70439         this,
70440         {
70441             click: function (e) {
70442                 if (geo.map.calculateBounds(null, 1) === null) {
70443                     geo.map.zoomTo(geo.map.zoom);
70444                 }
70445                 var location = geo.map.getLonLatFromViewPortPx(e.xy),
70446                     size = new OpenLayers.Size(21, 25),
70447                     offset = new OpenLayers.Pixel(-(size.w / 2), -size.h),
70448                     icon = new OpenLayers.Icon('images/map_marker.png', size, offset),
70449                     marker = new OpenLayers.Marker(new OpenLayers.LonLat(location.lon, location.lat), icon);
70450
70451                 geo.map.addLayer(_routeMarkers);
70452                 _routeMarkers.addMarker(marker);
70453                 _routePoints.push({
70454                     lonlat : location,
70455                     marker : marker
70456                 });
70457             }
70458         },
70459         {double: true}
70460     );
70461     clickHandler.dblclick = function () {
70462         _updateRoutes();
70463         this.deactivate();
70464     };
70465
70466     if (!_playState.play) {
70467         clickHandler.setMap(geo.map);
70468         clickHandler.activate();
70469     }
70470 }
70471
70472 function playRoute() {
70473     var speed = document.getElementById("play-route-speed"),
70474         getPlaySpeed = function () {
70475             return 20 / speed.value * 1000 / 50;
70476         },
70477         draw = function () {
70478             if (_routes.length <= 1) {
70479                 window.clearTimeout(_drawLineTimeout);
70480                 geo.map.panTo(new OpenLayers.LonLat(
70481                     _routePoints[_routePoints.length - 1].lonlat.lon,
70482                     _routePoints[_routePoints.length - 1].lonlat.lat),
70483                     _gpsMapZoomLevel);
70484                 _playState.play = false;
70485                 _playState.replay = true;
70486                 document.getElementById('play-btn-icon').src = "images/play.png";
70487             } else {
70488                 _drawLine(_routes);
70489                 _routes.splice(0, 1);
70490                 _drawLineTimeout = window.setTimeout(draw, getPlaySpeed());
70491             }
70492         };
70493
70494     if (!_playState.play && _routes.length !== 0) {
70495         if (_lineLayer && _playState.replay) {
70496             _lineLayer.removeFeatures(_lineLayer.features);
70497             _updateRoutes();
70498         }
70499         draw();
70500         _playState.play = true;
70501         document.getElementById('play-btn-icon').src = "images/pause.png";
70502     } else if (_playState.play) {
70503         window.clearTimeout(_drawLineTimeout);
70504         _playState.play = false;
70505         _playState.replay = false;
70506         document.getElementById('play-btn-icon').src = "images/play.png";
70507     }
70508 }
70509
70510 function skipTo(position) {
70511     if (_routes.length !== 0) {
70512         var index = (position === 'start' ? 0 : _routePoints.length - 1);
70513         window.clearTimeout(_drawLineTimeout);
70514         _lineLayer.removeFeatures(_lineLayer.features);
70515         geo.map.panTo(new OpenLayers.LonLat(_routePoints[index].lonlat.lon, _routePoints[index].lonlat.lat), _gpsMapZoomLevel);
70516         _routes = [];
70517         _updateRoutes();
70518         _playFrequency = 0;
70519         _playState.play = false;
70520         _playState.replay = false;
70521         document.getElementById('play-btn-icon').src = "images/play.png";
70522     }
70523 }
70524
70525 module.exports = {
70526     panel: {
70527         domId: "gps-container",
70528         collapsed: true,
70529         pane: "left",
70530         titleName: "Geolocation",
70531         display: true
70532     },
70533     initialize: function () {
70534         var GEO_OPTIONS = constants.GEO.OPTIONS,
70535             positionInfo = geo.getPositionInfo(),
70536             positionEvent = "PositionInfoUpdatedEvent",
70537             latitude = document.getElementById(GEO_OPTIONS.LATITUDE),
70538             longitude = document.getElementById(GEO_OPTIONS.LONGITUDE),
70539             altitude = document.getElementById(GEO_OPTIONS.ALTITUDE),
70540             accuracy = document.getElementById(GEO_OPTIONS.ACCURACY),
70541             altitudeAccuracy = document.getElementById(GEO_OPTIONS.ALTITUDE_ACCURACY),
70542             heading = document.getElementById(GEO_OPTIONS.HEADING),
70543             speed = document.getElementById(GEO_OPTIONS.SPEED),
70544             cellID = document.getElementById(GEO_OPTIONS.CELL_ID),
70545             delay = document.getElementById(GEO_OPTIONS.DELAY),
70546             delayLabel = document.getElementById(GEO_OPTIONS.DELAY_LABEL),
70547             headingLabel = document.getElementById(GEO_OPTIONS.HEADING_LABEL),
70548             headingMapLabel = document.getElementById(GEO_OPTIONS.HEADING_MAP_LABEL),
70549             timeout = document.getElementById(GEO_OPTIONS.TIMEOUT),
70550             gpxMultiplier = document.getElementById(GEO_OPTIONS.GPXMULTIPLIER),
70551             gpxReplayStatus = document.getElementById(GEO_OPTIONS.GPXREPLAYSTATUS),
70552             gpxGo = $(document.getElementById(GEO_OPTIONS.GPXGO)).find("span")[0],
70553             mapContainer = document.getElementById(GEO_OPTIONS.MAP_CONTAINER),
70554             map = null,
70555             track = [],
70556             _replayingGpxFile = false,
70557             _haltGpxReplay = false;
70558
70559         function updateGeo() {
70560             if (parseFloat(latitude.value) > 90)
70561                 latitude.value = 90;
70562             else if (parseFloat(latitude.value) < -90)
70563                 latitude.value = -90;
70564
70565             if (parseFloat(longitude.value) > 180)
70566                 longitude.value = 180;
70567             else if (parseFloat(longitude.value) < -180)
70568                 longitude.value = -180;
70569
70570             geo.updatePositionInfo({
70571                 latitude: parseFloat(latitude.value),
70572                 longitude: parseFloat(longitude.value),
70573                 altitude: parseInt(altitude.value, 10),
70574                 accuracy: parseInt(accuracy.value, 10),
70575                 altitudeAccuracy: parseInt(altitudeAccuracy.value, 10),
70576                 heading: heading.value ? parseFloat(heading.value) : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
70577                 speed: speed.value ? parseInt(speed.value, 10) : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
70578                 cellID: cellID.value,
70579                 timeStamp: new Date()
70580             },
70581             delay.value,
70582             timeout.checked);
70583         }
70584
70585         function updateHeadingValues() {
70586             var headingDeg = parseFloat(heading.value),
70587                 headingText = _getTextHeading(parseFloat(heading.value));
70588
70589             headingLabel.innerText = headingText;
70590             headingMapLabel.innerHTML = headingText + "</br>" + headingDeg + "&deg;";
70591         }
70592
70593         function updateValsFromMap() {
70594             var center = geo.map.getCenter().transform(
70595                 new OpenLayers.Projection("EPSG:900913"),
70596                 new OpenLayers.Projection("EPSG:4326"));
70597             longitude.value = center.lon;
70598             latitude.value = center.lat;
70599             updateGeo();
70600         }
70601
70602         function initializeValues() {
70603             latitude.value =          positionInfo.latitude;
70604             longitude.value =         positionInfo.longitude;
70605             altitude.value =          positionInfo.altitude;
70606             accuracy.value =          positionInfo.accuracy;
70607             altitudeAccuracy.value =  positionInfo.altitudeAccuracy;
70608             cellID.value =            positionInfo.cellID;
70609             delay.value = document.getElementById(GEO_OPTIONS.DELAY_LABEL).innerText = geo.delay || 0;
70610             if (geo.timeout) {
70611                 timeout.checked = true;
70612             }
70613             updateHeadingValues();
70614         }
70615
70616         function initMap() {
70617             var marker, clickHandler;
70618             // override image location so we don't have to include image assets
70619             OpenLayers.ImgPath = 'http://openlayers.org/api/img/';
70620
70621             // init map
70622             geo.map = new OpenLayers.Map(mapContainer, { controls: [] });
70623
70624             // add controls and OSM map layer
70625             geo.map.addLayer(new OpenLayers.Layer.OSM());
70626             geo.map.addControl(new OpenLayers.Control.Navigation());
70627
70628             // override behaviour of click to pan and double click to zoom in
70629             clickHandler = new OpenLayers.Handler.Click(
70630                 this,
70631                 {
70632                     click: function (e) {
70633                         if (geo.map.calculateBounds(null, 1) === null) {
70634                             geo.map.zoomTo(geo.map.zoom);
70635                         }
70636                         var location = geo.map.getLonLatFromViewPortPx(e.xy);
70637                         geo.map.panTo(new OpenLayers.LonLat(location.lon, location.lat), _gpsMapZoomLevel);
70638                     },
70639
70640                     dblclick: function () {
70641                         _updateGpsMapZoom(true);
70642                     }
70643                 },
70644                 {double: true}
70645             );
70646
70647             // add click handler to map
70648             clickHandler.setMap(geo.map);
70649             clickHandler.activate();
70650
70651             // update long and lat when map is panned
70652             geo.map.events.register("moveend", map, function () {
70653                 updateValsFromMap();
70654             });
70655             geo.map.events.register("zoomend", map, function (obj) {
70656                 if ((obj.object.zoom > _gpsMapZoomLevel && _gpsMapZoomLevel < constants.GEO.MAP_ZOOM_MAX) ||
70657                     (obj.object.zoom < _gpsMapZoomLevel && _gpsMapZoomLevel > constants.GEO.MAP_ZOOM_MIN)) {
70658                     _gpsMapZoomLevel = obj.object.zoom;
70659                 }
70660             });
70661
70662             markers = new OpenLayers.Layer.Markers("markers");
70663             _routeMarkers = new OpenLayers.Layer.Markers("markers");
70664             geo.map.addLayer(markers);
70665
70666             event.on("ApplicationState", function (obj) {
70667                 if (obj && obj[0].id === 'gps-container' && obj.hasClass('ui-box-open')) {
70668                     _updateGpsMap();
70669
70670                     // Update the position if user accept location sharing
70671                     if (_locationSharing === false) {
70672                         _originalNavigator.geolocation.getCurrentPosition(function(geoPosition) {
70673                             geo.map.panTo(new OpenLayers.LonLat(geoPosition.coords.longitude, geoPosition.coords.latitude).transform(
70674                                 new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel);
70675                             _locationSharing = true;
70676                         });
70677                     }
70678
70679                     // Simulator is loaded with geo panel folded, now it's the first time it's unfolded
70680                     if (!marker) {
70681                         // Only when the geo panel is unfolded, getCenter() will go well
70682                         marker = new OpenLayers.Marker(geo.map.getCenter(),
70683                             new OpenLayers.Icon("images/arrow.png", new OpenLayers.Size(22, 30), new OpenLayers.Pixel(-11, -15)));
70684                         markers.addMarker(marker);
70685
70686                         navigator.geolocation.getCurrentPosition(function (geoPosition) {
70687                             geo.map.panTo(new OpenLayers.LonLat(geoPosition.coords.longitude, geoPosition.coords.latitude).transform(
70688                                 new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel);
70689                         });
70690                     }
70691                 }
70692             });
70693             _updateGpsMap();
70694
70695             // Simulator is loaded with geo panel unfolded
70696             if (mapContainer && jQuery(mapContainer).is(':visible')) {
70697                 marker = new OpenLayers.Marker(geo.map.getCenter(),
70698                     new OpenLayers.Icon("images/arrow.png", new OpenLayers.Size(22, 30), new OpenLayers.Pixel(-11, -15)));
70699                 markers.addMarker(marker);
70700
70701                 navigator.geolocation.getCurrentPosition(function (geoPosition) {
70702                     geo.map.panTo(new OpenLayers.LonLat(geoPosition.coords.longitude, geoPosition.coords.latitude).transform(
70703                         new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")), _gpsMapZoomLevel);
70704                     _locationSharing = true;
70705                 });
70706             }
70707
70708             geo.map.events.register("move", map, function () {
70709                 markers.clearMarkers();
70710                 marker = new OpenLayers.Marker(geo.map.getCenter(),
70711                         new OpenLayers.Icon("images/arrow.png", new OpenLayers.Size(22, 30), new OpenLayers.Pixel(-11, -15)));
70712                 markers.addMarker(marker);
70713             });
70714         }
70715
70716         function loadGpxFile(win, fail, args) {
70717             var reader = new FileReader(),
70718                 file = args[0],
70719                 _xml,
70720                 t,
70721                 att,
70722                 lastAtt,
70723                 _ele,
70724                 _timestamp,
70725                 _lastTimestamp,
70726                 _useTimestamp = new Date().getTime(),
70727                 _tempTimestamp,
70728                 _tempPosition,
70729                 _lastPosition,
70730                 _useLastTimestamp,
70731                 _heading = 0,
70732                 _speed = 0,
70733                 _dist = 0,
70734                 navUtils = new utils.navHelper();
70735
70736             reader.onload = function (e) {
70737                 _xml = e.target.result;
70738                 t = $(_xml).find('trkpt');
70739
70740                 track = [];
70741
70742                 utils.forEach(t, function (p, i) {
70743                     if (!isNaN(i)) {
70744                         att = t[i].attributes;
70745                         lastAtt = t[i - 1] ? t[i - 1].attributes : {};
70746                         _ele = $(t[i]).find("ele")[0];
70747                         _timestamp = $(t[i]).find("time")[0];
70748                         _lastTimestamp = $(t[i - 1]).find("time")[0];
70749
70750                         if (_timestamp) {
70751                             //files recorded with endomondo and others have timestamps, this is not a route plan but a record of a track
70752                             _useTimestamp = new Date(_timestamp.innerText).getTime();
70753                         }
70754
70755                         if (t[i - 1]) {
70756                             _dist = navUtils.getDistance(att["lat"].value, att["lon"].value, lastAtt["lat"].value, lastAtt["lon"].value);
70757
70758                             if (_lastTimestamp) {
70759                                 _useLastTimestamp = new Date(_lastTimestamp.innerText).getTime();
70760                             }
70761                             else {
70762                                 //routes from YOURS come in as tracks (rather than routes under the GPX schema), but with no timestamps.  This is a route.
70763                                 _useLastTimestamp = _useTimestamp;
70764                                 _useTimestamp += Math.round(_dist / 22.2222 * 1000);  //80km/h in m/s
70765                             }
70766
70767                             _heading = navUtils.getHeading(lastAtt["lat"].value, lastAtt["lon"].value, att["lat"].value, att["lon"].value);
70768                             _speed = (_dist / ((_useTimestamp - _useLastTimestamp) / 1000)).toFixed(2);
70769
70770                             if (!_lastTimestamp) {
70771                                 //on YOURS routes, make sure we have at least one update a second
70772                                 _tempTimestamp = _useLastTimestamp;
70773
70774                                 while (_useTimestamp - _tempTimestamp > 1000) {
70775                                     _tempTimestamp += 1000;
70776                                     _lastPosition = track[track.length - 1].coords;
70777                                     _tempPosition = navUtils.simulateTravel(_lastPosition.latitude, _lastPosition.longitude, _heading, _speed);
70778                                     track.push({
70779                                         coords: {
70780                                             latitude: _tempPosition.latitude,
70781                                             longitude: _tempPosition.longitude,
70782                                             altitude: _ele ? _ele.innerText : 0,
70783                                             accuracy: 150,
70784                                             altitudeAccuracy: 80,
70785                                             heading: _heading,
70786                                             speed: _speed
70787                                         },
70788                                         timestamp: _tempTimestamp
70789                                     });
70790                                 }
70791                             }
70792                         }
70793
70794                         track.push({
70795                             coords: {
70796                                 latitude: att["lat"].value,
70797                                 longitude: att["lon"].value,
70798                                 altitude: _ele ? _ele.innerText : 0,
70799                                 accuracy: 150,
70800                                 altitudeAccuracy: 80,
70801                                 heading: _heading,
70802                                 speed: _speed
70803                             },
70804                             timestamp: _useTimestamp
70805                         });
70806                     }
70807                 });
70808             };
70809             reader.onerror = function (e) {
70810                 fail(e);
70811             };
70812             reader.readAsText(file.target.files[0], "UTF-8");
70813         }
70814
70815         function replayGpxTrack() {
70816             if (_replayingGpxFile) {
70817                 _haltGpxReplay = true;
70818                 gpxGo.innerText = constants.GEO.GPXGO_LABELS.GO;
70819             }
70820             else {
70821                 if (track.length > 0) {
70822                     _haltGpxReplay = false;
70823                     gpxGo.innerText = constants.GEO.GPXGO_LABELS.STOP;
70824
70825                     latitude.value = track[0].coords.latitude;
70826                     longitude.value = track[0].coords.longitude;
70827                     altitude.value = track[0].coords.altitude;
70828                     accuracy.value = track[0].coords.accuracy;
70829                     altitudeAccuracy.value = track[0].coords.altitudeAccuracy;
70830                     heading.value = track[0].coords.heading;
70831                     speed.value = track[0].coords.speed;
70832
70833                     updateGeo();
70834                     updateHeadingValues();
70835                     _triggerEvent();
70836
70837                     moveNextGpxTrack(1);
70838                 }
70839             }
70840         }
70841
70842         function moveNextGpxTrack(i)
70843         {
70844             if (_haltGpxReplay) {
70845                 _replayingGpxFile = false;
70846                 _haltGpxReplay = false;
70847                 console.log("Ripple :: User interrupted replay of GPX file (Aye Captain, answers All Stop.)");
70848             }
70849             else {
70850                 _replayingGpxFile = true;
70851                 var _timeMultiplier = !isNaN(gpxMultiplier.value) ? gpxMultiplier.value : 1,
70852                 _step = 0,
70853                 _interval = 0;
70854
70855                 while (_interval < 250) {
70856                     _step++;
70857                     if ((i + _step) >= track.length) { break; }
70858                     _interval = (track[i + _step].timestamp - track[i].timestamp) / _timeMultiplier;
70859                 }
70860
70861                 gpxReplayStatus.textContent = (_interval / 1000).toFixed(2) + "s (" + (_interval / 1000 * _timeMultiplier).toFixed(2) + "s realtime), " + (i + 1) + " of " + track.length + " (stepping " + _step + " at " + _timeMultiplier + "x)";
70862
70863                 setTimeout(function () {
70864                     latitude.value = track[i].coords.latitude;
70865                     longitude.value = track[i].coords.longitude;
70866                     altitude.value = track[i].coords.altitude;
70867                     accuracy.value = track[i].coords.accuracy;
70868                     altitudeAccuracy.value = track[i].coords.altitudeAccuracy;
70869                     heading.value = track[i].coords.heading;
70870                     speed.value = track[i].coords.speed;
70871
70872                     updateGeo();
70873                     updateHeadingValues();
70874                     _triggerEvent();
70875
70876                     if (track[i + _step]) {
70877                         moveNextGpxTrack(i + _step);
70878                     }
70879                     else {
70880                         if (i < track.length - 1) {
70881                             moveNextGpxTrack(track.length - 1);
70882                         }
70883                         else {
70884                             _replayingGpxFile = false;
70885                             gpxGo.innerText = constants.GEO.GPXGO_LABELS.GO;
70886                             console.log("Ripple :: Finished replaying GPX file (Arriving at our destination, assuming standard orbit Captain.)");
70887                         }
70888                     }
70889                 }, _interval);
70890             }
70891         }
70892
70893         // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847 (double HACK!!!)
70894         if (platform.current().id === 'phonegap' ||
70895             platform.current().id === 'webworks' ||
70896             platform.current().id === 'cordova') {
70897             // make the fields visible
70898             jQuery("#geo-cellid-container").hide();
70899             jQuery("#geo-heading-container").show();
70900             jQuery("#geo-speed-container").show();
70901         }
70902         else {
70903             jQuery("#geo-cellid-container").show();
70904             jQuery("#geo-heading-container").hide();
70905             jQuery("#geo-speed-container").hide();
70906         }
70907
70908         _gpsMapZoomLevel = db.retrieve(constants.GEO.MAP_ZOOM_KEY) || 14;
70909
70910         jQuery("#geo-map-zoom-decrease").bind("click", function () {
70911             _updateGpsMapZoom(false);
70912         });
70913
70914         jQuery("#geo-map-zoom-increase").bind("click", function () {
70915             _updateGpsMapZoom(true);
70916         });
70917
70918         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.LATITUDE), updateGeo);
70919         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.LONGITUDE), updateGeo);
70920         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ALTITUDE), updateGeo);
70921         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ACCURACY), updateGeo);
70922         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.ALTITUDE_ACCURACY), updateGeo);
70923         utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.CELL_ID), updateGeo);
70924
70925         jQuery("#play-route-speed-label").html(jQuery("#play-route-speed").val() + 'x');
70926         jQuery("#play-route-speed").bind("change", function () {
70927             jQuery("#play-route-speed-label").html(jQuery("#play-route-speed").val() + 'x');
70928         });
70929         jQuery("#clear-route-btn").bind("click", function () {
70930             clearRoute();
70931         });
70932         jQuery("#set-route-btn").bind("click", function () {
70933             setRoute();
70934         });
70935         jQuery("#play-route-btn").bind("click", function () {
70936             playRoute();
70937         });
70938         jQuery("#back-route-btn").bind("click", function () {
70939             skipTo("start");
70940         });
70941         jQuery("#forward-route-btn").bind("click", function () {
70942             skipTo("end");
70943         });
70944
70945         jQuery("#" + GEO_OPTIONS.DELAY).bind("change", function () {
70946             updateGeo();
70947             delayLabel.innerText = delay.value;
70948         });
70949         jQuery("#" + GEO_OPTIONS.TIMEOUT).bind("click", function () {
70950             updateGeo();
70951         });
70952         jQuery("#" + GEO_OPTIONS.GPXFILE).bind("change", function (a) {
70953             loadGpxFile(null, null, [a]);
70954         });
70955         jQuery("#" + GEO_OPTIONS.GPXGO).bind("click", function () {
70956             replayGpxTrack();
70957         });
70958
70959         // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847 (double HACK!!!)
70960         if (platform.current().id === 'phonegap' || platform.current().id === 'webworks' || platform.current().id === 'cordova') {
70961             jQuery("#" + GEO_OPTIONS.HEADING).bind("change", function () {
70962                 updateGeo();
70963                 updateHeadingValues();
70964             });
70965
70966             utils.bindAutoSaveEvent(jQuery("#" + GEO_OPTIONS.SPEED), updateGeo);
70967             heading.value =       positionInfo.heading;
70968             speed.value =         positionInfo.speed;
70969         }
70970
70971         initMap();
70972         if (navigator.onLine === false) {
70973             jQuery("#disable_geo_panel").show();
70974         }
70975         jQuery(window).bind("online", function () {
70976             jQuery("#disable_geo_panel").hide();
70977             console.log("ONLINE");
70978         });
70979         jQuery(window).bind("offline", function () {
70980             jQuery("#disable_geo_panel").show();
70981             console.log("OFFLINE");
70982         });
70983
70984         initializeValues();
70985         _initTimeZone();
70986
70987         event.on(positionEvent, function () {
70988             _updateGpsMap();
70989         });
70990
70991         _triggerEvent();
70992
70993         function _triggerEvent() {
70994             event.trigger(positionEvent, [{
70995                 latitude: latitude.value,
70996                 longitude: longitude.value,
70997                 altitude: altitude.value,
70998                 accuracy: accuracy.value,
70999                 altitudeAccuracy: altitudeAccuracy.value,
71000                 heading: heading ? heading.value : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
71001                 speed: speed ? speed.value : 0, // HACK: see techdebt http://www.pivotaltracker.com/story/show/5478847
71002                 cellID: cellID.value,
71003                 timeStamp: new Date()
71004             }]);
71005         }
71006     }
71007 };
71008
71009 });
71010 define('ripple/ui/plugins/goodVibrations', function (require, exports, module) {
71011 /*
71012  *  Copyright 2011 Research In Motion Limited.
71013  *
71014  * Licensed under the Apache License, Version 2.0 (the "License");
71015  * you may not use this file except in compliance with the License.
71016  * You may obtain a copy of the License at
71017  *
71018  * http://www.apache.org/licenses/LICENSE-2.0
71019  *
71020  * Unless required by applicable law or agreed to in writing, software
71021  * distributed under the License is distributed on an "AS IS" BASIS,
71022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71023  * See the License for the specific language governing permissions and
71024  * limitations under the License.
71025  */
71026 var constants = require('ripple/constants');
71027
71028 module.exports = {
71029     vibrateDevice: function (milliseconds) {
71030         var node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
71031             x, times;
71032
71033         times = Math.floor(milliseconds / 100);
71034
71035         for (x = 1; x <= times; x++) {
71036             node.animate({ left: -10 }, 5)
71037             .animate({ left: 0 }, 1)
71038             .animate({ left: 10 }, 5)
71039             .animate({ left: 0 }, 1);
71040
71041             node.animate({ top: -10 }, 5)
71042             .animate({ top: 0 }, 1)
71043             .animate({ top: 10 }, 5)
71044             .animate({ top: 0 }, 1);
71045         }
71046     },
71047     shakeDevice: function (times) {
71048         var node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
71049             x;
71050
71051         for (x = 1; x <= times; x++) {
71052             node.animate({ left: -25 }, 50)
71053             .animate({ left: 0 }, 30)
71054             .animate({ left: 25 }, 50)
71055             .animate({ left: 0 }, 30);
71056         }
71057     }
71058 };
71059
71060 });
71061 define('ripple/ui/plugins/time', function (require, exports, module) {
71062 /*
71063  *  Copyright 2012 Intel Corporation.
71064  *
71065  * Licensed under the Apache License, Version 2.0 (the "License");
71066  * you may not use this file except in compliance with the License.
71067  * You may obtain a copy of the License at
71068  *
71069  * http://www.apache.org/licenses/LICENSE-2.0
71070  *
71071  * Unless required by applicable law or agreed to in writing, software
71072  * distributed under the License is distributed on an "AS IS" BASIS,
71073  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71074  * See the License for the specific language governing permissions and
71075  * limitations under the License.
71076  */
71077
71078 function _init() {
71079     var db = require('ripple/db'),
71080         utils = require('ripple/utils'),
71081         allTZ, dbTZ, node = jQuery("#time-locale-select"),
71082         timezone = require('ripple/platform/tizen/2.0/timezone_info'),
71083         event = require('ripple/event'),
71084         alarms, time;
71085
71086     function triggerAlarm() {
71087         time = new Date();
71088         alarms = db.retrieveObject("tizen1.0-db-alarms");
71089         if (alarms !== null) {
71090             utils.forEach(alarms, function (obj) {
71091                 if (obj.id !== undefined) {
71092                     event.trigger("CheckAlarm", [obj.id]);
71093                 }
71094             });
71095         }
71096     }
71097     window.setInterval(triggerAlarm, 1000);
71098
71099     allTZ = timezone.getAllTimezone();
71100     utils.forEach(allTZ, function (tz) {
71101         node.append(utils.createElement("option", {
71102             "value": tz,
71103             "innerHTML": tz + " - " + timezone.getTimezoneAbbr(tz) + "(" + timezone.getTimezoneDiff(tz) + ")"
71104         }));
71105     });
71106     dbTZ = db.retrieve("tizen-timezone");
71107     if (timezone.isValidTimezone(dbTZ)) {
71108         node.val(dbTZ);
71109     } else {
71110         db.save("tizen-timezone", node.val());
71111     }
71112     node.bind("change", function () {
71113         db.save("tizen-timezone", node.val());
71114     });
71115 /* FIXME: Node "trigger-alarm-id" will be removed from Time panel
71116  *        due to "time" panel will changed to "time zone" panel(PTSDK-875)
71117
71118     event.on("SendTriggerAppId", function (applicationId) {
71119         if (timeId !== undefined)
71120             clearTimeout(timeId);
71121         triggerNode.empty();
71122         triggerNode.append(utils.createElement("p", {
71123             "innerHTML": applicationId + " is triggered"
71124         }));
71125         triggerNode.show();
71126         timeId = setTimeout("jQuery('#trigger-alarm-id').empty();", 10000);// Comments will disappear after 10s
71127     });
71128 */
71129 }
71130
71131 module.exports = {
71132     panel: {
71133         domId: "time-container",
71134         collapsed: true,
71135         pane: "right",
71136         titleName: "Time",
71137         display: true
71138     },
71139     initialize: _init
71140 };
71141
71142 });
71143 define('ripple/ui/plugins/multimedia', function (require, exports, module) {
71144 /*
71145  *  Copyright 2011 Research In Motion Limited.
71146  *
71147  * Licensed under the Apache License, Version 2.0 (the "License");
71148  * you may not use this file except in compliance with the License.
71149  * You may obtain a copy of the License at
71150  *
71151  * http://www.apache.org/licenses/LICENSE-2.0
71152  *
71153  * Unless required by applicable law or agreed to in writing, software
71154  * distributed under the License is distributed on an "AS IS" BASIS,
71155  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71156  * See the License for the specific language governing permissions and
71157  * limitations under the License.
71158  */
71159 var constants = require('ripple/constants'),
71160     event = require('ripple/event'),
71161     volumeField = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_FIELD_ID),
71162     volume = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_SLIDER_ID);
71163
71164 module.exports = {
71165     panel: {
71166         domId: "multimedia-container",
71167         collapsed: true,
71168         pane: "left"
71169     },
71170     initialize: function () {
71171         var volumeField = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_FIELD_ID),
71172             volume = document.getElementById(constants.COMMON.MULTIMEDIA_VOLUME_SLIDER_ID);
71173
71174         event.on("MultimediaVolumeChanged", function (volume) {
71175             volumeField.innerText = volume > 9 ? volume : "0" + volume;
71176             if (volume.value !== volume) {
71177                 volume.value = volume;
71178             }
71179         });
71180
71181         volume.addEventListener('change', function () {
71182             event.trigger("MultimediaVolumeChanged", [this.value], true);
71183         }, false);
71184
71185         event.on("MultimediaAudioStateChanged", function updateIsAudioPlaying(state) {
71186             document.getElementById(constants.COMMON.MULTIMEDIA_AUDIO_PLAYING_FIELD_ID).innerHTML = state === constants.MULTIMEDIA.AUDIO_STATES.PLAYING;
71187         });
71188     }
71189 };
71190
71191 });
71192 define('ripple/ui/plugins/exec-dialog', function (require, exports, module) {
71193 /*
71194  *  Copyright 2011 Research In Motion Limited.
71195  *
71196  * Licensed under the Apache License, Version 2.0 (the "License");
71197  * you may not use this file except in compliance with the License.
71198  * You may obtain a copy of the License at
71199  *
71200  * http://www.apache.org/licenses/LICENSE-2.0
71201  *
71202  * Unless required by applicable law or agreed to in writing, software
71203  * distributed under the License is distributed on an "AS IS" BASIS,
71204  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71205  * See the License for the specific language governing permissions and
71206  * limitations under the License.
71207  */
71208
71209 function exec(func) {
71210     return function () {
71211         var val = $("#exec-response").val();
71212
71213         //TODO: handle multiple args
71214         func.apply(null, val ? [JSON.parse(val)] : []);
71215         $("#exec-dialog").dialog("close");
71216     };
71217 }
71218
71219 module.exports = {
71220     initialize: function () {
71221         $("#exec-dialog").dialog({
71222             autoOpen: false,
71223             modal: true,
71224             title: "I Haz Cheeseburger?!?!",
71225             width: 500,
71226             position: 'center'
71227         }).hide();
71228
71229         $("#exec-success").button();
71230         $("#exec-fail").button();
71231     },
71232
71233     show: function (service, action, success, fail) {
71234         console.log(service);
71235         console.log(action);
71236         $("#exec-service").text(service);
71237         $("#exec-action").text(action);
71238         $("#exec-dialog").dialog("open");
71239         $("#exec-success").unbind().bind('click', exec(success));
71240         $("#exec-fail").unbind().bind('click', exec(fail));
71241     }
71242 };
71243
71244 });
71245 define('ripple/ui/plugins/camera', function (require, exports, module) {
71246 /*
71247  *  Copyright 2011 Research In Motion Limited.
71248  *
71249  * Licensed under the Apache License, Version 2.0 (the "License");
71250  * you may not use this file except in compliance with the License.
71251  * You may obtain a copy of the License at
71252  *
71253  * http://www.apache.org/licenses/LICENSE-2.0
71254  *
71255  * Unless required by applicable law or agreed to in writing, software
71256  * distributed under the License is distributed on an "AS IS" BASIS,
71257  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71258  * See the License for the specific language governing permissions and
71259  * limitations under the License.
71260  */
71261
71262 var ui = require('ripple/ui'),
71263     event = require('ripple/event'),
71264     video = document.getElementById('camera-video'),
71265     upload = document.getElementById('picture-upload'),
71266     select = document.getElementById('select-file'),
71267     take = document.getElementById('take-file'),
71268     pic = document.getElementById("camera-image");
71269
71270
71271 select.addEventListener('click', function () {
71272     upload.click();
71273 });
71274
71275 upload.addEventListener('change', function () {
71276     pic.src = window.webkitURL.createObjectURL(upload.files[0]);
71277     take.style.display = "inline";
71278 });
71279
71280 take.addEventListener('click', function () {
71281     console.log("captured-image: " + pic.src);
71282     event.trigger('captured-image', [pic.src, upload.files[0]]);
71283     module.exports.hide();
71284 });
71285
71286 module.exports = {
71287     show: function () {
71288         ui.showOverlay("camera-window");
71289         if (pic.src) {
71290             take.style.display = "inline";
71291         }
71292         else {
71293             take.style.display = "none";
71294         }
71295     },
71296     hide: function () {
71297         ui.hideOverlay("camera-window");
71298     }
71299 };
71300
71301 });
71302 define('ripple/ui/plugins/network', function (require, exports, module) {
71303 /*
71304  *  Copyright 2012 Intel Corporation
71305  *
71306  * Licensed under the Apache License, Version 2.0 (the "License");
71307  * you may not use this file except in compliance with the License.
71308  * You may obtain a copy of the License at
71309  *
71310  * http://www.apache.org/licenses/LICENSE-2.0
71311  *
71312  * Unless required by applicable law or agreed to in writing, software
71313  * distributed under the License is distributed on an "AS IS" BASIS,
71314  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71315  * See the License for the specific language governing permissions and
71316  * limitations under the License.
71317  */
71318
71319 var db = require('ripple/db'),
71320     utils = require('ripple/utils'),
71321     event = require('ripple/event'),
71322     deviceSettings = require('ripple/deviceSettings'),
71323     dbinit = require('ripple/platform/tizen/2.0/dbinit'),
71324     _NFC_TAG = "tizen1.0-nfc-tag",
71325     _NFC_PEER = "tizen1.0-nfc-peer",
71326     _NFC_OUTPUT_MESSAGE = "tizen1.0-nfc-output-message",
71327     _powered = false,
71328     _isConnected = false,
71329     _tagNDEF = {
71330         type: "GENERIC_TARGET",
71331         isSupportedNDEF: true,
71332         ndefSize: 3,
71333         ndefs: [{
71334             recordCount: 2,
71335             records: [{
71336                 tnf: 1,
71337                 type: "TypeA",
71338                 id: "ID001",
71339                 payload: "This is 1st payload"
71340             }, {
71341                 tnf: 1,
71342                 type: "TypeA",
71343                 id: "ID002",
71344                 payload: "This is 2nd payload"
71345             }]
71346         },
71347         {
71348             recordCount: 2,
71349             records: [{
71350                 tnf: 1,
71351                 type: "TypeA",
71352                 id: "ID003",
71353                 payload: "This is 1st payload"
71354             }, {
71355                 tnf: 1,
71356                 type: "TypeA",
71357                 id: "ID004",
71358                 payload: "This is 2nd payload"
71359             }]
71360         },
71361         {
71362             recordCount: 2,
71363             records: [{
71364                 tnf: 1,
71365                 type: "TypeA",
71366                 id: "ID005",
71367                 payload: "This is 1st payload"
71368             }, {
71369                 tnf: 1,
71370                 type: "TypeA",
71371                 id: "ID006",
71372                 payload: "This is 2nd payload"
71373             }]
71374         }]
71375     },
71376     _tagRaw = {
71377         type: "GENERIC_TARGET",
71378         isSupportedNDEF: false,
71379         rawData : ""
71380     },
71381     _peerNDEF = {
71382         ndef: {
71383             recordCount: 2,
71384             records: [{
71385                 tnf: 1,
71386                 type: "TypeA",
71387                 id: "ID001",
71388                 payload: "This is 1st payload"
71389             }, {
71390                 tnf: 1,
71391                 type: "TypeA",
71392                 id: "ID002",
71393                 payload: "This is 2nd payload"
71394             }]
71395         }
71396     },
71397     btNodes,
71398     _btDeviceTemplate = "",
71399     _btSimulatedDevs = {},
71400     _btBluetoothDB;
71401
71402 function elementEnableDisableSetting(prop) {
71403     jQuery("#nfc-attach-msg").text("\xa0");
71404     jQuery("#nfc-peer-send-msg").text("\xa0");
71405     if (prop && prop.power !== undefined && prop.power !== null) {
71406         if (!prop.power) {
71407             $("#nfc-type").removeAttr("disabled");
71408         }
71409     }
71410     if (prop && prop.connectedState !== undefined && prop.connectedState !== null) {
71411         if (prop.connectedState) {
71412             $("#nfc-type").attr("disabled", "disabled");
71413             $("#nfc-tag-type-text").text($("#nfc-tag-type option:selected").text());
71414             $("#nfc-tag-type").hide();
71415             $("#nfc-tag-type-text").show();
71416             $("#nfc-tag-NDEF-support-text").text($("#nfc-tag-NDEF-support option:selected").text());
71417             $("#nfc-tag-NDEF-support").hide();
71418             $("#nfc-tag-NDEF-support-text").show();
71419             $("#nfc-raw-data").attr("disabled", "disabled");
71420         } else {
71421             $("#nfc-type").removeAttr("disabled");
71422             $("#nfc-tag-type").show();
71423             $("#nfc-tag-type-text").hide();
71424             $("#nfc-tag-NDEF-support").show();
71425             $("#nfc-tag-NDEF-support-text").hide();
71426             $("#nfc-raw-data").removeAttr("disabled");
71427         }
71428     }
71429 }
71430
71431 function _initializeElements() {
71432     jQuery(function () {
71433         var stop = false,
71434         wifiRadio = $("#wifi-radio"),
71435         isSupportNDEF, type;
71436
71437         // initialize main menus
71438         wifiRadio.buttonset();
71439
71440         $("#cellular-radio").buttonset();
71441         $("#nfc-radio").buttonset();
71442         $("#bluetooth-radio").buttonset();
71443         $("#bearer-radio").buttonset();
71444
71445         $("#wifi-radio1").prop('checked', false);
71446         $("#wifi-radio2").prop('checked', false);
71447         if (deviceSettings.retrieve("WIFI_NETWORK.status") === true) {
71448             $("#wifi-radio1").prop('checked', true);
71449             $("#wifi-radio1-label").css({'color': '#000000'});
71450             $("#wifi-radio2-label").css({'color': '#bbbbbb'});
71451         }
71452         else {
71453             $("#wifi-radio2").prop('checked', true);
71454             $("#wifi-radio1-label").css({'color': '#bbbbbb'});
71455             $("#wifi-radio2-label").css({'color': '#222222'});
71456         }
71457         $("#wifi-radio1").button("refresh");
71458         $("#wifi-radio2").button("refresh");
71459
71460         $("#cellular-radio1").prop('checked', false);
71461         $("#cellular-radio2").prop('checked', false);
71462         if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === true) {
71463             $("#cellular-radio1").prop('checked', true);
71464             $("#cellular-radio1-label").css({'color': '#000000'});
71465             $("#cellular-radio2-label").css({'color': '#bbbbbb'});
71466         }
71467         else {
71468             $("#cellular-radio2").prop('checked', true);
71469             $("#cellular-radio1-label").css({'color': '#bbbbbb'});
71470             $("#cellular-radio2-label").css({'color': '#222222'});
71471         }
71472
71473         if (deviceSettings.retrieve("CELLULAR_NETWORK.isFlightMode") === true) {
71474             $("#cellular-radio1").prop('disabled', true);
71475             $("#cellular-radio2").prop('disabled', true);
71476             $("#panel_flight_mode_notice").show();
71477         }
71478         else {
71479             $("#cellular-radio1").prop('disabled', false);
71480             $("#cellular-radio2").prop('disabled', false);
71481             $("#panel_flight_mode_notice").hide();
71482         }
71483
71484         $("#cellular-radio1").button("refresh");
71485         $("#cellular-radio2").button("refresh");
71486
71487         $("#bearer-radio2").prop('checked', true);
71488         $("#bearer-radio2").button("refresh");
71489
71490         $("#wifi-radio1").click(function () {
71491             $("#wifi-radio1-label").css({'color': '#000000'});
71492             $("#wifi-radio2-label").css({'color': '#bbbbbb'});
71493             deviceSettings.persist("WIFI_NETWORK.status", true);
71494             event.trigger("WiFiNetworkStatusChanged", [true]);
71495         });
71496
71497         $("#wifi-radio2").click(function () {
71498             $("#wifi-radio1-label").css({'color': '#bbbbbb'});
71499             $("#wifi-radio2-label").css({'color': '#222222'});
71500             deviceSettings.persist("WIFI_NETWORK.status", false);
71501             event.trigger("WiFiNetworkStatusChanged", [false]);
71502         });
71503
71504         $("#cellular-radio1").click(function () {
71505             $("#cellular-radio1-label").css({'color': '#000000'});
71506             $("#cellular-radio2-label").css({'color': '#bbbbbb'});
71507             deviceSettings.persist("CELLULAR_NETWORK.status", true);
71508             event.trigger("CellularNetworkStatusChanged", [true]);
71509         });
71510
71511         $("#cellular-radio2").click(function () {
71512             $("#cellular-radio1-label").css({'color': '#bbbbbb'});
71513             $("#cellular-radio2-label").css({'color': '#222222'});
71514             deviceSettings.persist("CELLULAR_NETWORK.status", false);
71515             event.trigger("CellularNetworkStatusChanged", [false]);
71516         });
71517
71518         $("#nfc-radio1-label").css({'color': '#bbbbbb'});
71519         $("#nfc-radio2-label").css({'color': '#222222'});
71520
71521         $("#bluetooth-radio1-label").css({'color': '#bbbbbb'});
71522         $("#bluetooth-radio2-label").css({'color': '#222222'});
71523
71524         $("#bearer-radio1-label").css({'color': '#bbbbbb'});
71525         $("#bearer-radio2-label").css({'color': '#222222'});
71526
71527         $("#nfc-radio1").click(function () {
71528             $("#nfc-radio2-label").css({'color': '#bbbbbb'});
71529             $("#nfc-radio1-label").css({'color': '#222222'});
71530             $("#nfc-main-container").show();
71531         });
71532
71533         $("#nfc-radio2").click(function () {
71534             $("#nfc-radio1-label").css({'color': '#bbbbbb'});
71535             $("#nfc-radio2-label").css({'color': '#222222'});
71536             $("#nfc-main-container").hide();
71537         });
71538
71539         $("#bluetooth-radio1").click(function () {
71540             $("#bluetooth-radio2-label").css({'color': '#bbbbbb'});
71541             $("#bluetooth-radio1-label").css({'color': '#222222'});
71542             $("#bluetooth-main-container").show();
71543         });
71544
71545         $("#bluetooth-radio2").click(function () {
71546             $("#bluetooth-radio1-label").css({'color': '#bbbbbb'});
71547             $("#bluetooth-radio2-label").css({'color': '#222222'});
71548             $("#bluetooth-main-container").hide();
71549         });
71550
71551         $("#bearer-radio1").click(function () {
71552             $("#bearer-radio2-label").css({'color': '#bbbbbb'});
71553             $("#bearer-radio1-label").css({'color': '#222222'});
71554             $("#bearer-main-container").show();
71555         });
71556
71557         $("#bearer-radio2").click(function () {
71558             $("#bearer-radio1-label").css({'color': '#bbbbbb'});
71559             $("#bearer-radio2-label").css({'color': '#222222'});
71560             $("#bearer-main-container").hide();
71561         });
71562
71563         // initialize nfc
71564         jQuery("nfc-tag-ndef-container h3").click(function (event) {
71565             if (stop) {
71566                 event.stopImmediatePropagation();
71567                 event.preventDefault();
71568                 stop = false;
71569             }
71570         });
71571         jQuery("#nfc-tag-ndef-container").accordion("destroy").accordion({
71572             header: "> div > h3",
71573             autoHeight: false
71574         });
71575         jQuery("nfc-nfcpeer h3").click(function (event) {
71576             if (stop) {
71577                 event.stopImmediatePropagation();
71578                 event.preventDefault();
71579                 stop = false;
71580             }
71581         });
71582         jQuery("#nfc-nfcpeer").accordion("destroy").accordion({
71583             header: "> div > h3",
71584             autoHeight: false
71585         });
71586         jQuery("#nfc-tag-NDEF-support").bind("change", function () {
71587             isSupportNDEF = jQuery("#nfc-tag-NDEF-support").val();
71588             if (isSupportNDEF === "Yes") {
71589                 jQuery("#nfc-tag-ndef-container").fadeIn();
71590                 jQuery("#nfc-tag-raw-container").hide();
71591             } else {
71592                 jQuery("#nfc-tag-ndef-container").hide();
71593                 jQuery("#nfc-tag-raw-container").fadeIn();
71594             }
71595         });
71596         jQuery("#nfc-type").bind("change", function () {
71597             type = jQuery("#nfc-type").val();
71598             if (type === "Tag") {
71599                 jQuery("#nfc-nfctag").fadeIn();
71600                 jQuery("#nfc-nfcpeer").hide();
71601             } else {
71602                 jQuery("#nfc-nfctag").hide();
71603                 jQuery("#nfc-nfcpeer").fadeIn();
71604             }
71605             elementEnableDisableSetting();
71606         });
71607         jQuery("#nfc-power").bind("change", function () {
71608             var status;
71609             status = jQuery("#nfc-power").val() === "On" ? true : false;
71610             if (status)
71611                 jQuery("#nfc").show();
71612             event.trigger("nfc-power-setting", [status]);
71613         });
71614         jQuery("#nfc-attach").bind("click", function () {
71615             var type, isAttached;
71616             isAttached = jQuery("#nfc-attach").children().text() === "Attach" ? true : false;
71617             jQuery("#nfc-attach-msg").text("\xa0");
71618
71619             if (!_powered && isAttached) {
71620                 jQuery("#nfc-attach-msg").text("Power:Off, attach won't work");
71621                 return;
71622             }
71623             type = jQuery("#nfc-type").val();
71624             event.trigger("nfc-attach-setting", [type, isAttached]);
71625         });
71626         jQuery("#nfc-peer-send").bind("click", function () {
71627             jQuery("#nfc-peer-send-msg").text("\xa0");
71628             if (!_isConnected) {
71629                 jQuery("#nfc-peer-send-msg").text("Disconnected. Send won't work");
71630                 return;
71631             }
71632             db.saveObject(_NFC_PEER, _peerNDEF);
71633             event.trigger("nfc-peer-sending-ndef", []);
71634         });
71635
71636         // Initialize network bearer selection
71637         $("#bearer-cellular-radio1").prop('checked', true);
71638         $("#bearer-unknown-radio2").prop('checked', true);
71639         $("#bearer-cellular-radio1").button("refresh");
71640         $("#bearer-unknown-radio2").button("refresh");
71641
71642         $("#bearer-cellular-radio2").click(function () {
71643             $("#bearer-cellular button").click();
71644         });
71645
71646         $("#bearer-unknown-radio2").click(function () {
71647             $("#bearer-unknown button").click();
71648         });
71649     });
71650 }
71651
71652 function _btRender() {
71653     var devicesHTML, btHtmlContent = "";
71654
71655     utils.forEach(_btSimulatedDevs, function (item) {
71656         var uuidsHTML = "", firstService = null;
71657
71658         utils.forEach(item.services, function (s, index) {
71659             if (!firstService) {
71660                 firstService = s;
71661             }
71662             uuidsHTML += '<option value="' + index + '">' + s.name + '</option>';
71663         });
71664
71665         devicesHTML = _btDeviceTemplate.replace(/#name/g, item.name)
71666         .replace(/#address/g, item.address)
71667         .replace(/#class-major/, item.deviceClass.majorName)
71668         .replace(/#class-minor/, item.deviceClass.minorName)
71669         .replace(/#class-service/, item.deviceClass.servicesName.join(","))
71670         .replace(/#bonded/, "No")
71671         .replace(/#trusted/, item.isTrusted ? "Yes" : "No")
71672         .replace(/#connected/, "No")
71673         .replace(/#uuids/, uuidsHTML)
71674         .replace(/#service-uuid/, firstService.uuid)
71675         .replace(/#service-protocol/, firstService.protocol)
71676         .replace(/#service-state/, firstService.state || "CLOSED")
71677         .replace(/#id/g, item.address.replace(/:/g, ""));
71678
71679         btHtmlContent += devicesHTML;
71680     });
71681
71682     $("#network-bt-box").accordion("destroy");
71683     $("#network-bt-box").html(btHtmlContent).accordion({
71684         active : false,
71685         collapsible : true,
71686         autoHeight : false
71687     });
71688 }
71689
71690 function _btRemove(index) {
71691     delete _btSimulatedDevs[index];
71692     db.saveObject("bt-simulated-devices", _btSimulatedDevs);
71693     event.trigger("bt-simulated-devices-changed", []);
71694     _btRender();
71695 }
71696
71697 function _bearerRelease(type, idBearer, evNetworkDisconnected) {
71698     if ($("#bearer-row-" + idBearer).length > 0) {
71699         $("tr[id='bearer-row-" + idBearer + "']").remove();
71700     }
71701
71702     event.trigger(evNetworkDisconnected);
71703
71704     $("#bearer-" + type + " tr:even").css("background-color", "white");
71705     $("#bearer-" + type + " tr:odd").css("background-color", "whitesmoke");
71706 }
71707
71708 module.exports = {
71709     panel: {
71710         domId: "network-container",
71711         collapsed: true,
71712         pane: "left",
71713         titleName: "Network Management",
71714         display: true
71715     },
71716     initialize: function () {
71717         _initializeElements();
71718
71719         // Events for nfc module
71720         event.on("nfc-power-changed", function (status) {
71721             _powered = status;
71722             if (_powered === true) {
71723                 $("#nfc-power").val("On");
71724             } else {
71725                 $("#nfc-power").val("Off");
71726             }
71727             elementEnableDisableSetting({power: status});
71728         });
71729         event.on("nfc-connectedState-changed", function (state) {
71730             var i, type, isSupportedNDEF, str, bytes = [];
71731             _isConnected = state;
71732             elementEnableDisableSetting({connectedState: state});
71733             type = jQuery("#nfc-type").val();
71734             if (state) {
71735                 jQuery("#nfc-attach").children().text("Detach");
71736                 jQuery("#nfc-tag-connection").text("Connected");
71737                 jQuery("#nfc-peer-connection").text("Connected");
71738                 if (type === "Tag") {
71739                     isSupportedNDEF = jQuery("#nfc-tag-NDEF-support").val() === "Yes" ? true : false;
71740                     if (isSupportedNDEF) {
71741                         _tagNDEF.type = jQuery("#nfc-tag-type").val();
71742                         db.saveObject(_NFC_TAG, _tagNDEF);
71743                     } else {
71744                         _tagRaw.type = jQuery("#nfc-tag-type").val();
71745                         str = jQuery("#nfc-raw-data").val();
71746                         for (i = 0; i < str.length; i++) {
71747                             bytes.push(str.charCodeAt(i));
71748                         }
71749                         _tagRaw.rawData = bytes;
71750                         db.saveObject(_NFC_TAG, _tagRaw);
71751                     }
71752                     event.trigger("nfc-tag-send", [true]);
71753                 } else {
71754                     event.trigger("nfc-peer-send", [true]);
71755                 }
71756             } else {
71757                 jQuery("#nfc-attach").children().text("Attach");
71758                 jQuery("#nfc-tag-connection").text("Disconnected");
71759                 jQuery("#nfc-peer-connection").text("Disconnected");
71760                 jQuery("#nfc-output").text("");
71761                 jQuery("#nfc-output-table").hide();
71762                 if (type === "Tag") {
71763                     event.trigger("nfc-tag-send", [false]);
71764                 } else {
71765                     event.trigger("nfc-peer-send", [false]);
71766                 }
71767             }
71768         });
71769         event.on("nfc-output-msg", function () {
71770             var msg;
71771             msg = db.retrieve(_NFC_OUTPUT_MESSAGE);
71772             jQuery("#nfc-output").text(msg);
71773             jQuery("#nfc-output-table").show();
71774         });
71775
71776         // Events for bluetooth module
71777         event.on("bluetoothPowerState", function (state) {
71778             if (state) {
71779                 $("#bluetooth-radio1").click();
71780             } else {
71781                 $("#bluetooth-radio2").click();
71782             }
71783         });
71784         event.on("bt-adapter-name-changed", function (name) {
71785             $("#bt-adapter-name").text(name);
71786         });
71787         event.on("bt-adapter-power-changed", function (state) {
71788             if (state) {
71789                 $("#bt-adapter-power").text("On");
71790             } else {
71791                 $("#bt-adapter-power").text("Off");
71792             }
71793         });
71794         event.on("bt-adapter-visible-changed", function (state) {
71795             if (state) {
71796                 $("#bt-adapter-visible").text("On");
71797             } else {
71798                 $("#bt-adapter-visible").text("Off");
71799             }
71800         });
71801         event.on("bt-device-bonded-changed", function (addr, isBonded) {
71802             var str = "No";
71803             if (isBonded) {
71804                 str = "Yes";
71805             }
71806             jQuery("#bonded-" + addr.replace(/:/g, "")).html(str);
71807         });
71808         event.on("bt-device-connected-changed", function (addr, isConnected) {
71809             var str = "No";
71810             if (isConnected) {
71811                 str = "Yes";
71812             }
71813             jQuery("#connected-" + addr.replace(/:/g, "")).html(str);
71814         });
71815         event.on("bt-service-state-changed", function (addr, uuid, state) {
71816             var str = "CLOSED";
71817             if (state) {
71818                 str = "OPEN";
71819             }
71820             _btSimulatedDevs[addr].services[uuid].state = str;
71821             jQuery("#service-state-" + addr.replace(/:/g, "")).html(str);
71822         });
71823         event.on("bt-service-write-msg", function (addr, uuid, data) {
71824             var msg = "", uuidNow;
71825             utils.forEach(data, function (char) {
71826                 msg += String.fromCharCode(char);
71827             });
71828             uuidNow = jQuery("#network-bt-uuid-" + addr.replace(/:/g, "")).html();
71829             if (uuidNow === uuid) {
71830                 jQuery("#service-receive-textarea-" + addr.replace(/:/g, "")).html(msg);
71831             }
71832         });
71833
71834         // Event for network bearer selection module
71835         event.on("NetworkRequest", function (networkType, domainName) {
71836             var type = networkType.toLowerCase(), name, idBearer,
71837                 evNetworkOpened       = "NO_" + networkType + "_" + domainName,
71838                 evNetworkDisconnected = "ND_" + networkType + "_" + domainName;
71839
71840             if (!$("#bearer-" + type + "-radio1").prop("checked")) {
71841                 event.trigger(evNetworkOpened, [false]);
71842                 event.trigger(evNetworkDisconnected);
71843
71844                 return;
71845             }
71846
71847             name = domainName.replace(/\./, "");
71848             idBearer = type + '-' + name;
71849
71850             if ($("#bearer-row-" + idBearer).length <= 0) {
71851                 $("#bearer-" + type).append("<tr id='bearer-row-" + idBearer + "'>" +
71852                      "<td>&nbsp<lable class='ui-text-label'>" + domainName + "</label></td>" +
71853                      "<td><button id='bearer-btn-" + idBearer + "'>X</button>&nbsp&nbsp</td>" +
71854                      "</tr>");
71855
71856                 $("#bearer-btn-" + idBearer).click(function () {
71857                     _bearerRelease(type, idBearer, evNetworkDisconnected);
71858                 });
71859
71860                 $("#bearer-" + type + " tr:even").css("background-color", "white");
71861                 $("#bearer-" + type + " tr:odd").css("background-color", "whitesmoke");
71862             }
71863
71864             event.trigger(evNetworkOpened, [true]);
71865         });
71866
71867         event.on("NetworkRelease", function (networkType, domainName) {
71868             var type = networkType.toLowerCase(),
71869                 name = domainName.replace(/\./, ""),
71870                 idBearer = type + '-' + name,
71871                 evNetworkDisconnected = "ND_" + networkType + "_" + domainName;
71872
71873             _bearerRelease(type, idBearer, evNetworkDisconnected);
71874         });
71875
71876         // Update UI for Flight Mode changing
71877         event.on("FlightModeChanged", function (value) {
71878             if (value === true) {
71879                 $("#cellular-radio1").prop('disabled', true);
71880                 $("#cellular-radio2").prop('disabled', true);
71881                 $("#panel_flight_mode_notice").show();
71882             }
71883             else {
71884                 $("#cellular-radio1").prop('disabled', false);
71885                 $("#cellular-radio2").prop('disabled', false);
71886                 $("#panel_flight_mode_notice").hide();
71887             }
71888
71889             $("#cellular-radio1").button("refresh");
71890             $("#cellular-radio2").button("refresh");
71891         });
71892
71893         $("#bt-adapter-name").text(db.retrieveObject("tizen1-db-bluetooth_adapter-name") || "Tizen BT Adapter");
71894         _btDeviceTemplate = $("#network-bt-template").html();
71895         $("#network-bt-box").empty();
71896         btNodes = jQuery("#network-bt-device-select");
71897         btNodes.html("");
71898
71899         _btBluetoothDB = db.retrieveObject("bt-simulated-devices") || dbinit.Bluetooth;
71900         utils.forEach(_btBluetoothDB, function (item, index) {
71901             btNodes.append(utils.createElement("option", {
71902                 "value": index,
71903                 "innerText": item.name
71904             }));
71905         });
71906
71907         jQuery("#network-bt-nearby-btn").click(function () {
71908             var index;
71909             index = jQuery("#network-bt-device-select").val();
71910             if (_btSimulatedDevs[index]) {
71911                 return;
71912             }
71913             _btSimulatedDevs[index] = _btBluetoothDB[index];
71914             db.saveObject("bt-simulated-devices", _btSimulatedDevs);
71915             event.trigger("bt-simulated-devices-changed", []);
71916             _btRender();
71917         });
71918         $(".network-bt-remove-btn").live("click", function () {
71919             _btRemove(this.id);
71920         });
71921         $(".network-bt-send-btn").live("click", function () {
71922             var msg = jQuery("#service-transfer-textarea-" + this.id.replace(/:/g, "")).val(),
71923             uuid = jQuery("#network-bt-uuid-" + this.id.replace(/:/g, "")).html();
71924             event.trigger("bt-service-rawdata-received", [this.id, uuid, msg]);
71925         });
71926         $(".network-bt-service-select").live("change", function () {
71927             var uuid = this.children[this.selectedIndex].value,
71928             index = this.id,
71929             addr,
71930             service;
71931             addr = index.replace(/:/g, "");
71932             service = _btSimulatedDevs[index].services[uuid];
71933             jQuery("#network-bt-uuid-" + index.replace(/:/g, "")).html(service.uuid);
71934             jQuery("#network-bt-protocol-" + index.replace(/:/g, "")).html(service.protocol);
71935             jQuery("#service-state-" + index.replace(/:/g, "")).html(service.state || "CLOSED");
71936             jQuery("#service-transfer-textarea-" + addr).val("");
71937             jQuery("#service-receive-textarea-" + addr).html("");
71938         });
71939
71940         //Default "Tizen Phone" is nearby
71941         //_btSimulatedDevs["00:02:60:00:05:63"] = _btBluetoothDB["00:02:60:00:05:63"];
71942         for (var address in _btBluetoothDB) {
71943             _btSimulatedDevs[address] = _btBluetoothDB[address];
71944             break;
71945         }
71946
71947         db.saveObject("bt-simulated-devices", _btSimulatedDevs);
71948         _btRender();
71949     }
71950 };
71951
71952 });
71953 define('ripple/ui/plugins/download', function (require, exports, module) {
71954 /*
71955  *  Copyright 2012 Intel Corporation.
71956  *
71957  * Licensed under the Apache License, Version 2.0 (the "License");
71958  * you may not use this file except in compliance with the License.
71959  * You may obtain a copy of the License at
71960  *
71961  * http://www.apache.org/licenses/LICENSE-2.0
71962  *
71963  * Unless required by applicable law or agreed to in writing, software
71964  * distributed under the License is distributed on an "AS IS" BASIS,
71965  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71966  * See the License for the specific language governing permissions and
71967  * limitations under the License.
71968  */
71969
71970 var db = require('ripple/db'),
71971     event = require('ripple/event'),
71972     utils = require('ripple/utils'),
71973     _data = {
71974         DB_DOWNLOAD_KEY : "tizen1-db-download",
71975         resources : []
71976     },
71977     _cleanInputs, intervalId,
71978     _downloads;
71979
71980 function _get() {
71981     _downloads = [
71982         {id: "0001", url : "http://tizen.org/small_file.zip", size : "5", speed : "1.0", estimatedTime : "5", MIMEType : "application/zip"},
71983         {id: "0002", url : "http://tizen.org/big_file.zip", size : "20", speed : "1.0", estimatedTime : "20", MIMEType : "application/zip"},
71984         {id: "0003", url : "http://download.tizen.org/tct/2_1/webapi-tizen-download-test-image-hq.png", size : "3937596", speed : "1968798", estimatedTime : "2", MIMEType : "image/png"},
71985         {id: "0004", url : "http://download.tizen.org/tct/2_1/webapi-tizen-download-test-image-lq.png", size : "589", speed : "589", estimatedTime : "1", MIMEType : "image/png"}
71986     ];
71987     _data.resources = db.retrieveObject(_data.DB_DOWNLOAD_KEY) || _downloads;
71988     if (db.retrieveObject(_data.DB_DOWNLOAD_KEY) && db.retrieveObject(_data.DB_DOWNLOAD_KEY).length === 0) {
71989         _data.resources = _downloads;
71990     } else {
71991         _data.resources = db.retrieveObject(_data.DB_DOWNLOAD_KEY) || _downloads;
71992     }
71993     _save();
71994 }
71995
71996 function _save() {
71997     db.saveObject(_data.DB_DOWNLOAD_KEY, _data.resources);
71998     event.trigger('downloadResourceChanged');
71999 }
72000
72001 function checkURL(url) {
72002     var rg = new RegExp("((^http)|(^https)|(^ftp)):\/\/()+");
72003     return rg.test(url);
72004 }
72005
72006 function loadResources() {
72007     var installed = document.getElementById("download-resource"), node, i;
72008     installed.innerHTML = "";
72009     for (i in _data.resources) {
72010         node = utils.createElement("option", {
72011             "innerText": _data.resources[i].url,
72012             "value": _data.resources[i].id
72013         });
72014         installed.appendChild(node);
72015     }
72016     _cleanInputs();
72017 }
72018
72019 function _displayInfo(text) {
72020     var info = document.getElementById("download-error");
72021     info.innerHTML = text;
72022     if (intervalId) {
72023         clearTimeout(intervalId);
72024     }
72025     intervalId = setTimeout(clearDisplayInfo, 5000);
72026 }
72027
72028 function clearDisplayInfo() {
72029     document.getElementById('download-error').innerHTML = '';
72030 }
72031
72032 function _cleanInputs() {
72033     document.getElementById("download-url").value = "";
72034     document.getElementById("download-size").value = "";
72035     document.getElementById("download-speed").value = "";
72036     document.getElementById("download-time").innerText = "0";
72037     document.getElementById("download-MIMEType").value = "";
72038 }
72039
72040 function checkProperties(optionType, url, size, speed, time, MIMEType) {
72041     var back = true;
72042     if (url === "" || size === "" ||  speed === "" || time === "" || MIMEType === "") {
72043         _displayInfo(optionType + " failed, empty input.");
72044         back = false;
72045     }
72046     if (!checkURL(url)) {
72047         _displayInfo(optionType + " failed, 'URL' is invalid.");
72048         back = false;
72049     }
72050     if (size <= 0 ||  speed <= 0) {
72051         _displayInfo(optionType + " failed, invalid input.");
72052         back = false;
72053     }
72054     return back;
72055 }
72056
72057 function showUpdateNotification() {
72058     var url     = document.getElementById("download-url").value,
72059         size    = document.getElementById("download-size").value,
72060         speed   = document.getElementById("download-speed").value,
72061         MIMEType = document.getElementById("download-MIMEType").value,
72062         isValid = true;
72063     if (url === "" || size === "" ||  speed === "" || MIMEType === "" || !checkURL(url) || size <= 0 ||  speed <= 0) {
72064         isValid = false;
72065     }
72066     if (isValid) {
72067         _displayInfo("Resource changed, please Add or Update the content.");
72068     }
72069 }
72070
72071 function _adding() {
72072     var id, time, url, size, speed, MIMEType, object, i, isValid;
72073     url     = document.getElementById("download-url").value;
72074     size    = document.getElementById("download-size").value;
72075     speed   = document.getElementById("download-speed").value;
72076     MIMEType = document.getElementById("download-MIMEType").value;
72077     time    = size / speed;
72078     id      = Math.uuid(null, 16);
72079
72080     isValid = checkProperties("Add", url, size, speed, time, MIMEType);
72081     if (!isValid)
72082         return;
72083     if (_data.resources.length !== 0) {
72084         for (i in _data.resources) {
72085             if (url === _data.resources[i].url) {
72086                 _displayInfo("Add failed, the download resource is already available.");
72087                 return;
72088             }
72089         }
72090     }
72091     document.getElementById("download-time").innerText = Math.round(time * 100) / 100;
72092     object = {'id': id, 'url': url, 'size': size, 'speed': speed, 'estimatedTime': time, MIMEType: MIMEType};
72093     _data.resources.push(object);
72094     _save();
72095     loadResources();
72096 }
72097
72098 function _update() {
72099     var id, time, url, size, speed, MIMEType, i, isExist = false, isValid;
72100
72101     id    = document.getElementById("download-resource").value;
72102     url   = document.getElementById("download-url").value;
72103     size  = document.getElementById("download-size").value;
72104     speed = document.getElementById("download-speed").value;
72105     MIMEType = document.getElementById("download-MIMEType").value;
72106     time  = size / speed;
72107
72108     if (_data.resources.length === 0) {
72109         _displayInfo("Update failed, there is no download resource now.");
72110         return;
72111     }
72112     isValid = checkProperties("Update", url, size, speed, time, MIMEType);
72113     if (!isValid)
72114         return;
72115     for (i in _data.resources) {
72116         if (_data.resources[i].url === url) {
72117             isExist = true;
72118             _data.resources[i] = {id: id, url : url, size : size, speed : speed, estimatedTime: time, MIMEType: MIMEType};
72119             loadResources();
72120             _save();
72121             break;
72122         }
72123     }
72124     if (!isExist)
72125         _displayInfo("Update failed, the download resource doesn't exist.");
72126 }
72127
72128 function _delete() {
72129     var i, id;
72130     id = document.getElementById("download-resource").value;
72131     if (id) {
72132         for (i in _data.resources) {
72133             if (_data.resources[i].id === id) {
72134                 _data.resources.splice(i, 1);
72135                 _save();
72136                 loadResources();
72137             }
72138         }
72139     }
72140 }
72141
72142 function _showAppDetail(id) {
72143     var i;
72144     for (i in _data.resources) {
72145         if (id === _data.resources[i].id) {
72146             document.getElementById("download-time").innerText = Math.round(_data.resources[i].estimatedTime * 100) / 100;
72147             jQuery("#download-url").val(_data.resources[i].url);
72148             jQuery("#download-size").val(_data.resources[i].size);
72149             jQuery("#download-speed").val(_data.resources[i].speed);
72150             jQuery("#download-MIMEType").val(_data.resources[i].MIMEType);
72151         }
72152     }
72153 }
72154
72155 function _changeAppData() {
72156     var id = jQuery("#download-resource").val();
72157     _showAppDetail(id);
72158 }
72159 function changeValue() {
72160     var size  = document.getElementById("download-size").value,
72161         speed = document.getElementById("download-speed").value;
72162     if (size > 0 && speed > 0) {
72163         document.getElementById("download-time").innerText = Math.round(size / speed * 100) / 100;
72164     } else {
72165         document.getElementById("download-time").innerText  = "";
72166     }
72167 }
72168 function checkInputValue(input) {
72169     if (input.value === "" || input.value <= 0) {
72170         input.style['border-color'] = 'red';
72171         _displayInfo("Invalided value.");
72172     } else {
72173         if (input.style['border-color']) {
72174             input.style.removeProperty('border-color');
72175         }
72176         changeValue();
72177         //showUpdateNotification();
72178     }
72179 }
72180 module.exports = {
72181     panel: {
72182         domId: "download-container",
72183         collapsed: true,
72184         pane: "left",
72185         titleName: "Download",
72186         display: true
72187     },
72188     initialize: function () {
72189         _get();
72190         loadResources();
72191
72192         document.getElementById("download-add").addEventListener("click", _adding, false);
72193         document.getElementById("download-update").addEventListener("click", _update, false);
72194         document.getElementById("download-delete").addEventListener("click", _delete, false);
72195
72196         jQuery("#download-resource").bind("focus change", function () {
72197             var url = document.getElementById("download-url"),
72198                 size = document.getElementById("download-size"),
72199                 speed = document.getElementById("download-speed"),
72200                 MIMEType = document.getElementById("download-MIMEType");
72201             if (url.style['border-color']) {
72202                 url.style.removeProperty('border-color');
72203             }
72204             if (MIMEType.style['border-color']) {
72205                 MIMEType.style.removeProperty('border-color');
72206             }
72207             if (size.value > 0 && size.style['border-color']) {
72208                 size.style.removeProperty('border-color');
72209             }
72210             if (speed.value > 0 && speed.style['border-color']) {
72211                 speed.style.removeProperty('border-color');
72212             }
72213             _changeAppData();
72214         });
72215         jQuery("#download-speed").bind("blur", function () {
72216             changeValue();
72217         });
72218         jQuery("#download-size").bind("blur", function () {
72219             changeValue();
72220         });
72221         jQuery("#download-speed").bind("change", function () {
72222             checkInputValue(this);
72223         });
72224         jQuery("#download-size").bind("change", function () {
72225             checkInputValue(this);
72226         });
72227         jQuery("#download-speed").bind("change", function () {
72228             checkInputValue(this);
72229         });
72230         jQuery("#download-url").bind("change", function () {
72231             if (this.style['border-color']) {
72232                 this.style.removeProperty('border-color');
72233             }
72234             if (this.value && checkURL(this.value)) {
72235                 //showUpdateNotification();
72236             } else  {
72237                 _displayInfo("Invalided URL.");
72238                 this.style['border-color'] = 'red';
72239             }
72240         });
72241     }
72242 };
72243
72244 });
72245 define('ripple/ui/plugins/tooltips', function (require, exports, module) {
72246 /*
72247  *  Copyright 2011 Research In Motion Limited.
72248  *
72249  * Licensed under the Apache License, Version 2.0 (the "License");
72250  * you may not use this file except in compliance with the License.
72251  * You may obtain a copy of the License at
72252  *
72253  * http://www.apache.org/licenses/LICENSE-2.0
72254  *
72255  * Unless required by applicable law or agreed to in writing, software
72256  * distributed under the License is distributed on an "AS IS" BASIS,
72257  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72258  * See the License for the specific language governing permissions and
72259  * limitations under the License.
72260  */
72261 // Class: UI.Tooltips
72262 // Purpose: build tooltips for UI
72263 // See here for Tooltip Options
72264 // http://jquery.bassistance.de/tooltip/demo/
72265 var utils = require('ripple/utils'),
72266     tooltip = require('ripple/ui/plugins/tooltip'),
72267     constants = require('ripple/constants'),
72268     db = require('ripple/db'),
72269     utils = require('ripple/utils');
72270
72271 function _updateButtonText() {
72272     document.querySelector("#settings-toggletooltips > span")
72273             .innerHTML = "Turn " + (tooltip.isOff() ? "On" : "Off");
72274 }
72275
72276 module.exports = {
72277     initialize: function () {
72278         var saved = db.retrieve(constants.SETTINGS.TOOLTIPS_KEY);
72279
72280         // blarg, tooltips are always enabled so if its saved to false disable it
72281         if (!tooltip.isOff() && (saved === "false" || saved === false)) {
72282             tooltip.toggle();
72283         }
72284
72285         _updateButtonText();
72286
72287         jQuery(constants.SETTINGS.TOOLTIPS_TOGGLE_DIV).click(function () {
72288             db.save(constants.SETTINGS.TOOLTIPS_KEY, !tooltip.toggle());
72289             _updateButtonText();
72290         });
72291     }
72292 };
72293
72294 });
72295 define('ripple/ui/plugins/secureElement', function (require, exports, module) {
72296 /*
72297  *  Copyright 2014 Intel Corporation
72298  *
72299  * Licensed under the Apache License, Version 2.0 (the "License");
72300  * you may not use this file except in compliance with the License.
72301  * You may obtain a copy of the License at
72302  *
72303  * http://www.apache.org/licenses/LICENSE-2.0
72304  *
72305  * Unless required by applicable law or agreed to in writing, software
72306  * distributed under the License is distributed on an "AS IS" BASIS,
72307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72308  * See the License for the specific language governing permissions and
72309  * limitations under the License.
72310  */
72311
72312 var db = require('ripple/db'),
72313     event = require('ripple/event'),
72314     _data = {
72315         DB_SECUREELEMENT_KEY: "tizen-secureelement",
72316         DEFAULT: [{
72317             name: "UICC and SIM",
72318             isPresent: true
72319         }, {
72320             name: "Secure SD Card",
72321             isPresent: true
72322         }],
72323         dbStorage: null
72324     };
72325
72326 function _initializeDB() {
72327     _data.dbStorage = db.retrieveObject(_data.DB_SECUREELEMENT_KEY) || [];
72328
72329     if (!_data.dbStorage || _data.dbStorage.length === 0) {
72330         _data.dbStorage = _data.DEFAULT;
72331         db.saveObject(_data.DB_SECUREELEMENT_KEY, _data.dbStorage);
72332     }
72333 }
72334
72335 function _getName(prefix) {
72336     var name = {
72337         us: "UICC and SIM",
72338         sc: "Secure SD Card"
72339     };
72340
72341     return name[prefix];
72342 }
72343
72344 function _getPrefix(name) {
72345     var prefix = {
72346         "UICC and SIM": "us",
72347         "Secure SD Card": "sc"
72348     };
72349
72350     return prefix[name];
72351 }
72352
72353 function _initializeElements(reader) {
72354     var name = reader.name,
72355         prop = reader.isPresent,
72356         prefix = _getPrefix(name),
72357         containerId = prefix + "-radio",
72358         container = $("#" + containerId),
72359         radioInsert = $("#" + containerId + "1"),
72360         radioLabelInsert = $("#" + containerId + "1-label"),
72361         radioEject = $("#" + containerId + "2"),
72362         radioLabelEject = $("#" + containerId + "2-label");
72363
72364     container.buttonset();
72365
72366     radioInsert.prop('checked', prop);
72367     radioLabelInsert.css({'color': prop ? '#000000' : '#bbbbbb'});
72368     radioInsert.button("refresh");
72369
72370     radioEject.prop('checked', !prop);
72371     radioLabelEject.css({'color': !prop ? '#000000' : '#bbbbbb'});
72372     radioEject.button("refresh");
72373
72374     _addElementsListeners(radioInsert, radioEject);
72375 }
72376
72377 function _addElementsListeners(radioInsert, radioEject) {
72378     radioInsert.click(function () {
72379         var prefix = /^us-/.test(this.id) ? "us" : "sc",
72380             name = _getName(prefix),
72381             containerId = prefix + "-radio",
72382             radioLabelInsert = $("#" + containerId + "1-label"),
72383             radioLabelEject = $("#" + containerId + "2-label");
72384
72385         radioLabelInsert.css({'color': '#000000'});
72386         radioLabelEject.css({'color': '#bbbbbb'});
72387
72388         event.trigger("ReaderChanged", [name, true]);
72389     });
72390
72391     radioEject.click(function () {
72392         var prefix = /^us-/.test(this.id) ? "us" : "sc",
72393             name = _getName(prefix),
72394             containerId = prefix + "-radio",
72395             radioLabelInsert = $("#" + containerId + "1-label"),
72396             radioLabelEject = $("#" + containerId + "2-label");
72397
72398         radioLabelInsert.css({'color': '#bbbbbb'});
72399         radioLabelEject.css({'color': '#222222'});
72400
72401         event.trigger("ReaderChanged", [name, false]);
72402     });
72403 }
72404
72405 module.exports = {
72406     panel: {
72407         domId: "secureElement-container",
72408         collapsed: true,
72409         pane: "left",
72410         titleName: "Secure Element",
72411         display: true
72412     },
72413     initialize: function () {
72414         var i;
72415
72416         _initializeDB();
72417
72418         for (i = 0; _data.dbStorage && i < _data.dbStorage.length; i++) {
72419             _initializeElements(_data.dbStorage[i]);
72420         }
72421
72422         event.on("ReadersClosed", function () {
72423             var i, reader, prefix, containerId, radioLabelInsert, radioLabelEject;
72424
72425             for (i = 0; _data.dbStorage && i < _data.dbStorage.length; i++) {
72426                 reader = _data.dbStorage[i];
72427
72428                 reader.isPresent = false;
72429
72430                 prefix = _getPrefix(reader.name);
72431                 containerId = prefix + "-radio";
72432                 radioLabelInsert = $("#" + containerId + "1-label");
72433                 radioLabelEject = $("#" + containerId + "2-label");
72434
72435                 radioLabelInsert.css({'color': '#bbbbbb'});
72436                 radioLabelEject.css({'color': '#222222'});
72437             }
72438         });
72439     }
72440 };
72441
72442 });
72443 define('ripple/ui/plugins/deviceSettings', function (require, exports, module) {
72444 /*
72445  *  Copyright 2011 Research In Motion Limited.
72446  *
72447  * Licensed under the Apache License, Version 2.0 (the "License");
72448  * you may not use this file except in compliance with the License.
72449  * You may obtain a copy of the License at
72450  *
72451  * http://www.apache.org/licenses/LICENSE-2.0
72452  *
72453  * Unless required by applicable law or agreed to in writing, software
72454  * distributed under the License is distributed on an "AS IS" BASIS,
72455  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72456  * See the License for the specific language governing permissions and
72457  * limitations under the License.
72458  */
72459 var event = require('ripple/event'),
72460     constants = require('ripple/constants'),
72461     deviceSettings = require('ripple/deviceSettings'),
72462     utils = require('ripple/utils'),
72463     exception = require('ripple/exception'),
72464     platform = require('ripple/platform'),
72465     db = require('ripple/db'),
72466     _CONST = {
72467         "CONTENT_CONTAINER_ID": "devicesettings-content-container",
72468         "UKNOWN_CONTROL_MESSAGE": "Unknown device control type"
72469     },
72470     _contentContainer,
72471     _network_contentContainer,
72472     DBNETWORKSETTING_KEY = "tizen2-preFlightModeNetworksetting",
72473     _CONTAINER_ID = _CONST.CONTENT_CONTAINER_ID;
72474
72475 function _retrieveDeviceInfo(key) {
72476     var layout, rtn, deviceInfo = require('ripple/devices').getCurrentDevice();
72477
72478     switch (key) {
72479     case "Device.model":
72480         return deviceInfo.model;
72481     case "Device.version":
72482         return deviceInfo.firmware;
72483     case "Device.vendor":
72484         return deviceInfo.manufacturer;
72485     case "DISPLAY.resolutionHeight":
72486         return deviceInfo.screen.height;
72487     case "DISPLAY.resolutionWidth":
72488         return deviceInfo.screen.width;
72489     case "DISPLAY.pixelAspectRatio":
72490         return (deviceInfo.screen.width / deviceInfo.screen.height).toFixed(2);
72491
72492     case "DISPLAY.physicalWidth":
72493         return Number((deviceInfo.screen.width / deviceInfo.ppi).toFixed(2));
72494     case "DISPLAY.physicalHeight":
72495         return Number((deviceInfo.screen.height / deviceInfo.ppi).toFixed(2));
72496     case "DISPLAY.dpiY":
72497     case "DISPLAY.dotsPerInchHeight":
72498         return deviceInfo.ppi;
72499     case "DISPLAY.dpiX":
72500     case "DISPLAY.dotsPerInchWidth":
72501         return deviceInfo.ppi;
72502     case "OperatingSystem.version":
72503         return deviceInfo.osVersion;
72504     case "OperatingSystem.name":
72505         return deviceInfo.osName;
72506     case "OperatingSystem.vendor":
72507         return deviceInfo.manufacturer;
72508     case "DEVICE_ORIENTATION.status":
72509         layout = db.retrieve("layout");
72510         if (layout === null || layout === undefined) {
72511             layout = deviceInfo.defaultOrientation || "portrait";
72512         }
72513         if (layout === "portrait") {
72514             return "PORTRAIT_PRIMARY";
72515         } else {
72516             return "LANDSCAPE_PRIMARY";
72517         }
72518         break;
72519     case "WIFI_NETWORK.status":
72520     case "CELLULAR_NETWORK.status":
72521         rtn = deviceSettings.retrieve(key);
72522         if (rtn === true) {
72523             return "ON";
72524         } else {
72525             return "OFF";
72526         }
72527         break;
72528     case "CPU.load":
72529         rtn = deviceSettings.retrieve(key);
72530         if (rtn > 1) {
72531             rtn = 1;
72532             deviceSettings.persist(key, rtn);
72533         }
72534         if (rtn < 0) {
72535             rtn = 0;
72536             deviceSettings.persist(key, rtn);
72537         }
72538         return rtn;
72539     case "DISPLAY.brightness":
72540         rtn = deviceSettings.retrieve(key);
72541         if (rtn > 1) {
72542             rtn = 1;
72543             deviceSettings.persist("DISPLAY.brightness", rtn);
72544         }
72545         if (rtn < 0) {
72546             rtn = 0;
72547             deviceSettings.persist("DISPLAY.brightness", rtn);
72548         }
72549         return rtn;
72550     case "BUILD.manufacturer":
72551         return deviceInfo.manufacturer;
72552     default:
72553         return deviceSettings.retrieve(key);
72554     }
72555 }
72556
72557 function _retrieveSettingName(type) {
72558
72559     switch (type) {
72560     case "CellularHardware":
72561         return "Cellular Hardware";
72562     case "CellularNetwork":
72563         return "Cellular Network";
72564     case "MemoryUnit":
72565         return "Memory Unit";
72566     case "OperatingSystem":
72567         return "Operating System";
72568     case "WebRuntime":
72569         return "Web Runtime";
72570     case "WiFiHardware":
72571         return "WiFi Hardware";
72572     case "WiFiNetwork":
72573         return "WiFi Network";
72574     default:
72575         return type;
72576     }
72577 }
72578
72579 function _appendSettingNode(labelNode, inputNode, label) {
72580     var frag = document.createDocumentFragment(),
72581         rowNode = frag.appendChild(utils.createElement("tr")),
72582         tempTdNode;
72583
72584     rowNode.appendChild(utils.createElement("td"))
72585            .appendChild(labelNode);
72586
72587     tempTdNode = rowNode.appendChild(utils.createElement("td"));
72588
72589     if (label) {
72590         tempTdNode.appendChild(label);
72591     }
72592
72593     tempTdNode.appendChild(inputNode);
72594
72595     return frag;
72596 }
72597
72598 function _getCurrentSetting(setting, settingType, key) {
72599     var ret, savedSetting, fullKey;
72600     fullKey = settingType + "." + key;
72601     savedSetting = _retrieveDeviceInfo(fullKey);
72602     if (fullKey === "WIFI_NETWORK.status" || fullKey === "CELLULAR_NETWORK.status") {
72603         if (savedSetting === "ON") {
72604             savedSetting = true;
72605         } else {
72606             savedSetting = false;
72607         }
72608     }
72609     ret = (savedSetting || savedSetting === false || savedSetting === "" || savedSetting === 0) ? savedSetting : setting.control.value;
72610     return ret;
72611 }
72612
72613 function _buildDOMNode(setting, settingType, key) {
72614     var settingsNode, tagName, jNode,
72615         fullKey = settingType + "." + key,
72616         savedSetting = _retrieveDeviceInfo(fullKey),
72617         // TODO: move this into Utils (isSet method)
72618         currentSetting,
72619         domNode,
72620         domNodeLabel = null;
72621
72622     if (fullKey === "WIFI_NETWORK.status" || fullKey === "CELLULAR_NETWORK.status") {
72623         if (savedSetting === "ON") {
72624             savedSetting = true;
72625         } else {
72626             savedSetting = false;
72627         }
72628     }
72629     currentSetting = (savedSetting || savedSetting === false || savedSetting === "" || savedSetting === 0) ? savedSetting : setting.control.value;
72630
72631     switch (setting.control.type) {
72632     case "text":
72633     case "number":
72634     case "range":
72635     case "checkbox":
72636         tagName = "input";
72637         break;
72638     case "textarea":
72639         tagName = "textarea";
72640         break;
72641     case "select":
72642         tagName = "select";
72643         break;
72644     case "label":
72645         tagName = "label";
72646         break;
72647     default:
72648         exception.raise(exception.types.Application, _CONST.UKNOWN_CONTROL_MESSAGE);
72649     }
72650
72651     settingsNode = utils.createElement(tagName, setting.control.type === "select" ? null : setting.control);
72652     settingsNode.setAttribute("id", "device-settings-" + settingType + "-" + key);
72653
72654     // TODO: this should really be part of utils.createControl? add element of type "range" with label?
72655     if (setting.control.type === "range") {
72656         domNodeLabel = utils.createElement("label", {
72657             "class": constants.UI.LEFT_RANGE_LABEL_CLASS
72658         });
72659     }
72660
72661     domNode = _appendSettingNode(utils.createElement("span", {"innerText": setting.name, "class": "configure-window-text-label"}), settingsNode, domNodeLabel);
72662
72663     jNode = jQuery(settingsNode);
72664     if (tagName !== "label") {
72665         jNode.addClass(constants.UI.JQUERY_UI_INPUT_CLASSES);
72666     }
72667
72668     switch (setting.control.type) {
72669     case "checkbox":
72670         jNode.bind("click", function () {
72671             var checked = this.checked ? true : false;
72672             deviceSettings.persist(fullKey, checked);
72673             if (typeof setting.callback === "function") {
72674                 setting.callback(checked);
72675             }
72676         });
72677
72678         if (currentSetting === true) {
72679             jNode.attr("checked", "checked");
72680         }
72681
72682         break;
72683
72684     case "text":
72685     case "textarea":
72686     case "number":
72687         jNode.val(currentSetting);
72688         utils.bindAutoSaveEvent(jNode, function () {
72689             if (setting.control.type === "number") {
72690                 deviceSettings.persist(fullKey, Number(jNode.val()));
72691             } else {
72692                 deviceSettings.persist(fullKey, jNode.val());
72693             }
72694
72695             if (typeof setting.callback === "function") {
72696                 setting.callback(jNode.val());
72697             }
72698         });
72699         break;
72700
72701     case "label":
72702         jNode.text(currentSetting);
72703         break;
72704
72705     case "select":
72706     case "range":
72707         if (setting.control.type === "select") {
72708             utils.forEach(setting.options,  function (value, option) {
72709                 jNode.append(utils.createElement("option", {
72710                     "value": option,
72711                     "innerText": value
72712                 }));
72713             });
72714         }
72715         else {
72716             if (domNodeLabel) {
72717                 domNodeLabel.innerText = currentSetting;
72718             }
72719         }
72720
72721         jNode.val(currentSetting)
72722              .bind("change", function () {
72723                 if (setting.control.type === "range" && domNodeLabel) {
72724                     domNodeLabel.innerText = jQuery(this).val();
72725                 }
72726                 deviceSettings.persist(fullKey, jQuery(this).val());
72727
72728                 if (typeof setting.callback === "function") {
72729                     setting.callback(jQuery(this).val(), currentSetting);
72730                 }
72731             }
72732         );
72733     }
72734
72735     // TODO: Brent, do in DeviceSettings on load instead?
72736     if (currentSetting !== setting.control.value) {
72737         deviceSettings.register(fullKey, currentSetting);
72738     }
72739
72740     return domNode;
72741 }
72742
72743 function displayBrightnessCB(value) {
72744     if (value > 1) value = 1;
72745     if (value < 0) value = 0;
72746     if (document.getElementById("device-settings-DISPLAY-brightness").value === value) {
72747         return;
72748     }
72749     deviceSettings.persist("DISPLAY.brightness", Number(value));
72750     document.getElementById("device-settings-DISPLAY-brightness").value = value;
72751 }
72752
72753 function cpuLoadCB(value) {
72754     if (value > 1) value = 1;
72755     if (value < 0) value = 0;
72756     if (document.getElementById("device-settings-CPU-load").value === value) {
72757         return;
72758     }
72759     deviceSettings.persist("CPU.load", Number(value));
72760     document.getElementById("device-settings-CPU-load").value = value;
72761 }
72762
72763 function availCapacityCB(value) {
72764     var capacity = deviceSettings.retrieve("STORAGE.capacity");
72765     if (Number(value) > Number(capacity)) value = capacity;
72766     if (Number(value) < 0) value = 0;
72767     deviceSettings.persist("STORAGE.availableCapacity", Number(value));
72768     document.getElementById("device-settings-STORAGE-availableCapacity").value = Number(value);
72769 }
72770
72771 function wiFiNetworkStatusCB(value) {
72772     document.getElementById("device-settings-WIFI_NETWORK-status").checked = value;
72773 }
72774
72775 function flightModeChangedCB(value) {
72776     var networkSettings = {};
72777     if (value === true) {
72778         networkSettings['wifiSetting'] = deviceSettings.retrieve("WIFI_NETWORK.status");
72779         networkSettings['cellularSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status");
72780         //networkSettings['bluetoothSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status");
72781         //networkSettings['nfcSetting'] = deviceSettings.retrieve("CELLULAR_NETWORK.status");
72782         db.saveObject(DBNETWORKSETTING_KEY, networkSettings);
72783
72784         deviceSettings.persist("CELLULAR_NETWORK.status", false);
72785         deviceSettings.persist("WIFI_NETWORK.status", false);
72786         event.trigger("nfc-power-setting", [false]);
72787         event.trigger("bt-power-setting", [false]);
72788
72789         document.getElementById("device-settings-WIFI_NETWORK-status").checked = false;
72790         document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = false;
72791         $("#device-settings-CELLULAR_NETWORK-status").parent().append("<span id='config_flight_mode_notice' style='color:#555555;'>  (Disabled for Flight Mode)</span>");
72792         document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = true;
72793
72794     } else {
72795         networkSettings = db.retrieveObject(DBNETWORKSETTING_KEY)||{"wifiSetting": true, "cellularSetting": true};
72796         deviceSettings.persist("WIFI_NETWORK.status", networkSettings['wifiSetting']);
72797         deviceSettings.persist("CELLULAR_NETWORK.status", networkSettings['cellularSetting']);
72798         document.getElementById("device-settings-WIFI_NETWORK-status").checked = networkSettings['wifiSetting'];
72799         document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = networkSettings['cellularSetting'];
72800         $("#config_flight_mode_notice").remove();
72801         document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = false;
72802     }
72803 }
72804
72805 function cellularNetworkStatusCB(value) {
72806     document.getElementById("device-settings-CELLULAR_NETWORK-status").checked = value;
72807 }
72808
72809 function layoutCB(value) {
72810     if (value === 'portrait') {
72811         deviceSettings.register("DEVICE_ORIENTATION.status", "PORTRAIT_PRIMARY");
72812         document.getElementById("device-settings-DEVICE_ORIENTATION-status").innerText = "PORTRAIT_PRIMARY";
72813     } else {
72814         deviceSettings.register("DEVICE_ORIENTATION.status", "LANDSCAPE_PRIMARY");
72815         document.getElementById("device-settings-DEVICE_ORIENTATION-status").innerText = "LANDSCAPE_PRIMARY";
72816     }
72817 }
72818
72819 // goes through current platforms device settings
72820 // adds nodes to panel and binds respective events
72821 // talks to DeviceSettings for persistence
72822 module.exports = {
72823     initialize: function () {
72824         var settings, value;
72825         _contentContainer = document.getElementById(_CONTAINER_ID);
72826         _network_contentContainer = document.getElementById("networksettings-content-container");
72827
72828         settings = platform.current().device;
72829         utils.forEach(settings, function (settingSection, settingType) {
72830
72831             var currentTableNode, currentTableNode2, settingNameNode, settingName = _retrieveSettingName(settingType);
72832
72833             settingNameNode = utils.createElement("h3", { "innerText": settingName });
72834             settingNameNode.setAttribute("class", "configure-window-session-title");
72835
72836             if (settingType === 'NETWORK' || settingType === 'WIFI_NETWORK' || settingType === 'CELLULAR_NETWORK' || settingType === 'SIM') {
72837                 _network_contentContainer.appendChild(settingNameNode);
72838                 currentTableNode2 = utils.createElement("table", {
72839                     "class": constants.UI.PANEL_TABLE_CLASS
72840                 });
72841                 currentTableNode2.setAttribute("class", "configure-window-panel-table");
72842                 _network_contentContainer.appendChild(currentTableNode2);
72843             }
72844             else {
72845                 _contentContainer.appendChild(settingNameNode);
72846                 currentTableNode = utils.createElement("table", {
72847                     "class": constants.UI.PANEL_TABLE_CLASS
72848                 });
72849                 currentTableNode.setAttribute("class", "configure-window-panel-table");
72850                 _contentContainer.appendChild(currentTableNode);
72851             }
72852
72853             utils.forEach(settingSection, function (setting, key) {
72854                 if (settingType === 'NETWORK' || settingType === 'WIFI_NETWORK' || settingType === 'CELLULAR_NETWORK' || settingType === 'SIM') {
72855                     currentTableNode2.appendChild(_buildDOMNode(setting, settingType, key));
72856                 }
72857                 else {
72858                     currentTableNode.appendChild(_buildDOMNode(setting, settingType, key));
72859                 }
72860                 value = _getCurrentSetting(setting, settingType, key);
72861                 if (setting.callback) {
72862                     setting.callback(value);
72863                 }
72864             });
72865         });
72866
72867         if (deviceSettings.retrieve("CELLULAR_NETWORK.isFlightMode") === true) {
72868             $("#device-settings-CELLULAR_NETWORK-status").parent().append("<span id='config_flight_mode_notice' style='color:#555555;'>  (Disabled for Flight Mode)</span>");
72869             document.getElementById("device-settings-CELLULAR_NETWORK-status").disabled = true;
72870         }
72871
72872         event.on("DisplayBrightnessChanged", displayBrightnessCB);
72873         event.on("DisplayBrightnessChangedByPower", displayBrightnessCB);
72874         event.on("CpuLoadChanged", cpuLoadCB);
72875         event.on("AvailCapacityChanged", availCapacityCB);
72876         event.on("CpuLoadChangedByPower", cpuLoadCB);
72877         event.on("FlightModeChanged", flightModeChangedCB);
72878         event.on("WiFiNetworkStatusChanged", wiFiNetworkStatusCB);
72879         event.on("CellularNetworkStatusChanged", cellularNetworkStatusCB);
72880         event.on("LayoutChanged", layoutCB);
72881     },
72882     terminate: function () {
72883         event.deleteEventHandler("DisplayBrightnessChanged", displayBrightnessCB);
72884         event.deleteEventHandler("DisplayBrightnessChangedByPower", displayBrightnessCB);
72885         event.deleteEventHandler("CpuLoadChanged", cpuLoadCB);
72886         event.deleteEventHandler("AvailCapacityChanged", availCapacityCB);
72887         event.deleteEventHandler("FlightModeChanged", flightModeChangedCB);
72888         event.deleteEventHandler("CpuLoadChangedByPower", cpuLoadCB);
72889         event.deleteEventHandler("WiFiNetworkStatusChanged", wiFiNetworkStatusCB);
72890         event.deleteEventHandler("CellularNetworkStatusChanged", cellularNetworkStatusCB);
72891         event.deleteEventHandler("LayoutChanged", layoutCB);
72892     }
72893 };
72894
72895 });
72896 define('ripple/ui/plugins/invoke', function (require, exports, module) {
72897 /*
72898  *  Copyright 2011 Research In Motion Limited.
72899  *
72900  * Licensed under the Apache License, Version 2.0 (the "License");
72901  * you may not use this file except in compliance with the License.
72902  * You may obtain a copy of the License at
72903  *
72904  * http://www.apache.org/licenses/LICENSE-2.0
72905  *
72906  * Unless required by applicable law or agreed to in writing, software
72907  * distributed under the License is distributed on an "AS IS" BASIS,
72908  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72909  * See the License for the specific language governing permissions and
72910  * limitations under the License.
72911  */
72912 var constants = require('ripple/constants'),
72913     event = require('ripple/event');
72914
72915 module.exports = {
72916     panel: {
72917         domId: "invoke-container",
72918         collapsed: true,
72919         pane: "left"
72920     },
72921     initialize: function () {
72922         document.getElementById("invoke-send")
72923             .addEventListener("click", function () {
72924                 var invokeInfo = {};
72925
72926                 invokeInfo.uri = document.getElementById("invoke-uri-text").value;
72927                 invokeInfo.source = document.getElementById("invoke-source-text").value;
72928                 invokeInfo.target = document.getElementById("invoke-target-text").value;
72929                 invokeInfo.action = document.getElementById("invoke-action-text").value;
72930                 invokeInfo.type = document.getElementById("invoke-mime-type-text").value;
72931                 invokeInfo.extension = document.getElementById("invoke-extension-text").value;
72932                 invokeInfo.data = document.getElementById("invoke-data-text").value;
72933                 if (invokeInfo.data) {
72934                     invokeInfo.data = window.btoa(invokeInfo.data);
72935                 }
72936
72937                 event.trigger("AppInvoke", [invokeInfo]);
72938             }, false);
72939     }
72940 };
72941
72942 });
72943 define('ripple/ui/plugins/touchEvent', function (require, exports, module) {
72944 /*
72945  *  Copyright 2012 Intel Corporation
72946  *
72947  * Licensed under the Apache License, Version 2.0 (the "License");
72948  * you may not use this file except in compliance with the License.
72949  * You may obtain a copy of the License at
72950  *
72951  * http://www.apache.org/licenses/LICENSE-2.0
72952  *
72953  * Unless required by applicable law or agreed to in writing, software
72954  * distributed under the License is distributed on an "AS IS" BASIS,
72955  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
72956  * See the License for the specific language governing permissions and
72957  * limitations under the License.
72958  */
72959
72960 var event = require('ripple/event'),
72961     db = require('ripple/db'),
72962     constants = require('ripple/constants'),
72963     colors  = ["red", "green", "magenta", "blue", "yellow"],
72964     Point,
72965     intervalId,
72966     moveEvents  = {},
72967     currentIndex = 0,
72968     enlargeRatio = 4;
72969
72970 function _exec(operation) {
72971     var canvas = document.getElementById(constants.TOUCHEVENT.CANVAS),
72972         cxt = canvas.getContext("2d"),
72973         altKey = document.getElementById(constants.TOUCHEVENT.ALTKEY),
72974         metaKey = document.getElementById(constants.TOUCHEVENT.METAKEY),
72975         ctrlKey = document.getElementById(constants.TOUCHEVENT.CTRLKEY),
72976         shiftKey = document.getElementById(constants.TOUCHEVENT.SHIFTKEY),
72977         key, eventType;
72978
72979     if (operation === "start") {
72980         altKey.disabled = 'disabled';
72981         metaKey.disabled = 'disabled';
72982         ctrlKey.disabled = 'disabled';
72983         shiftKey.disabled = 'disabled';
72984         clearInterval(intervalId);
72985         currentIndex = 0;
72986         eventType = "touchEvent";
72987     } else if (operation === "cancel") {
72988         altKey.disabled = '';
72989         metaKey.disabled = '';
72990         ctrlKey.disabled = '';
72991         shiftKey.disabled = '';
72992         altKey.checked = false;
72993         metaKey.checked = false;
72994         ctrlKey.checked = false;
72995         shiftKey.checked = false;
72996         cxt.clearRect(0, 0, canvas.width, canvas.height);
72997         moveEvents = {};
72998         eventType = "touchCancel";
72999     }
73000
73001     event.trigger(eventType, [{
73002         data : moveEvents,
73003         keys : [altKey.checked, metaKey.checked, ctrlKey.checked, shiftKey.checked]
73004     }]);
73005 }
73006
73007 Point = function (x, y, color, isDragging) {
73008     var _self = {};
73009
73010     _self.x = x;
73011     _self.y = y;
73012     _self.color = color;
73013     _self.isDragging = isDragging;
73014
73015     return _self;
73016 };
73017
73018 module.exports = {
73019     panel: {
73020         domId: "touchEvent-container",
73021         collapsed: true,
73022         pane: "left",
73023         titleName: "Touch Event",
73024         display: true
73025     },
73026
73027     initialize: function () {
73028         var deviceInfo = require('ripple/devices').getCurrentDevice(),
73029             canvas = document.getElementById(constants.TOUCHEVENT.CANVAS),
73030             button = document.getElementById(constants.TOUCHEVENT.OPTION),
73031             cxt = canvas.getContext("2d"),
73032             points = [],
73033             paint = false,
73034             currentPoint = {};
73035
73036         function drawPoints() {
73037             var key, index, points = [], point;
73038
73039             for (key in moveEvents) {
73040                 points = moveEvents[key];
73041                 cxt.fillStyle = colors[key];
73042
73043                 for (index = 0; index < points.length; index++) {
73044                     point = points[index];
73045                     cxt.beginPath();
73046                     cxt.arc(point.offsetX, point.offsetY, 5, 0, 2 * Math.PI, 1);
73047                     cxt.fill();
73048                 }
73049             }
73050         }
73051
73052         function endDraw(event) {
73053             if (paint) {
73054                 paint = false;
73055                 clearInterval(intervalId);
73056                 moveEvents[currentIndex].push(event);
73057                 drawPoints();
73058
73059                 currentIndex++;
73060                 if (currentIndex === 5)
73061                     currentIndex = 0;
73062             }
73063         }
73064
73065         canvas.addEventListener("mousedown", function (event) {
73066             if (button.value === "Touch Cancel") {
73067                 button.value = "Touch Start";
73068                 _exec("cancel");
73069             }
73070             moveEvents[currentIndex] = [];
73071             currentPoint = event;
73072             moveEvents[currentIndex].push(event);
73073             paint = true;
73074             drawPoints();
73075             intervalId = setInterval(function () {
73076                 moveEvents[currentIndex].push(currentPoint);
73077             }, 100);
73078         });
73079
73080         canvas.addEventListener("mousemove", function (event) {
73081             if (paint) {
73082                 currentPoint = event;
73083                 drawPoints();
73084             }
73085         });
73086
73087         canvas.addEventListener("mouseup", endDraw);
73088         canvas.addEventListener("mouseout", endDraw);
73089         canvas.addEventListener("mouseleave", endDraw);
73090
73091         document.getElementById(constants.TOUCHEVENT.OPTION).addEventListener("click", function () {
73092             if (!moveEvents[0])
73093                 return;
73094
73095             if (this.value === "Touch Start") {
73096                 this.value = "Touch Cancel";
73097                 _exec("start");
73098             } else if (this.value === "Touch Cancel") {
73099                 this.value = "Touch Start";
73100                 _exec("cancel");
73101             }
73102         }, false);
73103
73104         canvas.width = deviceInfo.screen.width / enlargeRatio;
73105         canvas.height = deviceInfo.screen.height / enlargeRatio;
73106     }
73107 };
73108
73109 });
73110 define('ripple/ui/plugins/options', function (require, exports, module) {
73111 /*
73112  *  Copyright 2011 Research In Motion Limited.
73113  *
73114  * Licensed under the Apache License, Version 2.0 (the "License");
73115  * you may not use this file except in compliance with the License.
73116  * You may obtain a copy of the License at
73117  *
73118  * http://www.apache.org/licenses/LICENSE-2.0
73119  *
73120  * Unless required by applicable law or agreed to in writing, software
73121  * distributed under the License is distributed on an "AS IS" BASIS,
73122  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
73123  * See the License for the specific language governing permissions and
73124  * limitations under the License.
73125  */
73126 var about = require('ripple/ui/plugins/about-dialog'),
73127     settings = require('ripple/ui/plugins/settings-dialog'),
73128     tooltip = require('ripple/ui/plugins/tooltip'),
73129     hide,
73130     show;
73131
73132 show = function () {
73133     if (settings.value("remoteInspector")) {
73134         $("#options-menu-build-warning").show();
73135         tooltip.create("#options-menu-build-warning", "Remote Web Inspector should be disabled when packaging for App World release");
73136     }
73137     else {
73138         $("#options-menu-build-warning").hide();
73139     }
73140
73141     $("#options-window").show();
73142     $("#options-menu").show();
73143 };
73144
73145 hide = function () {
73146     $("#options-window").hide();
73147     $("#options-menu").effect("fade", {}, 300);
73148 };
73149
73150 module.exports = {
73151     initialize: function () {
73152         $("#options-menu").menu().hide();
73153         $("#options-menu").bind("click", function (event) {
73154             var target = $("#" + event.target.parentElement.id),
73155                 action;
73156
73157             if (target.hasClass("not-ready")) {
73158                 return;
73159             }
73160
73161             switch (target.attr("id")) {
73162             case "options-menu-build":
73163             case "options-menu-launch":
73164             case "options-menu-sign":
73165                 action = target.attr("id").split("-")[2];
73166                 if (!settings.can(action)) {
73167                     settings.show(action);
73168                 }
73169                 else {
73170                     settings.perform(action);
73171                 }
73172                 break;
73173             case "options-menu-about":
73174                 about.show();
73175                 break;
73176             case "options-menu-settings":
73177                 settings.show();
73178                 break;
73179             default:
73180                 break;
73181             }
73182             hide();
73183         });
73184
73185         $("#options-window").click(hide);
73186         
73187         $("#options-button-about").bind("click", function (event) {
73188             about.show();
73189         });
73190         
73191         hide();
73192     }
73193 };
73194
73195 });
73196 define('ripple/ui/plugins/geoDB', function (require, exports, module) {
73197 /*
73198  *  Copyright 2012 Intel Corporation.
73199  *
73200  * Licensed under the Apache License, Version 2.0 (the "License");
73201  * you may not use this file except in compliance with the License.
73202  * You may obtain a copy of the License at
73203  *
73204  * http://www.apache.org/licenses/LICENSE-2.0
73205  *
73206  * Unless required by applicable law or agreed to in writing, software
73207  * distributed under the License is distributed on an "AS IS" BASIS,
73208  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
73209  * See the License for the specific language governing permissions and
73210  * limitations under the License.
73211  */
73212
73213 var db = require('ripple/db'),
73214     utils = require('ripple/utils'),
73215     lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
73216     _GEO_OBJECTS = "tizen1.0-geocode-objects",
73217     _geoList, _currentGeo, _saveID, _showGeoDetail;
73218
73219 function _getGeo() {
73220     var geoList = [],
73221         data = db.retrieveObject(_GEO_OBJECTS);
73222
73223     utils.forEach(data, function (geo) {
73224         geoList.push(geo);
73225     });
73226     return geoList;
73227 }
73228
73229 function _saveGeo() {
73230     db.saveObject(_GEO_OBJECTS, _geoList);
73231 }
73232
73233 function GeoEntry(addr, coord) {
73234     var _self;
73235     _self = {
73236         address : addr || null,
73237         coordinate : coord || null
73238     };
73239     return _self;
73240 }
73241
73242 function _updateGeoDBSelect() {
73243     var geoDBSelect = document.getElementById("geo-select"),
73244         geoNode, i;
73245
73246     geoDBSelect.innerHTML = "";
73247     for (i = 0; i < _geoList.length; i++) {
73248         geoNode = utils.createElement("option", {
73249             "innerText": "(" + _geoList[i].coordinate.latitude + ", " + _geoList[i].coordinate.longitude + ")",
73250             "value": i
73251         });
73252         if (_currentGeo === Number(geoNode.value)) {
73253             geoNode.selected = true;
73254             _showGeoDetail(_geoList[_currentGeo].coordinate, _geoList[_currentGeo].address);
73255         }
73256         geoDBSelect.appendChild(geoNode);
73257     }
73258 }
73259
73260 function _showGeoDetail(coord, addr) {
73261     jQuery("#geoDB-latitude").val(coord.latitude);
73262     jQuery("#geoDB-longitude").val(coord.longitude);
73263     jQuery("#geoDB-altitude").val(coord.altitude);
73264     jQuery("#geoDB-accuracy").val(coord.accuracy);
73265     jQuery("#geoDB-altitudeAccuracy").val(coord.altitudeAccuracy);
73266     jQuery("#geoDB-heading").val(coord.heading);
73267     jQuery("#geoDB-speed").val(coord.speed);
73268
73269     jQuery("#geoDB-country").val(addr.country);
73270     jQuery("#geoDB-region").val(addr.region);
73271     jQuery("#geoDB-county").val(addr.county);
73272     jQuery("#geoDB-city").val(addr.city);
73273     jQuery("#geoDB-street").val(addr.street);
73274     jQuery("#geoDB-streetNumber").val(addr.streetNumber);
73275     jQuery("#geoDB-premises").val(addr.premises);
73276     jQuery("#geoDB-additionalInformation").val(addr.additionalInformation);
73277     jQuery("#geoDB-postalCode").val(addr.postalCode);
73278 }
73279
73280 function _changeGeoData() {
73281     var id = Number(jQuery("#geo-select").val());
73282     _currentGeo = id;
73283     _showGeoDetail(_geoList[id].coordinate, _geoList[id].address);
73284 }
73285
73286 function _triggerReadOnly(on) {
73287     if (on === true) {
73288         jQuery("#geoDB-table input").attr("readonly", "readonly");
73289         jQuery("#geoDB-add").show();
73290         jQuery("#geoDB-modify").show();
73291         jQuery("#geoDB-delete").show();
73292         jQuery("#geo-select").removeAttr("disabled");
73293         jQuery("#geoDB-save").hide();
73294         jQuery("#geoDB-cancel").hide();
73295     } else {
73296         jQuery("#geoDB-table input").removeAttr("readonly");
73297         jQuery("#geoDB-add").hide();
73298         jQuery("#geoDB-modify").hide();
73299         jQuery("#geoDB-delete").hide();
73300         jQuery("#geo-select").attr("disabled", "disabled");
73301         jQuery("#geoDB-save").show();
73302         jQuery("#geoDB-cancel").show();
73303     }
73304 }
73305
73306 function _addGeoData() {
73307     _triggerReadOnly(false);
73308     jQuery("#geoDB-table input").val("");
73309     _saveID = _geoList.length;
73310     jQuery("#geo-select").val("");
73311 }
73312 function _modifyGeoData() {
73313     _triggerReadOnly(false);
73314     _saveID = _currentGeo;
73315 }
73316 function _deleteGeoData() {
73317     _geoList.splice(_currentGeo, 1);
73318     _saveGeo();
73319     _currentGeo = 0;
73320     _updateGeoDBSelect();
73321 }
73322 function _saveGeoData() {
73323     var entry;
73324     entry = new GeoEntry(new lbs.StructuredAddress({
73325         country: jQuery("#geoDB-country").val(),
73326         region: jQuery("#geoDB-region").val(),
73327         county: jQuery("#geoDB-county").val(),
73328         city: jQuery("#geoDB-city").val(),
73329         street: jQuery("#geoDB-street").val(),
73330         streetNumber: jQuery("#geoDB-streetNumber").val(),
73331         premises: jQuery("#geoDB-premises").val(),
73332         additionalInformation: jQuery("#geoDB-additionalInformation").val(),
73333         postalCode: jQuery("#geoDB-postalCode").val()
73334     }),
73335         new lbs.GeoCoordinates({
73336         latitude: parseFloat(jQuery("#geoDB-latitude").val()),
73337         longitude: parseFloat(jQuery("#geoDB-longitude").val()),
73338         altitude: parseFloat(jQuery("#geoDB-altitude").val()),
73339         accuracy: parseFloat(jQuery("#geoDB-accuracy").val()),
73340         altitudeAccuracy: parseFloat(jQuery("#geoDB-altitudeAccuracy").val()),
73341         heading: parseFloat(jQuery("#geoDB-heading").val()),
73342         speed: parseFloat(jQuery("#geoDB-speed").val())
73343     }));
73344     if (_saveID === _geoList.length)
73345         _geoList.push(entry);
73346     else
73347         _geoList[_saveID] = entry;
73348     
73349     _saveGeo();
73350     _currentGeo = _saveID;
73351     _updateGeoDBSelect();
73352     _triggerReadOnly(true);
73353 }
73354
73355 function _cancelGeoData() {
73356     _triggerReadOnly(true);
73357     _updateGeoDBSelect();
73358 }
73359
73360 module.exports = {
73361     panel: {
73362         domId: "geoDB-container",
73363         collapsed: true,
73364         pane: "right"
73365     },
73366
73367     initialize: function () {
73368         _currentGeo = 0; // set _geoList[0] as default value
73369         _geoList = _getGeo();
73370         _updateGeoDBSelect();
73371         _triggerReadOnly(true);
73372
73373         jQuery("#geo-select").bind("change", function () {
73374             _changeGeoData();
73375         });
73376         jQuery("#geoDB-add").bind("click", function () {
73377             _addGeoData();
73378         });
73379         jQuery("#geoDB-modify").bind("click", function () {
73380             _modifyGeoData();
73381         });
73382         jQuery("#geoDB-delete").bind("click", function () {
73383             _deleteGeoData();
73384         });
73385         jQuery("#geoDB-save").bind("click", function () {
73386             _saveGeoData();
73387         });
73388         jQuery("#geoDB-cancel").bind("click", function () {
73389             _cancelGeoData();
73390         });
73391     }
73392 };
73393
73394 });
73395 define('ripple/ui/plugins/nfc', function (require, exports, module) {
73396 /*
73397  *  Copyright 2012 Intel Corporation
73398  *
73399  * Licensed under the Apache License, Version 2.0 (the "License");
73400  * you may not use this file except in compliance with the License.
73401  * You may obtain a copy of the License at
73402  *
73403  * http://www.apache.org/licenses/LICENSE-2.0
73404  *
73405  * Unless required by applicable law or agreed to in writing, software
73406  * distributed under the License is distributed on an "AS IS" BASIS,
73407  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
73408  * See the License for the specific language governing permissions and
73409  * limitations under the License.
73410  */
73411
73412 var db = require('ripple/db'),
73413     event = require('ripple/event'),
73414     _NFC_TAG = "tizen1.0-nfc-tag",
73415     _NFC_PEER = "tizen1.0-nfc-peer",
73416     _NFC_OUTPUT_MESSAGE = "tizen1.0-nfc-output-message",
73417     powered = false,
73418     polling = false,
73419     isConnected = false,
73420     _tagNDEF = {
73421         type: "GENERIC_TARGET",
73422         isSupportedNDEF: true,
73423         ndefSize: 2,
73424         ndefs: [{
73425             recordCount: 2,
73426             records: [{
73427                 tnf: 1,
73428                 type: "TypeA",
73429                 id: "ID001",
73430                 payload: "This is 1st payload"
73431             }, {
73432                 tnf: 1,
73433                 type: "TypeA",
73434                 id: "ID002",
73435                 payload: "This is 2nd payload"
73436             }]
73437         },
73438             {
73439             recordCount: 2,
73440             records: [{
73441                 tnf: 1,
73442                 type: "TypeA",
73443                 id: "ID001",
73444                 payload: "This is 1st payload"
73445             }, {
73446                 tnf: 1,
73447                 type: "TypeA",
73448                 id: "ID002",
73449                 payload: "This is 2nd payload"
73450             }]
73451         }]
73452     },
73453     _tagRaw = {
73454         type: "GENERIC_TARGET",
73455         isSupportedNDEF: false,
73456         rawData : ""
73457     },
73458     _peerNDEF = {
73459         ndef: {
73460             recordCount: 2,
73461             records: [{
73462                 tnf: 1,
73463                 type: "TypeA",
73464                 id: "ID001",
73465                 payload: "This is 1st payload"
73466             }, {
73467                 tnf: 1,
73468                 type: "TypeA",
73469                 id: "ID002",
73470                 payload: "This is 2nd payload"
73471             }]
73472         }
73473     };
73474
73475 function elementEnableDisableSetting(prop) {
73476     jQuery("#nfc-attach-msg").text("\xa0");
73477     jQuery("#nfc-peer-send-msg").text("\xa0");
73478     if (prop && prop.power !== undefined && prop.power !== null) {
73479         if (prop.power) {
73480             $("#nfc-polling").removeAttr("disabled");
73481             $("#nfc-main-container").show();
73482         } else {
73483             $("#nfc-polling").attr("disabled", "disabled");
73484             $("#nfc-type").removeAttr("disabled");
73485             $("#nfc-main-container").hide();
73486         }
73487     }
73488     if (prop && prop.connectedState !== undefined && prop.connectedState !== null) {
73489         if (prop.connectedState) {
73490             $("#nfc-type").attr("disabled", "disabled");
73491             $("#nfc-tag-type-text").text($("#nfc-tag-type option:selected").text());
73492             $("#nfc-tag-type").hide();
73493             $("#nfc-tag-type-text").show();
73494             $("#nfc-tag-NDEF-support-text").text($("#nfc-tag-NDEF-support option:selected").text());
73495             $("#nfc-tag-NDEF-support").hide();
73496             $("#nfc-tag-NDEF-support-text").show();
73497             $("#nfc-raw-data").attr("disabled", "disabled");
73498         } else {
73499             $("#nfc-type").removeAttr("disabled");
73500             $("#nfc-tag-type").show();
73501             $("#nfc-tag-type-text").hide();
73502             $("#nfc-tag-NDEF-support").show();
73503             $("#nfc-tag-NDEF-support-text").hide();
73504             $("#nfc-raw-data").removeAttr("disabled");
73505         }
73506     }
73507 }
73508
73509 function _initializeElements() {
73510
73511     jQuery(function () {
73512         var stop = false,
73513             isSupportNDEF, type;
73514
73515         jQuery("nfc-tag-ndef-container h3").click(function (event) {
73516             if (stop) {
73517                 event.stopImmediatePropagation();
73518                 event.preventDefault();
73519                 stop = false;
73520             }
73521         });
73522         jQuery("#nfc-tag-ndef-container").accordion("destroy").accordion({
73523             header: "> div > h3",
73524             autoHeight: false
73525         });
73526         jQuery("nfc-nfcpeer h3").click(function (event) {
73527             if (stop) {
73528                 event.stopImmediatePropagation();
73529                 event.preventDefault();
73530                 stop = false;
73531             }
73532         });
73533         jQuery("#nfc-nfcpeer").accordion("destroy").accordion({
73534             header: "> div > h3",
73535             autoHeight: false
73536         });
73537         jQuery("#nfc-tag-NDEF-support").bind("change", function () {
73538             isSupportNDEF = jQuery("#nfc-tag-NDEF-support").val();
73539             if (isSupportNDEF === "Yes") {
73540                 jQuery("#nfc-tag-ndef-container").fadeIn();
73541                 jQuery("#nfc-tag-raw-container").hide();
73542             } else {
73543                 jQuery("#nfc-tag-ndef-container").hide();
73544                 jQuery("#nfc-tag-raw-container").fadeIn();
73545             }
73546         });
73547         jQuery("#nfc-type").bind("change", function () {
73548             type = jQuery("#nfc-type").val();
73549             if (type === "Tag") {
73550                 jQuery("#nfc-nfctag").fadeIn();
73551                 jQuery("#nfc-nfcpeer").hide();
73552             } else {
73553                 jQuery("#nfc-nfctag").hide();
73554                 jQuery("#nfc-nfcpeer").fadeIn();
73555             }
73556             elementEnableDisableSetting();
73557         });
73558         jQuery("#nfc-power").bind("change", function () {
73559             var status;
73560             status = jQuery("#nfc-power").val() === "On" ? true : false;
73561             event.trigger("nfc-power-setting", [status]);
73562         });
73563         jQuery("#nfc-polling").bind("change", function () {
73564             var status;
73565             status = jQuery("#nfc-polling").val() === "On" ? true : false;
73566             event.trigger("nfc-polling-setting", [status]);
73567         });
73568         jQuery("#nfc-attach").bind("click", function () {
73569             var type, isAttached;
73570             isAttached = jQuery("#nfc-attach").children().text() === "Attach" ? true : false;
73571             jQuery("#nfc-attach-msg").text("\xa0");
73572
73573             if (!polling && isAttached) {
73574                 jQuery("#nfc-attach-msg").text("Polling:Off, attach won't work");
73575                 return;
73576             }
73577             type = jQuery("#nfc-type").val();
73578             event.trigger("nfc-attach-setting", [type, isAttached]);
73579         });
73580         jQuery("#nfc-peer-send").bind("click", function () {
73581             jQuery("#nfc-peer-send-msg").text("\xa0");
73582             if (!isConnected) {
73583                 jQuery("#nfc-peer-send-msg").text("Disconnected. Send won't work");
73584                 return;
73585             }
73586             db.saveObject(_NFC_PEER, _peerNDEF);
73587             event.trigger("nfc-peer-sending-ndef", []);
73588         });
73589     });
73590 }
73591
73592 module.exports = {
73593     panel: {
73594         domId: "nfc-container",
73595         collapsed: true,
73596         pane: "left",
73597         titleName: "NFC",
73598         display: true
73599     },
73600     initialize: function () {
73601         _initializeElements();
73602         event.on("nfc-power-changed", function (status) {
73603             powered = status;
73604             if (powered === true) {
73605                 $("#nfc-power").val("On");
73606             } else {
73607                 $("#nfc-power").val("Off");
73608             }
73609             elementEnableDisableSetting({power: status});
73610         });
73611         event.on("nfc-polling-changed", function (status) {
73612             polling = status;
73613             if (polling === true) {
73614                 $("#nfc-polling").val("On");
73615             } else {
73616                 $("#nfc-polling").val("Off");
73617             }
73618             elementEnableDisableSetting();
73619         });
73620         event.on("nfc-connectedState-changed", function (state) {
73621             var i, type, isSupportedNDEF, str, bytes = [];
73622             isConnected = state;
73623             elementEnableDisableSetting({connectedState: state});
73624             type = jQuery("#nfc-type").val();
73625             if (state) {
73626                 jQuery("#nfc-attach").children().text("Detach");
73627                 jQuery("#nfc-tag-connection").text("Connected");
73628                 jQuery("#nfc-peer-connection").text("Connected");
73629                 if (type === "Tag") {
73630                     isSupportedNDEF = jQuery("#nfc-tag-NDEF-support").val() === "Yes" ? true : false;
73631                     if (isSupportedNDEF) {
73632                         _tagNDEF.type = jQuery("#nfc-tag-type").val();
73633                         db.saveObject(_NFC_TAG, _tagNDEF);
73634                     } else {
73635                         _tagRaw.type = jQuery("#nfc-tag-type").val();
73636                         str = jQuery("#nfc-raw-data").val();
73637                         for (i = 0; i < str.length; i++) {
73638                             bytes.push(str.charCodeAt(i));
73639                         }
73640                         _tagRaw.rawData = bytes;
73641                         db.saveObject(_NFC_TAG, _tagRaw);
73642                     }
73643                     event.trigger("nfc-tag-send", [true]);
73644                 } else {
73645                     event.trigger("nfc-peer-send", [true]);
73646                 }
73647             } else {
73648                 jQuery("#nfc-attach").children().text("Attach");
73649                 jQuery("#nfc-tag-connection").text("Disconnected");
73650                 jQuery("#nfc-peer-connection").text("Disconnected");
73651                 jQuery("#nfc-output").text("");
73652                 jQuery("#nfc-output-table").hide();
73653                 if (type === "Tag") {
73654                     event.trigger("nfc-tag-send", [false]);
73655                 } else {
73656                     event.trigger("nfc-peer-send", [false]);
73657                 }
73658             }
73659         });
73660         event.on("nfc-output-msg", function () {
73661             var msg;
73662             msg = db.retrieve(_NFC_OUTPUT_MESSAGE);
73663             jQuery("#nfc-output").text(msg);
73664             jQuery("#nfc-output-table").show();
73665         });
73666     }
73667 };
73668
73669
73670 });
73671 define('ripple/ui/plugins/settings-dialog', function (require, exports, module) {
73672 /*
73673  *  Copyright 2011 Research In Motion Limited.
73674  *
73675  * Licensed under the Apache License, Version 2.0 (the "License");
73676  * you may not use this file except in compliance with the License.
73677  * You may obtain a copy of the License at
73678  *
73679  * http://www.apache.org/licenses/LICENSE-2.0
73680  *
73681  * Unless required by applicable law or agreed to in writing, software
73682  * distributed under the License is distributed on an "AS IS" BASIS,
73683  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
73684  * See the License for the specific language governing permissions and
73685  * limitations under the License.
73686  */
73687 var db = require('ripple/db'),
73688     utils = require('ripple/utils'),
73689     platform = require('ripple/platform'),
73690     notifications = require('ripple/notifications'),
73691     tooltip = require('ripple/ui/plugins/tooltip'),
73692     bus = require('ripple/bus'),
73693     required = {
73694         build: {
73695             "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName"],
73696             "webworks.bb10": ["sdk", "projectPath", "outputPath", "projectName"],
73697             "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName"]
73698         },
73699         sign: {
73700             "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName", "csk_password", "p12_password", "bundle_number"],
73701             "webworks.bb10": ["sdk", "projectPath", "outputPath", "projectName", "signingPassword", "bundle_number"],
73702             "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName", "signingPassword"]
73703         },
73704         launch: {
73705             "webworks.tablet": ["sdk", "projectPath", "outputPath", "projectName", "device"],
73706             "webworks.bb10": ["sdk", "projectPath", "outputPath", "projectName", "device"],
73707             "webworks.handset": ["sdk", "projectPath", "outputPath", "projectName", "simulator"]
73708         }
73709     },
73710     _settings = {
73711         get: function () {
73712             var settings = db.retrieveObject("build-settings", platform.getPersistencePrefix()) || {};
73713             settings.debug = !!settings["remoteInspector"];
73714
73715             return settings;
73716         },
73717         save: function (settings) {
73718             db.saveObject("build-settings", settings, platform.getPersistencePrefix());
73719         }
73720     },
73721     port = "9910",
73722     host = "http://127.0.0.1:" + port + "/ripple",
73723     progressContainer = jQuery("#options-progress"),
73724     progressInterval,
73725     _passwordFields = [
73726         "signingPassword",
73727         "devicePassword",
73728         "csk_password",
73729         "p12_password"
73730     ],
73731     _checkboxFields = [
73732         "remoteInspector"
73733     ],
73734     _passwords = {},
73735     _self;
73736
73737 function missing(settings, action) {
73738     return required[action][platform.current().id].filter(function (field) {
73739         return !settings.hasOwnProperty(field);
73740     });
73741 }
73742
73743 function _isPasswordField(id) {
73744     var match = typeof id === "string" && new RegExp("^" + id + "$", "i");
73745     return match && utils.some(_passwordFields, function (name) {
73746         return match.test(name);
73747     });
73748 }
73749
73750 function _isCheckboxField(id) {
73751     var match = typeof id === "string" && new RegExp("^" + id + "$", "i");
73752     return match && utils.some(_checkboxFields, function (name) {
73753         return match.test(name);
73754     });
73755 }
73756
73757 function table(action) {
73758     var _table = $("<table class='panel-table'>"),
73759         _row = {
73760             row: function (item, desc, opts) {
73761                 var id = "settings-field-" + item.toLowerCase(),
73762                     input = "",
73763                     save = function () {
73764                         var s = _settings.get(),
73765                             v = $("#" + id).val(),
73766                             val = opts.type === "number" ? parseInt(v, 10) : v;
73767
73768                         if (_isCheckboxField(item)) {
73769                             s[item] = $("#" + id).prop("checked");
73770                         }
73771                         else if (val) {
73772                             (_isPasswordField(item) ? _passwords : s)[item] = val;
73773                         }
73774                         else {
73775                             delete s[item];
73776                         }
73777                         _settings.save(s);
73778
73779                         if (opts.onChanged) {
73780                             opts.onChanged(s[item]);
73781                         }
73782                     },
73783                     row;
73784
73785                 opts = opts || { type: "text" };
73786
73787                 switch (opts.type) {
73788                 case "select":
73789                     input = "<select id='" + id + "' class='ui-state-default ui-corner-all' style='width:100%'/>";
73790                     break;
73791                 case "span":
73792                     input = "<span id = '" + id + "'>" + opts.text + "</span>";
73793                     break;
73794                 default:
73795                     input = "<input id='" + id + "' type='" + opts.type + "' class='ui-state-default ui-corner-all' style='width:90%' />";
73796                     break;
73797                 }
73798
73799                 row = $("<tr>" +
73800                     "<td><label for='" + id + "' class='ui-text-label'>" + desc + "</label></td>" +
73801                     "<td>" + input + "</td>" +
73802                 "</tr>");
73803
73804                 row.appendTo(_table);
73805
73806                 //bind save handlers to the row
73807                 utils.bindAutoSaveEvent(row.find("#" + id).change(save), save);
73808
73809                 return _row;
73810             },
73811             appendTo: function (id) {
73812                 var fs = $("<fieldset class='main'><legend class='cap-text'>" + action + "</legend></fieldset>");
73813
73814                 $(_table).appendTo(fs);
73815                 fs.appendTo($(id));
73816             }
73817         };
73818
73819     return _row;
73820 }
73821
73822 function create() {
73823     var build = table('build'),
73824         sign = table('sign'),
73825         launch = table('launch');
73826
73827     build
73828         .row("sdk", "SDK Path")
73829         .row("projectPath", "Project Root")
73830         .row("projectName", "Archive Name")
73831         .row("outputPath", "Output Folder")
73832         .row("remoteInspector", "Enable Remote Web Inspector", {
73833             type: "checkbox",
73834             onChanged: function (enabled) {
73835                 if (enabled) {
73836                     $("#options-menu-build-warning").show();
73837                     tooltip.create("#options-menu-build-warning", "Remote Web Inspector should be disabled when packaging for App World release");
73838                 }
73839                 else {
73840                     $("#options-menu-build-warning").hide();
73841                 }
73842             }
73843         })
73844         .appendTo("#settings-tabs-build");
73845
73846     switch (platform.current().id) {
73847     case "webworks.handset":
73848         sign.row("signingPassword", "Password", {
73849             type: "password"
73850         });
73851
73852         launch.row("simulator", "Simulator", {
73853             type: "select"
73854         });
73855
73856         launch.row("simulatorstatus", "Simulator", {
73857             type: "span",
73858             text: "Searching for simulators ..."
73859         });
73860         
73861         break;
73862
73863     case "webworks.tablet":
73864         sign.row("csk_password", "CSK Password", {
73865             type: "password"
73866         });
73867         sign.row("p12_password", "P12 Password", {
73868             type: "password"
73869         });
73870         sign.row("bundle_number", "Bundle Number", {
73871             type: "number"
73872         });
73873
73874         launch.row("device", "Playbook IP");
73875         launch.row("devicePassword", "Playbook Password", {
73876             type: "password"
73877         });
73878
73879         break;
73880
73881     case "webworks.bb10":
73882         sign.row("signingPassword", "Signing Password", {
73883             type: "password"
73884         });
73885         sign.row("bundle_number", "Bundle Number", {
73886             type: "number"
73887         });
73888
73889         launch.row("device", "Device IP");
73890         launch.row("devicePassword", "Device Password", {
73891             type: "password"
73892         });
73893
73894         break;
73895     }
73896
73897     sign.appendTo("#settings-tabs-build");
73898     launch.appendTo("#settings-tabs-build");
73899
73900     $("#settings-field-simulator").parent().parent().hide();
73901 }
73902
73903 function populate(settings) {
73904     var fill = function (action, prop) {
73905         var element = $("#settings-field-" + prop.toLowerCase());
73906
73907         if (_isPasswordField(prop)) {
73908             element.val(_passwords[prop]);
73909         }
73910         else if (_isCheckboxField(prop)) {
73911             element.prop("checked", settings[prop]);
73912         }
73913         else {
73914             element.val(settings[prop]);
73915         }
73916     };
73917
73918     fill("build", "sdk");
73919     fill("build", "projectPath");
73920     fill("build", "outputPath");
73921     fill("build", "projectName");
73922     fill("build", "remoteInspector");
73923
73924     fill("sign", "signingPassword");
73925     fill("sign", "csk_password");
73926     fill("sign", "p12_password");
73927     fill("sign", "bundle_number");
73928
73929     fill("launch", "simulator");
73930     fill("launch", "device");
73931     fill("launch", "devicePassword");
73932 }
73933
73934 function url(action) {
73935     var target = "";
73936
73937     switch (platform.current().id) {
73938     case "webworks.bb10":
73939         target = "bb10";
73940         break;
73941     case "webworks.tablet":
73942         target = "tablet";
73943         break;
73944     case "webworks.handset":
73945         target = "smartphone";
73946         break;
73947     }
73948
73949     return host + "/" + action + "/" + target;
73950 }
73951
73952 function enable(action) {
73953     $("#options-menu-" + action).removeClass("not-ready");
73954     if (action === "launch") {
73955         $("#settings-field-simulatorstatus").parent().parent().hide();
73956         $("#settings-field-simulator").parent().parent().show();
73957     }
73958 }
73959
73960 function disable(action) {
73961     $("#options-menu-" + action).addClass("not-ready");
73962     if (action === "launch") {
73963         $("#settings-field-simulatorstatus").parent().parent().show();
73964         $("#settings-field-simulator").parent().parent().hide();
73965     }
73966 }
73967
73968 function getSimulators() {
73969     if (!_settings.get().sdk) {
73970         $("#settings-field-simulatorstatus").text("");
73971         disable("launch");
73972         return;
73973     }
73974
73975     bus.ajax(
73976         "POST",
73977         host + "/simulators",
73978         _settings.get(),
73979         function (resp) {
73980             var sims = resp.data.simulators;
73981
73982             $("#settings-field-simulator").empty();
73983             if (sims.length > 0) {
73984                 $(resp.data.simulators.map(function (sim) {
73985                     return "<option value='" + sim + "'>" + sim + "</option>";
73986                 }).join()).appendTo("#settings-field-simulator");
73987
73988                 enable("launch");
73989             }
73990             else {
73991                 disable("launch");
73992                 $("#settings-field-simulatorstatus").text("No simulators found :(");
73993             }
73994         },
73995         function () {
73996             disable("launch");
73997             $("#settings-field-simulatorstatus").text("Error attempting to get simulators :(");
73998         }
73999     );
74000 }
74001
74002 function _startProgress() {
74003     if (progressInterval) {
74004         window.clearInterval(progressInterval);
74005     }
74006     progressInterval = window.setInterval(function () {
74007         if (progressContainer.html().length === 5) {
74008             progressContainer.html(".");
74009         }
74010         else {
74011             progressContainer.html(progressContainer.html() + ".");
74012         }
74013     }, 250);
74014 }
74015
74016 function _endProgress() {
74017     window.clearInterval(progressInterval);
74018     progressInterval = null;
74019     progressContainer.html("");
74020 }
74021
74022
74023 _self = {
74024     initialize: function () {
74025         $("#settings-dialog").dialog({
74026             autoOpen: false,
74027             modal: true,
74028             width: 700,
74029             title: "Settings",
74030             position: 'center'
74031         }).hide();
74032
74033         $("#settings-tabs").tabs();
74034         $("#settings-action").button();
74035
74036         create();
74037
74038         if (platform.current().id === "webworks.handset") {
74039             enable("build");
74040             enable("sign");
74041             enable("settings");
74042
74043             getSimulators();
74044             $("#settings-field-sdk").change(getSimulators);
74045         }
74046         else if (platform.current().id === "webworks.tablet") {
74047             enable("build");
74048             enable("sign");
74049             enable("launch");
74050             enable("settings");
74051         }
74052         else if (platform.current().id === "webworks.bb10") {
74053             enable("build");
74054             enable("sign");
74055             enable("launch");
74056             enable("settings");
74057         }
74058     },
74059
74060     can: function (action) {
74061         var settings = {};
74062
74063         utils.mixin(_settings.get(), settings);
74064         utils.mixin(_passwords, settings);
74065
74066         return action && missing(settings, action).length === 0;
74067     },
74068
74069     value: function (prop) {
74070         var settings = {};
74071
74072         utils.mixin(_settings.get(), settings);
74073         return settings[prop];
74074     },
74075
74076     show: function (action) {
74077         var settings = {};
74078
74079         utils.mixin(_settings.get(), settings);
74080         utils.mixin(_passwords, settings);
74081
74082         populate(settings);
74083
74084         $("#settings-dialog").dialog("open");
74085         $("#settings-action").button("option", "label", action || "Close")[action ? "show" : "hide"]();
74086
74087         if (action) {
74088             missing(settings, action).forEach(function (field) {
74089                 $("#settings-field-" + field.toLowerCase()).effect("highlight", {color: "red"}, 1500);
74090             });
74091
74092             $("#settings-action").unbind("click").click(function () {
74093                 if (_self.can(action)) {
74094                     _self.perform(action);
74095                     $("#settings-dialog").dialog("close");
74096                 }
74097                 else {
74098                     _self.show(action);
74099                 }
74100             });
74101         }
74102     },
74103
74104     perform: function (action) {
74105         var settings = _settings.get(),
74106             data = {},
74107             poll = function (resp) {
74108                 var notifications = require("ripple/notifications");
74109
74110                 if (resp && resp.code !== 0) {
74111                     notifications.openNotification("error", "Build request failed with message: " + resp.msg);
74112                     _endProgress();
74113                 }
74114                 else {
74115                     if (resp && resp.data.status === "building") {
74116                         setTimeout(function () {
74117                             bus.ajax(
74118                                 "GET",
74119                                 host + "/build_status/" + resp.data.id,
74120                                 null,
74121                                 poll,
74122                                 function (error) {
74123                                     notifications.openNotification("error", "Build request failed with message: " + JSON.stringify(error));
74124                                     _endProgress();
74125                                 }
74126                             );
74127                         }, 500);
74128                     }
74129                     else {
74130                         if (action.match(/sign/)) {
74131                             settings["bundle_number"] = $("#settings-field-bundle_number").val(parseInt($("#settings-field-bundle_number").val(), 10) + 1).val();
74132                             _settings.save(settings);
74133                         }
74134                         notifications.openNotification("normal", "Build succeeded!");
74135                         _endProgress();
74136                     }
74137                 }
74138             };
74139
74140         utils.mixin(settings, data);
74141         utils.mixin(_passwords, data);
74142
74143         bus.ajax(
74144             "POST",
74145             url(action),
74146             data,
74147             function (resp) {
74148                 _startProgress();
74149                 poll(resp);
74150             },
74151             function (error) {
74152                 var message = "Build request failded with message: " + error.data;
74153
74154                 if (error.code === 0 || error.code === 404) {
74155                     message += "<br>This could be due to the Build and Deploy services not running or not being installed";
74156                 }
74157
74158                 notifications.openNotification("error", message);
74159             }
74160         );
74161     }
74162 };
74163
74164 module.exports = _self;
74165
74166 });
74167 define('ripple/ui/plugins/power', function (require, exports, module) {
74168 /*
74169  *  Copyright 2012 Intel Corporation
74170  *
74171  * Licensed under the Apache License, Version 2.0 (the "License");
74172  * you may not use this file except in compliance with the License.
74173  * You may obtain a copy of the License at
74174  *
74175  * http://www.apache.org/licenses/LICENSE-2.0
74176  *
74177  * Unless required by applicable law or agreed to in writing, software
74178  * distributed under the License is distributed on an "AS IS" BASIS,
74179  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
74180  * See the License for the specific language governing permissions and
74181  * limitations under the License.
74182  */
74183
74184 var db = require('ripple/db'),
74185     event = require('ripple/event'),
74186     constants = require('ripple/constants'),
74187     _volume  = document.getElementById(constants.BATTERY.VOLUME),
74188     _volumeLabel  = document.getElementById(constants.BATTERY.VOLUME + "-label"),
74189     _charging = document.getElementById(constants.BATTERY.CHARGING),
74190     _battery = {
74191         volume: 600,
74192         level:  1.0,
74193         timerId: null,
74194         charge: function (isStart, isCharge, callback) {
74195             var currentVolume,
74196                 checkValue = function () {
74197                     if (_battery.level < 0 || _battery.level > 1.0 || !isStart) {
74198                         clearInterval(_battery.timerId);
74199                         _battery.timerId = null;
74200                         if (_battery.level < 0)
74201                             _battery.level = 0;
74202                         else if (_battery.level > 1.0)
74203                             _battery.level = 1.0;
74204                     }
74205                 };
74206
74207             if (isStart && !_battery.timerId) {
74208                 _battery.timerId = setInterval(function () {
74209                     currentVolume = isCharge ? _battery.level * _battery.volume + 1 : _battery.level * _battery.volume - 1;
74210                     _battery.level = currentVolume / _battery.volume;
74211                     checkValue();
74212                     return callback && callback();
74213                 }, 1000);
74214             }
74215             checkValue();
74216             return callback && callback();
74217         }
74218     };
74219
74220 function _triggerEvent(chargingStatus, chargingTime, dischargingTime, level, type) {
74221     var status = {
74222         charging: chargingStatus,
74223         chargingTime: chargingTime,
74224         dischargingTime: dischargingTime,
74225         level: level,
74226         type: type
74227     };
74228     event.trigger("BatteryEvent", [status]); // for w3c battery api
74229     // for tizen systeminfo api
74230     if (type === "levelchange") {
74231         event.trigger("BatteryLevelChanged", [level]);
74232     }
74233     if (type === "chargingchange") {
74234         event.trigger("BatteryChargingChanged", [status]);
74235     }
74236 }
74237
74238 function _updateLevelIcons() {
74239     var colors = ["black", "black", "black", "black", "black", "black", "#404040", "#606060", "#808080", "#b0b0b0", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff"],
74240         colorIndex = 10 - Math.round(_battery.level * 10),
74241         index;
74242
74243     //map the battery level to the color range
74244     for (index = 0 ; index <= 5 ; index++) {
74245         $("#block" + index).css("backgroundColor", colors[colorIndex]);
74246         colorIndex++;
74247     }
74248 }
74249
74250 function _setVolumeReadOnly(flag) {
74251     if (flag) {
74252         $("#" + constants.BATTERY.VOLUME).hide();
74253         $("#" + constants.BATTERY.VOLUME + "-label").show();
74254     } else {
74255         $("#" + constants.BATTERY.VOLUME).show();
74256         $("#" + constants.BATTERY.VOLUME + "-label").hide();
74257     }
74258 }
74259
74260 function _startDischarging() {
74261     var remainVolume = 0;
74262
74263     if ($("#simulate-low-battery #low-battery-remain-time").val() <= 0) {
74264         $("#simulate-low-battery #low-battery-remain-time").val(0);
74265     }
74266     remainVolume = Number($("#simulate-low-battery #low-battery-remain-time").val());
74267     if ($("#simulate-low-battery #low-battery-start-at").val() > 100) {
74268         $("#simulate-low-battery #low-battery-start-at").val(100);
74269     }
74270     if ($("#simulate-low-battery #low-battery-start-at").val() <= 0) {
74271         $("#simulate-low-battery #low-battery-start-at").val(0);
74272     }
74273     _battery.level = $("#simulate-low-battery #low-battery-start-at").val() / 100.0;
74274     if (_battery.level === 0 || remainVolume === 0) {
74275         $("#simulate-low-battery").dialog("close");
74276         _stopDischarging();
74277         return;
74278     }
74279     _setVolumeReadOnly(true);
74280     if (_charging.checked) {
74281         _charging.checked = false;
74282         _battery.charge(false);
74283     }
74284
74285     _charging.disabled = true;
74286     $("#remaining-time-label").html("Remaining Time to empty (seconds)");
74287     $("#charging-state").html("Plugged in?");
74288
74289     $("#remain-time").show();
74290     _battery.volume = remainVolume / _battery.level;
74291     _volumeLabel.innerText = (_battery.level * 100).toFixed(2);
74292     _battery.charge(true, false, function () {
74293         _volumeLabel.innerText = (_battery.level * 100).toFixed(2);
74294         _volume.value = (_battery.level * 100).toFixed(2);
74295         changeBatteryVolume();
74296         $("#remain-time").html(Math.round(_battery.volume * _battery.level) + " Seconds");
74297         _updateLevelIcons();
74298         if (_battery.level <= 0.0) {
74299             _stopDischarging();
74300         }
74301     });
74302     $("#simulate-low-battery").dialog("close");
74303     $("#simulate-low-battery-btn").hide();
74304     $("#stop-btn").show();
74305     _triggerEvent(false, Infinity, Math.round(_battery.volume * _battery.level), _battery.level, "chargingtimechange");
74306 }
74307
74308 function _stopDischarging() {
74309     _charging.disabled = false;
74310     _battery.level = _volume.value / 100.0;
74311     $("#remain-time").hide();
74312     $("#remain-time").html("");
74313     $("#remaining-time-label").html("Remaining Time (seconds)");
74314     _setVolumeReadOnly(false);
74315     _battery.charge(false);
74316     $("#simulate-low-battery-btn").show();
74317     $("#stop-btn").hide();
74318     _updateLevelIcons();
74319 }
74320
74321 function _setCharging() {
74322     // update the UI parts
74323     if (_charging.checked) {
74324         _battery.volume = 600;
74325         _battery.level = _volume.value / 100;
74326         _setVolumeReadOnly(true);
74327         $("#remain-time").show();
74328         $("#remaining-time-label").html("Remaining Time to fully charged (seconds)");
74329         $("#charging-state").html("Plugged in - charging rate 0.17%/second");
74330         _triggerEvent(true, Math.round(_battery.volume * (1 - _battery.level)), Infinity, _battery.level, "chargingchange");
74331     } else {
74332         _battery.level = _volume.value / 100.0;
74333         _updateLevelIcons();
74334         $("#remain-time").hide();
74335         $("#remain-time").html("");
74336         _setVolumeReadOnly(false);
74337         $("#remaining-time-label").html("Remaining Time (seconds)");
74338         $("#charging-state").html("Plugged in?");
74339         _triggerEvent(false, Infinity, Math.round(_battery.volume * _battery.level), _battery.level, "chargingchange");
74340     }
74341     // if it's unchecked, the timer will stop in this function call, the UI update blow it
74342     _battery.charge(_charging.checked, true, function () {
74343         _volumeLabel.innerText = (_battery.level * 100).toFixed(2);
74344         _volume.value = (_battery.level * 100).toFixed(2);
74345         changeBatteryVolume();
74346         $("#remain-time").html(Math.round(_battery.volume * (1 - _battery.level)) + " Seconds");    //show current remain time
74347         _updateLevelIcons();
74348     });
74349 }
74350
74351 function changeBatteryVolume() {
74352     if (_volume.value < 0)
74353         _volume.value = 0;
74354     else if (_volume.value > 100)
74355         _volume.value = 100;
74356
74357     _battery.level = _volume.value / 100.0;
74358     if (_charging.checked === true) {
74359         _triggerEvent(true, Math.round(_battery.volume * (1 - _battery.level)), Infinity, _battery.level, "levelchange");
74360     } else {
74361         _triggerEvent(false, Infinity, Math.round(_battery.volume * _battery.level), _battery.level, "levelchange");
74362     }
74363     db.save(constants.BATTERY.VOLUME, _volume.value);
74364     _updateLevelIcons();
74365 }
74366
74367 function initBattery() {
74368     $("#" + constants.BATTERY.CHARGING).bind("change", _setCharging);
74369
74370     $("#simulate-low-battery-btn").bind("click", function () {
74371         $("#simulate-low-battery").dialog("open");
74372     });
74373
74374     $("#simulate-low-battery-cancel").bind("click", function () {
74375         $("#low-battery-start-at").val = 20;  //UI initialize
74376         $("#low-battery-remain-time").val = 1200;
74377         $("#simulate-low-battery").dialog("close");
74378     });
74379
74380     $("#simulate-low-battery-start").bind("click", _startDischarging);
74381     $("#stop-btn").bind("click", _stopDischarging);
74382
74383     $("#" + constants.BATTERY.VOLUME).bind("change", function () {
74384         changeBatteryVolume();
74385     });
74386
74387     _charging.checked = false;
74388     _battery.level = db.retrieve(constants.BATTERY.VOLUME) / 100.0;
74389     if (isNaN(_battery.level)) {
74390         _battery.level = 1;
74391     }
74392     _volume.value = (_battery.level * 100).toFixed(2);
74393     _updateLevelIcons();
74394     $("#simulate-low-battery").dialog({
74395         resizable: false,
74396         draggable: true,
74397         modal: true,
74398         autoOpen: false,
74399         position: 'center',
74400         minWidth: '460',
74401         minHeight: '240'
74402     });
74403 }
74404
74405 module.exports = {
74406     panel: {
74407         domId: "power-container",
74408         collapsed: true,
74409         pane: "left",
74410         titleName: "Power Manager",
74411         display: true
74412     },
74413
74414     initialize: function () {
74415         initBattery();
74416     }
74417 };
74418
74419 });
74420 define('ripple/ui/plugins/settings-menu', function (require, exports, module) {
74421 /*
74422  *  Copyright 2011 Research In Motion Limited.
74423  *
74424  * Licensed under the Apache License, Version 2.0 (the "License");
74425  * you may not use this file except in compliance with the License.
74426  * You may obtain a copy of the License at
74427  *
74428  * http://www.apache.org/licenses/LICENSE-2.0
74429  *
74430  * Unless required by applicable law or agreed to in writing, software
74431  * distributed under the License is distributed on an "AS IS" BASIS,
74432  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
74433  * See the License for the specific language governing permissions and
74434  * limitations under the License.
74435  */
74436 var utils = require('ripple/utils'),
74437     constants = require('ripple/constants'),
74438     platform = require('ripple/platform'),
74439     db = require('ripple/db'),
74440     _applicationStateId
74441     ;
74442
74443
74444 function reload() {
74445     window.tinyHipposReload = true;
74446     location.reload();
74447 }
74448
74449 function _showSettingMenu() {
74450     var contentTable = "",
74451     settings = [],
74452     _applicationState = [],
74453     _applicationStateTmp = [],
74454     unselectedNum = 0,
74455     i = 0;
74456
74457     if ($("#settings-menu-popup").is(":visible")) {
74458         $("#settings-menu-popup").hide("slide", {direction: "up"}, "slow");
74459         $("#overlayBackground").hide("fade", "slow");
74460         return;
74461     }
74462
74463     _applicationStateId = constants.COMMON.APPLICATION_STATE + platform.current().id;
74464
74465     _applicationStateTmp = db.retrieveObject(_applicationStateId) || [];
74466
74467     utils.forEach(_applicationStateTmp, function (obj) {
74468         if (obj.display)
74469             _applicationState.push(obj);
74470     });
74471
74472     utils.forEach(_applicationStateTmp, function (obj) {
74473         if (!obj.display)
74474             _applicationState.push(obj);
74475     });
74476
74477     $("#settings-menu-content-panel-table").remove();
74478
74479     contentTable = '<table id="settings-menu-content-panel-table" class="settings-menu-content-table">';
74480     utils.forEach(_applicationState, function (obj) {
74481         var checked = obj.display ? 'checked="yes"':"";
74482         contentTable += '<tr><td><input name="panel-display-setting" type="checkbox" class="settings-menu-checkbox "' +
74483                         checked + '></input>' +
74484                         obj.titleName + '</td></tr>\n';
74485     });
74486     contentTable += "</table>";
74487
74488     $("#settings-menu-container-div").append(contentTable);
74489     $("#settings-menu-popup").css("top", 50);
74490     $("#settings-menu-popup").css("left", $(window).width() - 340);
74491
74492     $("#overlayBackground").css("width", $(window).width());
74493     $("#overlayBackground").css("height", $(window).height());
74494     $("#overlayBackground").show("fade", "slow");
74495     $("#settings-menu-popup").show("slide", {direction: "up"}, "slow");
74496
74497     $("#settings-menu-save-btn").unbind('click');
74498     $("#settings-menu-save-btn").bind("click", function (event) {
74499         $("input[name='panel-display-setting']").each(function (i, a) {
74500             settings.push(a.checked);
74501         });
74502
74503         utils.forEach(_applicationState, function (obj) {
74504             if (!settings[i])
74505                 obj.collapsed = true;
74506             obj.display = settings[i];
74507             i++;
74508         }, this);
74509   
74510         db.saveObject(_applicationStateId, _applicationState);
74511         _applicationStateTmp = db.retrieveObject(_applicationStateId) || [];
74512
74513         $("#settings-menu-popup").hide("slide", {direction: "up"}, "slow");
74514         $("#overlayBackground").hide("fade", "slow");
74515         setTimeout(reload, 500);
74516     });
74517
74518     $(".settings-menu-content-table td").unbind('click');
74519     $(".settings-menu-content-table td").bind("click", function (event) {
74520         var checkbox;
74521         if (($(event.target).children().length === 0)) {
74522             return;
74523         } else {
74524             checkbox = $(event.target).children();
74525         }
74526         
74527         if (checkbox.is(':checked')) {
74528             checkbox.prop('checked', false);
74529         }
74530         else
74531             checkbox.prop('checked', true);
74532     });
74533
74534     $("#settings-menu-close-btn").unbind('click');
74535     $("#settings-menu-close-btn").bind("click", function (event) {
74536         if ($("#settings-menu-popup").is(":visible")) {
74537             $("#settings-menu-popup").hide("slide", {direction: "up"}, "slow");
74538             $("#overlayBackground").hide("fade", "slow");
74539             return;
74540         }
74541     });
74542
74543     $(window).bind('resize', function () {
74544         $("#settings-menu-popup").css("top", 50);
74545         $("#settings-menu-popup").css("left", $(window).width() - 340);
74546         $("#overlayBackground").css("width", $(window).width());
74547         $("#overlayBackground").css("height", $(window).height());
74548     });
74549
74550     $(".settings-menu-checkbox").each(function (i, a) {
74551         if (a.checked === false) {
74552             unselectedNum++;
74553         }
74554     });
74555
74556     if (unselectedNum === 0) {
74557         $("#select_unselect_text").text("Unselect All");
74558         $("#panelSettingSelectAll").prop('checked', true);
74559     }
74560
74561     $("#panelSettingSelectAll").unbind('click');
74562     $("#panelSettingSelectAll").bind("click", function (event) {
74563         if ($("#panelSettingSelectAll").is(':checked')) {
74564             $("#select_unselect_text").text("Unselect All");
74565             $(".settings-menu-checkbox").prop('checked', true);
74566         }
74567         else {
74568             $("#select_unselect_text").text("Select All");
74569             $(".settings-menu-checkbox").prop('checked', false);
74570         }
74571     });
74572 }
74573
74574 module.exports = {
74575     initialize: function () {
74576         $("#options-button-panels").bind("click", function (event) {
74577             _showSettingMenu();
74578         });
74579     }
74580 };
74581
74582 });
74583 define('ripple/ui/plugins/communication', function (require, exports, module) {
74584 /*
74585  *  Copyright 2011 Research In Motion Limited.
74586  *
74587  * Licensed under the Apache License, Version 2.0 (the "License");
74588  * you may not use this file except in compliance with the License.
74589  * You may obtain a copy of the License at
74590  *
74591  * http://www.apache.org/licenses/LICENSE-2.0
74592  *
74593  * Unless required by applicable law or agreed to in writing, software
74594  * distributed under the License is distributed on an "AS IS" BASIS,
74595  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
74596  * See the License for the specific language governing permissions and
74597  * limitations under the License.
74598  */
74599
74600 var ui = require('ripple/ui'),
74601     event = require('ripple/event'),
74602     deviceSettings = require('ripple/deviceSettings'),
74603     db = require('ripple/db'),
74604     utils = require('ripple/utils'),
74605     _messageType = {
74606         sms: "SMS",
74607         mms: "MMS",
74608         email: "E-mail"
74609     },
74610     _attachments = [],
74611 /*
74612     _exception = {
74613         "":                  "Connection Issue",
74614         "unknown":           "Unknown",
74615         "network":           "Network",
74616         "unreachable":       "Unreachable",
74617         "no-answer":         "No Answer",
74618         "bad-number":        "Bad Number",
74619         "number-not-in-use": "Number Not In Use",
74620         "media":             "Media",
74621         "no-sim":            "No Sim Card",
74622         "account-down":      "Account Down",
74623         "credit-down":       "Credit Down",
74624         "barred":            "Barred",
74625         "network-busy":      "Network Busy",
74626         "network-down":      "Network Down"
74627     },
74628 */
74629     _status = {
74630         IDLE:       0,
74631         DIALED:     1,
74632         INPROGRESS: 2,
74633     },
74634     _data = {
74635         status: _status.IDLE,
74636 //        isInException: false,
74637         conversationStartTime: null
74638     },
74639     _contactNameArr = [],
74640     _contactNumArr = [],
74641     _CONTACT_KEY = "tizen1-contact",
74642     _record = {},
74643     _conversationSeconds = 0,
74644     _conversationTimer,
74645     _msgTimer,
74646     _audioPlayersStatus = [];
74647
74648 function _showMsg() {
74649     var messageName = jQuery("#communication-senderName").val(),
74650         messageContent = jQuery("#communication-messageContent").val(),
74651         disMsgName = jQuery(".communication-messageContainer tr:first-child td"),
74652         disMsgContent = jQuery(".communication-messageContainer tr:nth-child(2) td textarea");
74653
74654     ui.showOverlay("communication-window");
74655
74656     disMsgName.text(messageName ? messageName : "Unknown name");
74657     disMsgContent.val(messageContent ? messageContent : "");
74658
74659     jQuery("#communication-viewport").css("height", jQuery("#viewport-container").css("height"))
74660                                      .show("slide", {direction: "up"}, "fast");
74661     jQuery(".communication-callContainer").hide();
74662     jQuery(".communication-messageContainer").show();
74663 }
74664
74665 function _msgEventInitialize() {
74666     jQuery("#communication-messageRadioStatus").hide();
74667     jQuery("#communication-sendMessage").unbind("click").click(function () {
74668         var messageItem,
74669             number = jQuery("#communication-senderName").val(),
74670             text = jQuery("#communication-messageContent").val(),
74671             type = jQuery("#communication-msgType").val(),
74672             message = {
74673                 type: type,
74674                 body: text,
74675                 from: number,
74676                 time: new Date(),
74677                 attachments: _attachments
74678             };
74679
74680         if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false &&
74681             (type === 'sms' || type === 'mms')) {
74682             jQuery("#communication-messageRadioStatus").html('cellular radio is off<br \>Turn it on from Network Management Panel.');
74683             jQuery("#communication-messageRadioStatus").show();
74684             setTimeout(function () {
74685                 jQuery("#communication-messageRadioStatus").hide();
74686             }, 3000);
74687             return;
74688         }
74689         if (deviceSettings.retrieve("WIFI_NETWORK.status") === false &&
74690             type === 'email') {
74691             jQuery("#communication-messageRadioStatus").html('wifi radio is off<br \>Turn it on from Network Management Panel.');
74692             jQuery("#communication-messageRadioStatus").show();
74693             setTimeout(function () {
74694                 jQuery("#communication-messageRadioStatus").hide();
74695             }, 3000);
74696             return;
74697         }
74698
74699         event.trigger("MessageReceived", [message]);
74700         _attachments = [];
74701         event.trigger("CommWinShow", [true]);
74702         _showMsg();
74703
74704         jQuery(".communication-messageContainer textarea").attr("disabled", "disabled");
74705         jQuery("#communication-messageOut td:nth-child(3)").text(jQuery("#communication-messageContent").val());
74706         messageItem = jQuery("#communication-messageOut").html();
74707         jQuery("#communication-messageDisplay").append(messageItem);
74708
74709         clearTimeout(_msgTimer);
74710         _msgTimer = setTimeout(function () {
74711             if (_data.status === _status.IDLE) {
74712                 ui.hideOverlay("communication-window");
74713                 event.trigger("CommWinShow", [false]);
74714             } else {
74715                 _showCall();
74716             }
74717         }, 5000);
74718     });
74719
74720     jQuery("#communication-clearMessage").unbind("click").click(function () {
74721             jQuery("#communication-messageDisplay").empty();
74722         });
74723
74724     event.on("LayoutChanged", function () {
74725         jQuery("#communication-viewport").css("height", jQuery("#viewport-container").css("height"));
74726
74727     });
74728     event.on("OutsideMessageReceived", function (message) {
74729         var i = 0,
74730             recipients = [],
74731             recipientsStatus = {},
74732             messageItem;
74733
74734         recipientsStatus.id = message.id;
74735         recipientsStatus.msg = message.msg;
74736         for (i in message.to) {
74737             recipientsStatus[message.to[i]] = true;
74738             recipients.push(message.to[i]);
74739         }
74740         for (i in message.cc) {
74741             recipientsStatus[message.cc[i]] = true;
74742             recipients.push(message.cc[i]);
74743         }
74744         for (i in message.bcc) {
74745             recipientsStatus[message.bcc[i]] = true;
74746             recipients.push(message.bcc[i]);
74747         }
74748
74749         event.trigger("MessageSent", [recipientsStatus]);
74750         jQuery("#communication-messageIn td:nth-child(1)").text(message.body);
74751         messageItem = jQuery("#communication-messageIn").html();
74752         jQuery("#communication-messageDisplay").append(messageItem);
74753     });
74754
74755     jQuery("#communication-ok").unbind("click").click(function () {
74756         if (_data.status === _status.IDLE) {
74757             ui.hideOverlay("communication-window");
74758             event.trigger("CommWinShow", [false]);
74759         } else {
74760             _showCall();
74761         }
74762         clearTimeout(_msgTimer);
74763     });
74764 }
74765
74766 function _msgInitialize() {
74767     _msgEventInitialize();
74768
74769     utils.forEach(_messageType, function (msgTypeText, msgType) {
74770         var typeNode = utils.createElement("option", {
74771                 "innerText": msgTypeText,
74772                 "value": msgType
74773             });
74774
74775         jQuery("#communication-msgType").append(typeNode);
74776     });
74777 }
74778
74779 function pauseAllAudioPlayer() {
74780     var audios = $("#document").contents().find("audio"),
74781         index;
74782     for (var index = 0; index < audios.length; index++) {
74783         if (audios[index].paused) {
74784             _audioPlayersStatus[index] = 0;
74785         }
74786         else {
74787             _audioPlayersStatus[index] = 1;
74788             audios[index].pause();
74789         }
74790     }
74791 }
74792
74793 function playAllAudioPlayer() {
74794     var audios = $("#document").contents().find("audio"),
74795         index;
74796     for (var index = 0; index < audios.length; index++) {
74797         if (_audioPlayersStatus[index] === 1) {
74798             audios[index].play();
74799         }
74800     }
74801     _audioPlayersStatus = [];
74802 }
74803
74804 function _showCall() {
74805     var callName = jQuery("#communication-callerName").val(),
74806         callNum = jQuery("#communication-callNum").val(),
74807         disCallName = jQuery(".communication-callContainer tr:first-child td"),
74808         disCallNum = jQuery(".communication-callContainer tr:nth-child(2) td");
74809
74810     ui.showOverlay("communication-window");
74811     event.trigger("CommWinShow", [true]);
74812
74813     disCallName.text(callName ? callName : "Unknown Name");
74814     disCallNum.text(callNum ? callNum : "Unknown Number");
74815
74816     jQuery("#communication-viewport").css("height", jQuery("#viewport-container").css("height"))
74817                                      .show("slide", {direction: "up"}, "fast");
74818     jQuery(".communication-callContainer").show();
74819     jQuery(".communication-messageContainer").hide();
74820     pauseAllAudioPlayer();
74821 }
74822
74823 function _initRecord() {
74824     var callerName = jQuery("#communication-callerName").val(),
74825         callerNum = jQuery("#communication-callNum").val(),
74826         displayName = callerName ? callerName : "Unknown",
74827         displayNum = callerNum ? callerNum : "Unknown";
74828
74829     _record = {};
74830     _record.type = "TEL";
74831     if ($("#is-videoCall").prop("checked") === true) {
74832         _record.features = ["CALL", "VIDEOCALL"];
74833     } else {
74834         _record.features = ["CALL", "VOICECALL"];
74835     }
74836     _record.remoteParties = [{
74837         remoteParty: displayNum,
74838         personId: displayName,
74839     }];
74840     _record.startTime = new Date();
74841 }
74842
74843 function _endCall(callEndReason) {
74844     _record.duration = _data.conversationStartTime ? _conversationSeconds : 0;
74845
74846     _data.conversationStartTime = null;
74847
74848     switch (callEndReason) {
74849     case 'rejected':
74850         _record.direction = "REJECTED";
74851         break;
74852     case 'remote':
74853         _record.direction = "RECEIVED";
74854         break;
74855     case 'local':
74856         _record.direction = "MISSEDNEW";
74857         break; 
74858     }
74859
74860     event.trigger("CallRecorded", [_record]);
74861     event.trigger("CallInProgress", [false]);
74862
74863     _data.status = _status.IDLE;
74864     _record = {};
74865
74866     _conversationSeconds = 0;
74867     window.clearInterval(_conversationTimer);
74868     ui.hideOverlay("communication-window");
74869     event.trigger("CommWinShow", [false]);
74870     playAllAudioPlayer();
74871 }
74872
74873 function _callEventInitialize() {
74874     jQuery("#communication-cellularStatus").hide();
74875     jQuery("#communication-callStart").unbind('click').click(
74876         function () {
74877             if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false) {
74878                 jQuery("#communication-cellularStatus").show();
74879                 setTimeout(function () {
74880                     jQuery("#communication-cellularStatus").hide();
74881                 }, 3000);
74882
74883                 return;
74884             }
74885             if (_data.status === _status.IDLE) {
74886                 _data.status = _status.DIALED;
74887                 _initRecord();
74888                 _showCall();
74889                 jQuery("#callSettings tr:last-child td").text("Calling...");
74890                 jQuery("#communication-callStart > span").text("End Call");
74891                 jQuery("#callSettings input").attr("disabled", "disabled");
74892             } else {
74893                 _endCall("local");
74894
74895                 jQuery("#callSettings tr:last-child td").text("");
74896                 jQuery("#communication-callStart > span").text("Call");
74897                 jQuery(".communication-callContainer tr:nth-child(3)").show();
74898                 jQuery(".communication-callContainer tr:last-child").hide();
74899                 jQuery("#callSettings input").removeAttr("disabled");
74900             }
74901
74902         }
74903     );
74904
74905     event.on("ApplicationLoad", function () {
74906         switch (_data.status) {
74907         case _status.INPROGRESS:
74908             jQuery("#communication-callStart").click();
74909             break;
74910         case _status.DIALED:
74911             jQuery("#communication-ignore").click();
74912             break;
74913         default:
74914             break;
74915         }
74916     });
74917
74918     jQuery("#communication-ignore").unbind('click').click(function () {
74919         _endCall("rejected");
74920
74921         jQuery("#callSettings tr:last-child td").text("");
74922         jQuery("#communication-callStart > span").text("Call");
74923         jQuery("#communication-callStart").removeData();
74924         jQuery("#callSettings input").removeAttr("disabled");
74925     });
74926
74927     jQuery("#communication-answer").unbind('click').click(function () {
74928         _data.conversationStartTime = new Date();
74929         event.trigger("CallInProgress", [true]);
74930         _data.status = _status.INPROGRESS;
74931
74932         _conversationTimer = setInterval(function () {
74933             var timeObj = new Date(1970, 0, 1),
74934                 timeString;
74935
74936             timeObj.setSeconds(_conversationSeconds);
74937             timeString = timeObj.toTimeString().substr(0, 8);
74938             jQuery("#callSettings tr:last-child td").text(timeString);
74939             _conversationSeconds = _conversationSeconds + 1;
74940         }, 1000);
74941
74942         jQuery(".communication-callContainer tr:nth-child(3)").hide();
74943         jQuery(".communication-callContainer tr:last-child").show();
74944     });
74945
74946     jQuery("#communication-end").unbind('click').click(function () {
74947         _endCall("remote");
74948
74949         jQuery("#callSettings tr:last-child td").text("");
74950         jQuery("#communication-callStart > span").text("Call");
74951         jQuery("#communication-callStart").removeData();
74952         jQuery(".communication-callContainer tr:nth-child(3)").show();
74953         jQuery(".communication-callContainer tr:last-child").hide();
74954         jQuery("#callSettings input").removeAttr("disabled");
74955     });
74956 /*
74957     jQuery("#communication-callEndReason").unbind("change").change(function () {
74958         if (!jQuery("#communication-callEndReason").val()) {
74959             _data.isInException = false;
74960         } else {
74961             _data.isInException = true;
74962             if (_data.isInException && (_data.status !== _status.IDLE)) {
74963                 _endCall(jQuery("#communication-callEndReason").val());
74964             }
74965         }
74966
74967         jQuery("#callSettings tr:last-child td").text("");
74968         jQuery("#communication-callStart > span").text("Call");
74969         jQuery("#communication-callStart").removeData();
74970         jQuery(".communication-callContainer tr:nth-child(3)").show();
74971         jQuery(".communication-callContainer tr:last-child").hide();
74972         jQuery("#callSettings input").removeAttr("disabled");
74973     });
74974 */
74975 }
74976
74977 function _contactInitialize() {
74978     var data = db.retrieveObject(_CONTACT_KEY),
74979         displayName = null, number = null, index = 0;
74980
74981     _contactNameArr = [];
74982     _contactNumArr = [];
74983
74984     utils.forEach(data, function (addrBook) {
74985         utils.forEach(addrBook._contacts, function (contact) {
74986             if (contact.name && contact.name && contact.phoneNumbers && contact.phoneNumbers.length > 0) {
74987                 displayName = contact.name.firstName + ' ' + contact.name.lastName;
74988                 number = contact.phoneNumbers[0].number;
74989                 _contactNameArr.push(displayName);
74990                 _contactNumArr[displayName] = number;
74991                 index++;
74992             }
74993         });
74994     });
74995
74996     jQuery("#communication-callerName").autocomplete({
74997         source: _contactNameArr,
74998         select: function (event, ui) {
74999             jQuery("#communication-callNum").val(_contactNumArr[ui.item.value]);
75000         }
75001     });
75002     jQuery("#communication-senderName").autocomplete({
75003         source: _contactNameArr
75004     });
75005 }
75006
75007 function _callInitialize() {
75008     _callEventInitialize();
75009
75010     _contactInitialize();
75011 /*
75012     utils.forEach(_exception, function (value, key) {
75013         var typeNode = utils.createElement("option", {
75014                 "innerText": value,
75015                 "value": key
75016             });
75017
75018         jQuery("#communication-callEndReason").append(typeNode);
75019     });
75020 */
75021 }
75022
75023 function _pushEventInitialize() {
75024     function register(appService) {
75025         appService.registrationId = Math.uuid(null, 16);
75026
75027         window.setTimeout(function () {
75028             var appLabel;
75029
75030             if ($("#communication-push-" + appService.appId).length !== 0) {
75031                 $("#" + appService.appId).click();
75032                 $("#communication-push-status-" + appService.appId).html("||");
75033                 $("#communication-push-status-" + appService.appId).css("color", "#ff0000");
75034
75035                 return;
75036             }
75037
75038             if (!$("#communication-push-app > tbody").html()) {
75039                 $("#communication-push-header").show();
75040                 $("#communication-push-submit").removeAttr("disabled");
75041             }
75042
75043             appLabel = appService.appControl.uri || appService.appId;
75044
75045             $("#communication-push-app").append(
75046                 "<tr id='communication-push-" + appService.appId + "'>" +
75047                 "<td style='width: 90%'><input type='radio' name='communication-push-list' id='" +
75048                 appService.appId + "' style='margin: 5px' checked='checked' />" +
75049                 "<label for='" + appService.appId + "'>" + appLabel + "</label></td>" +
75050                 "<td id='communication-push-status-" + appService.appId + "'>||</td>" +
75051                 "</tr>");
75052
75053             $("label[for='" + appService.appId + "']").css({
75054                 "display": "inline-block",
75055                 "width": "220px",
75056                 "white-space": "nowrap",
75057                 "overflow": "hidden",
75058                 "text-overflow": "ellipsis"
75059             });
75060
75061             $("#communication-push-status-" + appService.appId).css({
75062                 "width": "10%",
75063                 "color": "#ff0000",
75064                 "text-align": "center",
75065                 "font-weight": "bold",
75066                 "font-size": "14px"
75067             });
75068
75069             $("#communication-push-app tr:even").css("background-color", "white");
75070             $("#communication-push-app tr:odd").css("background-color", "whitesmoke");
75071         }, 1);
75072     }
75073
75074     function unregister(appId) {
75075         if ($("#communication-push-" + appId).length === 0)
75076             return;
75077
75078         $("tr[id='communication-push-" + appId + "']").remove();
75079
75080         if (!$("#communication-push-app > tbody").html()) {
75081             $("#communication-push-header").hide();
75082             $("#communication-push-submit").attr("disabled", "disabled");
75083
75084             return;
75085         }
75086
75087         if ($("input[name='communication-push-list']:checked").length === 0) {
75088             $("#communication-push-app input:first").click();
75089         }
75090
75091         $("#communication-push-app tr:even").css("background-color", "white");
75092         $("#communication-push-app tr:odd").css("background-color", "whitesmoke");
75093     }
75094
75095     function connect(appId) {
75096         $("#communication-push-status-" + appId).html("<=>");
75097         $("#communication-push-status-" + appId).css("color", "#32cd32");
75098     }
75099
75100     function disconnect(appId) {
75101         $("#communication-push-status-" + appId).html("||");
75102         $("#communication-push-status-" + appId).css("color", "#ff0000");
75103     }
75104
75105     event.on("PushRequest", function (command, cmdData) {
75106         switch (command) {
75107         case "REGISTER":
75108             register(cmdData);
75109             break;
75110
75111         case "UNREGISTER":
75112             unregister(cmdData);
75113             break;
75114
75115         case "CONNECT":
75116             connect(cmdData);
75117             break;
75118
75119         case "DISCONNECT":
75120             disconnect(cmdData);
75121             break;
75122         }
75123     });
75124 }
75125
75126 function _pushElementInitialize() {
75127     $("#communication-push-submit").attr("disabled", "disabled");
75128     $("#communication-push-submit").unbind('click').click(function () {
75129         var appId, pushMessage;
75130
75131         appId = $("#communication-push-app :checked").attr("id");
75132         if (!appId)
75133             return;
75134
75135         pushMessage = {
75136             appData:      $("#communication-push-data").val(),
75137             alertMessage: $("#communication-push-msg").val(),
75138             date:         new Date()
75139         };
75140
75141         if (!pushMessage.appData || !pushMessage.alertMessage)
75142             return;
75143
75144         event.trigger("PushNotified", [appId, pushMessage]);
75145     });
75146
75147     $("#communication-push-clear").unbind('click').click(function () {
75148         $("#communication-push-msg").val("");
75149         $("#communication-push-data").val("");
75150     });
75151 }
75152
75153 function _pushInitialize() {
75154     _pushEventInitialize();
75155     _pushElementInitialize();
75156 }
75157
75158 module.exports = {
75159     panel: {
75160         domId: "communication-container",
75161         collapsed: true,
75162         pane: "left",
75163         titleName: "Communications",
75164         display: true
75165     },
75166     initialize: function () {
75167         jQuery("#communication-select").tabs();
75168         _callInitialize();
75169         _msgInitialize();
75170         _pushInitialize();
75171     }
75172 };
75173
75174 });
75175 define('ripple/ui/plugins/package', function (require, exports, module) {
75176 /*
75177  *  Copyright 2011 Research In Motion Limited.
75178  *
75179  * Licensed under the Apache License, Version 2.0 (the "License");
75180  * you may not use this file except in compliance with the License.
75181  * You may obtain a copy of the License at
75182  *
75183  * http://www.apache.org/licenses/LICENSE-2.0
75184  *
75185  * Unless required by applicable law or agreed to in writing, software
75186  * distributed under the License is distributed on an "AS IS" BASIS,
75187  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75188  * See the License for the specific language governing permissions and
75189  * limitations under the License.
75190  */
75191
75192 var db = require('ripple/db'),
75193     utils = require('ripple/utils'),
75194     event = require('ripple/event'),
75195     dbinit = require('ripple/platform/tizen/2.0/dbinit'),
75196     PackageInformation = require('ripple/platform/tizen/2.0/PackageInformation'),
75197     DB_PACKAGE_KEY = "tizen-db-package",
75198     _data = {
75199         packageList: {},
75200         installedList: {}
75201     },
75202     _currentPackageId = null,
75203     _packages,
75204     _installedList,
75205     _packageListTemplate,
75206     _packageInstalledTemplate;
75207
75208 function _get() {
75209     _data = db.retrieveObject(DB_PACKAGE_KEY);
75210     if (_data === undefined) {
75211         _data = {
75212             packageList: _packages,
75213             installedList: _installedList
75214         };
75215     }
75216     utils.forEach(_data.installedList, function (item) {
75217         item.lastModified = new Date(item.lastModified);
75218     });
75219 }
75220
75221 function _save() {
75222     db.saveObject(DB_PACKAGE_KEY, _data);
75223 }
75224
75225 function loadPackageList() {
75226     var nodes = jQuery("#package-list-select");
75227     nodes.html("");
75228     utils.forEach(_data.packageList, function (item, index) {
75229         nodes.append(utils.createElement("option", {
75230             "value": index,
75231             "innerText": item.name
75232         }));
75233     });
75234     renderPackageListBox($("#package-list-select option:selected").val());
75235 }
75236
75237 function loadInstalledList() {
75238     var html = "";
75239     jQuery("#package-installed-box").empty();
75240     utils.forEach(_data.installedList, function (item) {
75241         html += _packageInstalledTemplate.replace(/#Name/g, item.name)
75242             .replace(/#ID/g, item.id)
75243             .replace(/#IconPath/, item.iconPath)
75244             .replace(/#Version/, item.version)
75245             .replace(/#TotalSize/, item.totalSize)
75246             .replace(/#DataSize/, item.dataSize)
75247             .replace(/#LastModified/, item.lastModified)
75248             .replace(/#Author/, item.author)
75249             .replace(/#Description/, item.description)
75250             .replace(/#APPIDs/, item.appIds.join("<br>"));
75251     });
75252     $("#package-installed-box").accordion("destroy");
75253     $("#package-installed-box").html(html).accordion({
75254         active: false,
75255         collapsible: true,
75256         autoHeight: false
75257     });
75258     $("." + "package-remove-btn").bind("click", function () {
75259         var id = this.id;
75260         if (id === _currentPackageId) {
75261             $("#msg-" + id).html("Can't Uninstall:<br> Package including running app");
75262             setTimeout(function () {
75263                 $("#msg-" + id).text("");
75264             }, 5000);
75265             return;
75266         }
75267         utils.forEach(_data.packageList, function (item) {
75268             if (item.id === id) {
75269                 event.trigger("remove-apps", [item.appIds]);
75270             }
75271         });
75272         delete _data.installedList[this.id];
75273         _save();
75274         loadPackageList();
75275         loadInstalledList();
75276         event.trigger("uninstall-package", [this.id]);
75277     });
75278 }
75279
75280 function renderPackageListBox(path) {
75281     var item, html;
75282     jQuery("#package-list-box").empty();
75283     item = _data.packageList[path];
75284     html = _packageListTemplate.replace(/#Path/, path)
75285         .replace(/#ID/, item.id)
75286         .replace(/#Name/, item.name)
75287         .replace(/#IconPath/, item.iconPath)
75288         .replace(/#Version/, item.version)
75289         .replace(/#TotalSize/, item.totalSize)
75290         .replace(/#DataSize/, item.dataSize)
75291         .replace(/#Author/, item.author)
75292         .replace(/#Description/, item.description)
75293         .replace(/#APPList/, item.appIds.join("<br>"));
75294     jQuery("#package-list-box").html(html);
75295     if (_data.installedList[item.id]) {
75296         jQuery("#package-update-btn").show();
75297     } else {
75298         jQuery("#package-install-btn").show();
75299     }
75300 }
75301
75302 function addPackage(path, type) {
75303     var item;
75304     if (!_data.packageList[path]) {
75305         return;
75306     }
75307     item = _data.packageList[path];
75308     _data.installedList[item.id] = new PackageInformation(
75309         item.id, item.name, item.iconPath, item.version,
75310         item.totalSize, item.dataSize, new Date(),
75311         item.author, item.description, item.appIds
75312     );
75313     if (type === "install") {
75314         event.trigger("install-apps", [item.appIds]);
75315     } else {
75316         event.trigger("update-apps", [item.appIds]);
75317     }
75318     _save();
75319 }
75320
75321 module.exports = {
75322     panel: {
75323         domId: "package-container",
75324         collapsed: true,
75325         pane: "left",
75326         titleName: "Packages and Applications",
75327         display: true
75328     },
75329     initialize: function () {
75330         _packages = dbinit.Package.packages;
75331         _installedList = dbinit.Package.installedList;
75332         _packageListTemplate = jQuery("#package-list-template").html();
75333         _packageInstalledTemplate = jQuery("#package-installed-template").html();
75334
75335         _get();
75336         _save();
75337         loadPackageList();
75338         loadInstalledList();
75339         jQuery("#package-list-select").bind("focus change", function () {
75340             var path = $("#package-list-select option:selected").val();
75341             renderPackageListBox(path);
75342         });
75343         jQuery("#package-install-btn").live("click", function () {
75344             var path = $("#package-list-select option:selected").val();
75345             addPackage(path, "install");
75346             _get();
75347             loadPackageList();
75348             loadInstalledList();
75349             event.trigger("install-packge", [path]);
75350         });
75351         jQuery("#package-update-btn").live("click", function () {
75352             var path = $("#package-list-select option:selected").val();
75353             addPackage(path, "update");
75354             loadPackageList();
75355             loadInstalledList();
75356             event.trigger("update-package", [path]);
75357         });
75358         jQuery("#package-select").tabs();
75359         event.on("installedList-updated", function () {
75360             _get();
75361             loadPackageList();
75362             loadInstalledList();
75363         });
75364         event.on("install-current-package", function (item) {
75365             _data.installedList[item.id] = new PackageInformation(
75366                 item.id, item.name, item.iconPath, item.version,
75367                 item.totalSize, item.dataSize, item.lastModified,
75368                 item.author, item.description, item.appIds);
75369             _currentPackageId = item.id;
75370             loadInstalledList();
75371         });
75372     }
75373 };
75374
75375 });
75376 define('ripple/ui/plugins/application', function (require, exports, module) {
75377 /*
75378  *  Copyright 2012 Intel Corporation.
75379  *
75380  * Licensed under the Apache License, Version 2.0 (the "License");
75381  * you may not use this file except in compliance with the License.
75382  * You may obtain a copy of the License at
75383  *
75384  * http://www.apache.org/licenses/LICENSE-2.0
75385  *
75386  * Unless required by applicable law or agreed to in writing, software
75387  * distributed under the License is distributed on an "AS IS" BASIS,
75388  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75389  * See the License for the specific language governing permissions and
75390  * limitations under the License.
75391  */
75392
75393 var event = require('ripple/event'),
75394     utils = require('ripple/utils'),
75395     db = require('ripple/db'),
75396     dbinit = require('ripple/platform/tizen/2.0/dbinit'),
75397     DB_APPLICATION_KEY = "tizen1-db-application",
75398     _data = {
75399         appList: {},
75400         installedAppList: {}
75401     },
75402     _appInstalledTemplate,
75403     _apps,
75404     _installedAppList;
75405
75406 function _get() {
75407     _data = db.retrieveObject(DB_APPLICATION_KEY);
75408     if (_data === undefined) {
75409         _data = {
75410             appList: _apps,
75411             installedAppList: _installedAppList
75412         };
75413     }
75414 }
75415
75416 function _save() {
75417     db.saveObject(DB_APPLICATION_KEY, _data);
75418 }
75419
75420 function _loadInstalledAppList() {
75421     var html = "";
75422     jQuery("#application-installed-box").empty();
75423     utils.forEach(_data.installedAppList, function (item) {
75424         html += _appInstalledTemplate.replace(/#Name/g, item.name)
75425             .replace(/#ID/g, item.id)
75426             .replace(/#IconPath/, item.iconPath)
75427             .replace(/#Version/, item.version)
75428             .replace(/#Show/, item.show)
75429             .replace(/#Categories/, item.categories.join("<br>"))
75430             .replace(/#InstallDate/, item.installDate)
75431             .replace(/#Size/, item.size)
75432             .replace(/#PackageID/, item.packageId)
75433             .replace(/#SharedURI/, item.sharedURI)
75434             .replace(/#Operation/, item.operation)
75435             .replace(/#URI/, item.appControl.uri)
75436             .replace(/#MIME/, item.appControl.mime)
75437             .replace(/#category/, item.appControl.category)
75438             .replace(/#Data/, item.appControl.data);
75439     });
75440     jQuery("#application-installed-box").accordion("destroy");
75441     jQuery("#application-installed-box").html(html).accordion({
75442         active: false,
75443         collapsible: true,
75444         autoHeight: false
75445     });
75446 }
75447
75448 function _displayInfo(text) {
75449     var html = "<b>" + text + "</b>";
75450     document.getElementById("application-error").innerHTML = html;
75451 }
75452
75453 function _programChanged(status, id) {
75454     event.trigger("programChanged", [status, id]);
75455 }
75456
75457 function updateApp(id, updateFlag) {
75458     var item = _data.appList[id];
75459     if (!item) {
75460         return;
75461     }
75462     _data.installedAppList[id] = {
75463         id: item.id,
75464         name: item.name,
75465         iconPath: item.iconPath,
75466         version: item.version,
75467         show: item.show,
75468         categories: item.categories,
75469         installDate: new Date(),
75470         size: item.size,
75471         packageId: item.packageId,
75472         sharedURI: item.sharedURI,
75473         operation: item.operation,
75474         appControl: {
75475             uri: item.appControl.uri,
75476             mime: item.appControl.mime,
75477             category: item.appControl.category,
75478             data: item.appControl.data
75479         },
75480         type: item.type,
75481         value: item.value
75482     };
75483     _save();
75484     if (updateFlag) {
75485         _programChanged("updated", id);
75486     } else {
75487         _programChanged("installed", id);
75488     }
75489     _loadInstalledAppList();
75490 }
75491
75492 function removeApp(id) {
75493     delete _data.installedAppList[id];
75494     _save();
75495     _programChanged("uninstalled", id);
75496     _loadInstalledAppList();
75497 }
75498
75499 event.on("install-current-app", function (item) {
75500     _data.installedAppList[item.id] = {
75501         id: item.id,
75502         name: item.name,
75503         iconPath: item.iconPath,
75504         version: item.version,
75505         show: item.show,
75506         categories: item.categories,
75507         installDate: item.installDate,
75508         size: item.size,
75509         packageId: item.packageId,
75510         sharedURI: item.sharedURI,
75511         operation: item.operation,
75512         appControl: {
75513             uri: item.appControl.uri,
75514             mime: item.appControl.mime,
75515             category: item.appControl.category,
75516             data: item.appControl.data
75517         },
75518         type: item.type,
75519         value: item.value
75520     };
75521     _loadInstalledAppList();
75522 });
75523
75524 event.on("appServiceReplied", function () {
75525     _displayInfo("The application has been launched successfully");
75526 });
75527
75528 event.on("install-apps", function (ids) {
75529     utils.forEach(ids, function (id) {
75530         updateApp(id, false);
75531     });
75532 });
75533
75534 event.on("update-apps", function (ids) {
75535     utils.forEach(ids, function (id) {
75536         updateApp(id, true);
75537     });
75538 });
75539
75540 event.on("remove-apps", function (ids) {
75541     utils.forEach(ids, function (id) {
75542         removeApp(id);
75543     });
75544 });
75545
75546 module.exports = {
75547     initialize: function () {
75548         _apps = dbinit.Application.apps;
75549         _installedAppList = dbinit.Application.installedAppList;
75550         _appInstalledTemplate = jQuery("#application-installed-template").html();
75551         _get();
75552         _save();
75553         _loadInstalledAppList();
75554     }
75555 };
75556
75557 });
75558 define('ripple/ui/plugins/sensorSettings', function (require, exports, module) {
75559 /*
75560  *  Copyright 2012 Intel Corporation.
75561  *
75562  * Licensed under the Apache License, Version 2.0 (the "License");
75563  * you may not use this file except in compliance with the License.
75564  * You may obtain a copy of the License at
75565  *
75566  * http://www.apache.org/licenses/LICENSE-2.0
75567  *
75568  * Unless required by applicable law or agreed to in writing, software
75569  * distributed under the License is distributed on an "AS IS" BASIS,
75570  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75571  * See the License for the specific language governing permissions and
75572  * limitations under the License.
75573  */
75574
75575 var constants = require('ripple/constants'),
75576     sensorSettings = require('ripple/sensorSettings'),
75577     utils = require('ripple/utils'),
75578     exception = require('ripple/exception'),
75579     platform = require('ripple/platform'),
75580     _CONST = {
75581         "CONTENT_CONTAINER_ID": "sensorsettings-content-container",
75582         "UKNOWN_CONTROL_MESSAGE": "Unknown sensor control type"
75583     },
75584     _contentContainer,
75585     _CONTAINER_ID = _CONST.CONTENT_CONTAINER_ID;
75586
75587 function _appendSettingNode(labelNode, inputNode, label) {
75588     var frag = document.createDocumentFragment(),
75589         rowNode = frag.appendChild(utils.createElement("tr")),
75590         tempTdNode;
75591
75592     rowNode.appendChild(utils.createElement("td"))
75593            .appendChild(labelNode);
75594
75595     tempTdNode = rowNode.appendChild(utils.createElement("td"));
75596
75597     if (label) {
75598         tempTdNode.appendChild(label);
75599     }
75600
75601     tempTdNode.appendChild(inputNode);
75602
75603     return frag;
75604 }
75605
75606 function _buildDOMNode(setting, settingType, key) {
75607     var settingsNode, tagName, jNode,
75608         fullKey = settingType + "." + key,
75609         savedSetting = sensorSettings.retrieve(fullKey),
75610         // TODO: move this into Utils (isSet method)
75611         currentSetting = (savedSetting || savedSetting === false || savedSetting === "" || savedSetting === 0) ? savedSetting : setting.control.value,
75612         domNode,
75613         domNodeLabel = null;
75614
75615     switch (setting.control.type) {
75616     case "text":
75617     case "number":
75618     case "range":
75619     case "checkbox":
75620         tagName = "input";
75621         break;
75622     case "textarea":
75623         tagName = "textarea";
75624         break;
75625     case "select":
75626         tagName = "select";
75627         break;
75628     default:
75629         exception.raise(exception.types.Application, _CONST.UKNOWN_CONTROL_MESSAGE);
75630     }
75631
75632     settingsNode = utils.createElement(tagName, setting.control.type === "select" ? null : setting.control);
75633
75634     // TODO: this should really be part of utils.createControl? add element of type "range" with label?
75635     if (setting.control.type === "range") {
75636         domNodeLabel = utils.createElement("label", {
75637             "class": constants.UI.LEFT_RANGE_LABEL_CLASS
75638         });
75639     }
75640
75641     domNode = _appendSettingNode(utils.createElement("span", {"innerText": setting.name, "class": constants.UI.TEXT_LABEL_CLASS}), settingsNode, domNodeLabel);
75642
75643     jNode = jQuery(settingsNode);
75644     jNode.addClass(constants.UI.JQUERY_UI_INPUT_CLASSES);
75645
75646     switch (setting.control.type) {
75647     case "checkbox":
75648         jNode.bind("click", function () {
75649             var checked = this.checked ? true : false;
75650             sensorSettings.persist(fullKey, checked);
75651             if (typeof setting.callback === "function") {
75652                 setting.callback(checked);
75653             }
75654         });
75655
75656         if (currentSetting === true) {
75657             jNode.attr("checked", "checked");
75658         }
75659
75660         break;
75661
75662     case "text":
75663     case "textarea":
75664     case "number":
75665         jNode.val(currentSetting);
75666         utils.bindAutoSaveEvent(jNode, function () {
75667             sensorSettings.persist(fullKey, jNode.val());
75668             if (typeof setting.callback === "function") {
75669                 setting.callback(jNode.val());
75670             }
75671         });
75672         break;
75673
75674     case "select":
75675     case "range":
75676         if (setting.control.type === "select") {
75677             utils.forEach(setting.options,  function (value, option) {
75678                 jNode.append(utils.createElement("option", {
75679                     "value": option,
75680                     "innerText": value
75681                 }));
75682             });
75683         }
75684         else {
75685             if (domNodeLabel) {
75686                 domNodeLabel.innerText = currentSetting;
75687             }
75688         }
75689
75690         jNode.val(currentSetting)
75691              .bind("change", function () {
75692                 if (setting.control.type === "range" && domNodeLabel) {
75693                     domNodeLabel.innerText = jQuery(this).val();
75694                 }
75695                 sensorSettings.persist(fullKey, jQuery(this).val());
75696
75697                 if (typeof setting.callback === "function") {
75698                     setting.callback(jQuery(this).val());
75699                 }
75700             }
75701         );
75702     }
75703
75704     // TODO: Brent, do in DeviceSettings on load instead?
75705     if (currentSetting !== setting.control.value) {
75706         sensorSettings.register(fullKey, currentSetting);
75707     }
75708
75709     return domNode;
75710 }
75711
75712 // goes through current platforms sensor settings
75713 // adds nodes to panel and binds respective events
75714 // talks to SensorSettings for persistence
75715 module.exports = {
75716     panel: {
75717         domId: "sensors-panel-container",
75718         collapsed: true,
75719         pane: "right",
75720         titleName: "Sensors",
75721         display: true
75722     },
75723     initialize: function () {
75724         var settings;
75725
75726         _contentContainer = document.getElementById(_CONTAINER_ID);
75727
75728         settings = platform.current().sensor;
75729
75730         utils.forEach(settings, function (settingSection, settingType) {
75731
75732             var currentTableNode, flag = false;
75733             
75734             utils.forEach(settingSection, function (setting, key) {
75735                 if (typeof setting === "object") {
75736                     flag = true;
75737                     return;
75738                 }
75739             });
75740
75741             if (flag) {
75742                 _contentContainer.appendChild(utils.createElement("h3", { "innerText": settingType }));
75743             }
75744
75745             currentTableNode = utils.createElement("table", {
75746                 "class": constants.UI.PANEL_TABLE_CLASS
75747             });
75748
75749             _contentContainer.appendChild(currentTableNode);
75750
75751             utils.forEach(settingSection, function (setting, key) {
75752                 if (typeof setting === "object") {
75753                     currentTableNode.appendChild(_buildDOMNode(setting, settingType, key));
75754                 }
75755
75756             });
75757         });
75758     }
75759 };
75760
75761 });
75762 define('ripple/ui/plugins/configWindow', function (require, exports, module) {
75763 /*
75764  *  Copyright 2011 Research In Motion Limited.
75765  *
75766  * Licensed under the Apache License, Version 2.0 (the "License");
75767  * you may not use this file except in compliance with the License.
75768  * You may obtain a copy of the License at
75769  *
75770  * http://www.apache.org/licenses/LICENSE-2.0
75771  *
75772  * Unless required by applicable law or agreed to in writing, software
75773  * distributed under the License is distributed on an "AS IS" BASIS,
75774  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
75775  * See the License for the specific language governing permissions and
75776  * limitations under the License.
75777  */
75778 var utils = require('ripple/utils'),
75779     event = require('ripple/event'),
75780     db = require('ripple/db'),
75781     tooltip = require('ripple/ui/plugins/tooltip'),
75782     platform = require('ripple/platform'),
75783     items = [{name: "DEVICE", id: "device-conf-panel"},
75784              {name: "SYSTEM SETTINGS", id: "system-settings-conf-panel"},
75785              {name: "NETWORK", id: "network-conf-panel"}
75786             ],
75787     _KEY = "tizen-configuration-window-setting",
75788     _PERSISTENCE_KEY = "devicesettings",
75789     _DEVICESETTING_SAVE_KEY = "tizen-configuration-window-device-setting",
75790     _DB_APPLICATION_KEY = "tizen1-db-application",
75791     _DB_APPLICATION_SAVE_KEY = "tizen-configuration-window-application-key";
75792
75793 function reload() {
75794     window.tinyHipposReload = true;
75795     location.reload();
75796 }
75797
75798 function _hideConfigWindow() {
75799     $("#configure-window-popup").hide("slide", {direction: "up"}, "slow");
75800     $("#overlayBackground").hide("fade", "slow");
75801 }
75802
75803
75804 function checkResolutionValue(val) {
75805     var ret = false;
75806     if (val >= 200 && val <= 2000) {
75807         ret = true;
75808     }
75809     return ret;
75810 }
75811
75812 function _showConfigWindow() {
75813     var position_x;
75814     $("#item_container").empty();
75815     items.forEach(function (item) {
75816         $("#item_container").append('<div class="configuration-window-item">' + item.name + '</div>');
75817         $("#" + item.id).hide();
75818     });
75819
75820     $("#content_container").show();
75821     $("#" + items[0].id).show("fast");
75822     
75823     $(".configuration-window-item:eq(0)").css("background-color", "#003399");
75824     $(".configuration-window-item:eq(0)").css("color", "#ffffff");
75825
75826     $(".configuration-window-item").unbind('click');
75827     $(".configuration-window-item").bind("click", function () {
75828         $(".configuration-window-item").css("background-color", "#eeeeee");
75829         $(".configuration-window-item").css("color", "#333333");
75830        
75831         $(this).css("background-color", "#003399");
75832         $(this).css("color", "#ffffff");
75833
75834         items.forEach(function (item) {
75835             $("#" + item.id).hide();
75836         });
75837         $("#" + items[$(this).index()].id).show("fast");
75838     });
75839
75840     if ($("#configure-window-popup").is(":visible")) {
75841         $("#configure-window-popup").hide("slide", {direction: "up"}, "slow");
75842         $("#overlayBackground").hide("fade", "slow");
75843         return;
75844     }
75845
75846     position_x = (($(window).width() - 800) / 2)  < 0 ? 0 : ($(window).width() - 800) / 2;
75847     $("#configure-window-popup").css("top", 80);
75848     $("#configure-window-popup").css("left", position_x);
75849
75850     position_x = (($(window).width() - 400) / 2)  < 0 ? 0 : ($(window).width() - 400) / 2;
75851     $("#configure-window-done-popup").css("top", 80);
75852     $("#configure-window-done-popup").css("left", position_x);
75853
75854     $("#overlayBackground").css("width", $(window).width());
75855     $("#overlayBackground").css("height", $(window).height());
75856     $("#overlayBackground").show("fade", "slow");
75857     $("#configure-window-popup").show("slide", {direction: "up"}, "slow");
75858
75859     $("#configuration-window-done-btn").unbind('click');
75860     $("#configuration-window-done-btn").bind("click", function () {
75861         var platformId, version, device, type, width, height, url;
75862
75863         // device & resolution setting
75864         platformId = jQuery("#platform-select").val();
75865         version = jQuery("#version-select").val();
75866         device = jQuery("#device-select").val();
75867         width = jQuery("#resolution-custom-width").val();
75868         height = jQuery("#resolution-custom-height").val();
75869         type = jQuery('input:radio[name="resolution-type"]:checked').val();
75870
75871         if (type === "custom") {
75872             device = "custom";
75873             if (!checkResolutionValue(width) || !checkResolutionValue(height)) {
75874                 return;
75875             }
75876         }
75877
75878         if (platformId === "mobile" || platformId === "tizen") {
75879             platformId = "tizen";
75880             version = "2.0";
75881         }
75882         else {
75883             platformId = "ivi";
75884             version = "3.0";
75885         }
75886
75887         platform.changeEnvironment({
75888             "name": platformId,
75889             "version": version
75890         }, device, function () {
75891             _hideConfigWindow();
75892             window.tinyHipposReload = true;
75893             url = location.href.replace(/&platform=(.+?)-(.+?)$/, "&platform=" + platformId + "-" + version);
75894             location.href = url;
75895             //reload();
75896         });
75897     });
75898
75899     $("#configuration-window-close-btn").unbind('click');
75900     $("#configuration-window-close-btn").bind("click", function () {
75901         if ($("#configure-window-popup").is(":visible")) {
75902             _hideConfigWindow();
75903             return;
75904         }
75905     });
75906     tooltip.create("#configuration-window-save-btn", "Save Configuration");
75907     $("#configuration-window-save-btn").unbind('click');
75908     $("#configuration-window-save-btn").bind("click", function () {
75909         var _type, _device, _custom_width = 0, _custom_height = 0, programs, deviceInfo, _settings;
75910
75911         deviceInfo = db.retrieveObject(_PERSISTENCE_KEY);
75912         db.saveObject(_DEVICESETTING_SAVE_KEY, deviceInfo);
75913
75914         _device = jQuery("#device-select").val();
75915         _type = jQuery('input:radio[name="resolution-type"]:checked').val();
75916         if (_type === "custom") {
75917             _device = "custom";
75918             _custom_width = jQuery("#resolution-custom-width").val();
75919             _custom_height = jQuery("#resolution-custom-height").val();
75920         }
75921         _settings = {
75922             platformId : jQuery("#platform-select").val(),
75923             version : jQuery("#version-select").val(),
75924             device : _device,
75925             type : _type,
75926             custom_width : _custom_width,
75927             custom_height : _custom_height
75928         };
75929         db.saveObject(_KEY, _settings);
75930         programs = db.retrieveObject(_DB_APPLICATION_KEY);
75931         db.saveObject(_DB_APPLICATION_SAVE_KEY, programs);
75932
75933     });
75934     tooltip.create("#configuration-window-load-btn", "Load Configuration");
75935     $("#configuration-window-load-btn").unbind('click');
75936     $("#configuration-window-load-btn").bind("click", function () {
75937         var platformList,
75938             programs,
75939             deviceInfo,
75940             _settings,
75941             versionSelect = document.getElementById("version-select");
75942         if (db.retrieveObject(_DEVICESETTING_SAVE_KEY) === undefined) {
75943             //Never saving data exist
75944             return;
75945         }
75946         //reload system & network setting
75947         deviceInfo = db.retrieveObject(_DEVICESETTING_SAVE_KEY);
75948         db.saveObject("devicesettings", deviceInfo);
75949         jQuery("#devicesettings-content-container").empty();
75950         jQuery("#networksettings-content-container").empty();
75951         require('ripple/deviceSettings').initialize();
75952         require('ripple/ui/plugins/deviceSettings').terminate();
75953         require('ripple/ui/plugins/deviceSettings').initialize();
75954
75955         //reload device setting
75956         jQuery(versionSelect).empty();
75957         _settings = db.retrieveObject(_KEY);
75958         jQuery("#platform-select").val(_settings.platformId);
75959         jQuery("#device-select").val(_settings.device);
75960         if (_settings.type === "custom") {
75961             $('input:radio[name="resolution-type"][value="custom"]').click();
75962             jQuery("#resolution-custom-width").val(parseInt(_settings.custom_width, 10));
75963             jQuery("#resolution-custom-height").val(parseInt(_settings.custom_height, 10));
75964         } else {
75965             $('input:radio[name="resolution-type"][value="predefined"]').click();
75966         }
75967
75968         platformList = platform.getList();
75969         utils.forEach(platformList, function (platform) {
75970             utils.forEach(platform, function (version, versionNumber) {
75971                 if (_settings.platformId === version.id) {
75972                     versionSelect.appendChild(utils.createElement("option", {
75973                         "innerText": versionNumber,
75974                         "value":  versionNumber
75975                     }));
75976                 }
75977             });
75978         });
75979         jQuery("#version-select").val(_settings.version);
75980     });
75981
75982     $(window).bind('resize', function () {
75983         var position_x = 0;
75984         $("#configure-window-popup").css("top", 80);
75985         position_x = (($(window).width() - 800) / 2)  < 0 ? 0 : ($(window).width() - 800) / 2;
75986         $("#configure-window-popup").css("left", position_x);
75987
75988         $("#configure-window-done-popup").css("top", 180);
75989         position_x = (($(window).width() - 400) / 2)  < 0 ? 0 : ($(window).width() - 400) / 2;
75990         $("#configure-window-done-popup").css("left", position_x);
75991
75992         $("#overlayBackground").css("width", $(window).width());
75993         $("#overlayBackground").css("height", $(window).height());
75994     });
75995
75996     if (jQuery("#platform-select").val() === "ivi") {
75997         jQuery("#configuration-window-save-btn").hide();
75998         jQuery("#configuration-window-load-btn").hide();
75999
76000         jQuery("#item_container :nth-child(2)").hide();
76001         jQuery("#item_container :nth-child(3)").hide();
76002
76003         //jQuery("#hwkeys-panel").hide();
76004     }
76005     else {
76006         jQuery("#configuration-window-save-btn").show();
76007         jQuery("#configuration-window-load-btn").show();
76008
76009         jQuery("#item_container :nth-child(2)").show();
76010         jQuery("#item_container :nth-child(3)").show();
76011
76012         //jQuery("#hwkeys-panel").show();
76013     }
76014 }
76015
76016 module.exports = {
76017     initialize: function () {
76018         if (platform.current().id === "cordova") {
76019             items.splice(1, 1);
76020         }
76021         $("#options-button-config-window").bind("click", function ()  {
76022             _showConfigWindow();
76023         });
76024     }
76025 };
76026
76027 });
76028 define('ripple/ui/plugins/firstRunCheck', function (require, exports, module) {
76029 /*
76030  *  Copyright 2011 Research In Motion Limited.
76031  *
76032  * Licensed under the Apache License, Version 2.0 (the "License");
76033  * you may not use this file except in compliance with the License.
76034  * You may obtain a copy of the License at
76035  *
76036  * http://www.apache.org/licenses/LICENSE-2.0
76037  *
76038  * Unless required by applicable law or agreed to in writing, software
76039  * distributed under the License is distributed on an "AS IS" BASIS,
76040  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76041  * See the License for the specific language governing permissions and
76042  * limitations under the License.
76043  */
76044 var utils = require('ripple/utils'),
76045     _platform = require('ripple/platform'),
76046     db = require('ripple/db');
76047
76048 function _handleFirstRunResponse(platform, version) {
76049     var device = jQuery("#device-select").val(),
76050         api = {
76051             name: platform.id,
76052             version: version
76053         };
76054
76055
76056     _platform.changeEnvironment(api, device, function () {
76057         window.tinyHipposReload = true;
76058         location.reload();
76059     });
76060 }
76061
76062 function _addPlatformButton(platform, version) {
76063     var section = jQuery(".platform-select-buttons"),
76064         buttonID = "platform-" + platform.id,
76065         button = utils.createElement("button", {
76066             "id": buttonID,
76067             "class": "ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
76068         });
76069
76070     button.appendChild(utils.createElement("span", {
76071         "class": "ui-button-text",
76072         "innertext" : platform.name
76073     }));
76074
76075     section.append(button);
76076
76077     document.getElementById(buttonID).addEventListener("click", function () {
76078         _handleFirstRunResponse(platform, version);
76079     });
76080 }
76081
76082 function _initializeFirstRunCheck() {
76083     var savedPlatform = db.retrieveObject("api-key"),
76084         firstRunOverlayNode, firstRunOptionsNode,
76085         width, p;
76086
76087     if (!savedPlatform) {
76088         width = jQuery(document).width();
76089         p = (width / 2) - 277;
76090
76091         firstRunOverlayNode = jQuery(".first-run-window").css({display: 'block'});
76092         firstRunOptionsNode = jQuery(".platform-select-dialog").css({display: 'block', left: p + "px"});
76093
76094         utils.forEach(_platform.getList(), function (platform) {
76095             utils.forEach(platform, function (details, version) {
76096                 _addPlatformButton(details, version);
76097             });
76098         });
76099     }
76100 }
76101
76102 module.exports = {
76103     initialize: function () {
76104         if (utils.map(_platform.getList(), function (platform) {
76105             return platform;
76106         }).length > 1) {
76107             _initializeFirstRunCheck();
76108         }
76109     }
76110 };
76111
76112 });
76113 define('ripple/ui/plugins/themeSwitcher', function (require, exports, module) {
76114 /*
76115  *  Copyright 2011 Research In Motion Limited.
76116  *
76117  * Licensed under the Apache License, Version 2.0 (the "License");
76118  * you may not use this file except in compliance with the License.
76119  * You may obtain a copy of the License at
76120  *
76121  * http://www.apache.org/licenses/LICENSE-2.0
76122  *
76123  * Unless required by applicable law or agreed to in writing, software
76124  * distributed under the License is distributed on an "AS IS" BASIS,
76125  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76126  * See the License for the specific language governing permissions and
76127  * limitations under the License.
76128  */
76129 var utils = require('ripple/utils'),
76130     db = require('ripple/db'),
76131     THEME_KEY = "ui-theme",
76132     THEME_SELECTOR = "#theme-select",
76133     _currentTheme;
76134
76135 function _saveAndReload(key, value) {
76136     jWorkflow.order(function (prev, baton) {
76137                 baton.take();
76138                 db.save(key, value, null, baton.pass);
76139             }).start(function () {
76140                 window.tinyHipposReload = true;
76141                 location.reload();
76142             });
76143 }
76144
76145 module.exports = {
76146     initialize: function () {
76147         var themeToSet = db.retrieve(THEME_KEY);
76148
76149         // Hide the theme switcher and always set the theme to light
76150         jQuery(".theme-switcher").hide();
76151                 if (themeToSet !== "light") {
76152             _saveAndReload(THEME_KEY, "light");
76153                 }
76154                 return;
76155     }
76156 };
76157
76158 });
76159 define('ripple/ui/plugins/about-dialog', function (require, exports, module) {
76160 /*
76161  *  Copyright 2011 Research In Motion Limited.
76162  *
76163  * Licensed under the Apache License, Version 2.0 (the "License");
76164  * you may not use this file except in compliance with the License.
76165  * You may obtain a copy of the License at
76166  *
76167  * http://www.apache.org/licenses/LICENSE-2.0
76168  *
76169  * Unless required by applicable law or agreed to in writing, software
76170  * distributed under the License is distributed on an "AS IS" BASIS,
76171  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76172  * See the License for the specific language governing permissions and
76173  * limitations under the License.
76174  */
76175 var bus = require('ripple/bus');
76176
76177 module.exports = {
76178     initialize: function () {
76179         $("#about-dialog").dialog({
76180             resizable: false,
76181             draggable: false,
76182             modal: true,
76183             autoOpen: false,
76184             position: 'center',
76185             minWidth: '464',
76186             minHeight: '262'
76187         });
76188     },
76189     show: function () {
76190         //TODO: Restore this line once framework issue is resolved
76191         //var port =  window.stagewebview ? stagewebview.serverPort : "9900";
76192         var port = "9910";
76193
76194         bus.send("version", null, function (resp) {
76195             $("#about-dialog-ripple-ui-version").html("(v" + resp + ")");
76196         });
76197
76198         bus.ajax(
76199             "GET",
76200             "http://127.0.0.1:" + port + "/ripple/about",
76201             null,
76202             function (resp) {
76203                 $("#about-dialog-ripple-build-deploy-version").html("(v" + resp.data.version + ")");
76204             },
76205             function (error) {
76206                 var version = error.data;
76207                 
76208                 if (error.code === 0 || error.code === 404) {
76209                     version = "The service is not running";
76210                 }
76211                 $("#about-dialog-ripple-build-deploy-version").html("(" + version + ")");
76212             }
76213         );
76214
76215         $("#about-dialog").dialog("open");
76216     }
76217 };
76218
76219 });
76220 define('ripple/ui/plugins/videoPlayer', function (require, exports, module) {
76221 /*
76222  *  Copyright 2011 Research In Motion Limited.
76223  *
76224  * Licensed under the Apache License, Version 2.0 (the "License");
76225  * you may not use this file except in compliance with the License.
76226  * You may obtain a copy of the License at
76227  *
76228  * http://www.apache.org/licenses/LICENSE-2.0
76229  *
76230  * Unless required by applicable law or agreed to in writing, software
76231  * distributed under the License is distributed on an "AS IS" BASIS,
76232  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76233  * See the License for the specific language governing permissions and
76234  * limitations under the License.
76235  */
76236 var constants = require('ripple/constants'),
76237     event = require('ripple/event');
76238
76239 module.exports = {
76240     initialize: function () {
76241         var videoObj,
76242             videoProgress = document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_PROGRESS_ID);
76243
76244         event.on("MultimediaAppVideoPlayerCreated", function (videoDOMObj) {
76245             videoObj = videoDOMObj;
76246
76247             videoObj.addEventListener("timeupdate", function () {
76248                 var s = parseInt(videoObj.currentTime % 60, 10),
76249                     m = parseInt((videoObj.currentTime / 60) % 60, 10);
76250
76251                 videoProgress.innerText = ((m > 9) ? m  : "0" + m) + ':' + ((s > 9) ? s  : "0" + s);
76252             }, false);
76253         });
76254
76255         event.on("MultimediaVolumeChanged", function (volume) {
76256             if (videoObj) {
76257                 videoObj.volume = parseFloat(volume / 10);
76258             }
76259         });
76260
76261         event.on("MultimediaVideoStateChanged", function (state) {
76262             document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_STATE_FIELD_ID).innerText = state;
76263             document.getElementById(constants.COMMON.MULTIMEDIA_VIDEO_FILE_FIELD_ID).innerText = videoObj.getAttribute("src");
76264         });
76265     }
76266 };
76267
76268 });
76269 define('ripple/ui/plugins/information', function (require, exports, module) {
76270 /*
76271  *  Copyright 2011 Research In Motion Limited.
76272  *
76273  * Licensed under the Apache License, Version 2.0 (the "License");
76274  * you may not use this file except in compliance with the License.
76275  * You may obtain a copy of the License at
76276  *
76277  * http://www.apache.org/licenses/LICENSE-2.0
76278  *
76279  * Unless required by applicable law or agreed to in writing, software
76280  * distributed under the License is distributed on an "AS IS" BASIS,
76281  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76282  * See the License for the specific language governing permissions and
76283  * limitations under the License.
76284  */
76285 var constants = require('ripple/constants'),
76286     devices = require('ripple/devices'),
76287     event = require('ripple/event'),
76288     platform = require('ripple/platform'),
76289     utils = require('ripple/utils'),
76290     app = require('ripple/app'),
76291     tooltip = require('ripple/ui/plugins/tooltip'),
76292     db = require('ripple/db');
76293
76294 function _updateInformationView() {
76295     var infoPane = document.getElementById(constants.COMMON.INFO_SECTION),
76296         infoList = [],
76297         device = devices.getCurrentDevice(),
76298         tempString = "",
76299         widgetInfo = app.getInfo(),
76300         layout = db.retrieve("layout") || "portrait",
76301         _systemSettings = db.retrieveObject("tizen2-systemsetting") || {"HOME_SCREEN": "", "LOCK_SCREEN": "", "INCOMING_CALL": "", "NOTIFICATION_EMAIL": ""};
76302
76303     //TODO: refactor this stuff to grab info from API, do this in a loop rather then hardcoded. Better DOM injection approach. This is legacy code
76304
76305     infoList.push('<section id=\"information-banner\" style=\"display:none\"><img id=\"information-banner-icon\" width=\"16px\" height=\"16px\"/> <span id=\"information-banner-count\"></span></section>');
76306
76307     if (widgetInfo.icon) {
76308         infoList.push('<section style="position: absolute; left: 260px;"  class="information-widgeticon"><img class="ui-corner-all" width="64" src="' + utils.appLocation() + widgetInfo.icon + '" alt="widget icon"/></section>');
76309     }
76310     if (widgetInfo.name) {
76311         infoList.push("<section><div id=\"systemSummaryAppNameContainer\" style=\"width:240px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">App Name: </label><span class=\"text-is-selectable\">" + widgetInfo.name + "</span></div></section>");
76312         //Update Title
76313         document.title = "Web Simulator - " + widgetInfo.name;
76314     }
76315
76316     infoList.push('<table class="tf_panel-table" style="border-spacing: 0px;">');
76317    
76318     if (widgetInfo.version) {
76319         infoList.push('<section class="information-widgetversion"><label class=\"ui-text-label\">Version: </label><span class="text-is-selectable">' + widgetInfo.version + '</span></section>');
76320     }
76321     infoList.push("<section><label class=\"ui-text-label\">Platform: </label><span class=\"text-is-selectable\">" + platform.current().name + "</span></section>");
76322     infoList.push("<section><label class=\"ui-text-label\">Device: </label><span class=\"text-is-selectable\">" + device.name + "</span></section>");
76323     infoList.push("<section><label class=\"ui-text-label\">OS: </label><span class=\"text-is-selectable\">" + device.osName + " " + device.osVersion + "</span></section>");
76324     infoList.push("<section><label class=\"ui-text-label\">Manufacturer: </label><span class=\"text-is-selectable\">" + device.manufacturer + "</span></section>");
76325     infoList.push("<section><label class=\"ui-text-label\">Screen: </label><span class=\"text-is-selectable\">" + device.screen.width + "x" + device.screen.height + "</span></section>");
76326     infoList.push("<section><label class=\"ui-text-label\">Viewport: </label><span class=\"text-is-selectable\">" + device.viewPort[layout].width.toFixed(0) + "x" + device.viewPort[layout].height.toFixed(0) + "</span></section>");
76327     infoList.push("<section><label class=\"ui-text-label\">Density: </label><span class=\"text-is-selectable\">" + device.ppi + " PPI</span></section>");
76328     infoList.push("<section><label class=\"ui-text-label\" style=\"float:left; padding-top: 0px; \">User Agent: </label>" +
76329                     "<div class=\"text-is-selectable\" style=\"padding-left: 80px\">" + device.userAgent + "</div></section>");
76330
76331     if (device.notes) {
76332         utils.forEach(device.notes, function (note) {
76333             tempString += "<li class=\"text-is-selectable\">" + note + "</li>";
76334         });
76335         infoList.push("<section><div style=\"clear:both;\"></div><label class=\"ui-text-label\">Notes: </label><ul>" + tempString + "</ul></section>");
76336     }
76337
76338     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"systemSummaryHomeScreenContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">Home Screen Image: </label><span>" + _systemSettings["HOME_SCREEN"] + "</span></div></section>");
76339     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"systemSummaryLockScreenContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">Lock Screen Image: </label><span>" + _systemSettings["LOCK_SCREEN"] + "</span></div></section>");
76340     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"systemSummaryInComingCallContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">Incoming Call Number: </label><span>" + _systemSettings["INCOMING_CALL"] + "</span></div></section>");
76341     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"systemSummaryNotiEMailContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">Notification Email: </label><span>" + _systemSettings["NOTIFICATION_EMAIL"] + "</span></div></section>");
76342     infoList.push("<section><div style=\"clear:both;\"></div><div id=\"NFCExclusiveModeContainer\" style=\"width:320px; height:20px; overflow:hidden; white-space: nowrap; text-overflow: ellipsis;\" ><label class=\"ui-text-label\">NFC Exclusive Mode: </label><span id=\"NFCExclusiveModeValue\">false</span></div></section>");
76343     infoPane.innerHTML = infoList.join("");
76344
76345     // Make tooltip if it needed
76346     if ((jQuery("#systemSummaryAppNameContainer").children("label").width() + jQuery("#systemSummaryAppNameContainer").children("span").width()) > 240) {
76347         tooltip.create("#systemSummaryAppNameContainer", jQuery("#systemSummaryAppNameContainer").children("span").text());
76348     }
76349     if ((jQuery("#systemSummaryHomeScreenContainer").children("label").width() + jQuery("#systemSummaryHomeScreenContainer").children("span").width()) > 320) {
76350         tooltip.create("#systemSummaryHomeScreenContainer", jQuery("#systemSummaryHomeScreenContainer").children("span").text());
76351     }
76352     if ((jQuery("#systemSummaryLockScreenContainer").children("label").width() + jQuery("#systemSummaryLockScreenContainer").children("span").width()) > 320) {
76353         tooltip.create("#systemSummaryLockScreenContainer", jQuery("#systemSummaryLockScreenContainer").children("span").text());
76354     }
76355     if ((jQuery("#systemSummaryInComingCallContainer").children("label").width() + jQuery("#systemSummaryInComingCallContainer").children("span").width()) > 320) {
76356         tooltip.create("#systemSummaryInComingCallContainer", jQuery("#systemSummaryInComingCallContainer").children("span").text());
76357     }
76358     if ((jQuery("#systemSummaryNotiEMailContainer").children("label").width() + jQuery("#systemSummaryNotiEMailContainer").children("span").width()) > 320) {
76359         tooltip.create("#systemSummaryNotiEMailContainer", jQuery("#systemSummaryNotiEMailContainer").children("span").text());
76360     }
76361 }
76362
76363 function _updateBanner(icon, count) {
76364     var bannerSection = document.getElementById("information-banner"),
76365         iconImg  = document.getElementById("information-banner-icon"),
76366         countSpan = document.getElementById("information-banner-count");
76367
76368     if (icon && (count === undefined || count !== 0)) {
76369         count = count || "";
76370         jQuery("#" + constants.COMMON.INFO_SECTION).show();
76371         jQuery(bannerSection).fadeToggle(1000);
76372         jQuery(bannerSection).fadeIn(1000);
76373     }
76374     else {
76375         jQuery(bannerSection).fadeOut(1000);
76376     }
76377
76378     iconImg.src = utils.appLocation() + icon;
76379     if (icon.indexOf("http") === 0) {
76380         iconImg.src = icon;
76381     }
76382
76383     countSpan.innerHTML = count > 99 ? "99+" : count;
76384 }
76385
76386 module.exports = {
76387     panel: {
76388         domId: "information-container",
76389         collapsed: false,
76390         pane: "left",
76391         titleName: "System Summary",
76392         display: true
76393     },
76394     initialize: function () {
76395         event.on("BannerUpdated", function (icon, count) {
76396             _updateBanner(icon, count);
76397         });
76398
76399         event.on("PlatformChangedEvent", function () {
76400             _updateInformationView();
76401         });
76402
76403         event.on("WidgetInformationUpdated", function () {
76404             _updateInformationView();
76405         });
76406         
76407         event.on("SystemSettingChanged", function () {
76408             _updateInformationView();
76409         });
76410
76411         event.on("ScreenChangeDimensions", function() {
76412             _updateInformationView();
76413         });
76414         _updateInformationView();
76415     }
76416 };
76417
76418 });
76419 define('ripple/ui/plugins/vehicle', function (require, exports, module) {
76420 /*
76421  *  Copyright 2013 Research In Motion Limited.
76422  *
76423  * Licensed under the Apache License, Version 2.0 (the "License");
76424  * you may not use this file except in compliance with the License.
76425  * You may obtain a copy of the License at
76426  *
76427  * http://www.apache.org/licenses/LICENSE-2.0
76428  *
76429  * Unless required by applicable law or agreed to in writing, software
76430  * distributed under the License is distributed on an "AS IS" BASIS,
76431  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76432  * See the License for the specific language governing permissions and
76433  * limitations under the License.
76434  */
76435 var event = require('ripple/event'),
76436     exception = require('ripple/exception'),
76437     vehiclePanelEngine = require('ripple/platform/ivi/3.0/VehiclePanelEngine').VehiclePanelEngine,
76438     _vehicleGlobalVars = {
76439         currentAutoStatus: false,
76440         currentDataIndex: 0,
76441         timeFlag: null,
76442         timeInterval: 1000, //ms
76443         timeCurrent: 0,
76444         timeHistoryArray: [],
76445         timeHistoryLimit: 60 * 60,
76446         registerListeners: {},
76447         vehicleCache: {},
76448         history: {},
76449         notShowProperties: [
76450             "zone", "time", "source"
76451         ]
76452     };
76453
76454 function _interceptString (str, length) {
76455     return str.length > length ? str.substring(0, length) + "...": str;
76456 }
76457
76458 function _setVehicleConfigurationSel (configuration) {
76459     var selContainer = jQuery("#vehicle-container #vehicle-configuration-types"),
76460         html = "", i = 0;
76461
76462     for (var value in configuration) {
76463         html += '<option value="' + value + '">' +
76464             'Car ' + i +
76465             '</option>';
76466
76467         i++;
76468     }
76469
76470     selContainer.html(html);
76471 }
76472
76473 function _setVehicleConfiguration (configuration, currentType) {
76474     var container = jQuery("#vehicle-container #vehicle-configuration-show"),
76475         selContainer = jQuery("#vehicle-container #vehicle-configuration-types"),
76476         current, property, propertyList, item, unit, html = "", i,
76477         enums, showValue;
76478
76479     if (currentType !== selContainer.val()) {
76480         for (i = 0; i < selContainer[0].options.length; i++) {
76481             if (selContainer[0].options[i].value === currentType) {
76482                 selContainer[0].selectedIndex = i;
76483                 break;
76484             }
76485         }
76486         if (i >= selContainer[0].options.length ) {
76487             throw "undefined configuration: " + currentType + ".";
76488         }
76489     }
76490
76491     current = configuration[currentType];
76492     if (!current) {
76493         throw "undefined configuration: " + currentType + ".";
76494     }
76495
76496     for (property in current) {
76497         html += '<tr><td colspan="2" class="vehicle-property-header">' + property + '</td></tr>';
76498
76499         propertyList = current[property];
76500         for (item in propertyList) {
76501             showValue = propertyList[item];
76502             unit = vehiclePanelEngine.getPropertyUnit(property, item);
76503             enums = vehiclePanelEngine.getPropertyConstant(property, item);
76504             if (enums) {
76505                 showValue = enums["val" + showValue];
76506             }
76507
76508             html += '<tr class="vehicle-property-content">' +
76509                 '<td class="vehicle-property-label"> ' + item + unit + '</td>' +
76510                 '<td class="vehicle-property-value" id="' + property + '-' + item + '-show">' + showValue + '</td>' +
76511                 '<td style="display: none;">' +
76512                 '<input id="' + property + '-' + item + '-set" type="hidden" ' + 'value="' + propertyList[item] + '" />' +
76513                 '</td></tr>';
76514         }
76515     }
76516
76517     container.html(html);
76518     return;
76519 }
76520
76521 function _setVehicleSupported (properties, supported) {
76522     var hideContainer = jQuery("#vehicle-container #vehicle-supported-hide"),
76523         showContainer = jQuery("#vehicle-container #vehicle-supported-show"),
76524         hideHtml = "", showHtml = "", tempHtml, column = 0, columnNum = 3, className,
76525         i, property, propertyAbbr;
76526
76527     for (i = 0; i < properties.length; i++) {
76528         property = properties[i];
76529         propertyAbbr = _interceptString(property, 12);
76530
76531         if (supported.indexOf(property) > -1) {
76532             className = "vehicle-property-supported";
76533             hideHtml += '<input type="checkbox" id="' + property + '-supported" value="' + property + '" checked="checked" />';
76534         }
76535         else {
76536             className = "vehicle-property-unsupported";
76537             hideHtml += '<input type="checkbox" id="' + property + '-supported" value="' + property + '" />';
76538         }
76539
76540         tempHtml = '<td id="' + property + '-supported-show" ' + 'class="' + className + '" title="' + property + '">' + propertyAbbr + '</td>';
76541
76542         if (column % columnNum === 0) {
76543             showHtml += '<tr>' + tempHtml;
76544         }
76545         else if (column % columnNum === (columnNum - 1)){
76546             showHtml += tempHtml + '</tr>';
76547         }
76548         else {
76549             showHtml += tempHtml;
76550         }
76551         column++;
76552     }
76553
76554     hideContainer.html(hideHtml);
76555     showContainer.html(showHtml);
76556 }
76557
76558 function _setVehicleSetting (settings) {
76559     var settingContainer = jQuery("#vehicle-container #vehicle-setting-show"),
76560         property, propertyItems, item, html = "", unit, range,
76561         optionHtml = "", i, optionName, option, options;
76562
76563     for (property in settings) {
76564         html += '<tr><td colspan="2" class="vehicle-property-header">' + property + '</td></tr>';
76565
76566         propertyItems = settings[property];
76567         for (item in propertyItems) {
76568             unit = vehiclePanelEngine.getPropertyUnit(property, item);
76569
76570             if (propertyItems[item].type === "radio" || propertyItems[item].type === "select") {
76571                 optionHtml = "";
76572                 options = propertyItems[item].options;
76573                 for (i = 0; i < options.length; i++) {
76574                     option = options[i];
76575                     for (optionName in option) {
76576                         if (option[optionName].toString() === propertyItems[item].value.toString()) {
76577                             optionHtml += '<option value="' + option[optionName] + '" selected>' +
76578                                 optionName + '</option>';
76579                         }
76580                         else {
76581                             optionHtml += '<option value="' + option[optionName] + '">' +
76582                                 optionName + '</option>';
76583                         }
76584                         break;
76585                     }
76586                 }
76587                 html += '<tr class="vehicle-property-content">' +
76588                     '<td class="vehicle-property-label" title="' + item + unit  + '">' + _interceptString(item + unit, 18)  + '</td>' +
76589                     '<td class="vehicle-property-value">' +
76590                     '<select id="' + property + '-' + item + '-set">' + optionHtml + '</select>' +
76591                     '</td></tr>';
76592             }
76593             else if (propertyItems[item].type === "range") {
76594                 range = vehiclePanelEngine.getPropertyRange(property, item);
76595
76596                 html += '<tr class="vehicle-property-content">' +
76597                     '<td class="vehicle-property-label" title="' + item + unit  + '">' + _interceptString(item + unit, 18)  + '</td>' +
76598                     '<td class="vehicle-property-value">' +
76599                     '<label id="' + property + '-' + item + '-num">' + propertyItems[item].value + '</label>' +
76600                     '<input id="' + property + '-' + item + '-set" type="range" value="' + propertyItems[item].value + '"' +
76601                         ' min="' + range[0] + '" max="' + range[1] + '" step="' + range[2] + '" class="vehicle-property-range" />' +
76602                     '</td></tr>';
76603             }
76604             else if (propertyItems[item].type === "text") {
76605                 html += '<tr class="vehicle-property-content">' +
76606                     '<td class="vehicle-property-label" title="' + item + unit  + '">' + _interceptString(item + unit, 18)  + '</td>' +
76607                     '<td class="vehicle-property-value">' +
76608                     '<input id="' + property + '-' + item + '-set" type="text" value="' + propertyItems[item].value + '" />' +
76609                     '</td></tr>';
76610             }
76611         }
76612     }
76613
76614     settingContainer.html(html);
76615 }
76616
76617 function _addArrayValueEnter (property, item, value) {
76618     var itemValue, html = "", i,
76619         id = property + '-' + item + "-set";
76620
76621     itemValue = value.split(",");
76622
76623     if (jQuery("#" + id + "Array") && jQuery("#" + id + "Array").length === 1) {
76624         html += '<td colspan="3">';
76625     }
76626     else {
76627         html += '<tr id="'+ id + 'Array" class="vehicle-property-array">' +
76628             '<td colspan="3">';
76629     }
76630
76631     if (itemValue.length === 0) {
76632         html += '<div class="vehicle-property-arrayItem">' +
76633             '<button>add</button>' +
76634             '<input type="text" value="0" />' +
76635             '<button>del</button>' +
76636             '</div>';
76637     }
76638     else {
76639         for (i = 0; i < itemValue.length; i++) {
76640             if (i === itemValue.length - 1) {
76641                 html += '<div class="vehicle-property-arrayItem">' +
76642                     '<button style="margin-left: -60px;">add</button>' +
76643                     '<input type="text" value="' + itemValue[i] + '" />' +
76644                     '<button >del</button>' +
76645                     '</div>';
76646             }
76647             else {
76648                 html += '<div class="vehicle-property-arrayItem">' +
76649                     '<button style="display: none;">add</button>' +
76650                     '<input type="text" value="' + itemValue[i] + '" />' +
76651                     '<button >del</button>' +
76652                     '</div>';
76653             }
76654         }
76655     }
76656
76657     if (jQuery("#" + id + "Array") && jQuery("#" + id + "Array").length === 1) {
76658         html += '</td>';
76659
76660         jQuery("#" + id + "Array").html(html);
76661     }
76662     else {
76663         html += '</td></tr>';
76664
76665         html += '<tr id="'+ id + 'OK" class="vehicle-property-array">' +
76666             '<td colspan="3">';
76667         html += '<button class="vehicle-property-arrayOk">OK</button>';
76668         html += '</td></tr>';
76669     }
76670
76671     return html;
76672 }
76673
76674 function _setVehicleAutoRunning (autoRunning, isFill) {
76675     var autoContainer = jQuery("#vehicle-container #vehicle-running-show"),
76676         timeStamp, html = "", unit,  range, property, propertyItem, value, data,
76677         showContainer, setContainer, valueField, options, option, optionName, i,
76678         enums, showValue;
76679
76680     timeStamp = (new Date()).getTime();
76681     data = autoRunning["auto" + _vehicleGlobalVars.currentDataIndex];
76682     if (!data) {
76683         _vehicleGlobalVars.currentDataIndex = 0;
76684         data = autoRunning["auto0"];
76685     }
76686     _vehicleGlobalVars.timeCurrent = timeStamp;
76687
76688     if (!isFill) {
76689         html += '<tr class="vehicle-property-content">' +
76690             '<td class="vehicle-property-label">Time</td>' +
76691             '<td class="vehicle-property-value" id="vehicle-time-show">' + timeStamp + '</td></tr>';
76692
76693         for (property in data) {
76694             html += '<tr><td colspan="2" class="vehicle-property-header">' + property + '</td></tr>';
76695
76696             for (propertyItem in data[property]) {
76697                 value = data[property][propertyItem].value;
76698                 unit = vehiclePanelEngine.getPropertyUnit(property, propertyItem);
76699
76700                 if (Object.prototype.toString.call(value) === '[object Array]') {
76701                     value = value.join(",");
76702                 }
76703
76704                 if (data[property][propertyItem].type === "radio" || data[property][propertyItem].type === "select") {
76705                     valueField = "";
76706                     options = data[property][propertyItem].options;
76707                     for (i = 0; i < options.length; i++) {
76708                         option = options[i];
76709                         for (optionName in option) {
76710                             if (option[optionName].toString() === data[property][propertyItem].value) {
76711                                 valueField += '<option value="' + option[optionName] + '" selected>' +
76712                                     optionName + '</option>';
76713                             }
76714                             else {
76715                                 valueField += '<option value="' + option[optionName] + '">' +
76716                                     optionName + '</option>';
76717                             }
76718                             break;
76719                         }
76720                     }
76721
76722                     valueField = '<select id="' + property + '-' + propertyItem + '-set">' + valueField + '</select>';
76723                 }
76724                 else if (data[property][propertyItem].type === "range") {
76725                     range = vehiclePanelEngine.getPropertyRange(property, propertyItem);
76726
76727                     valueField = '<label id="' + property + '-' + propertyItem + '-num">' + value + '</label>' +
76728                         '<input id="' + property + '-' + propertyItem + '-set" type="range" value="' + value + '"' +
76729                         ' min="' + range[0] + '" max="' + range[1] + '" step="' + range[2] + '" class="vehicle-property-range" />';
76730                 }
76731                 else if (data[property][propertyItem].type === "text") {
76732                     valueField = '<input type="text" value="' + value +'" id="' + property + '-' + propertyItem + '-set" disabled />';
76733                 }
76734
76735                 enums = vehiclePanelEngine.getPropertyConstant(property, propertyItem);
76736                 if (enums) {
76737                     showValue = enums["val" + value];
76738                 }
76739
76740                 html += '<tr class="vehicle-property-content">' +
76741                     '<td class="vehicle-property-label" title="' + propertyItem + unit  + '">' + _interceptString(propertyItem + unit, 18) + '</td>' +
76742                     '<td class="vehicle-property-value vehicle-property-value-auto" id="' + property + '-' + propertyItem + '-show">' + showValue + '</td>' +
76743                     '<td class="vehicle-property-value vehicle-property-value-manual">' +
76744                     valueField +
76745                     '</td></tr>';
76746
76747                 if (data[property][propertyItem].type === "text") {
76748                     html += _addArrayValueEnter(property, propertyItem, value);
76749                 }
76750
76751                 if (_vehicleGlobalVars.registerListeners[property]) {
76752                     event.trigger("vehicle-subscribe-request", [property, false, 0]);
76753                 }
76754             }
76755         }
76756
76757         autoContainer.html(html);
76758         _switchAutoManual(false);
76759     }
76760     else {
76761         if (_vehicleGlobalVars.currentAutoStatus) {
76762             for (property in data) {
76763
76764                 for (propertyItem in data[property]) {
76765                     value = data[property][propertyItem].value;
76766
76767                     showContainer = jQuery("#vehicle-container #vehicle-running-show #" + property + '-' + propertyItem + "-show");
76768                     setContainer = jQuery("#vehicle-container #vehicle-running-show #" + property + '-' + propertyItem + "-set");
76769
76770                     if (Object.prototype.toString.call(value) === '[object Array]') {
76771                         value = value.join(",");
76772                     }
76773
76774                     if (data[property][propertyItem].type === "text") {
76775                         _addArrayValueEnter(property, propertyItem, value);
76776                     }
76777
76778                     if (showContainer && setContainer) {
76779                         showContainer.html(value);
76780                         setContainer.val(value);
76781                     }
76782                 }
76783             }
76784         }
76785         else {
76786         }
76787         jQuery("#vehicle-container #vehicle-running-show #vehicle-time-show").html(timeStamp);
76788     }
76789
76790     for (property in _vehicleGlobalVars.registerListeners) {
76791         event.trigger("vehicle-subscribe-request", [property, false, 0]);
76792     }
76793
76794     _saveVehicleData();
76795     _vehicleGlobalVars.currentDataIndex++;
76796 }
76797
76798 function _formatHistory (historyData, time, zone, source) {
76799     var format = {}, property, name, item, value;
76800
76801     for (property in historyData) {
76802         name = property.split("-")[0];
76803         item = property.split("-")[1];
76804
76805         if (!format[name]) {
76806             format[name] = {};
76807             format[name].time = time;
76808             format[name].zone = zone;
76809             format[name].source = source;
76810         }
76811
76812         value = historyData[property];
76813         if (value.indexOf(",") > -1) {
76814             value = value.split(",");
76815         }
76816         if (value === "true") value = true;
76817         if (value === "false") value = false;
76818
76819         format[name][item] = value;
76820     }
76821
76822     return format;
76823 }
76824
76825 function _saveVehicleData () {
76826     var configurationContainer = jQuery("#vehicle-container #vehicle-configuration-show *[id$='-set']"),
76827         currentConfigContainer = jQuery("#vehicle-container #vehicle-configuration-types"),
76828         settingContainer = jQuery("#vehicle-container #vehicle-setting-show  *[id$='-set']"),
76829         autoContainer = jQuery("#vehicle-container #vehicle-running-show  *[id$='-set']"),
76830         supportedContainer = jQuery("#vehicle-container #vehicle-supported-hide  *[id$='-supported']:checked"),
76831         supported = [], currentConfig, configuration = [], setting = [], autoRunning = [],
76832         history = {}, itemKey, format, delTime, time, zone, source;
76833
76834     supportedContainer.each(function (index, item) {
76835         supported.push(item.value);
76836     });
76837
76838     currentConfig = currentConfigContainer.val().replace("configuration", "");
76839
76840     configurationContainer.each(function (index, item) {
76841         itemKey = item.id.replace("-set", "");
76842         history[itemKey] = item.value;
76843
76844         configuration.push(item.value);
76845     });
76846
76847     settingContainer.each(function (index, item) {
76848         itemKey = item.id.replace("-set", "");
76849         history[itemKey] = item.value;
76850
76851         setting.push(item.value);
76852     });
76853
76854     autoContainer.each(function (index, item) {
76855         var value;
76856
76857         value = item.value;
76858         if (item.id.indexOf("TripMeter") > -1) {
76859             value = item.value.split(",");
76860         }
76861
76862         itemKey = item.id.replace("-set", "");
76863         history[itemKey] = value;
76864
76865         autoRunning.push(value);
76866     });
76867
76868     _vehicleGlobalVars.timeHistoryArray.push(_vehicleGlobalVars.timeCurrent);
76869     if (_vehicleGlobalVars.timeHistoryArray.length > _vehicleGlobalVars.timeHistoryLimit) {
76870         delTime = _vehicleGlobalVars.timeHistoryArray.shift();
76871         delete _vehicleGlobalVars.history[delTime];
76872     }
76873
76874     time = _vehicleGlobalVars.timeCurrent;
76875     source = "";
76876     zone = 0;
76877
76878     format = _formatHistory(history, time, zone, source);
76879     _vehicleGlobalVars.history[_vehicleGlobalVars.timeCurrent] = format;
76880     event.trigger("vehicle-cache-refresh", [supported, format]);
76881
76882     vehiclePanelEngine.saveData(supported, currentConfig, configuration, setting, autoRunning);
76883 }
76884
76885 function _switchAutoManual (isAuto) {
76886     var autoContainer = jQuery("#vehicle-container #vehicle-running-show .vehicle-property-value-auto"),
76887         manualContainer = jQuery("#vehicle-container #vehicle-running-show .vehicle-property-value-manual"),
76888         arrayContainer = jQuery("#vehicle-container #vehicle-running-show .vehicle-property-array"),
76889         autoBtnContainer = jQuery("#vehicle-container #vehicle-running-auto");
76890
76891     if (isAuto) {
76892         autoBtnContainer.addClass("vehicle-property-supported");
76893         autoBtnContainer.removeClass("vehicle-property-unsupported");
76894         autoContainer.show();
76895         manualContainer.hide();
76896         arrayContainer.hide();
76897     }
76898     else {
76899         autoBtnContainer.addClass("vehicle-property-unsupported");
76900         autoBtnContainer.removeClass("vehicle-property-supported");
76901         autoContainer.hide();
76902         manualContainer.show();
76903         arrayContainer.show();
76904     }
76905 }
76906
76907 function _addVehicleDomEventListener () {
76908     var configSelection = jQuery("#vehicle-container #vehicle-configuration-types"),
76909         supportedSelection = jQuery("#vehicle-container #vehicle-supported-show td"),
76910         autoSelection = jQuery("#vehicle-container #vehicle-running-auto"),
76911         arraySelection = jQuery("#vehicle-container .vehicle-property-array"),
76912         arrayOKSelection = jQuery("#vehicle-container .vehicle-property-arrayOk"),
76913         rangeSelection = jQuery("#vehicle-container input[type='range']");
76914
76915     arraySelection.delegate("button", "click", function () {
76916         var els = jQuery(this), appHtml;
76917
76918         appHtml = '<div class="vehicle-property-arrayItem">' +
76919             '<button style="margin-left: -60px;">add</button>' +
76920             '<input type="text" value="0" />' +
76921             '<button >del</button>' +
76922             '</div>';
76923
76924         if (els.html() === "add") {
76925             jQuery(appHtml).insertAfter(els.parent());
76926             els.hide();
76927         }
76928         else if (els.html() === "del") {
76929             if (els.parent().prev().length === 0 && els.parent().next().length === 0)
76930                 return;
76931             els.parent().prev().find("button")[0].style.marginLeft = "-60px";
76932             els.parent().prev().find("button")[0].style.display = "";
76933             els.parent().remove();
76934         }
76935     });
76936
76937     arrayOKSelection.click("click", function () {
76938         var els = jQuery(this), inputEls, i, trEls,
76939             setElsId, value = [];
76940
76941         trEls = els.parent().parent();
76942         setElsId = trEls.attr("id").replace("OK", "");
76943
76944         inputEls = trEls.prev().find("input");
76945         for (i = 0; i < inputEls.length; i++)  {
76946             value.push(inputEls[i].value);
76947         }
76948
76949         jQuery("#vehicle-container #" + setElsId).val(value.join(","));
76950     });
76951
76952     rangeSelection.bind("change", function () {
76953         var domJQuery = jQuery(this);
76954
76955         domJQuery.prev().html(domJQuery.val());
76956     });
76957
76958     configSelection.bind("change", function () {
76959         var configuration, current,
76960             domJQuery = jQuery(this);
76961
76962         configuration = _vehicleGlobalVars.vehicleCache.configurationData;
76963         current = domJQuery.val();
76964         _setVehicleConfiguration(configuration, current);
76965     });
76966
76967     //add vehicle supported click event
76968     supportedSelection.bind("click", function () {
76969         var domJQuery = jQuery(this), vehicleChecked,
76970             propertiesSelector = "#vehicle-container #vehicle-supported-hide",
76971             content, supportedId, inputJQuery;
76972
76973         content = domJQuery.html();
76974         supportedId = content + "-supported";
76975         inputJQuery = jQuery(propertiesSelector + " #" + supportedId);
76976         if (domJQuery.hasClass("vehicle-property-unsupported")) {
76977             inputJQuery.attr("checked", "checked");
76978             domJQuery.removeClass("vehicle-property-unsupported");
76979             domJQuery.addClass("vehicle-property-supported");
76980         }
76981         else {
76982             inputJQuery.removeAttr("checked");
76983             domJQuery.removeClass("vehicle-property-supported");
76984             domJQuery.addClass("vehicle-property-unsupported");
76985         }
76986
76987         vehicleChecked = jQuery("#vehicle-container #vehicle-supported-hide input:checked");
76988         _vehicleGlobalVars.vehicleCache.supported.length = 0;
76989         vehicleChecked.each(function (index, els) {
76990             _vehicleGlobalVars.vehicleCache.supported.push(els.value);
76991         });
76992     });
76993
76994     //add vehicle auto click event
76995     autoSelection.bind("click", function () {
76996         if (_vehicleGlobalVars.currentAutoStatus) {
76997             _vehicleGlobalVars.currentAutoStatus = false;
76998             jQuery("#vehicle-container #vehicle-configuration-noOperation").hide();
76999             jQuery("#vehicle-container #vehicle-supported-noOperation").hide();
77000         }
77001         else {
77002             _vehicleGlobalVars.currentAutoStatus = true;
77003             jQuery("#vehicle-container #vehicle-configuration-noOperation").show();
77004             jQuery("#vehicle-container #vehicle-supported-noOperation").show();
77005         }
77006         _switchAutoManual(_vehicleGlobalVars.currentAutoStatus);
77007
77008         _vehicleGlobalVars.timeFlag = setInterval(function () {
77009             _setVehicleAutoRunning(_vehicleGlobalVars.vehicleCache.autoRunningData, true);
77010         }, _vehicleGlobalVars.timeInterval);
77011     });
77012 }
77013
77014 function _addVehicleEventListener () {
77015     event.once("vehicle-cache-request", function (data) {
77016         data.supported = _vehicleGlobalVars.vehicleCache.supported;
77017         data.data = _vehicleGlobalVars.history[_vehicleGlobalVars.timeCurrent];
77018     });
77019
77020     event.on("vehicle-subscribe-request", function (property, isRegister, zone) {
77021         if (isRegister) {
77022             _vehicleGlobalVars.registerListeners[property] = true;
77023             return;
77024         }
77025
77026         var value, status, time, history,
77027             propertyObj = {};
77028
77029         if (_vehicleGlobalVars.vehicleCache.supported.indexOf(property) === -1) {
77030             propertyObj.val = null;
77031             propertyObj.supported = false;
77032             propertyObj.type = property;
77033         }
77034         else {
77035             history = _vehicleGlobalVars.history;
77036             time = _vehicleGlobalVars.timeCurrent;
77037
77038             value = history[time][property];
77039             value.time = time;
77040             status = true;
77041
77042             propertyObj.val = value;
77043             propertyObj.supported = status;
77044             propertyObj.type = property;
77045         }
77046
77047         event.trigger("vehicle-subscribe-response", [propertyObj]);
77048     });
77049
77050     event.on("vehicle-set-request", function (property, value) {
77051         var status = true, enums, showValue;
77052
77053         for (var item in value) {
77054             var enterID = property + "-" + item + "-set";
77055             var showID = property + "-" + item + "-show";
77056             var enterContainer = jQuery("#vehicle-container #" + enterID);
77057             var showContainer = jQuery("#vehicle-container #" + showID);
77058
77059             if (Object.prototype.toString.call(value[item]) === '[object Array]') {
77060                 enterContainer.val(value[item].join(","));
77061             }
77062             else {
77063                 enterContainer.val(value[item].toString());
77064             }
77065             if (showContainer) {
77066                 enums = vehiclePanelEngine.getPropertyConstant(property, item);
77067                 showValue = value[item];
77068                 if (enums) {
77069                     showValue = enums["val" + value[item]];
77070                 }
77071                 showContainer.html(showValue);
77072             }
77073         }
77074
77075         event.trigger("vehicle-set-response", [status]);
77076     });
77077
77078     event.on("vehicle-history-request", function (property, zone, startTime, endTime) {
77079         var history, historyResponse = [], obj, status, time;
77080
77081         history = _vehicleGlobalVars.history;
77082
77083         for (time in history) {
77084             if (time >= startTime && time <= endTime &&
77085                 history[time].hasOwnProperty(property)) {
77086                 obj = history[time][property];
77087                 obj.time = time;
77088                 historyResponse.push(obj);
77089             }
77090         }
77091         status = true;
77092
77093         event.trigger("vehicle-history-response", [historyResponse, status]);
77094     });
77095 }
77096
77097 function _initializeVehiclePanel () {
77098     try {
77099         var stop = false,
77100             configuration, current, properties, supported, settings,
77101             autoRunning;
77102
77103         _vehicleGlobalVars.timeHistoryArray = [];
77104
77105         configuration = vehiclePanelEngine.getConfiguration();
77106         current = vehiclePanelEngine.getCurrentConfiguration();
77107         _setVehicleConfigurationSel(configuration);
77108         _vehicleGlobalVars.vehicleCache.configurationData = configuration;
77109         _vehicleGlobalVars.vehicleCache.currentConfiguration = current;
77110         _setVehicleConfiguration(configuration, current);
77111
77112         properties = vehiclePanelEngine.getProperties();
77113         supported = vehiclePanelEngine.getSupported();
77114         _vehicleGlobalVars.vehicleCache.properties = properties;
77115         _vehicleGlobalVars.vehicleCache.supported = supported;
77116         _setVehicleSupported(properties, supported);
77117
77118         settings = vehiclePanelEngine.getSettings();
77119         _vehicleGlobalVars.vehicleCache.settingData = settings;
77120         _setVehicleSetting(settings);
77121
77122         autoRunning = vehiclePanelEngine.getAutoRunning();
77123         _vehicleGlobalVars.vehicleCache.autoRunningData = autoRunning;
77124         _setVehicleAutoRunning(autoRunning, false);
77125         _vehicleGlobalVars.currentDataIndex = 0;
77126
77127         _vehicleGlobalVars.timeFlag = setInterval(function () {
77128             _setVehicleAutoRunning(_vehicleGlobalVars.vehicleCache.autoRunningData, true);
77129         }, _vehicleGlobalVars.timeInterval);
77130
77131         _addVehicleDomEventListener();
77132
77133         _addVehicleEventListener();
77134
77135         jQuery("#vehicle-properties h3").click(function (event) {
77136             if (stop) {
77137                 event.stopImmediatePropagation();
77138                 event.preventDefault();
77139                 stop = false;
77140             }
77141         });
77142         jQuery("#vehicle-properties").accordion("destroy").accordion({
77143             header: "> div > h3",
77144             autoHeight: false
77145         });
77146     } catch (e) {
77147         exception.handle(e, true);
77148     }
77149 }
77150
77151 module.exports = {
77152     panel: {
77153         domId: "vehicle-container",
77154         collapsed: true,
77155         pane: "right",
77156         titleName: "Vehicle Information",
77157         display: true
77158     },
77159     initialize: function () {
77160         _initializeVehiclePanel();
77161     }
77162 };
77163
77164 });
77165 define('ripple/ui/plugins/build', function (require, exports, module) {
77166 /*
77167  *  Copyright 2011 Research In Motion Limited.
77168  *
77169  * Licensed under the Apache License, Version 2.0 (the "License");
77170  * you may not use this file except in compliance with the License.
77171  * You may obtain a copy of the License at
77172  *
77173  * http://www.apache.org/licenses/LICENSE-2.0
77174  *
77175  * Unless required by applicable law or agreed to in writing, software
77176  * distributed under the License is distributed on an "AS IS" BASIS,
77177  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77178  * See the License for the specific language governing permissions and
77179  * limitations under the License.
77180  */
77181 var tooltip = require('ripple/ui/plugins/tooltip'),
77182     settings = require('ripple/ui/plugins/settings-dialog'),
77183     bus = require('ripple/bus');
77184
77185 function handleBuild() {
77186     var node = $(this),
77187         action = node.attr('id').split("-")[2];
77188
77189     if (node.hasClass("not-ready")) {
77190         return;
77191     }
77192
77193     if (!settings.can(action)) {
77194         settings.show(action);
77195     }
77196     else {
77197         settings.perform(action);
77198     }
77199 }
77200
77201 function areServicesRunning(success, fail) {
77202     bus.ajax(
77203         "GET",
77204         "http://127.0.0.1:9910/ripple/about",
77205         null,
77206         function () {
77207             success();
77208         },
77209         function (error) {
77210             fail();
77211         }
77212     );
77213 }
77214
77215 function manageServices(action, callBack) {
77216     bus.send("services", action, function () {
77217         if (typeof callBack === "function") {
77218             callBack();
77219         }
77220     });
77221 }
77222
77223 module.exports = {
77224     panel: {
77225         domId: "build-container",
77226         collapsed: true,
77227         pane: "right"
77228     },
77229
77230     initialize: function () {
77231         $("#options-menu-build").click(handleBuild);
77232         $("#options-menu-sign").click(handleBuild);
77233         $("#options-menu-launch").click(handleBuild);
77234
77235         $('#options-menu-start-service').click(function () {
77236             manageServices("start", function (result) {
77237                 $('#options-menu-services-stop').show();
77238                 $('#options-menu-services-start').hide();
77239             });
77240         });
77241
77242         $('#options-menu-stop-service').click(function () {
77243             manageServices("stop", function (result) {
77244                 $('#options-menu-services-stop').hide();
77245                 $('#options-menu-services-start').show();
77246             });
77247         });
77248
77249         $("#options-menu-settings").click(function () {
77250             settings.show(); 
77251         });
77252
77253         if (settings.value("remoteInspector")) {
77254             $("#options-menu-build-warning").show();
77255             tooltip.create("#options-menu-build-warning", "Remote Web Inspector should be disabled when packaging for App World release");
77256         }
77257
77258         areServicesRunning(
77259             function () {
77260                 $('#options-menu-services-stop').show();
77261                 $('#options-menu-services-start').hide();
77262             }, 
77263             function () {
77264                 $('#options-menu-services-stop').hide();
77265                 $('#options-menu-services-start').show();
77266             }
77267         );
77268     }
77269 };
77270
77271 });
77272 define('ripple/ui/plugins/sensors', function (require, exports, module) {
77273 /*
77274  * Copyright (c) 2010 Epic Train Hack
77275  * Copyright (c) 2011 Research In Motion Limited
77276  * Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
77277  *
77278  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
77279  *
77280  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
77281  *
77282  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
77283  */
77284 var event = require('ripple/event'),
77285     accelerometer = require('ripple/accelerometer'),
77286     deviceSettings = require('ripple/deviceSettings'),
77287     Acceleration = require('ripple/platform/w3c/1.0/Acceleration'),
77288     Rotation = require('ripple/platform/w3c/1.0/Rotation'),
77289     sensorSettings = require('ripple/sensorSettings'),
77290     _oldX, _oldY, _oldAlphaX,
77291     _camera, _scene, _renderer, _mesh,
77292     _offsets = {
77293         x: 0,
77294         y: 0,
77295         z: -9.81,
77296     },
77297     _flag, // whether the browser supports webGL
77298     _shape =
77299         //
77300         // The front side
77301         //
77302         // x, y, z      x, y, z         x, y, z
77303         // for some strange reason for y -100 is top, 100 is bottom
77304         "-30,30,10,     30,30,10,       30,60,10,       100,100,100,-1,0;" + // top left, top right, bottom right - of the right triangle
77305         "-30,30,10,     30,60,10,       -30,60,10,      100,100,100,-1,0;" + // top left, right bottom, left bottom - of the left triangle
77306         // front side "the phone display"
77307         "-20,-50,11,    20,-50,11,      20,20,11,       100,100,100,-1,0;" +
77308         "-20,-50,11,    20,20,11,       -20,20,11,      100,100,100,-1,0;" +
77309         // below the display
77310         "-30,30,10,     30,20,10,       30,30,10,       0,0,0,-1,0;" +
77311         "-30,30,10,     -30,20,10,      30,20,10,       0,0,0,-1,0;" +
77312         // above the display
77313         "-30,-60,10,    30,-60,10,      30,-50,10,      0,0,0,-1,0;" +
77314         "-30,-60,10,    30,-50,10,      -30,-50,10,     0,0,0,-1,0;" +
77315         // left of the display
77316         "-30,-50,10,    -20,-50,10,     -20,20,10,      0,0,0,-1,0;" +
77317         "-30,-50,10,    -20,20,10,      -30,20,10,      0,0,0,-1,0;" +
77318         // right of the display
77319         "20,-50,10,     30,-50,10,      30,20,10,       0,0,0,-1,0;" +
77320         "20,-50,10,     30,20,10,       20,20,10,       0,0,0,-1,0;" +
77321
77322
77323         // back side, opposite side to the above one
77324         "-30,-60,-10,   30,60,-10,      30,-60,-10,     0,0,0,-1,0;" +
77325         "-30,-60,-10,   -30,60,-10,     30,60,-10,      0,00,-1,0;" +
77326         // right side
77327         "30,-60,-10,    30,60,-10,      30,60,10,       50,50,80,-1,0;" +
77328         "30,-60,-10,    30,60,10,       30,-60,10,      50,50,80,-1,0;" +
77329         // left side
77330         "-30,-60,-10,   -30,60,10,      -30,60,-10,     50,50,80,-1,0;" +
77331         "-30,-60,-10,   -30,-60,10,     -30,60,10,      50,50,80,-1,0;" +
77332
77333         // top
77334         "30,-60,-10,    -30,-60,10, -30,-60,-10,    50,80,50,-1,0;" +
77335         "30,-60,-10,    30,-60,10,      -30,-60,10, 50,80,50,-1,0;" +
77336         // bottom
77337         "30,60,-10, -30,60,-10,     -30,60,10,      80,50,50,-1,0;" +
77338         "30,60,-10, -30,60,10,      30,60,10,       80,50,50,-1,0";
77339
77340 function _createThreeDModel() {
77341     var node,
77342         shader,
77343         hemiLight,
77344         dirLight,
77345         material,
77346         uniforms,
77347         container,
77348         loader,
77349         directionalLight,
77350         isDiffuseTextureLoaded,
77351         isNormalTextureLoaded,
77352         shiftKeyDown,
77353         mouseDown,
77354         ctrlKeyDown = false;
77355
77356     if (_flag) {
77357         // create a 3D phone model with three.js if webGL is supported
77358         node = document.getElementById("accelerometer-div");
77359         container = document.createElement("div");
77360         $("#accelerometer-div").append(container);
77361
77362         _camera = new THREE.PerspectiveCamera(50, 1.5, 0.1, 100);
77363         _camera.position.set(4.32823, 3.74714, 2.62985);
77364         _scene = new THREE.Scene();
77365         _scene.add(new THREE.AmbientLight(0xffffff));
77366         directionalLight = new THREE.DirectionalLight(0xffffff, 1);
77367         directionalLight.position.set(1, 1, 1).normalize();
77368         _scene.add(directionalLight);
77369         hemiLight = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
77370         hemiLight.color.setHSV(0.6, 0.75, 1);
77371         hemiLight.groundColor.setHSV(0.095, 0.5, 1);
77372         hemiLight.position.set(0, 500, 0);
77373         _scene.add(hemiLight);
77374         dirLight = new THREE.DirectionalLight(0xffffff, 1);
77375         dirLight.color.setHSV(0.1, 0.1, 1);
77376         dirLight.position.set(-1, 1.75, 1);
77377         dirLight.position.multiplyScalar(50);
77378         _scene.add(dirLight);
77379         shader = THREE.ShaderSkin["skin"];
77380         uniforms = THREE.UniformsUtils.clone(shader.uniforms);
77381         uniforms["tNormal"].value = THREE.ImageUtils.loadTexture("images/phoneMap_tNormal.png", {}, function () {
77382             isNormalTextureLoaded = true;
77383             if (isDiffuseTextureLoaded) {
77384                 _renderer.clear();
77385                 _renderer.render(_scene, _camera);
77386             }
77387         });
77388         uniforms["uNormalScale"].value = 0.75;
77389         uniforms["tDiffuse"].value = THREE.ImageUtils.loadTexture("images/phoneMap_tDiffuse.png", {}, function () {
77390             isDiffuseTextureLoaded = true;
77391             if (isNormalTextureLoaded) {
77392                 _renderer.clear();
77393                 _renderer.render(_scene, _camera);
77394             }
77395         });
77396         uniforms["uDiffuseColor"].value.setHex(0xbbbbbb);
77397         uniforms["uSpecularColor"].value.setHex(0x070707);
77398         uniforms["uAmbientColor"].value.setHex(0x111111);
77399         uniforms["uRoughness"].value = 0.185;
77400         uniforms["uSpecularBrightness"].value = 0.8;
77401         material = new THREE.ShaderMaterial({ fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true });
77402         loader = new THREE.JSONLoader(true);
77403         document.body.appendChild(loader.statusDomElement);
77404
77405         loader.load("phoneModel.js", function (geometry) {
77406             loader.statusDomElement.style.display = "none";
77407             geometry.computeTangents();
77408             _mesh = new THREE.Mesh(geometry, material);
77409             _mesh.position.set(7, 2, -50);
77410             _mesh.scale.set(18, 12, 18);
77411             _scene.add(_mesh);
77412             _renderer.clear();
77413             _renderer.render(_scene, _camera);
77414         });
77415
77416         _renderer = new THREE.WebGLRenderer({antialias: false});
77417         _renderer.setSize(300, 280);
77418         _renderer.setClearColorHex(0xffffff, 1);
77419         _renderer.autoClear = false;
77420
77421         container.appendChild(_renderer.domElement);
77422     } else { // create the model with 3d.js
77423         node = document.querySelector("#accelerometer-canvas");
77424
77425         jQuery("#accelerometer-div").css("display", "none");
77426         jQuery("#accelerometer-canvas").css("display", "block");
77427         ThreeDee.setCenter(150, 100);
77428         ThreeDee.setLight(-300, -300, 800);
77429         _updateCanvas(0, 0);
77430     }
77431
77432     //change accelerometer and phone by moving the mouse and the key "shift"
77433     node.addEventListener("mousemove", function (event) {
77434         var cosX, sinX, cosY, sinY,
77435             alpha = accelerometer.getInfo().orientation.alpha,
77436             beta = accelerometer.getInfo().orientation.beta,
77437             gamma = accelerometer.getInfo().orientation.gamma,
77438             x = accelerometer.getInfo().acceleration.x,
77439             y = accelerometer.getInfo().acceleration.y,
77440             z = accelerometer.getInfo().acceleration.z;
77441
77442         if (!mouseDown) {
77443             return;
77444         }
77445
77446         // if the shift key is pressed down, only the alpha value will be chagned
77447         if (!shiftKeyDown) {
77448             _offsets.x = (_offsets.x + _oldX - event.offsetX) % 360;
77449             _offsets.y = (_offsets.y + _oldY - event.offsetY) % 360;
77450
77451             alpha = alpha || 0;
77452
77453             // enforce gamma in [-90,90] as per w3c spec
77454             gamma = -_offsets.x;
77455             if (gamma < -90) {
77456                 gamma = -90;
77457             }
77458             if (gamma > 90) {
77459                 gamma = 90;
77460             }
77461
77462             // enforce beta in [-180,180] as per w3c spec
77463             beta = -_offsets.y % 360;
77464             if (beta < -180) {
77465                 beta += 360;
77466             }
77467             else if (beta >= 180) {
77468                 beta -= 360;
77469             }
77470
77471             cosX = Math.cos(gamma * (Math.PI / 180));
77472             sinX = Math.sin(gamma * (Math.PI / 180));
77473             cosY = Math.cos(beta * (Math.PI / 180));
77474             sinY = Math.sin(beta * (Math.PI / 180));
77475             x = 9.81 * cosY * sinX;
77476             y = -9.81 * sinY;
77477             z = -9.81 * cosY * cosX;
77478
77479         } else {
77480             alpha = (alpha - (_oldAlphaX - event.offsetX) * 2.5) % 360;
77481         }
77482         _oldX = event.offsetX;
77483         _oldY = event.offsetY;
77484         _oldAlphaX = event.offsetX;
77485         if (_flag)
77486             _updatePhoneModel(alpha, beta, gamma);
77487         else
77488             _updateCanvas(alpha, -beta, gamma);
77489         accelerometer.setInfo({
77490             x: x,
77491             y: y,
77492             z: z,
77493             alpha: alpha,
77494             beta: beta,
77495             gamma: gamma
77496         });
77497     }, false);
77498
77499     node.addEventListener("mousedown", function (e) {
77500         mouseDown = true;
77501         _oldX = e.offsetX;
77502         _oldY = e.offsetY;
77503         if (shiftKeyDown) {
77504             _oldAlphaX = _oldX;
77505         }
77506     });
77507
77508     node.addEventListener("mouseup", function () {
77509         mouseDown = false;
77510     });
77511
77512     document.addEventListener("mouseup", function () {
77513         //Catch mouseup events that fire when outside canvas bounds
77514         mouseDown = false;
77515     });
77516
77517     document.addEventListener("keydown", function (e) {
77518         switch (e.keyCode) {
77519         case 16:                // Shift Key
77520             shiftKeyDown = true;
77521             break;
77522         case 17:                // Ctrl Key
77523             ctrlKeyDown = true;
77524             break;
77525         case 74:                // J Key
77526             if (shiftKeyDown && ctrlKeyDown) { //if shift+ctrl+j keydown in the meantime, console comes up rather than shift key down
77527                 shiftKeyDown = false;
77528                 ctrlKeyDown = false;
77529             }
77530             break;
77531         }
77532     });
77533
77534     document.addEventListener("keyup", function (e) {
77535         if (e.keyCode === 16) { // Shift Key
77536             shiftKeyDown = false;
77537         }
77538     });
77539 }
77540
77541 // update the 3d model created by 3d.js
77542 function _updateCanvas(a, b, g) {
77543     ThreeDee.loadMesh(_shape);
77544     g = g || 0;
77545     ThreeDee.rotate(0, g, 0);
77546     ThreeDee.rotate(b, 0, a);
77547     ThreeDee.backface();
77548     ThreeDee.shade();
77549     ThreeDee.zSort();
77550     Draw.initialize(document.querySelector("#accelerometer-canvas"));
77551     Draw.clear(0, 0, 480, 300);
77552     Draw.drawScene(ThreeDee.getTranslation(), 3);
77553 }
77554
77555 // update the 3d model created by three.js
77556 function _updatePhoneModel(a, b, g) {
77557     _mesh.rotation.x = b / 90 * 1.5;
77558     _mesh.rotation.y = g / 90 * 1.5;
77559     _mesh.rotation.z = a / 90 * 1.5;
77560     _renderer.clear();
77561     _renderer.render(_scene, _camera);
77562 }
77563
77564 function _resetAccelerometer() {
77565     _oldX = 0;
77566     _oldY = 0;
77567     _oldAlphaX = 0;
77568     _offsets = {
77569         x: 0,
77570         y: 0,
77571         z: -9.81
77572     };
77573     if (_flag) {
77574         _mesh.rotation.x = 0;
77575         _mesh.rotation.y = 0;
77576         _mesh.rotation.z = 0;
77577         _renderer.clear();
77578         _renderer.render(_scene, _camera);
77579     } else {
77580         _updateCanvas(0, 0);
77581     }
77582
77583     accelerometer.setInfo({
77584         acceleration: new Acceleration(0, 0, 0),
77585         accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
77586         rotationRate: new Rotation(0, 0, 0),
77587         orientation: new Rotation(0, 0, 0),
77588         timestamp: new Date().getTime()
77589     });
77590     accelerometer.triggerEvent();
77591 }
77592
77593 function _resetMagneticField() {
77594     jQuery("#magnetic-x").val("100");
77595     jQuery("#magnetic-y").val("100");
77596     jQuery("#magnetic-z").val("100");
77597 }
77598
77599 function _resetLightLevel() {
77600     $("#display-state").children().each(function() {
77601         if ($(this).val() === "OFF") {
77602             $(this).attr("selected", "true");
77603             this.selected = true;
77604         }
77605         else {
77606             $(this).attr("selected", "false");
77607             this.selected = false;
77608         }
77609     });
77610 }
77611
77612
77613 // set a typical mode for accelerometer simulation, when the phone drops,
77614 // x will become to be 0, y will become to be -9.81 and z will become to be 0
77615 function _setDrop() {
77616     //duration = 20 * 50 = 1000ms. 20 is ths number of steps and 50 is the duration of steps.
77617     var alpha = Number(accelerometer.getInfo().orientation.alpha),
77618         beta = Number(accelerometer.getInfo().orientation.beta),
77619         gamma = Number(accelerometer.getInfo().orientation.gamma),
77620         cosX, cosY, sinX, sinY, x, y, z,
77621         alphaStep = Math.abs(alpha) / 20,
77622         betaStep = Math.abs(beta - 90) / 20,
77623         gammaStep = Math.abs(gamma) / 20,
77624         counts = 0, dropTimeout,
77625         drop = function () {
77626             if (counts >= 20) {
77627                 window.clearTimeout(dropTimeout);
77628                 // to avoid showing "-0" or "-0.00"
77629                 if (_flag)
77630                     _updatePhoneModel(0, 90, 0);
77631                 else
77632                     _updateCanvas(0, -90, 0);
77633                 accelerometer.setInfo({
77634                     x: 0,
77635                     y: -9.81,
77636                     z: 0,
77637                     alpha: 0,
77638                     beta: 90,
77639                     gamma: 0
77640                 });
77641             } else {
77642                 dropTimeout = setTimeout(drop, 50);
77643                 step();
77644                 counts++;
77645             }
77646         },
77647         step = function () {
77648             var _beta;
77649
77650             alpha = alpha > 0 ? alpha - alphaStep : alpha + alphaStep;
77651             beta = beta > 90 ? beta - betaStep : beta + betaStep;
77652             gamma = gamma > 0 ? gamma - gammaStep : gamma + gammaStep;
77653             _beta = _flag ? beta + betaStep : -(beta + betaStep);
77654             if (_flag)
77655                 _updatePhoneModel(alpha, _beta, gamma);
77656             else
77657                 _updateCanvas(alpha, _beta, gamma);
77658
77659             cosX = Math.cos(gamma * (Math.PI / 180));
77660             sinX = Math.sin(gamma * (Math.PI / 180));
77661             cosY = Number(Math.cos(beta * (Math.PI / 180)).toFixed(6));
77662             sinY = Math.sin(beta * (Math.PI / 180));
77663             x = 9.81 * cosY * sinX;
77664             y = -9.81 * sinY;
77665             z = -9.81 * cosY * cosX;
77666             accelerometer.setInfo({
77667                 x: x,
77668                 y: y,
77669                 z: z,
77670                 alpha: alpha,
77671                 beta: beta,
77672                 gamma: gamma
77673             });
77674             _offsets.x = -gamma;
77675             _offsets.y = -beta;
77676         };
77677
77678     drop();
77679 }
77680
77681 function _initializeSensorSettings() {
77682     var sensorsInputID = ["accelerometer-alpha", "accelerometer-beta", "accelerometer-gamma", "magnetic-x", "magnetic-y", "magnetic-z"],
77683         magneticEvent = ["MagneticField-xChanged", "MagneticField-yChanged", "MagneticField-zChanged"],
77684          magneticData = ["MagneticField.x", "MagneticField.y", "MagneticField.z"],
77685         oldValue, oldInputX,
77686         inputMouseDown,
77687         triggerFunction,
77688         selectedInputID = null;
77689
77690     triggerFunction = function (val, index) {
77691         var cosX, cosY, sinX, sinY, x, y, z,
77692             alpha = accelerometer.getInfo().orientation.alpha,
77693             beta = accelerometer.getInfo().orientation.beta,
77694             gamma = accelerometer.getInfo().orientation.gamma;
77695
77696         //choose which value to change according to index
77697         switch (index) {
77698         case 0:
77699             alpha = val;
77700             break;
77701         case 1:
77702             beta = val;
77703             break;
77704         case 2:
77705             gamma = val;
77706             break;
77707         default:
77708             sensorSettings.persist(magneticData[index - 3], val);
77709             event.trigger(magneticEvent[index - 3], [val]);
77710         }
77711
77712         //change the phone model and values of other inputs when changing a value of input
77713         if (_flag)
77714             _updatePhoneModel(alpha, beta, gamma);
77715         else
77716             _updateCanvas(alpha, -beta, gamma);
77717         cosX = Math.cos(gamma * (Math.PI / 180));
77718         sinX = Math.sin(gamma * (Math.PI / 180));
77719         cosY = Math.cos(beta * (Math.PI / 180));
77720         sinY = Math.sin(beta * (Math.PI / 180));
77721         x = 9.81 * cosY * sinX;
77722         y = -9.81 * sinY;
77723         z = -9.81 * cosY * cosX;
77724         accelerometer.setInfo({
77725             x: x,
77726             y: y,
77727             z: z,
77728             alpha: alpha,
77729             beta: beta,
77730             gamma: gamma
77731         });
77732         _offsets.x = -gamma;
77733         _offsets.y = -beta;
77734     };
77735
77736     // make the input elements more powful: drag mouse to left to decrease the value and right to increase it;
77737     // also change the value with arrow keys.
77738
77739
77740     sensorsInputID.forEach(function (id, index) {
77741         jQuery("#" + id).mousedown(function (e) {
77742             selectedInputID = id;
77743             oldValue = parseInt(this.value, 10);
77744             oldInputX = e.offsetX;
77745             inputMouseDown = true;
77746         });
77747
77748         jQuery("#" + id).mousemove(function (e) {
77749             if (inputMouseDown && (selectedInputID !== null)) {
77750                 jQuery("#" + selectedInputID).val(parseInt(oldValue + (e.offsetX - oldInputX) / 2, 10));
77751                 if (parseInt(this.value, 10) <= parseInt(jQuery(this).attr("minValue"), 10)) {
77752                     this.value = jQuery(this).attr("minValue");
77753                 }
77754                 if (parseInt(this.value, 10) >= parseInt(jQuery(this).attr("maxValue"), 10)) {
77755                     this.value = jQuery(this).attr("maxValue");
77756                 }
77757                 triggerFunction(this.value, index);
77758             }
77759         });
77760
77761         jQuery("#" + id).mouseup(function () {
77762             selectedInputID = null;
77763             inputMouseDown = false;
77764         });
77765         jQuery(document).mouseup(function () {
77766             selectedInputID = null;
77767             inputMouseDown = false;
77768         });
77769
77770         jQuery("#" + id).click(function () {
77771             this.select();
77772         });
77773
77774         jQuery("#" + id).blur(function () {
77775             if (isNaN(this.value)) {
77776                 this.value = 0;
77777             }
77778             else if (parseInt(this.value, 10) > parseInt(jQuery(this).attr("maxValue"), 10))
77779                 this.value = jQuery(this).attr("maxValue");
77780             else if (parseInt(this.value, 10) < parseInt(jQuery(this).attr("minValue"), 10))
77781                 this.value = jQuery(this).attr("minValue");
77782             else
77783                 this.value = parseInt(this.value, 10);
77784             triggerFunction(this.value, index);
77785         });
77786
77787         jQuery("#" + id).keydown(function (e) {
77788             switch (e.keyCode) {
77789             case 38:
77790                 if (parseInt(this.value, 10) < parseInt(jQuery(this).attr("maxValue"), 10)) {
77791                     this.value = parseInt(this.value, 10) + 1;
77792                     triggerFunction(this.value, index);
77793                 }
77794                 break;
77795             case 40:
77796                 if (parseInt(this.value, 10) > parseInt(jQuery(this).attr("minValue"), 10)) {
77797                     this.value = parseInt(this.value, 10) - 1;
77798                     triggerFunction(this.value, index);
77799                 }
77800                 break;
77801             default:
77802                 return;
77803             }
77804         });
77805     });
77806 }
77807
77808 /*
77809 //initialize light settings
77810 function _initializeLightSettings() {
77811     var displayObj = document.getElementById("display-state"),
77812         DISPLAY_STATE  = require('ripple/constants').POWER_RESOURCE.SCREEN.STATE,
77813         brightness;
77814
77815     displayObj.addEventListener("change", function () {
77816         var state = displayObj.value, value;
77817         value = DISPLAY_STATE[state].VALUE;
77818         deviceSettings.persist("Display.brightness", value);
77819         event.trigger("DisplayBrightnessChanged", [value]);
77820     });
77821
77822     brightness = deviceSettings.retrieve("Display.brightness");
77823     if (brightness ===  DISPLAY_STATE.SCREEN_OFF.MAX) {
77824         displayObj.options[0].selected = true;
77825     } else if (brightness <= DISPLAY_STATE.SCREEN_DIM.MAX) {
77826         displayObj.options[1].selected = true;
77827     } else if (brightness <= DISPLAY_STATE.SCREEN_NORMAL.MAX) {
77828         displayObj.options[2].selected = true;
77829     } else {
77830         displayObj.options[3].selected = true;
77831     }
77832 }
77833 */
77834
77835 module.exports = {
77836     panel: {
77837         domId: "sensors-container",
77838         collapsed: true,
77839         pane: "left",
77840         titleName: "Sensors",
77841         display: true
77842     },
77843     initialize: function () {
77844         var gl,
77845             testCanvas = document.getElementById("accelerometer-canvas");
77846
77847         try { // check whether the browser supports webGL, returns null if not support
77848             gl = testCanvas.getContext("experimental-webgl");
77849             gl.viewport(0, 0, testCanvas.width, testCanvas.height);
77850         } catch (e) {
77851             console.log("unsupport webgl");
77852         }
77853
77854         _flag = gl ? true : false;
77855
77856         accelerometer.init();
77857         _createThreeDModel();
77858         _initializeSensorSettings();
77859         //_initializeLightSettings();
77860
77861         jQuery("#accelerometer-shake").click(function () {
77862             window.setTimeout(require('ripple/ui/plugins/goodVibrations').shakeDevice(8), 1);
77863             accelerometer.shake();
77864         });
77865
77866         jQuery("#sensor-reset-all").click(function () {
77867             _resetAccelerometer();
77868             _resetMagneticField();
77869             _resetLightLevel();
77870         });
77871
77872         jQuery("#accelerometer-drop").click(_setDrop);
77873
77874         event.on("AccelerometerInfoChangedEvent", function (motion) {
77875             jQuery("#accelerometer-x").html(motion.accelerationIncludingGravity.x.toFixed(2));
77876             jQuery("#accelerometer-y").html(motion.accelerationIncludingGravity.y.toFixed(2));
77877             jQuery("#accelerometer-z").html(motion.accelerationIncludingGravity.z.toFixed(2));
77878             jQuery("#accelerometer-alpha").val(Number(motion.orientation.alpha).toFixed(2));
77879             jQuery("#accelerometer-beta").val(Number(motion.orientation.beta).toFixed(2));
77880             jQuery("#accelerometer-gamma").val(Number(motion.orientation.gamma).toFixed(2));
77881         }, this);
77882     }
77883 };
77884
77885 });
77886 define('ripple/ui/plugins/push', function (require, exports, module) {
77887 /*
77888  *  Copyright 2011 Research In Motion Limited.
77889  *
77890  * Licensed under the Apache License, Version 2.0 (the "License");
77891  * you may not use this file except in compliance with the License.
77892  * You may obtain a copy of the License at
77893  *
77894  * http://www.apache.org/licenses/LICENSE-2.0
77895  *
77896  * Unless required by applicable law or agreed to in writing, software
77897  * distributed under the License is distributed on an "AS IS" BASIS,
77898  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77899  * See the License for the specific language governing permissions and
77900  * limitations under the License.
77901  */
77902 var constants = require('ripple/constants'),
77903     event = require('ripple/event'),
77904     utils = require('ripple/utils'),
77905     db = require('ripple/db'),
77906     PUSH_OPTIONS = constants.PUSH.OPTIONS;
77907
77908 function _updatePushPanel(ports) {
77909     var portsSelect = document.getElementById("port-select"),
77910         currentPort = portsSelect.value;
77911
77912     portsSelect.innerHTML = "";
77913
77914     ports.forEach(function (port) {
77915         portsSelect.appendChild(utils.createElement("option", {
77916             innerText: port,
77917             value: port,
77918             selected: currentPort === port
77919         }));
77920     });
77921 }
77922
77923 module.exports = {
77924     panel: {
77925         domId: "push-container",
77926         collapsed: true,
77927         pane: "left"
77928     },
77929     initialize: function () {
77930         event.on("PushListenersChanged", function (listeners) {
77931             _updatePushPanel(listeners);
77932             jQuery("#port-select").effect("highlight", {color: "#62B4C8"}, 1000);
77933         });
77934
77935         _updatePushPanel([]);
77936
77937         document.getElementById("push-send")
77938             .addEventListener("click", function () {
77939                 var port = document.getElementById("port-select").value,
77940                     text = document.getElementById(PUSH_OPTIONS.PAYLOAD).value,
77941                     pushData = {
77942                         headerField: ["21f39092"],
77943                         requestURI: "/",
77944                         source: "ripple",
77945                         isChannelEncrypted: false,
77946                         payload: text
77947                     };
77948
77949                 event.trigger("Push", [pushData, port], true);
77950             }, false);
77951
77952         utils.bindAutoSaveEvent(jQuery("#" + PUSH_OPTIONS.PAYLOAD), function () {
77953             db.save(PUSH_OPTIONS.PAYLOAD, document.getElementById(PUSH_OPTIONS.PAYLOAD).value);
77954         });
77955
77956         document.getElementById(PUSH_OPTIONS.PAYLOAD).value = db.retrieve(PUSH_OPTIONS.PAYLOAD) || "My payload data";
77957     }
77958 };
77959
77960 });
77961 define('ripple/ui/plugins/accelerometer', function (require, exports, module) {
77962 /*
77963  * Copyright (c) 2010 Epic Train Hack
77964  * Copyright (c) 2011 Research In Motion Limited
77965  * Contributors: Wolfram Kriesing, Dan Silivestru, Brent Lintner
77966  *
77967  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
77968  *
77969  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
77970  *
77971  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
77972  */
77973 var ui = require('ripple/ui'),
77974     goodVibrations = require('ripple/ui/plugins/goodVibrations'),
77975     accelerometer = require('ripple/accelerometer'),
77976     event = require('ripple/event'),
77977     Rotation = require('ripple/platform/w3c/1.0/Rotation'),
77978     Acceleration = require('ripple/platform/w3c/1.0/Acceleration'),
77979     _mouseDown,
77980     _shiftKeyDown,
77981     _offsets = {
77982         x: 0,
77983         y: 0,
77984         z: -9.81,
77985     },
77986     _oldX,
77987     _oldY,
77988     _oldAlphaX,
77989     _shape =
77990         //
77991         // The front side
77992         //
77993         // x, y, z      x, y, z         x, y, z
77994         // for some strange reason for y -100 is top, 100 is bottom
77995         "-30,30,10,     30,30,10,       30,60,10,       100,100,100,-1,0;" + // top left, top right, bottom right - of the right triangle
77996         "-30,30,10,     30,60,10,       -30,60,10,      100,100,100,-1,0;" + // top left, right bottom, left bottom - of the left triangle
77997         // front side "the phone display"
77998         "-20,-50,11,    20,-50,11,      20,20,11,       100,100,100,-1,0;" +
77999         "-20,-50,11,    20,20,11,       -20,20,11,      100,100,100,-1,0;" +
78000         // below the display
78001         "-30,30,10,     30,20,10,       30,30,10,       0,0,0,-1,0;" +
78002         "-30,30,10,     -30,20,10,      30,20,10,       0,0,0,-1,0;" +
78003         // above the display
78004         "-30,-60,10,    30,-60,10,      30,-50,10,      0,0,0,-1,0;" +
78005         "-30,-60,10,    30,-50,10,      -30,-50,10,     0,0,0,-1,0;" +
78006         // left of the display
78007         "-30,-50,10,    -20,-50,10,     -20,20,10,      0,0,0,-1,0;" +
78008         "-30,-50,10,    -20,20,10,      -30,20,10,      0,0,0,-1,0;" +
78009         // right of the display
78010         "20,-50,10,     30,-50,10,      30,20,10,       0,0,0,-1,0;" +
78011         "20,-50,10,     30,20,10,       20,20,10,       0,0,0,-1,0;" +
78012
78013
78014         // back side, opposite side to the above one
78015         "-30,-60,-10,   30,60,-10,      30,-60,-10,     0,0,0,-1,0;" +
78016         "-30,-60,-10,   -30,60,-10,     30,60,-10,      0,00,-1,0;" +
78017         // right side
78018         "30,-60,-10,    30,60,-10,      30,60,10,       50,50,80,-1,0;" +
78019         "30,-60,-10,    30,60,10,       30,-60,10,      50,50,80,-1,0;" +
78020         // left side
78021         "-30,-60,-10,   -30,60,10,      -30,60,-10,     50,50,80,-1,0;" +
78022         "-30,-60,-10,   -30,-60,10,     -30,60,10,      50,50,80,-1,0;" +
78023
78024         // top
78025         "30,-60,-10,    -30,-60,10, -30,-60,-10,    50,80,50,-1,0;" +
78026         "30,-60,-10,    30,-60,10,      -30,-60,10, 50,80,50,-1,0;" +
78027         // bottom
78028         "30,60,-10, -30,60,-10,     -30,60,10,      80,50,50,-1,0;" +
78029         "30,60,-10, -30,60,10,      30,60,10,       80,50,50,-1,0";
78030
78031 function _shakeDevice() {
78032     window.setTimeout(goodVibrations.shakeDevice(8), 1);
78033     accelerometer.shake();
78034 }
78035
78036 function _updateAccelerometerPanel(motion) {
78037     jQuery("#accelerometer-x").html(Math.round(motion.accelerationIncludingGravity.x * 100) / 100);
78038     jQuery("#accelerometer-y").html(Math.round(motion.accelerationIncludingGravity.y * 100) / 100);
78039     jQuery("#accelerometer-z").html(Math.round(motion.accelerationIncludingGravity.z * 100) / 100);
78040     jQuery("#accelerometer-alpha").html(Math.round(motion.orientation.alpha));
78041     jQuery("#accelerometer-beta").html(Math.round(motion.orientation.beta));
78042     jQuery("#accelerometer-gamma").html(Math.round(motion.orientation.gamma));
78043 }
78044
78045 function _updateCanvas(a, b, g) {
78046     ThreeDee.loadMesh(_shape);
78047     g = g || 0;
78048     ThreeDee.rotate(0, g, 0);
78049     ThreeDee.rotate(b, 0, a);
78050     ThreeDee.backface();
78051     ThreeDee.shade();
78052     ThreeDee.zSort();
78053     Draw.initialize(document.querySelector("#accelerometer-canvas"));
78054     Draw.clear(0, 0, 480, 300);
78055     Draw.drawScene(ThreeDee.getTranslation(), 3);
78056 }
78057
78058 function _createCanvas() {
78059     var node = document.querySelector("#accelerometer-canvas"),
78060         x = 0, y = 0, z = -9.81,
78061         alpha = 0, beta = 0, gamma = 0,
78062         cosX, sinX, cosY, sinY,
78063         deltaAlpha = 360;
78064
78065     ThreeDee.setCenter(150, 100);
78066     ThreeDee.setLight(-300, -300, 800);
78067
78068     node.addEventListener("mousemove", function (e) {
78069         if (!_mouseDown)
78070             return;
78071
78072         if (!_shiftKeyDown) {
78073             _offsets.x = (_offsets.x + _oldX - e.offsetX) % 360;
78074             _offsets.y = (_offsets.y + _oldY - e.offsetY) % 360;
78075
78076             alpha = alpha || 0;
78077
78078             // enforce gamma in [-90,90] as per w3c spec
78079             gamma = -_offsets.x;
78080             if (gamma < -90) {
78081                 gamma = -90;
78082             }
78083             if (gamma > 90) {
78084                 gamma = 90;
78085             }
78086
78087             // enforce beta in [-180,180] as per w3c spec
78088             beta = -_offsets.y % 360;
78089             if (beta < -180) {
78090                 beta += 360;
78091             }
78092             else if (beta >= 180) {
78093                 beta -= 360;
78094             }
78095
78096             cosX = Math.cos((gamma) * (Math.PI / 180));
78097             sinX = Math.sin((gamma) * (Math.PI / 180));
78098             cosY = Math.cos((beta) * (Math.PI / 180));
78099             sinY = Math.sin((beta) * (Math.PI / 180));
78100             x = 9.81 * cosY * sinX;
78101             y = -9.81 * sinY;
78102             z = -9.81 * cosY * cosX;
78103
78104         }
78105         else {
78106             deltaAlpha = (deltaAlpha - (_oldAlphaX - e.offsetX) * 2.5) % 360;
78107             alpha = (360 - deltaAlpha) % 360;
78108         }
78109
78110         _oldX = e.offsetX;
78111         _oldY = e.offsetY;
78112         _oldAlphaX = e.offsetX;
78113
78114         _updateCanvas(deltaAlpha, -beta, gamma);
78115         accelerometer.setInfo({
78116             x: x,
78117             y: y,
78118             z: z,
78119             alpha: alpha,
78120             beta: beta,
78121             gamma: gamma
78122         });
78123
78124     });
78125
78126     node.addEventListener("mousedown", function (e) {
78127         _oldX = e.offsetX;
78128         _oldY = e.offsetY;
78129         if (_shiftKeyDown) {
78130             _oldAlphaX = _oldX;
78131         }
78132         _mouseDown = true;
78133     });
78134
78135     node.addEventListener("mouseup", function (e) {
78136         _mouseDown = false;
78137     });
78138
78139     node.addEventListener("dblclick", function (e) {   
78140         x = 0;
78141         y = 0;
78142         z = -9.81;
78143         alpha = 0;
78144         beta = 0;
78145         gamma = 0;
78146         deltaAlpha = 360;
78147         _resetAccelerometer();
78148     });
78149
78150     document.addEventListener("mouseup", function (e) {
78151         //Catch mouseup events that fire when outside canvas bounds
78152         _mouseDown = false;
78153     });
78154
78155     document.addEventListener("keydown", function (e) {
78156         if (e.keyCode === 16) { // Shift Key            
78157             _shiftKeyDown = true;
78158         }
78159     });
78160
78161     document.addEventListener("keyup", function (e) {
78162         if (e.keyCode === 16) { // Shift Key
78163             _shiftKeyDown = false;
78164         }
78165     });    
78166 }
78167
78168 function _resetAccelerometer() {    
78169     _updateCanvas(0, 0);
78170     _oldX = 0;
78171     _oldY = 0;
78172     _oldAlphaX = 0;
78173     _offsets = {
78174         x: 0,
78175         y: 0,
78176         z: -9.81,
78177     };
78178     accelerometer.setInfo({
78179         acceleration: new Acceleration(0, 0, 0),
78180         accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
78181         rotationRate: new Rotation(0, 0, 0),
78182         orientation: new Rotation(0, 0, 0),
78183         timestamp: new Date().getTime()
78184     });
78185 }
78186
78187 module.exports = {
78188     panel: {
78189         domId: "accelerometer-container",
78190         collapsed: true,
78191         pane: "left",
78192         titleName: "Accelerometer",
78193         display: true
78194     },
78195     initialize: function () {
78196         _createCanvas();
78197         
78198         _resetAccelerometer();
78199
78200         _updateAccelerometerPanel(accelerometer.getInfo());
78201
78202         jQuery("#accelerometer-shake").click(_shakeDevice);
78203
78204         event.on("AccelerometerInfoChangedEvent", _updateAccelerometerPanel, this);
78205     }
78206 };
78207
78208 });
78209 define('ripple/ui/plugins/phone', function (require, exports, module) {
78210 /*
78211  *  Copyright 2011 Research In Motion Limited.
78212  *
78213  * Licensed under the Apache License, Version 2.0 (the "License");
78214  * you may not use this file except in compliance with the License.
78215  * You may obtain a copy of the License at
78216  *
78217  * http://www.apache.org/licenses/LICENSE-2.0
78218  *
78219  * Unless required by applicable law or agreed to in writing, software
78220  * distributed under the License is distributed on an "AS IS" BASIS,
78221  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78222  * See the License for the specific language governing permissions and
78223  * limitations under the License.
78224  */
78225 var utils = require('ripple/utils'),
78226     Phone = require('ripple/platform/webworks.handset/2.0.0/client/Phone'),
78227     CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
78228     event = require('ripple/event'),
78229     _console = require('ripple/console'),
78230     eventSelect = document.getElementById("phone-event-types"),
78231     eventErrorContainer = document.getElementById("phone-event-error-container"),
78232     eventErrorSelect = document.getElementById("phone-event-error-types");
78233
78234 function _firePhoneLogEvents(type, number, error) {
78235     if (type === Phone.CB_CALL_INITIATED ||
78236         type === Phone.CB_CALL_ANSWERED) {
78237         event.trigger("PhoneCallLogAdded", [{
78238             date: new Date(),
78239             number: number,
78240             status: CallLog.STATUS_NORMAL,
78241             type: CallLog.TYPE_RECEIVED_CALL
78242         }], true);
78243     } else if (type === Phone.CB_CALL_ENDED_BYUSER ||
78244                 type === Phone.CB_CALL_FAILED) {
78245         event.trigger("PhoneCallLogAdded", [{
78246             date: new Date(),
78247             number: number,
78248             status: CallLog.STATUS_NORMAL,
78249             type: CallLog.TYPE_PLACED_CALL
78250         }], true);
78251     }
78252 }
78253
78254 function _updateActiveCalls(type, number, error) {
78255     if (type === Phone.CB_CALL_INITIATED ||
78256         type === Phone.CB_CALL_CONNECTED ||
78257         type === Phone.CB_CALL_CONFERENCECALL_ESTABLISHED ||
78258         type === Phone.CB_CALL_DIRECTCONNECT_CONNECTED ||
78259         type === Phone.CB_CALL_ANSWERED) {
78260         event.trigger("PhoneCallInitiated", [{
78261             id: number,
78262             onhold: false,
78263             outgoing: false,
78264             recipient: {
78265                 name: "",
78266                 number: String(number)
78267             }
78268         }], true);
78269     } else if (type === Phone.CB_CALL_ENDED_BYUSER ||
78270                 type === Phone.CB_CALL_FAILED ||
78271                 type === Phone.CB_CALL_DISCONNECTED ||
78272                 type === Phone.CB_CONFERENCECALL_DISCONNECTED ||
78273                 type === Phone.CB_CALL_DIRECTCONNECT_DISCONNECTED) {
78274         event.trigger("PhoneCallEnded", [{
78275             id: number
78276         }], true);
78277     }
78278 }
78279
78280 module.exports = {
78281     panel: {
78282         domId: "phone-container",
78283         collapsed: true,
78284         pane: "right"
78285     },
78286     initialize: function (prev, baton) {
78287         utils.forEach(Phone, function (value, prop) {
78288             if (prop.match(/^CB_/)) {
78289                 eventSelect.appendChild(utils.createElement("option", {
78290                     value: value,
78291                     innerHTML: prop.replace(/^CB_(CALL_)?/, "")
78292                 }));
78293             }
78294
78295             if (prop.match(/^CALL_ERROR_/)) {
78296                 eventErrorSelect.appendChild(utils.createElement("option", {
78297                     value: value,
78298                     innerHTML: prop.replace(/^CALL_ERROR_/, "")
78299                 }));
78300             }
78301         });
78302
78303         document.getElementById("phone-event-types").addEventListener("change", function () {
78304             eventErrorContainer.setAttribute("style", parseInt(eventSelect.value, 10) === Phone.CB_CALL_FAILED ? "" : "display: none");
78305         });
78306
78307         document.getElementById("phone-logs-clear").addEventListener("click", function () {
78308             event.trigger("PhoneCallLogReset");
78309         });
78310
78311         document.getElementById("phone-event-send").addEventListener("click", function () {
78312             var type = parseInt(eventSelect.value, 10),
78313                 error = type === Phone.CB_CALL_FAILED ? eventErrorSelect.value : undefined,
78314                 callId = document.getElementById("phone-call-id").value;
78315
78316             _firePhoneLogEvents(type, callId, error);
78317             _updateActiveCalls(type, callId, error);
78318
78319             event.trigger("PhoneEvent", [type, callId, error]);
78320
78321             _console.log("Fired PhoneEvent (type " + type +  ") CallID: " +
78322                          callId + (error ? (" (error type " + error + ")") : ""));
78323         }, false);
78324     }
78325 };
78326
78327 });
78328 define('ripple/ui/plugins/HWKeys', function (require, exports, module) {
78329 /*
78330  *  Copyright 2012 Intel Corporation
78331  *
78332  * Licensed under the Apache License, Version 2.0 (the "License");
78333  * you may not use this file except in compliance with the License.
78334  * You may obtain a copy of the License at
78335  *
78336  * http://www.apache.org/licenses/LICENSE-2.0
78337  *
78338  * Unless required by applicable law or agreed to in writing, software
78339  * distributed under the License is distributed on an "AS IS" BASIS,
78340  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78341  * See the License for the specific language governing permissions and
78342  * limitations under the License.
78343  */
78344
78345 var db = require('ripple/db'),
78346     event = require('ripple/event');
78347
78348
78349 function initHWKey() {
78350     var left = 0,
78351         orientation = db.retrieve('deviceOrientation'),
78352         scaleFactor = db.retrieve('deviceScaleFactor');
78353
78354     if (orientation === 'portrait') {
78355         if (db.retrieve("layout") === "portrait") {
78356             left = 350 + $('#device-layout').width()*scaleFactor;
78357         } else {
78358             left = 470 + $('#device-layout').height()*scaleFactor;
78359         }
78360     } else {
78361         if (db.retrieve("layout") === "portrait") {
78362             left = 490 + $('#device-layout').height()*scaleFactor;
78363         } else {
78364             left = 350 + $('#device-layout').width()*scaleFactor;
78365         }
78366     }
78367
78368     $("#hwkeys-panel").css("top", "40px");
78369     $("#hwkeys-panel").css("left", left+"px");
78370     $("#hwkeys-panel").draggable({ cursor: 'move', containment: [0, 52, 1480, 800]});
78371
78372     jQuery("#hwkey-menu-btn").bind("click", function () {
78373         event.trigger("tizenhwkeyEvent", ["menu"], true);
78374     });
78375     jQuery("#hwkey-back-btn").bind("click", function () {
78376         event.trigger("tizenhwkeyEvent", ["back"], true);
78377     });
78378 }
78379
78380 module.exports = {
78381     initialize: function () {
78382         initHWKey();
78383     }
78384 };
78385
78386 });
78387 define('ripple/ui/plugins/panelCollapse', function (require, exports, module) {
78388 /*
78389  *  Copyright 2011 Research In Motion Limited.
78390  *
78391  * Licensed under the Apache License, Version 2.0 (the "License");
78392  * you may not use this file except in compliance with the License.
78393  * You may obtain a copy of the License at
78394  *
78395  * http://www.apache.org/licenses/LICENSE-2.0
78396  *
78397  * Unless required by applicable law or agreed to in writing, software
78398  * distributed under the License is distributed on an "AS IS" BASIS,
78399  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78400  * See the License for the specific language governing permissions and
78401  * limitations under the License.
78402  */
78403 // TODO: could use a bit of refactoring sugar
78404 var db = require('ripple/db'),
78405     constants = require('ripple/constants'),
78406     _LEFT_PANEL_COLLAPSE = ".left-panel-collapse",
78407     _RIGHT_PANEL_COLLAPSE = ".right-panel-collapse",
78408     _LEFT_PANEL = ".left",
78409     _RIGHT_PANEL = ".right",
78410     _SAVE_KEY = "panel-collapsed",
78411     platform = require('ripple/platform'),
78412     devices = require('ripple/devices'),
78413     _leftEngaged, _rightEngaged, _store;
78414
78415
78416 $(function () { 
78417     $(window).resize(function () {
78418         var windowHeight = $(window).height();
78419         jQuery(".PanelCollapseBar").css("top", windowHeight - 56);
78420         jQuery("#left_div").css("height", $(window).height() - 21);
78421         if (_store["left"] === true) {
78422             jQuery("#middle_div").css("width", $(window).width());
78423         } else {
78424             jQuery("#middle_div").css("width", $(window).width());
78425         }
78426     });
78427 });
78428
78429
78430 function _persist() {
78431     db.saveObject(_SAVE_KEY, _store);
78432 }
78433
78434
78435 function updateZoomingValues(value, origin) {
78436     var scaleFactor = value / 100, scaleString;
78437     scaleString = "scale(" + scaleFactor + ")";
78438     jQuery('#device-layout').css('-webkit-transform', scaleString);
78439     if (origin === "center") {
78440         jQuery('#device-layout').css('-webkit-transform-origin', 'center top');
78441     } else {
78442         jQuery('#device-layout').css('-webkit-transform-origin', 'left top');
78443     }
78444 }
78445
78446
78447 function _process(collapseNode, panelNode, side, callback) {
78448     var jNode = collapseNode.children("span"),
78449         jPanelNode = jQuery(panelNode),
78450         properties = {},
78451         collapseProperties = {},
78452         options = {
78453             duration: 600,
78454             complete: callback
78455         },
78456         oldIcon, newIcon,
78457         zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING);
78458
78459     if (_store[side] === true) {
78460         _store[side] = false;
78461         
78462         if (side === "left") {
78463             jQuery('#left_div').show("fast");
78464             collapseNode.removeClass("PanelCollapseBarCollapsed");
78465             collapseNode.addClass("PanelCollapseBar");
78466             collapseNode.children().remove();
78467             collapseNode.append('<img src="images/sideCollapseIconLeftSide.png" style="margin-left:330px; margin-top: 6px;"/>');
78468             collapseNode.css("top", $(window).height() - 56);
78469             collapseNode.css("left", 0);
78470             jQuery("#middle_div").css("width", $(window).width());
78471             updateZoomingValues(zoomingValue, "left");
78472         }
78473         oldIcon = (side === "left" ? "ui-icon-arrowthick-1-e" : "ui-icon-arrowthick-1-w");
78474         newIcon = (side === "left" ? "ui-icon-arrowthick-1-w" : "ui-icon-arrowthick-1-e");
78475
78476         properties[side] = "0px";
78477         collapseProperties[side] = "345px";
78478         properties.opacity = "1";
78479
78480         if (jQuery("#device-layout").position().left < 290 ) {
78481             jQuery("#device-layout").animate({left: "350px"}, 200 );
78482         }
78483     } else {
78484         _store[side] = true;
78485         
78486         if (side === "left") {
78487             collapseNode.removeClass("PanelCollapseBar");
78488             collapseNode.addClass("PanelCollapseBarCollapsed");
78489             collapseNode.children().remove();
78490             collapseNode.append('<img src="images/sideCollapseIconRightSide.png" style="position: absolute; margin-left:5px; margin-top:48%;"/>');
78491             collapseNode.css("top", 10);
78492             collapseNode.css("left", 0);
78493             collapseNode.css("margin-left", 0);
78494             jQuery('#left_div').hide("slow");
78495             jQuery("#middle_div").css("width", $(window).width());
78496             updateZoomingValues(zoomingValue, "left");
78497         }
78498
78499         oldIcon = (side === "left" ? "ui-icon-arrowthick-1-w" : "ui-icon-arrowthick-1-e");
78500         newIcon = (side === "left" ? "ui-icon-arrowthick-1-e" : "ui-icon-arrowthick-1-w");
78501
78502         properties[side] = "-340px";
78503         collapseProperties[side] = "5px";
78504         properties.opacity = "0.1";
78505     }
78506
78507     jNode.removeClass(oldIcon).addClass(newIcon);
78508
78509     jPanelNode.animate(properties, options);
78510     _persist();
78511 }
78512
78513 module.exports = {
78514     initialize: function () {
78515         var rightCollapseNode = jQuery(_RIGHT_PANEL_COLLAPSE),
78516             leftCollapseNode = jQuery(_LEFT_PANEL_COLLAPSE),
78517             device = devices.getCurrentDevice(),
78518             zoomingValue =  db.retrieve(constants.ENCAPSULATOR.ZOOMING),
78519             deviceNode = jQuery("#device-layout");
78520            
78521         _store = db.retrieveObject(_SAVE_KEY) || {
78522             left: false,
78523             right: false
78524         };
78525
78526         jQuery("#left_div").css("height", $(window).height() - 21);
78527         jQuery("#middle_div").css("width", $(window).width());
78528
78529         jQuery("#device-container").bind("mousedown", function () {
78530             jQuery("#device-maskmask").show();
78531         });
78532
78533         jQuery("#device-container").bind("mouseup", function () {
78534             jQuery("#device-maskmask").hide();
78535         });
78536
78537         jQuery("#deviceTitleBar").bind("mousedown", function () {
78538             jQuery("#device-maskmask").show();
78539         });
78540
78541         jQuery("#deviceTitleBar").bind("mouseup", function () {
78542             jQuery("#device-maskmask").hide();
78543         });
78544
78545         deviceNode.draggable({ cursor: 'move', handle: "#deviceTitleBar", containment: [0, 52, 1280, 800]});
78546         jQuery("#deviceTitle").text(device.name);
78547         if (_store.left === true) {
78548             jQuery(_LEFT_PANEL).css({
78549                 left: "-340px",
78550                 opacity: "0.1"
78551             });
78552
78553             leftCollapseNode.removeClass("PanelCollapseBar");
78554             leftCollapseNode.addClass("PanelCollapseBarCollapsed");
78555             leftCollapseNode.children().remove();
78556             leftCollapseNode.append('<img src="images/sideCollapseIconRightSide.png" style="position: absolute; margin-left:5px; margin-top:48%;"/>');
78557             leftCollapseNode.css("top", 10);
78558             leftCollapseNode.css("left", 0);
78559             leftCollapseNode.css("margin-left", 0);
78560             jQuery('#left_div').hide();
78561             jQuery("#device-layout").css("left", "21px");
78562             updateZoomingValues(zoomingValue, "left");
78563         } else {
78564             jQuery('#left_div').show("fast");
78565             leftCollapseNode.removeClass("PanelCollapseBarCollapsed");
78566             leftCollapseNode.addClass("PanelCollapseBar");
78567             leftCollapseNode.children().remove();
78568             leftCollapseNode.append('<img src="images/sideCollapseIconLeftSide.png" style="margin-left:330px; margin-top: 6px;"/>');
78569             leftCollapseNode.css("top", $(window).height() - 56);
78570             leftCollapseNode.css("left", 0);
78571             jQuery("#device-layout").css("left", "350px");
78572             updateZoomingValues(zoomingValue, "left");
78573         }   
78574
78575         if (_store.right === true) {
78576             jQuery(_RIGHT_PANEL).css({
78577                 right: "-340px",
78578                 opacity: "0.1"
78579             });
78580
78581             rightCollapseNode.css({
78582                 right: "5px"
78583             }).children("span").removeClass("ui-icon-arrowthick-1-e").addClass("ui-icon-arrowthick-1-w");
78584         }
78585
78586         leftCollapseNode.bind("click", function () {
78587             if (!_leftEngaged) {
78588                 _leftEngaged = true;
78589                 _process(leftCollapseNode, _LEFT_PANEL, "left", function () {
78590                     _leftEngaged = false;
78591                 });
78592             }
78593         });
78594
78595         rightCollapseNode.bind("click", function () {
78596             if (!_rightEngaged) {
78597                 _rightEngaged = true;
78598                 _process(rightCollapseNode, _RIGHT_PANEL, "right", function () {
78599                     _rightEngaged = false;
78600                 });
78601             }
78602         });
78603     }
78604 };
78605
78606 });
78607 define('ripple/ui/plugins/eulaCheck', function (require, exports, module) {
78608 /*
78609  *  Copyright 2011 Research In Motion Limited.
78610  *
78611  * Licensed under the Apache License, Version 2.0 (the "License");
78612  * you may not use this file except in compliance with the License.
78613  * You may obtain a copy of the License at
78614  *
78615  * http://www.apache.org/licenses/LICENSE-2.0
78616  *
78617  * Unless required by applicable law or agreed to in writing, software
78618  * distributed under the License is distributed on an "AS IS" BASIS,
78619  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78620  * See the License for the specific language governing permissions and
78621  * limitations under the License.
78622  */
78623 var utils = require('ripple/utils'),
78624     bus = require('ripple/bus');
78625
78626 function _initializeEulaCheck() {
78627     var width = jQuery(document).width(),
78628         p = (width / 2) - 277;
78629
78630
78631     $(".eula-window").show();
78632     $(".eula-dialog").show().css({left: p + "px"});
78633
78634     $("#eula-accept").click(function () {
78635         bus.send("acceptEula", null, function (result) {
78636             $(".eula-window").hide();
78637             $(".eula-dialog").hide();
78638         });
78639     });
78640
78641     $("#eula-decline").click(function () {
78642         bus.send("disable", null, null);
78643     });
78644 }
78645
78646 module.exports = {
78647     initialize: function () {
78648         //HACK: there has to be a better way!!!
78649         if ($("#extension-url").val().match(/geelfhphabnejjhdalkjhgipohgpdnoc/)) {
78650             // do nothing, extension was installed from the Chrome Store
78651             return;
78652         }
78653
78654         bus.send("checkEula", null, function (response) {
78655             console.log("eula response: ", response);
78656             if (response === false) {
78657                 _initializeEulaCheck();
78658             }
78659         });
78660     }
78661 };
78662
78663 });
78664 define('ripple/ui/plugins/platformEvents', function (require, exports, module) {
78665 /*
78666  *  Copyright 2011 Research In Motion Limited.
78667  *
78668  * Licensed under the Apache License, Version 2.0 (the "License");
78669  * you may not use this file except in compliance with the License.
78670  * You may obtain a copy of the License at
78671  *
78672  * http://www.apache.org/licenses/LICENSE-2.0
78673  *
78674  * Unless required by applicable law or agreed to in writing, software
78675  * distributed under the License is distributed on an "AS IS" BASIS,
78676  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78677  * See the License for the specific language governing permissions and
78678  * limitations under the License.
78679  */
78680 var _console = require('ripple/console'),
78681     platform = require('ripple/platform'),
78682     event = require('ripple/event'),
78683     exception = require('ripple/exception'),
78684     utils = require('ripple/utils');
78685
78686 module.exports = {
78687     panel: {
78688         domId: "platform-events-container",
78689         collapsed: true,
78690         pane: "right",
78691         titleName: "Platform Events",
78692         display: true
78693     },
78694     initialize: function () {
78695         var eventSelect = document.getElementById("platform-events-select"),
78696             spec = platform.current();
78697
78698         if (!spec.events) {
78699             return;
78700         }
78701
78702         utils.forEach(spec.events, function (method, name) {
78703             eventSelect.appendChild(utils.createElement("option", {
78704                 "innerText": name,
78705                 "value": name
78706             }));
78707         });
78708
78709         jQuery("#platform-events-fire").click(function () {
78710             var eventName = document.getElementById("platform-events-select").value,
78711                 args = spec.events[eventName].args ? document.getElementById("platform-events-args").value : null,
78712                 callback = spec.events[eventName].callback;
78713
78714             _console.log("fired event => " + eventName);
78715
78716             try {
78717                 callback(args);
78718             } catch (e) {
78719                 exception.throwMaskedException(e);
78720             }
78721         });
78722
78723         jQuery(eventSelect).change(function () {
78724             var argsSelect = jQuery("#platform-events-args"),
78725                 args = spec.events[this.value].args;
78726
78727             argsSelect.empty();
78728
78729             if (args) {
78730                 utils.forEach(spec.events[this.value].args, function (arg, index) {
78731                     argsSelect.append(utils.createElement("option", {
78732                         innerText: arg,
78733                         value: index
78734                     }));
78735                 });
78736
78737                 argsSelect.show();
78738             } else {
78739                 argsSelect.hide();
78740             }
78741         });
78742     }
78743 };
78744
78745 });
78746 define('ripple/ui/themes', function (require, exports, module) {
78747 /*
78748  *  Copyright 2011 Research In Motion Limited.
78749  *
78750  * Licensed under the Apache License, Version 2.0 (the "License");
78751  * you may not use this file except in compliance with the License.
78752  * You may obtain a copy of the License at
78753  *
78754  * http://www.apache.org/licenses/LICENSE-2.0
78755  *
78756  * Unless required by applicable law or agreed to in writing, software
78757  * distributed under the License is distributed on an "AS IS" BASIS,
78758  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78759  * See the License for the specific language governing permissions and
78760  * limitations under the License.
78761  */
78762 //module.exports = ["dark", "light"];
78763 module.exports = ["light"];
78764
78765 });
78766 define('ripple/xhr', function (require, exports, module) {
78767 /*
78768  *  Copyright 2011 Research In Motion Limited.
78769  *
78770  * Licensed under the Apache License, Version 2.0 (the "License");
78771  * you may not use this file except in compliance with the License.
78772  * You may obtain a copy of the License at
78773  *
78774  * http://www.apache.org/licenses/LICENSE-2.0
78775  *
78776  * Unless required by applicable law or agreed to in writing, software
78777  * distributed under the License is distributed on an "AS IS" BASIS,
78778  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78779  * See the License for the specific language governing permissions and
78780  * limitations under the License.
78781  */
78782 var constants = require('ripple/constants'),
78783     utils = require('ripple/utils'),
78784     ui = require('ripple/ui'),
78785     helpers = require('ripple/xhr/helpers'),
78786     XHR = window.XMLHttpRequest;
78787
78788 module.exports = {
78789     initialize: function (previous, baton) {
78790         window.XMLHttpRequest = require('ripple/xhr/base');
78791
78792         if (helpers.proxyEnabled() && !ui.registered("omnibar")) {
78793             var isFileScheme = utils.location().protocol.match(/^file:/);
78794             window.XMLHttpRequest = require(isFileScheme ? 'ripple/xhr/jsonp' : 'ripple/xhr/cors');
78795         }
78796     }
78797 };
78798
78799 });
78800 define('ripple/sensorSettings', function (require, exports, module) {
78801 /*
78802  *  Copyright 2012 Intel Corporation.
78803  *
78804  * Licensed under the Apache License, Version 2.0 (the "License");
78805  * you may not use this file except in compliance with the License.
78806  * You may obtain a copy of the License at
78807  *
78808  * http://www.apache.org/licenses/LICENSE-2.0
78809  *
78810  * Unless required by applicable law or agreed to in writing, software
78811  * distributed under the License is distributed on an "AS IS" BASIS,
78812  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78813  * See the License for the specific language governing permissions and
78814  * limitations under the License.
78815  */
78816 var _PERSISTENCE_KEY = "sensorsettings",
78817     db = require('ripple/db'),
78818     platform = require('ripple/platform'),
78819     _currentSensorSettings = {},
78820     _self;
78821
78822 function _default(key) {
78823     var keys = key.split("."),
78824         defaults = platform.current().sensor;
78825
78826     if (keys.length === 1)
78827         return defaults[key];
78828
78829     return keys.length === 2 &&
78830            defaults[keys[0]] &&
78831            defaults[keys[0]][keys[1]] &&
78832            defaults[keys[0]][keys[1]].control ?
78833            defaults[keys[0]][keys[1]].control.value : undefined;
78834 }
78835
78836 _self = {
78837     initialize: function () {
78838         _currentSensorSettings = db.retrieveObject(_PERSISTENCE_KEY) || {};
78839     },
78840     register: function (key, obj) {
78841         _currentSensorSettings[key] = obj;
78842     },
78843
78844     persist: function (key, obj) {
78845         if (key) {
78846             _currentSensorSettings[key] = obj;
78847         }
78848
78849         db.saveObject(_PERSISTENCE_KEY, _currentSensorSettings);
78850     },
78851
78852     retrieve: function (key) {
78853         return _currentSensorSettings.hasOwnProperty(key) ?
78854                _currentSensorSettings[key] : _default(key);
78855     },
78856
78857     retrieveAsInt: function (key) {
78858         return parseInt(_self.retrieve(key), 10);
78859     },
78860
78861     retrieveAsBoolean: function (key) {
78862         return !!_self.retrieve(key);
78863     }
78864 };
78865
78866 module.exports = _self;
78867
78868 });
78869 define('ripple/utils', function (require, exports, module) {
78870 /*
78871  *  Copyright 2011 Research In Motion Limited.
78872  *
78873  * Licensed under the Apache License, Version 2.0 (the "License");
78874  * you may not use this file except in compliance with the License.
78875  * You may obtain a copy of the License at
78876  *
78877  * http://www.apache.org/licenses/LICENSE-2.0
78878  *
78879  * Unless required by applicable law or agreed to in writing, software
78880  * distributed under the License is distributed on an "AS IS" BASIS,
78881  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
78882  * See the License for the specific language governing permissions and
78883  * limitations under the License.
78884  */
78885 var self,
78886     exception = require('ripple/exception'),
78887     constants = require('ripple/constants'),
78888     _HtmlElements = ['header', 'footer', 'section', 'aside', 'nav', 'article'];
78889
78890 self = module.exports = {
78891     validateNumberOfArguments: function (lowerBound, upperBound, numberOfArguments, customExceptionType, customExceptionMessage, customExceptionObject) {
78892
78893         customExceptionMessage = customExceptionMessage || "";
78894
78895         if (arguments.length < 3 || arguments.length > 6) {
78896             exception.raise(exception.types.Argument, "Wrong number of arguments when calling: validateNumberOfArguments()");
78897         }
78898
78899         if (isNaN(lowerBound) && isNaN(upperBound) && isNaN(numberOfArguments)) {
78900             exception.raise(exception.types.ArgumentType, "(validateNumberOfArguments) Arguments are not numbers");
78901         }
78902
78903         lowerBound = parseInt(lowerBound, 10);
78904         upperBound = parseInt(upperBound, 10);
78905         numberOfArguments = parseInt(numberOfArguments, 10);
78906
78907         if (numberOfArguments < lowerBound || numberOfArguments > upperBound) {
78908             exception.raise((customExceptionType || exception.types.ArgumentLength), (customExceptionMessage + "\n\nWrong number of arguments"), customExceptionObject);
78909         }
78910
78911     },
78912
78913     validateArgumentType: function (arg, argType, customExceptionType, customExceptionMessage, customExceptionObject) {
78914         var invalidArg = false,
78915             msg;
78916
78917         switch (argType) {
78918         case "array":
78919             if (!arg instanceof Array) {
78920                 invalidArg = true;
78921             }
78922             break;
78923         case "date":
78924             if (!arg instanceof Date) {
78925                 invalidArg = true;
78926             }
78927             break;
78928         case "integer":
78929             if (typeof arg === "number") {
78930                 if (arg !== Math.floor(arg)) {
78931                     invalidArg = true;
78932                 }
78933             }
78934             else {
78935                 invalidArg = true;
78936             }
78937             break;
78938         default:
78939             if (typeof arg !== argType) {
78940                 invalidArg = true;
78941             }
78942             break;
78943         }
78944
78945         if (invalidArg) {
78946             msg = customExceptionMessage +  ("\n\nInvalid Argument type. argument: " + arg + " ==> was expected to be of type: " + argType);
78947             exception.raise((customExceptionType || exception.types.ArgumentType), msg, customExceptionObject);
78948         }
78949     },
78950
78951     validateMultipleArgumentTypes: function (argArray, argTypeArray, customExceptionType, customExceptionMessage, customExceptionObject) {
78952         for (var i = 0; i < argArray.length; i++) {
78953             this.validateArgumentType(argArray[i], argTypeArray[i], customExceptionType, customExceptionMessage, customExceptionObject);
78954         }
78955     },
78956
78957     createElement: function (elementType, attributes) {
78958         var d = document.createElement(elementType);
78959
78960         if (attributes) {
78961             this.forEach(attributes, function (attributeValue, attributeName) {
78962
78963                 switch (attributeName.toLowerCase()) {
78964
78965                 case "innerhtml":
78966                     d.innerHTML = attributeValue;
78967                     break;
78968
78969                 case "innertext":
78970                     d.innerText = attributeValue;
78971                     break;
78972
78973                 default:
78974                     d.setAttribute(attributeName, attributeValue);
78975                 }
78976
78977             });
78978         }
78979
78980         return d;
78981     },
78982
78983
78984     loadHTMLElements: function () {
78985         for (var i = 0; i < _HtmlElements.length; i += 1) {
78986             document.createElement(_HtmlElements[i]);
78987         }
78988     },
78989
78990     getAllStylesheetRules: function getAllStylesheetRules(title) {
78991         this.validateNumberOfArguments(1, 1, arguments.length);
78992
78993         var i, x, sheet, rules, styles_array = [];
78994
78995         // get style sheet according to title
78996         for (i = 0; i < document.styleSheets.length; i += 1) {
78997
78998             sheet = document.styleSheets[i];
78999             rules = sheet.cssRules;
79000
79001             if (rules) {
79002                 for (x = 0; x < rules.length; x += 1) {
79003                     if (rules[x].selectorText && rules[x].selectorText === (title.toString())) {
79004                         styles_array.push(rules[x]);
79005                     }
79006                 }
79007             }
79008         }
79009
79010         return (styles_array);
79011     },
79012
79013     location: function () {
79014         return window.location;
79015     },
79016
79017     queryString: function () {
79018         // trim the leading ? and split each name=value
79019         var args = this.location().search.replace(/^\?/, '').split('&');
79020
79021         return args.reduce(function (obj, value) {
79022             if (value) {
79023                 value = value.toLowerCase().split("=");
79024                 obj[value[0]] = value[1];
79025             }
79026             return obj;
79027         }, {});
79028     },
79029
79030     extensionUrl: function () {
79031         return document.getElementById("extension-url").innerText;
79032     },
79033
79034     appLocation: function () {
79035         if (require('ripple/ui').registered("omnibar")) {
79036             /* rootURL can only get url saved from 'FrameHistoryChange' event
79037                it causes trouble when navigating directory through online 
79038                version as index.html is automatically loaded.
79039                Need a way to get more updated URL */
79040
79041             var path = require('ripple/ui/plugins/omnibar').rootURL(),
79042                 parts;
79043
79044             if ((parts = path.match(/^((http[s]?|ftp|file):\/\/)(.+\/)?([^\/].+)$/i)) !== null && parts.length === 5) {
79045                 // this is a path already.
79046                 if (path.search(/\/$/, "") !== -1) {
79047                     return path;
79048                 }
79049                 if (parts[4] === "about:blank") {
79050                     path = "";
79051                 }
79052                 else if (parts[3]) {
79053                     path = parts[1] + parts[3];
79054                     if (parts[4].indexOf(".") === -1) {
79055                         path += parts[4] + "/";
79056                     }
79057                 }
79058                 else {
79059                     path = parts[1] + parts[4] + "/";
79060                 }
79061             }
79062             else {
79063                 path = "";
79064             }
79065             return path;
79066         }
79067         return self.rippleLocation();
79068     },
79069
79070     rippleLocation: function () {
79071         var loc = self.location(),
79072             parts = loc.pathname.replace(/\/$/, "").split("/"),
79073             base = "",
79074             port = loc.port ? ":" + loc.port : "";
79075
79076         if (parts[parts.length - 1].indexOf(".") !== -1) {
79077             parts = parts.splice(0, parts.length - 1);
79078         }
79079         base = parts.join("/");
79080
79081         return loc.protocol + "//" + loc.hostname + port + base + "/";
79082     },
79083
79084     arrayContains: function (array, obj) {
79085         var i = array.length;
79086         while (i--) {
79087             if (array[i] === obj) {
79088                 return true;
79089             }
79090         }
79091         return false;
79092     },
79093
79094     some: function (obj, predicate, scope) {
79095         if (obj instanceof Array) {
79096             return obj.some(predicate, scope);
79097         }
79098         else {
79099             var values = self.map(obj, predicate, scope);
79100
79101             return self.reduce(values, function (some, value) {
79102                 return value ? value : some;
79103             }, false);
79104         }
79105     },
79106
79107     count: function (obj) {
79108         return self.sum(obj, function (total) {
79109             return 1;
79110         });
79111     },
79112
79113     sum: function (obj, selector, scope) {
79114         var values = self.map(obj, selector, scope);
79115         return self.reduce(values, function (total, value) {
79116             return total + value;
79117         });
79118     },
79119
79120     max: function (obj, selector, scope) {
79121         var values = self.map(obj, selector, scope);
79122         return self.reduce(values, function (max, value) {
79123             return max < value ? value : max;
79124         }, Number.MIN_VALUE);
79125     },
79126
79127     min: function (obj, selector, scope) {
79128         var values = self.map(obj, selector, scope);
79129         return self.reduce(values, function (min, value) {
79130             return min > value ? value : min;
79131         }, Number.MAX_VALUE);
79132     },
79133
79134     forEach: function (obj, action, scope) {
79135         if (obj instanceof Array) {
79136             return obj.forEach(action, scope);
79137         }
79138         else {
79139             self.map(obj, action, scope);
79140         }
79141     },
79142
79143     filter: function (obj, predicate, scope) {
79144         if (obj instanceof Array) {
79145             return obj.filter(predicate, scope);
79146         }
79147         else {
79148             var result = [];
79149             self.forEach(obj, function (value, index) {
79150                 if (predicate.apply(scope, [value, index])) {
79151                     result.push(value);
79152                 }
79153
79154             }, scope);
79155
79156             return result;
79157         }
79158     },
79159
79160     reduce: function (obj, func, init, scope) {
79161         var i,
79162             initial = init === undefined ? 0 : init,
79163             result = initial;
79164
79165
79166         if (obj instanceof Array) {
79167             return obj.reduce(func, initial);
79168         }
79169         else if (obj instanceof NamedNodeMap) {
79170             for (i = 0; i < obj.length; i++) {
79171                 result = func.apply(scope, [result, obj[i], i]);
79172             }
79173         }
79174         else {
79175             for (i in obj) {
79176                 if (obj.hasOwnProperty(i)) {
79177                     result = func.apply(scope, [result, obj[i], i]);
79178                 }
79179             }
79180         }
79181
79182         return result;
79183
79184     },
79185
79186     map: function (obj, func, scope) {
79187         var i,
79188             returnVal = null,
79189             result = [];
79190
79191         if (obj instanceof Array) {
79192             return obj.map(func, scope);
79193         }
79194         else if (obj instanceof NamedNodeMap) {
79195             for (i = 0; i < obj.length; i++) {
79196                 returnVal = func.apply(scope, [obj[i], i]);
79197                 result.push(returnVal);
79198             }
79199         }
79200         else {
79201             for (i in obj) {
79202                 if (obj.hasOwnProperty(i)) {
79203                     returnVal = func.apply(scope, [obj[i], i]);
79204                     result.push(returnVal);
79205                 }
79206             }
79207         }
79208
79209         return result;
79210     },
79211
79212     regexSanitize: function (regexString) {
79213         return regexString.replace("^", "\\^")
79214                     .replace("$", "\\$")
79215                     .replace("(", "\\(")
79216                     .replace(")", "\\)")
79217                     .replace("<", "\\<")
79218                     .replace("[", "\\[")
79219                     .replace("{", "\\{")
79220                     .replace(/\\/, "\\\\")
79221                     .replace("|", "\\|")
79222                     .replace(">", "\\>")
79223                     .replace(".", "\\.")
79224                     .replace("*", "\\*")
79225                     .replace("+", "\\+")
79226                     .replace("?", "\\?");
79227     },
79228
79229     bindAutoSaveEvent: function (node, saveCallback) {
79230         var oldSetTimeoutId,
79231             jNode = jQuery(node);
79232
79233         jNode.bind("keyup", function (event) {
79234             if (event.keyCode !== 9) {
79235                 clearTimeout(oldSetTimeoutId);
79236                 oldSetTimeoutId = window.setTimeout(function () {
79237                     saveCallback();
79238                 }, 500);
79239             }
79240         });
79241     },
79242
79243     find: function (comparison, collection, startInx, endInx, callback) {
79244         var results = [],
79245             compare = function (s, pattern) {
79246
79247                 if (typeof(s) !== "string" || pattern === null) {
79248                     return s === pattern;
79249                 }
79250
79251                 var regex = pattern.replace(/\./g, "\\.")
79252                                    .replace(/\^/g, "\\^")
79253                                    .replace(/\*/g, ".*")
79254                                    .replace(/\\\.\*/g, "\\*");
79255
79256                 regex = "^".concat(regex, "$");
79257
79258                 return !!s.match(new RegExp(regex, "i"));
79259             };
79260
79261         self.forEach(collection, function (c) {
79262             var match,
79263                 fail = false;
79264
79265             self.forEach(comparison, function (value, key) {
79266                 if (!fail && value !== undefined) {
79267
79268                     if (compare(c[key], value)) {
79269                         match = c;
79270                     }
79271                     else {
79272                         fail = true;
79273                         match = null;
79274                     }
79275                 }
79276             });
79277
79278             if (match) {
79279                 results.push(match);
79280             }
79281         });
79282
79283         if (callback) {
79284             if (startInx === undefined) {
79285                 startInx = 0;
79286             }
79287             if (endInx === undefined) {
79288                 endInx = results.length;
79289             }
79290             if (startInx === endInx) {
79291                 endInx = startInx + 1;
79292             }
79293
79294             callback.apply(null, [results.slice(startInx, endInx)]);
79295         }
79296     },
79297
79298     mixin: function (mixin, to) {
79299         for (var prop in mixin) {
79300             if (Object.hasOwnProperty.call(mixin, prop)) {
79301                 to[prop] = mixin[prop];
79302             }
79303         }
79304         return to;
79305     },
79306
79307     copy: function (obj) {
79308         var i,
79309             newObj = jQuery.isArray(obj) ? [] : {};
79310
79311         if (typeof obj === 'number' ||
79312             typeof obj === 'string' ||
79313             typeof obj === 'boolean' ||
79314             obj === null ||
79315             obj === undefined) {
79316             return obj;
79317         }
79318
79319         if (obj instanceof Date) {
79320             return new Date(obj);
79321         }
79322
79323         if (obj instanceof RegExp) {
79324             return new RegExp(obj);
79325         }
79326
79327         for (i in obj) {
79328             if (obj.hasOwnProperty(i)) {
79329                 if (obj[i] && typeof obj[i] === "object") {
79330                     if (obj[i] instanceof Date) {
79331                         newObj[i] = obj[i];
79332                     }
79333                     else {
79334                         newObj[i] = self.copy(obj[i]);
79335                     }
79336                 }
79337                 else {
79338                     newObj[i] = obj[i];
79339                 }
79340             }
79341         }
79342
79343         return newObj;
79344     },
79345
79346     navHelper: function () {
79347         return {
79348             getHeading: function (lat1, lon1, lat2, lon2) {
79349                 var dLon = this.rad(lon2 - lon1),
79350                     llat1 = this.rad(lat1),
79351                     llat2 = this.rad(lat2),
79352                     y = Math.sin(dLon) * Math.cos(llat2),
79353                     x = Math.cos(llat1) * Math.sin(llat2) - Math.sin(llat1) * Math.cos(llat2) * Math.cos(dLon);
79354                 return (this.deg(Math.atan2(y, x)) + 360) % 360;
79355             },
79356
79357             getDistance: function (lat1, lon1, lat2, lon2) {
79358                 var dLat = this.rad(lat2 - lat1),
79359                     dLon = this.rad(lon2 - lon1),
79360                     a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(this.rad(lat1)) * Math.cos(this.rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2),
79361                     c = 2 * Math.asin(Math.sqrt(a)),
79362                     d = 6378100 * c;
79363                 return d;
79364             },
79365
79366             simulateTravel: function (lat, lon, hdg, dist) {
79367                 var lat1 = this.rad(lat),
79368                     lon1 = this.rad(lon),
79369                     brng = this.rad(hdg),
79370                     angularDistance = dist / 6378100,
79371                     lat2 = Math.asin(Math.sin(lat1) * Math.cos(angularDistance) + Math.cos(lat1) * Math.sin(angularDistance) * Math.cos(brng)),
79372                     lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(angularDistance) * Math.cos(lat1), Math.cos(angularDistance) - Math.sin(lat1) * Math.sin(lat2));
79373                 lon2 = (lon2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI; // Normalise to -180..+180
79374
79375                 return {
79376                     latitude: this.deg(lat2),
79377                     longitude: this.deg(lon2)
79378                 };
79379             },
79380
79381             deg: function (num) {
79382                 return num * 180 / Math.PI;
79383             },
79384
79385             rad: function (num) {
79386                 return num * Math.PI / 180;
79387             }
79388         };
79389     },
79390
79391     getURIParams: function (uriString) {
79392         var params = {};
79393
79394         uriString.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(str, key, value) {
79395             params[key] = value;
79396         });
79397
79398         return params;
79399     }
79400 };
79401
79402 });
79403 define('ripple/fs', function (require, exports, module) {
79404 /*
79405  *  Copyright 2011 Research In Motion Limited.
79406  *
79407  * Licensed under the Apache License, Version 2.0 (the "License");
79408  * you may not use this file except in compliance with the License.
79409  * You may obtain a copy of the License at
79410  *
79411  * http://www.apache.org/licenses/LICENSE-2.0
79412  *
79413  * Unless required by applicable law or agreed to in writing, software
79414  * distributed under the License is distributed on an "AS IS" BASIS,
79415  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79416  * See the License for the specific language governing permissions and
79417  * limitations under the License.
79418  */
79419 var utils = require('ripple/utils'),
79420     constants = require('ripple/constants'),
79421     event = require('ripple/event'),
79422     _console = require('ripple/console'),
79423     _self, _fs;
79424
79425 function _map(array, callback) {
79426     var map = [], i;
79427     for (i = 0; i < array.length; i++) {
79428         map[i] = callback(array[i], i);
79429     }
79430     return map;
79431 }
79432
79433 function _resolveLocalFileSystemURL(path, success, error) {
79434     return (window.resolveLocalFileSystemURL || window.webkitResolveLocalFileSystemURL)(path, success, error);
79435 }
79436
79437 function _blobBuilder() {
79438     var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder;
79439     return new BlobBuilder();
79440 }
79441
79442 function _error(e) {
79443     var msg = '';
79444
79445     switch (e.code) {
79446     case FileError.QUOTA_EXCEEDED_ERR:
79447         msg = 'QUOTA_EXCEEDED_ERR';
79448         break;
79449     case FileError.NOT_FOUND_ERR:
79450         msg = 'NOT_FOUND_ERR';
79451         break;
79452     case FileError.SECURITY_ERR:
79453         msg = 'SECURITY_ERR';
79454         break;
79455     case FileError.INVALID_MODIFICATION_ERR:
79456         msg = 'INVALID_MODIFICATION_ERR';
79457         break;
79458     case FileError.INVALID_STATE_ERR:
79459         msg = 'INVALID_STATE_ERR';
79460         break;
79461     default:
79462         msg = 'Unknown Error';
79463         break;
79464     }
79465
79466     _console.log('FileSystem error: ' + msg);
79467 }
79468
79469 _self = {
79470     initialize: function (prev, baton) {
79471         try {
79472             var requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
79473
79474             if (requestFileSystem) {
79475                 baton.take();
79476             }
79477
79478             requestFileSystem(window.TEMPORARY, constants.FS_SIZE, function (fs) {
79479                 _fs = fs;
79480                 event.trigger("FileSystemInitialized", null, true);
79481                 baton.pass();
79482             }, _error);
79483         }
79484         catch (e) {
79485             console.log("File System Not Available");
79486         }
79487     },
79488
79489     ls: function (path, success, error) {
79490         path = path || "/";
79491
79492         _fs.root.getDirectory(path, {}, function (dirEntry) {
79493             var dirReader = dirEntry.createReader();
79494             dirReader.readEntries(function (entries) {
79495                 success(_map(entries, function (entry, index) {
79496                     return entry;
79497                 }));
79498             }, error);
79499         }, error);
79500     },
79501
79502     rm: function (path, success, error, options) {
79503         options = options || {};
79504
79505         _fs.root[options.recursive ? "getDirectory" : "getFile"](path, {create: false}, function (entry) {
79506             entry[options.recursive ? "removeRecursively" : "remove"](function () {
79507                 success();
79508             }, error);
79509         }, error);
79510     },
79511
79512     rmdir: function (path, success, error, options) {
79513         options = options || {};
79514
79515         _fs.root.getDirectory(path, {create: false}, function (entry) {
79516             entry.remove(function () {
79517                 success();
79518             }, error);
79519         }, error);
79520     },
79521
79522     mkdir: function (path, success, error) {
79523         _fs.root.getDirectory(path, {create: true}, function (dirEntry) {
79524             success(dirEntry);
79525         }, error);
79526     },
79527
79528     mv: function (from, to, success, error) {
79529         var path = to.replace(/^\//, "").split("/"),
79530             fileName = path.splice(path.length - 1, 1).toString();
79531
79532         _self.stat(from, function (entry) {
79533             _self.stat(path.length > 0 ? path.join("/") : "/", function (dest) {
79534                 entry.moveTo(dest, fileName, function (finalDestination) {
79535                     success(finalDestination);
79536                 }, error);
79537             }, error);
79538         }, error);
79539     },
79540
79541     touch: function (path, success, error) {
79542         _fs.root.getFile(path, {create: true}, function (fileEntry) {
79543             success(fileEntry);
79544         }, error);
79545     },
79546
79547     cp: function (from, to, success, error) {
79548         var path = to.replace(/^\//, "").split("/"),
79549             fileName = path.splice(path.length - 1, 1).toString();
79550
79551         _self.stat(from, function (entry) {
79552             _self.stat(path.length > 0 ? path.join("/") : "/", function (dest) {
79553                 entry.copyTo(dest, fileName, function (finalDestination) {
79554                     success(finalDestination);
79555                 }, error);
79556             }, error);
79557         }, error);
79558     },
79559
79560     stat: function (path, success, error) {
79561         var url = "filesystem:" + utils.location().origin + "/temporary/" + path;
79562         _resolveLocalFileSystemURL(url, function (entry) {
79563             success(entry);
79564         }, error);
79565     },
79566
79567     write: function (path, contents, success, error, options) {
79568         options = options || {};
79569
79570         function write(entry) {
79571             entry.createWriter(function (fileWriter) {
79572                 var bb = _blobBuilder();
79573
79574                 fileWriter.onwriteend = function (progressEvent) {
79575                     success(entry);
79576                 };
79577                 fileWriter.onerror = error;
79578
79579                 if (options.mode === "append") {
79580                     fileWriter.seek(fileWriter.length);
79581                 }
79582
79583                 bb.append(contents);
79584                 fileWriter.write(bb.getBlob('text/plain'));
79585             }, error);
79586         }
79587
79588         _self.stat(path, function (entry) {
79589             if (options.mode === "append") {
79590                 write(entry);
79591             } else {
79592                 _self.rm(path, function () {
79593                     _self.touch(path, write, error);
79594                 }, error);
79595             }
79596         }, function (e) {
79597             if (e.code === FileError.NOT_FOUND_ERR) {
79598                 _self.touch(path, write, error);
79599             } else {
79600                 error(e);
79601             }
79602         });
79603     },
79604
79605     read: function (path, success, error) {
79606         _self.stat(path, function (entry) {
79607             entry.file(function (file) {
79608                 var reader = new FileReader();
79609
79610                 reader.onloadend = function (progressEvent) {
79611                     success(progressEvent.target.result);
79612                 };
79613                 reader.onerror = error;
79614
79615                 reader.readAsText(file);
79616             }, error);
79617         }, error);
79618     }
79619 };
79620
79621 module.exports = _self;
79622
79623 });
79624 define('ripple/geo', function (require, exports, module) {
79625 /*
79626  *  Copyright 2011 Research In Motion Limited.
79627  *
79628  * Licensed under the Apache License, Version 2.0 (the "License");
79629  * you may not use this file except in compliance with the License.
79630  * You may obtain a copy of the License at
79631  *
79632  * http://www.apache.org/licenses/LICENSE-2.0
79633  *
79634  * Unless required by applicable law or agreed to in writing, software
79635  * distributed under the License is distributed on an "AS IS" BASIS,
79636  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79637  * See the License for the specific language governing permissions and
79638  * limitations under the License.
79639  */
79640 var db = require('ripple/db'),
79641     exception = require('ripple/exception'),
79642     event = require('ripple/event'),
79643     utils = require('ripple/utils'),
79644     _positionInfo = {
79645         "latitude": 39.968362,
79646         "longitude": 116.410186,
79647         "altitude": 50,
79648         "accuracy": 150,
79649         "altitudeAccuracy": 80,
79650         "heading": 0,
79651         "speed": 0,
79652         "cellID": 1130433
79653     },
79654     self;
79655
79656 function _serialize(settings) {
79657     var tempSettings = utils.copy(settings);
79658     tempSettings.position.timeStamp = "new Date(" + tempSettings.position.timeStamp.getTime() + ")";
79659     return tempSettings;
79660 }
79661
79662 function _validatePositionInfo(pInfo) {
79663     return (pInfo &&
79664         !(isNaN(pInfo.latitude) ||
79665         isNaN(pInfo.longitude) ||
79666         isNaN(pInfo.altitude) ||
79667         isNaN(pInfo.accuracy) ||
79668         isNaN(pInfo.altitudeAccuracy) ||
79669         isNaN(pInfo.heading) ||
79670         isNaN(pInfo.speed) ||
79671         isNaN(pInfo.cellID))) ? true : false;
79672 }
79673
79674 self = module.exports = {
79675     initialize: function () {
79676         var settings = db.retrieveObject("geosettings");
79677         if (settings) {
79678             utils.forEach(_positionInfo, function (value, key) {
79679                 _positionInfo[key] = parseFloat(settings.position[key] || value);
79680             });
79681
79682             self.timeout = settings.timeout;
79683             self.delay = settings.delay || 0;
79684
79685         }
79686     },
79687
79688     getPositionInfo: function () {
79689         var pi = utils.copy(_positionInfo);
79690         pi.timeStamp = new Date();
79691
79692         return pi;
79693     },
79694
79695     updatePositionInfo: function (newPositionInfo, delay, timeout) {
79696         if (!_validatePositionInfo(newPositionInfo)) {
79697             exception.raise(exception.types.Geo, "invalid positionInfo object");
79698         }
79699
79700         _positionInfo = utils.copy(newPositionInfo);
79701         _positionInfo.timeStamp = new Date();
79702
79703         self.delay = delay || 0;
79704         self.timeout = timeout;
79705
79706         db.saveObject("geosettings", _serialize({
79707             position: _positionInfo,
79708             delay: self.delay,
79709             timeout: self.timeout
79710         }));
79711
79712         event.trigger("PositionInfoUpdatedEvent", [_positionInfo]);
79713     },
79714
79715     timeout: false,
79716     delay: 0,
79717     map: {}
79718 };
79719
79720 });
79721 define('ripple/console', function (require, exports, module) {
79722 /*
79723  *  Copyright 2011 Research In Motion Limited.
79724  *
79725  * Licensed under the Apache License, Version 2.0 (the "License");
79726  * you may not use this file except in compliance with the License.
79727  * You may obtain a copy of the License at
79728  *
79729  * http://www.apache.org/licenses/LICENSE-2.0
79730  *
79731  * Unless required by applicable law or agreed to in writing, software
79732  * distributed under the License is distributed on an "AS IS" BASIS,
79733  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79734  * See the License for the specific language governing permissions and
79735  * limitations under the License.
79736  */
79737 var _self;
79738
79739 function _log(msg, method) {
79740     try {
79741         console[method](_self.prefix ? _self.prefix + " :: " + msg : msg);
79742     } catch (e) {
79743         // silent
79744     }
79745 }
79746
79747 _self = {
79748     log: function (msg) {
79749         _log(msg, "log");
79750     },
79751
79752     warn: function (msg) {
79753         _log(msg, "warn");
79754     },
79755
79756     error: function (msg) {
79757         _log(msg, "error");
79758     }
79759 };
79760
79761 module.exports = _self;
79762
79763 });
79764 define('ripple/resizer', function (require, exports, module) {
79765 /*
79766  *  Copyright 2011 Research In Motion Limited.
79767  *
79768  * Licensed under the Apache License, Version 2.0 (the "License");
79769  * you may not use this file except in compliance with the License.
79770  * You may obtain a copy of the License at
79771  *
79772  * http://www.apache.org/licenses/LICENSE-2.0
79773  *
79774  * Unless required by applicable law or agreed to in writing, software
79775  * distributed under the License is distributed on an "AS IS" BASIS,
79776  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79777  * See the License for the specific language governing permissions and
79778  * limitations under the License.
79779  */
79780 var db = require('ripple/db'),
79781     exception = require('ripple/exception'),
79782     utils = require('ripple/utils'),
79783     devices = require('ripple/devices'),
79784     constants = require('ripple/constants'),
79785     event = require('ripple/event'),
79786     _win,
79787     _doc,
79788     _self;
79789
79790 function _validateLayoutType(layoutType) {
79791     return (layoutType === "landscape" || layoutType === "portrait");
79792 }
79793
79794 function _validateOrientation(orientation) {
79795     return (orientation === "landscape" || orientation === "portrait");
79796 }
79797
79798 function _getContainers() {
79799     return {
79800         device: {
79801             div: document.getElementById("device-container"),
79802             containerClass: document.getElementById("device-container").getAttribute("class") || ""
79803         },
79804         viewport: {
79805             div: document.getElementById("viewport-container"),
79806             containerClass: document.getElementById("viewport-container").getAttribute("class") || ""
79807         },
79808         "menu-button": {
79809             div: document.getElementById(constants.COMMON.MENU_BUTTON),
79810             containerClass: document.getElementById(constants.COMMON.MENU_BUTTON).getAttribute("class") || ""
79811         },
79812         "back-button": {
79813             div: document.getElementById(constants.COMMON.BACK_BUTTON),
79814             containerClass: document.getElementById(constants.COMMON.BACK_BUTTON).getAttribute("class") || ""
79815         }
79816     };
79817 }
79818
79819 function _setContainers(containers, device, orientation) {
79820     var suffix = {
79821             portrait:  "-wrapper" + (device.skin ? "-" + device.skin : ""),
79822             landscape: "-wrapper-landscape" + (device.skin ? "-" + device.skin : "")
79823         };
79824
79825     utils.forEach(containers, function (container, key) {
79826         container.div.setAttribute("class", container.containerClass.replace(/\s.*$/, "") + " " + key + suffix[orientation]);
79827     });
79828 }
79829
79830 function _getDimensions(device, orientation) {
79831     return {
79832         deviceWidth: orientation === "portrait" ? device.screen.width : device.screen.height,
79833         deviceHeight: orientation === "portrait" ? device.screen.height : device.screen.width,
79834         paddingLeft: device.viewPort[orientation].paddingLeft,
79835         paddingTop: device.viewPort[orientation].paddingTop,
79836         viewPort: {
79837             width: device.viewPort[orientation].width,
79838             height: device.viewPort[orientation].height
79839         }
79840     };
79841 }
79842
79843 function _formatSkin(containers, dimensions) {
79844     var scaleFactor = dimensions.deviceWidth / dimensions.viewPort.width,
79845     scaleString = "scale(" + scaleFactor + ")";
79846
79847     containers.device.div.style.width = (dimensions.deviceWidth + 4) + "px";
79848     containers.device.div.style.height = (dimensions.deviceHeight + 4) + "px";
79849     containers.viewport.div.style.width = dimensions.viewPort.width + "px";
79850     containers.viewport.div.style.height = dimensions.viewPort.height + "px";
79851     containers.viewport.div.style.padding = "0";
79852
79853     jQuery('#viewport-container').css('-webkit-transform', scaleString);
79854     jQuery('#viewport-container').css('-webkit-transform-origin', 'left top');
79855 }
79856
79857 function _setOrientation(layout) {
79858     _win.orientation = window.orientation = layout === "portrait" ? 0 : 90;
79859 }
79860
79861 function _upDateHWKeyPanelPosition(orientation, scaleFactor) {
79862     var left = 0;
79863
79864     if (orientation === 'portrait') {
79865         if (db.retrieve("layout") === "portrait") {
79866             left = 350 + $('#device-layout').width()*scaleFactor;
79867         } else {
79868             left = 470 + $('#device-layout').height()*scaleFactor;
79869         }
79870     } else {
79871         if (db.retrieve("layout") === "portrait") {
79872             left = 490 + $('#device-layout').height()*scaleFactor;
79873         } else {
79874             left = 350 + $('#device-layout').width()*scaleFactor;
79875         }
79876     }
79877
79878     $("#hwkeys-panel").css("top", "40px");
79879     $("#hwkeys-panel").css("left", left+"px");
79880 }
79881
79882 function _getTransformString(orientation, scaleFactor) {
79883     var transformString = "",
79884     offset;
79885
79886     if (orientation === "landscape") {
79887         if (db.retrieve("layout") === "portrait") {
79888             offset = devices.getCurrentDevice().screen.height * scaleFactor + 170;
79889             transformString = "translate("+ offset + "px, 0px) rotate(90deg) scale("+ scaleFactor +")";
79890         } else {
79891             transformString = "translate(0px,0px) rotate(0deg) scale("+ scaleFactor +")";
79892         }
79893     } else {
79894         if (db.retrieve("layout") === "portrait") {
79895             transformString = "translate(0px,0px) rotate(0deg) scale("+ scaleFactor +")";
79896         } else {
79897             offset = devices.getCurrentDevice().screen.width * scaleFactor + 150;
79898             transformString = "translate("+ offset + "px, 0px) rotate(90deg) scale("+ scaleFactor +")";
79899         }
79900     }
79901
79902     return transformString;
79903 }
79904
79905
79906 _self = {
79907     init: function (win, doc) {
79908         _win = win;
79909         _doc = doc;
79910
79911         var layout = db.retrieve("layout") || "portrait";
79912
79913         _setOrientation(layout);
79914
79915         _win.onorientationchange = undefined;
79916     },
79917     // TODO: redo/refactor this in general, seems bloated, also devices REQUIRE viewport schemas which they shouldnt
79918     resize: function (device) {
79919         var layout = db.retrieve("layout"),
79920             orientation = "portrait",
79921             containers, dimensions;
79922
79923         if (layout && layout === "landscape" && device.viewPort.landscape) {
79924             orientation = "landscape";
79925         }
79926
79927         containers = _getContainers();
79928         _setContainers(containers, device, orientation);
79929
79930         dimensions = _getDimensions(device, orientation);
79931         if (!device.skin) {
79932             _formatSkin(containers, dimensions);
79933         }
79934
79935         event.trigger("ScreenChangeDimensions", [dimensions.viewPort.width, dimensions.viewPort.height]);
79936     },
79937
79938     changeLayoutType: function (layoutType) {
79939         var orientation = db.retrieve("deviceOrientation") || "portrait";
79940         if (!_validateLayoutType(layoutType)) {
79941             exception.raise(exception.types.LayoutType, "unknown layout type requested!");
79942         }
79943
79944         db.save("layout", layoutType);
79945         _self.resize(devices.getCurrentDevice());
79946         _self.rotateDevice(orientation);
79947
79948         if (!_win) return;
79949         _setOrientation(layoutType);
79950     },
79951
79952     scaleDevice: function (scaleFactor) {
79953         var orientation = db.retrieve("deviceOrientation") || "portrait",
79954         transformString = _getTransformString(orientation, scaleFactor);
79955         _upDateHWKeyPanelPosition(orientation, scaleFactor);
79956         db.save("deviceScaleFactor", scaleFactor);
79957         jQuery('#device-layout').css('-webkit-transform-origin', '0% 0%');
79958         jQuery('#device-layout').css('-webkit-transform',  transformString);
79959     },
79960
79961     rotateDevice: function (orientation) {
79962         if (!_validateOrientation(orientation)) {
79963             exception.raise(exception.types.OrientationType, "unknown orientation type requested!");
79964         }
79965
79966         db.save("deviceOrientation", orientation);
79967         jQuery('#device-layout').css('-webkit-transform-origin', '0% 0%');
79968         jQuery('#device-layout').css('-webkit-transform',
79969                 _getTransformString(orientation, db.retrieve("deviceScaleFactor")));
79970         _upDateHWKeyPanelPosition(orientation, db.retrieve("deviceScaleFactor"))
79971         if (!_win) return;
79972         if (_win.onorientationchange) {
79973             _win.onorientationchange();
79974         }
79975
79976         var evt = _doc.createEvent("Event");
79977         evt.initEvent("orientationchange", true, true);
79978         _win.dispatchEvent(evt);
79979     }
79980 };
79981
79982 module.exports = _self;
79983
79984 });
79985 define('ripple/platform/tizen/2.0/BluetoothSocket', function (require, exports, module) {
79986 /*
79987  *  Copyright 2013 Intel Corporation.
79988  *
79989  * Licensed under the Apache License, Version 2.0 (the "License");
79990  * you may not use this file except in compliance with the License.
79991  * You may obtain a copy of the License at
79992  *
79993  * http://www.apache.org/licenses/LICENSE-2.0
79994  *
79995  * Unless required by applicable law or agreed to in writing, software
79996  * distributed under the License is distributed on an "AS IS" BASIS,
79997  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
79998  * See the License for the specific language governing permissions and
79999  * limitations under the License.
80000  */
80001
80002 var utils = require('ripple/utils'),
80003     event = require('ripple/event'),
80004     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
80005     t = require('ripple/platform/tizen/2.0/typecast'),
80006     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
80007     BluetoothSocket,
80008     _security;
80009
80010 BluetoothSocket = function (prop) {
80011     var bluetoothSocket = {}, buffer = [];
80012
80013     _security = prop.metaData;
80014
80015     bluetoothSocket.uuid      = prop.uuid;
80016     bluetoothSocket.state     = prop.state;
80017     bluetoothSocket.peer      = prop.peer;
80018     bluetoothSocket.onmessage = null;
80019     bluetoothSocket.onclose   = null;
80020
80021     this.__defineGetter__("uuid", function () {
80022         return bluetoothSocket.uuid;
80023     });
80024
80025     this.__defineGetter__("state", function () {
80026         return bluetoothSocket.state;
80027     });
80028
80029     this.__defineGetter__("peer", function () {
80030         return bluetoothSocket.peer;
80031     });
80032
80033     this.__defineGetter__("onmessage", function () {
80034         return bluetoothSocket.onmessage;
80035     });
80036     this.__defineSetter__("onmessage", function (val) {
80037         try {
80038             bluetoothSocket.onmessage = t.SuccessCallback(val, "?");
80039         } catch (e) {
80040         }
80041     });
80042
80043     this.__defineGetter__("onclose", function () {
80044         return bluetoothSocket.onclose;
80045     });
80046     this.__defineSetter__("onclose", function (val) {
80047         try {
80048             bluetoothSocket.onclose = t.SuccessCallback(val, "?");
80049         } catch (e) {
80050         }
80051     });
80052
80053     this.writeData = function (data) {
80054         if (!_security.writeData) {
80055             throw new WebAPIException(errorcode.SECURITY_ERR);
80056         }
80057
80058         t.BluetoothSocket("writeData", arguments);
80059
80060         if (bluetoothSocket.state === "CLOSED") {
80061             return;
80062         }
80063
80064         event.trigger("bt-service-write-msg", [bluetoothSocket.peer.address,
80065                 bluetoothSocket.uuid, data]);
80066
80067         return data.length;
80068     };
80069
80070     this.readData = function () {
80071         var data;
80072
80073         if (!_security.readData) {
80074             throw new WebAPIException(errorcode.SECURITY_ERR);
80075         }
80076
80077         if (bluetoothSocket.state === "CLOSED") {
80078             return;
80079         }
80080
80081         data = utils.copy(buffer);
80082         buffer = [];
80083
80084         return data;
80085     };
80086
80087     this.close = function () {
80088         if (!_security.close) {
80089             throw new WebAPIException(errorcode.SECURITY_ERR);
80090         }
80091
80092         bluetoothSocket.state = "CLOSED";
80093
80094         event.trigger("bt-service-state-changed", [bluetoothSocket.peer.address,
80095                 bluetoothSocket.uuid, false]);
80096         event.trigger("bt-device-connected-update",
80097                 [bluetoothSocket.peer.address, false]);
80098
80099         if (bluetoothSocket.onclose) {
80100             bluetoothSocket.onclose();
80101         }
80102     };
80103
80104     event.on("bt-service-state-update", function (addr, state) {
80105         var stateStr = "CLOSED";
80106
80107         if (addr !== bluetoothSocket.peer.address) {
80108             return;
80109         }
80110         if (state) {
80111             stateStr = "OPEN";
80112         }
80113
80114         bluetoothSocket.state = stateStr;
80115
80116         event.trigger("bt-service-state-changed",
80117                 [bluetoothSocket.peer.address, bluetoothSocket.uuid,
80118                 state]);
80119         event.trigger("bt-device-connected-update",
80120                 [bluetoothSocket.peer.address, state]);
80121     });
80122
80123     event.on("bt-service-rawdata-received", function (addr, uuid, msg) {
80124         var i;
80125
80126         if ((addr !== bluetoothSocket.peer.address) ||
80127                 (uuid !== bluetoothSocket.uuid)) {
80128             return;
80129         }
80130         buffer = [];
80131         for (i = 0; i < msg.length; i++) {
80132             buffer.push(msg.charCodeAt(i));
80133         }
80134         if (bluetoothSocket.onmessage) {
80135             bluetoothSocket.onmessage();
80136         }
80137     });
80138
80139     event.on("bt-device-connected-changed", function (addr, isConnected) {
80140         bluetoothSocket.state = isConnected ? "OPEN" : "CLOSED";
80141     });
80142 };
80143
80144 module.exports = BluetoothSocket;
80145
80146 });
80147 define('ripple/platform/tizen/2.0/msg_utils', function (require, exports, module) {
80148 /*
80149  *  Copyright 2012 Intel Corporation.
80150  *
80151  * Licensed under the Apache License, Version 2.0 (the "License");
80152  * you may not use this file except in compliance with the License.
80153  * You may obtain a copy of the License at
80154  *
80155  * http://www.apache.org/licenses/LICENSE-2.0
80156  *
80157  * Unless required by applicable law or agreed to in writing, software
80158  * distributed under the License is distributed on an "AS IS" BASIS,
80159  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80160  * See the License for the specific language governing permissions and
80161  * limitations under the License.
80162  */
80163
80164
80165 var db = require('ripple/db'),
80166     utils = require('ripple/utils'),
80167     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
80168     MessageBody = require('ripple/platform/tizen/2.0/MessageBody'),
80169     _TIZEN_MESSAGE_DB_KEY = "tizen_db_messages",
80170     MessageElement = function (_type, _id) {
80171         return {
80172             type: _type,
80173             id: _id,
80174             msg: {},
80175             conv: {}
80176         };
80177     },
80178
80179     _conversationCount = function (msg, cid, rst) {
80180         var old_time = new Date(0), t;
80181
80182         utils.forEach(msg.msg, function (o) {
80183             if (o.priv.conversationId === cid &&
80184                 o.priv.messageStatus !== "DRAFT") {
80185                 rst.cnt += 1;
80186                 t = new Date(o.priv.timestamp);
80187                 if (t > old_time) {
80188                     rst.lastid = o.priv.id;
80189                     old_time = t;
80190                 }
80191                 if (o.isRead === false) {
80192                     rst.unread++;
80193                 }
80194             }
80195         });
80196     },
80197
80198     _updateConversation = function (msg, cid) {
80199         var privConv = {}, lastm, rst = {};
80200
80201         rst.cnt = 0;
80202         rst.unread = 0;
80203         rst.lastid = "";
80204         _conversationCount(msg, cid, rst);
80205         if (rst.cnt === 0) {
80206             if (msg.conv[cid] !== undefined) {
80207                 delete msg.conv[cid];
80208             }
80209             return;
80210         }
80211         lastm = msg.msg[rst.lastid];
80212
80213         privConv.id = cid;
80214         privConv.type = msg.type;
80215         privConv.timestamp = new Date(lastm.priv.timestamp);
80216         privConv.messageCount = rst.cnt;
80217         privConv.unreadMessages = rst.unread;
80218         privConv.preview = lastm.body.plainBody;
80219         privConv.subject = lastm.subject;
80220         privConv.isRead = lastm.isRead;
80221         privConv.from = lastm.priv.from;
80222         privConv.to = lastm.to.slice(0);
80223         privConv.cc = lastm.cc.slice(0);
80224         privConv.bcc = lastm.bcc.slice(0);
80225         privConv.lastMessageId = rst.lastid;
80226         msg.conv[cid] = privConv;
80227     };
80228
80229 module.exports = {
80230     conversationCount: _conversationCount,
80231     setMsg: function (m, newm) {
80232         if ((m.to === null) || (m.to === undefined)) {
80233             newm.to = [];
80234         } else {
80235             if (tizen1_utils.isValidArray(m.to)) {
80236                 newm.to = m.to.slice(0);
80237             } else {
80238                 return false;
80239             }
80240         }
80241
80242         if ((m.cc === null) || (m.cc === undefined)) {
80243             newm.cc = [];
80244         } else {
80245             if (tizen1_utils.isValidArray(m.cc)) {
80246                 newm.cc = m.cc.slice(0);
80247             } else {
80248                 return false;
80249             }
80250         }
80251
80252         if ((m.bcc === null) || (m.bcc === undefined)) {
80253             newm.bcc = [];
80254         } else {
80255             if (tizen1_utils.isValidArray(m.bcc)) {
80256                 newm.bcc = m.bcc.slice(0);
80257             } else {
80258                 return false;
80259             }
80260         }
80261
80262         if ((m.body === null) || (m.body === undefined)) {
80263             if (m.htmlBody === null || m.htmlBody === undefined) {
80264                 m.htmlBody = "";
80265             }
80266             if (m.plainBody === null || m.plainBody === undefined) {
80267                 m.plainBody = "";
80268             }
80269             if (typeof m.plainBody !== 'string' || typeof m.htmlBody !== 'string') {
80270                 return false;
80271             }
80272             m.body = new MessageBody(null, true, m.plainBody, m.htmlBody, []);
80273         } else {
80274             if (typeof m.body.plainBody !== 'string' || typeof m.body.htmlBody !== 'string') {
80275                 return false;
80276             }
80277             m.body = new MessageBody(null, true, m.body.plainBody, m.body.htmlBody, []);
80278         }
80279         newm.body = utils.copy(m.body);
80280
80281         if (typeof m.isRead === 'boolean') {
80282             newm.isRead = m.isRead;
80283         } else {
80284             newm.isRead = false;
80285         }
80286
80287         if (typeof m.isHighPriority === 'boolean') {
80288             newm.isHighPriority = m.isHighPriority;
80289         } else {
80290             newm.isHighPriority = false;
80291         }
80292
80293         if ((m.subject === null) || (m.subject === undefined)) {
80294             newm.subject = "";
80295         } else {
80296             newm.subject = String(m.subject);
80297         }
80298
80299         if ((m.inResponseTo === null) || (m.inResponseTo === undefined)) {
80300             newm.inResponseTo = null;
80301         } else {
80302             newm.inResponseTo = String(m.inResponseTo);
80303         }
80304
80305         if ((m.attachments === null) || (m.attachments === undefined)) {
80306             newm.attachments = [];
80307         } else {
80308             newm.attachments = utils.copy(m.attachments);
80309         }
80310         return true;
80311     },
80312
80313     loadMsg: function (type, id) {
80314         var i, ret, msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || null;
80315         if (msg === null) {
80316             ret = new MessageElement(type, id);
80317         } else {
80318             for (i = 0; i < msg.length; i++) {
80319                 if (msg[i].type === type && msg[i].id === id) {
80320                     ret = msg[i];
80321                     break;
80322                 }
80323             }
80324             if (ret === undefined) {
80325                 ret = new MessageElement(type, id);
80326             } else {
80327                 /* after getting Date out of DB, Date will become
80328                    a string, so need to recast it back to Date */
80329                 for (i in ret.msg) {
80330                     ret.msg[i].priv.timestamp = new Date(ret.msg[i].priv.timestamp);
80331                 }
80332             }
80333         }
80334         return ret;
80335     },
80336
80337     delMsg: function (m) { // m is a PrivMessage
80338         var i, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || [];
80339         if (_msg.length === 0) {
80340             return;
80341         } else {
80342             for (i = 0; i < _msg.length; i++) {
80343                 if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) {
80344                     delete _msg[i].msg[m.priv.id];
80345                     if (m.priv.messageStatus !== "DRAFT") {
80346                         _updateConversation(_msg[i], m.priv.conversationId);
80347                     }
80348                     db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
80349                     return;
80350                 }
80351             }
80352         }
80353     },
80354
80355     saveMsg: function (m) { // m is a PrivMessage
80356         var i, new_msg, _msg = db.retrieveObject(_TIZEN_MESSAGE_DB_KEY) || [];
80357         if (_msg.length === 0) {
80358             _msg = new MessageElement(m.priv.type, m.priv.serviceId);
80359             _msg.msg[m.priv.id] = m;
80360             if (m.priv.messageStatus !== "DRAFT") {
80361                 _updateConversation(_msg, m.priv.conversationId);
80362             }
80363             db.saveObject(_TIZEN_MESSAGE_DB_KEY, [_msg]);
80364         } else {
80365             for (i = 0; i < _msg.length; i++) {
80366                 if (_msg[i].type === m.priv.type && _msg[i].id === m.priv.serviceId) {
80367                     _msg[i].msg[m.priv.id] = m;
80368                     if (m.priv.messageStatus !== "DRAFT") {
80369                         _updateConversation(_msg[i], m.priv.conversationId);
80370                     }
80371                     db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
80372                     break;
80373                 }
80374             }
80375             if (i === _msg.length) {
80376                 new_msg = new MessageElement(m.priv.type, m.priv.serviceId);
80377                 new_msg.msg[m.priv.id] = m;
80378                 if (m.priv.messageStatus !== "DRAFT") {
80379                     _updateConversation(new_msg, m.priv.conversationId);
80380                 }
80381                 _msg.push(new_msg);
80382                 db.saveObject(_TIZEN_MESSAGE_DB_KEY, _msg);
80383             }
80384         }
80385     },
80386
80387     loadConv: function (type, id) {
80388         var i, ret;
80389         ret = this.loadMsg(type, id).conv;
80390         for (i in ret) {
80391             ret[i].timestamp = new Date(ret[i].timestamp);
80392         }
80393         return ret;
80394     }
80395 };
80396
80397 });
80398 define('ripple/platform/tizen/2.0/BluetoothClassDeviceMajor', function (require, exports, module) {
80399 /*
80400  *  Copyright 2013 Intel Corporation.
80401  *
80402  * Licensed under the Apache License, Version 2.0 (the "License");
80403  * you may not use this file except in compliance with the License.
80404  * You may obtain a copy of the License at
80405  *
80406  * http://www.apache.org/licenses/LICENSE-2.0
80407  *
80408  * Unless required by applicable law or agreed to in writing, software
80409  * distributed under the License is distributed on an "AS IS" BASIS,
80410  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80411  * See the License for the specific language governing permissions and
80412  * limitations under the License.
80413  */
80414
80415 var BluetoothClassDeviceMajor = function () {
80416     this.__defineGetter__("MISC", function () {
80417         return 0x00;
80418     });
80419
80420     this.__defineGetter__("COMPUTER", function () {
80421         return 0x01;
80422     });
80423
80424     this.__defineGetter__("PHONE", function () {
80425         return 0x02;
80426     });
80427
80428     this.__defineGetter__("NETWORK", function () {
80429         return 0x03;
80430     });
80431
80432     this.__defineGetter__("AUDIO_VIDEO", function () {
80433         return 0x04;
80434     });
80435
80436     this.__defineGetter__("PERIPHERAL", function () {
80437         return 0x05;
80438     });
80439
80440     this.__defineGetter__("IMAGING", function () {
80441         return 0x06;
80442     });
80443
80444     this.__defineGetter__("WEARABLE", function () {
80445         return 0x07;
80446     });
80447
80448     this.__defineGetter__("TOY", function () {
80449         return 0x08;
80450     });
80451
80452     this.__defineGetter__("HEALTH", function () {
80453         return 0x09;
80454     });
80455
80456     this.__defineGetter__("UNCATEGORIZED", function () {
80457         return 0x1F;
80458     });
80459 };
80460
80461 module.exports = BluetoothClassDeviceMajor;
80462
80463 });
80464 define('ripple/platform/tizen/2.0/SyncServiceInfo', function (require, exports, module) {
80465 /*
80466  *  Copyright 2013 Intel Corporation.
80467  *
80468  * Licensed under the Apache License, Version 2.0 (the "License");
80469  * you may not use this file except in compliance with the License.
80470  * You may obtain a copy of the License at
80471  *
80472  * http://www.apache.org/licenses/LICENSE-2.0
80473  *
80474  * Unless required by applicable law or agreed to in writing, software
80475  * distributed under the License is distributed on an "AS IS" BASIS,
80476  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80477  * See the License for the specific language governing permissions and
80478  * limitations under the License.
80479  */
80480
80481 var db = require('ripple/db'),
80482     t = require('ripple/platform/tizen/2.0/typecast'),
80483     SyncServiceInfo,
80484     _accounts = {},
80485     _counter = 0;
80486
80487 SyncServiceInfo = function (enable, serviceType, serverDatabaseUri, id,
80488         password) {
80489     var syncServiceInfo = {}, index;
80490
80491     function save() {
80492         _accounts[index] = {
80493             id: syncServiceInfo.id,
80494             password: syncServiceInfo.password
80495         };
80496         db.saveObject("save-syncserviceinfo", _accounts);
80497     }
80498
80499     t.SyncServiceInfo(arguments, this);
80500
80501     syncServiceInfo.enable            = enable;
80502     syncServiceInfo.serviceType       = serviceType;
80503     syncServiceInfo.serverDatabaseUri = serverDatabaseUri;
80504     syncServiceInfo.id                = id || null;
80505     syncServiceInfo.password          = password || null;
80506
80507     this.__defineGetter__("enable", function () {
80508         return syncServiceInfo.enable;
80509     });
80510     this.__defineSetter__("enable", function (enable) {
80511         try {
80512             syncServiceInfo.enable = t.boolean(enable);
80513         } catch (e) {
80514         }
80515     });
80516
80517     this.__defineGetter__("serviceType", function () {
80518         return syncServiceInfo.serviceType;
80519     });
80520     this.__defineSetter__("serviceType", function (serviceType) {
80521         try {
80522             syncServiceInfo.serviceType = t.SyncServiceType(serviceType);
80523         } catch (e) {
80524         }
80525     });
80526
80527     this.__defineGetter__("serverDatabaseUri", function () {
80528         return syncServiceInfo.serverDatabaseUri;
80529     });
80530     this.__defineSetter__("serverDatabaseUri", function (serverDatabaseUri) {
80531         try {
80532             syncServiceInfo.serverDatabaseUri = t.DOMString(serverDatabaseUri);
80533         } catch (e) {
80534         }
80535     });
80536
80537     this.__defineGetter__("id", function () {
80538         return null;
80539     });
80540     this.__defineSetter__("id", function (id) {
80541         try {
80542             syncServiceInfo.id = t.DOMString(id);
80543             save();
80544         } catch (e) {
80545         }
80546     });
80547
80548     this.__defineGetter__("password", function () {
80549         return null;
80550     });
80551     this.__defineSetter__("password", function (password) {
80552         try {
80553             syncServiceInfo.password = t.DOMString(password);
80554             save();
80555         } catch (e) {
80556         }
80557     });
80558
80559     index = _counter++;
80560     Object.defineProperty(this, "__syncServiceInfoID__", {
80561         "configurable": false,
80562         "enumerable":   false,
80563         "get": (function (_id_) {
80564             return function () { return _id_; };
80565         })(index)
80566     });
80567     save();
80568 };
80569
80570 module.exports = SyncServiceInfo;
80571
80572 });
80573 define('ripple/platform/tizen/2.0/systeminfo', function (require, exports, module) {
80574 /*
80575  *  Copyright 2013 Intel Corporation.
80576  *
80577  * Licensed under the Apache License, Version 2.0 (the "License");
80578  * you may not use this file except in compliance with the License.
80579  * You may obtain a copy of the License at
80580  *
80581  * http://www.apache.org/licenses/LICENSE-2.0
80582  *
80583  * Unless required by applicable law or agreed to in writing, software
80584  * distributed under the License is distributed on an "AS IS" BASIS,
80585  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
80586  * See the License for the specific language governing permissions and
80587  * limitations under the License.
80588  */
80589
80590 var deviceSettings = require('ripple/deviceSettings'),
80591     db = require('ripple/db'),
80592     t = require('ripple/platform/tizen/2.0/typecast'),
80593     typedef = require('ripple/platform/tizen/2.0/typedef'),
80594     constants = require('ripple/constants'),
80595     event = require('ripple/event'),
80596     tizen_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
80597     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
80598     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
80599     SystemInfoDeviceCapability,
80600     _systemInfoProperties = typedef.SystemInfoPropertyId,
80601     _propertyMap = {}, // Object like: {"BATTERY": ["level", "isCharging"], ...}
80602     _batteryEvent = ["BatteryLevelChanged", "BatteryChargingChanged"],
80603     _watches = {},
80604     _firstCall_watches = {},
80605     _powerData = {},
80606     _systemInfoDeviceCapability = null,
80607     _security = {
80608         "http://tizen.org/privilege/system": ["SystemInfoSIM", "webApiVersion",
80609                 "nativeApiVersion", "platformVersion"],
80610         "http://tizen.org/privilege/systemmanager": ["NetworkImei"]
80611     },
80612     _self;
80613
80614 function _prepareObj(obj, aspect, property, value) {
80615     if ((aspect === "CELLULAR_NETWORK") && (property === "imei")) {
80616         obj.__defineGetter__("imei", function () {
80617             if (!_security.NetworkImei) {
80618                 throw new WebAPIException(errorcode.SECURITY_ERR);
80619             }
80620             return deviceSettings.retrieve("CELLULAR_NETWORK.imei");
80621         });
80622     } else {
80623         if (aspect === "WIFI_NETWORK" || aspect === "CELLULAR_NETWORK") {
80624             if (property === 'status') {
80625                 if (value === true) {
80626                     value = "ON";
80627                 } else {
80628                     value = "OFF";
80629                 }
80630             }
80631         }
80632         obj.__defineGetter__(property, function () {
80633             return value;
80634         });
80635     }
80636 }
80637
80638 function _getValue(aspect, successCallback) {
80639     var properties = [], value, index = 0, property, obj = {};
80640
80641     if ((aspect === "SIM") && !_security.SystemInfoSIM) {
80642         throw new WebAPIException(errorcode.SECURITY_ERR);
80643     }
80644
80645     if (aspect === "BATTERY") {
80646         successCallback(_powerData);
80647         return;
80648     }
80649
80650     properties = _propertyMap[aspect];
80651     for (; index < properties.length; index++) {
80652         property = properties[index];
80653         value = deviceSettings.retrieve(aspect + "." + property);
80654         _prepareObj(obj, aspect, property, value);
80655     }
80656
80657     if (aspect === "STORAGE") {
80658         obj.__defineGetter__("units", function () {
80659             return [obj];
80660         });
80661     }
80662
80663     successCallback(obj);
80664 }
80665
80666 function _initialize() {
80667     var aspectName, index, i, vol;
80668
80669     for (index = 0; index < _systemInfoProperties.length; index++) {
80670         aspectName = _systemInfoProperties[index];
80671         _propertyMap[aspectName] = [];
80672         for (i in deviceSettings.retrieve(aspectName)) {
80673             _propertyMap[aspectName].push(i);
80674         }
80675     }
80676
80677     _propertyMap.BATTERY.push("level");
80678     _propertyMap.BATTERY.push("isCharging");
80679
80680     _powerData.__defineGetter__("isCharging", function () {
80681         return false;
80682     });
80683
80684     vol = db.retrieve(constants.BATTERY.VOLUME) || 100.0;
80685     _powerData.__defineGetter__("level", function () {
80686         return Number((vol / 100.0).toFixed(4));
80687     });
80688
80689     event.on("BatteryEvent", function (status) {
80690         _powerData.__defineGetter__("isCharging", function () {
80691             return status.charging;
80692         });
80693         _powerData.__defineGetter__("level", function () {
80694             return Number(status.level.toFixed(4));
80695         });
80696     });
80697 }
80698
80699 function _isPropertyFound(property) {
80700     if (tizen_utils.isEmptyObject(_propertyMap)) {
80701         _initialize();
80702     }
80703
80704     if (_propertyMap[property]) {
80705         return true;
80706     }
80707
80708     return false;
80709 }
80710
80711 function _delayGetValue(timeout, property, successCallback, errorCallback) {
80712     return window.setInterval(function () {
80713         _getValue(property, successCallback, errorCallback);
80714     }, timeout);
80715 }
80716
80717 _self = function () {
80718     function getCapabilities() {
80719         if (_systemInfoDeviceCapability === null) {
80720             _systemInfoDeviceCapability = new SystemInfoDeviceCapability();
80721         }
80722         return _systemInfoDeviceCapability;
80723     }
80724
80725     function getPropertyValue(property, successCallback, errorCallback) {
80726         t.SystemInfo("getPropertyValue", arguments);
80727
80728         if (!_isPropertyFound(property)) {
80729             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
80730         }
80731
80732         window.setTimeout(function () {
80733             _getValue(property, successCallback, errorCallback);
80734         }, 1);
80735     }
80736
80737     function addPropertyValueChangeListener(property, successCallback, options) {
80738         var WatchOBJ, watchId = Number(Math.uuid(8, 10)),
80739             _options = new Object(options), properties, prop, index = 0,
80740             deviceEventType, watchObj, firstCallWatchObj;
80741
80742         t.SystemInfo("addPropertyValueChangeListener", arguments);
80743
80744         if (!_isPropertyFound(property)) {
80745             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
80746         }
80747
80748         WatchOBJ = function (deviceEventType, property, successCallback) {
80749             var obj = this;
80750
80751             this.eventType = deviceEventType;
80752             this.onEvent = function (newValue) {
80753                 if (obj.timeout) {
80754                     window.clearInterval(obj.intervalId);
80755                     obj.intervalId = window.setInterval(function () {
80756                         _getValue(property, successCallback, null);
80757                     }, obj.timeout);
80758                 }
80759
80760                 if ((obj.highThreshold && (newValue < obj.highThreshold)) ||
80761                     (obj.lowThreshold && (newValue > obj.lowThreshold))) {
80762                     return;
80763                 }
80764
80765                 _getValue(property, successCallback, null);
80766             };
80767         };
80768
80769         // A listener will listen all the properties of one aspect, each of the property
80770         // will have an internal watchObj to record the information.
80771         _watches[watchId] = [];
80772
80773         if (property === "BATTERY") {
80774             properties = _batteryEvent;
80775         } else {
80776             properties = _propertyMap[property];
80777         }
80778
80779         for (; index < properties.length; index++) {
80780             prop = properties[index];
80781             if (property === "BATTERY") {
80782                 deviceEventType = prop;
80783             } else {
80784                 deviceEventType = deviceSettings.retrieve(property)[prop].event;
80785             }
80786
80787             if (deviceEventType === undefined) continue;
80788             // These two items are needed when delete an event listener.
80789             watchObj = new WatchOBJ(deviceEventType, property, successCallback);
80790
80791             if (options && _options.timeout) {
80792                 watchObj.intervalId = _delayGetValue(_options.timeout, property,
80793                         successCallback, null);
80794             }
80795
80796             if ((watchObj.eventType === "CpuLoadChanged") ||
80797                     (watchObj.eventType === "DisplayBrightnessChanged") ||
80798                     (watchObj.eventType === "BatteryLevelChanged")) {
80799                 if (options && _options.highThreshold) {
80800                     watchObj.highThreshold = _options.highThreshold;
80801                 }
80802
80803                 if (options && _options.lowThreshold) {
80804                     watchObj.lowThreshold = _options.lowThreshold;
80805                 }
80806             }
80807
80808             _watches[watchId].push(watchObj);
80809             if (watchObj.eventType) {
80810                 event.on(watchObj.eventType, watchObj.onEvent);
80811             }
80812         }
80813
80814         firstCallWatchObj = window.setTimeout(function () {
80815             _getValue(property, successCallback, null);
80816             delete _firstCall_watches[watchId];
80817         }, 1);
80818
80819         _firstCall_watches[watchId] = firstCallWatchObj;
80820
80821         return watchId;
80822     }
80823
80824     function removePropertyValueChangeListener(listenerID) {
80825         var _handler = listenerID, index = 0, watchObjs = [], watchObj;
80826
80827         if (!_watches[_handler])
80828             return;
80829
80830         watchObjs = _watches[_handler];
80831         if (watchObjs) {
80832             for (; index < watchObjs.length; index++) {
80833                 watchObj = watchObjs[index];
80834                 event.deleteEventHandler(watchObj.eventType, watchObj.onEvent);
80835                 if (watchObj.intervalId) {
80836                     window.clearInterval(watchObj.intervalId);
80837                 }
80838             }
80839             delete _watches[_handler];
80840         }
80841
80842         if (_firstCall_watches[_handler]) {
80843             window.clearTimeout(_firstCall_watches[_handler]);
80844             delete _firstCall_watches[_handler];
80845         }
80846     }
80847
80848     function handleSubFeatures(subFeatures) {
80849         var i, subFeature;
80850
80851         for (subFeature in subFeatures) {
80852             for (i in _security[subFeature]) {
80853                 _security[_security[subFeature][i]] = true;
80854             }
80855         }
80856     }
80857
80858     var systeminfo = {
80859         getCapabilities: getCapabilities,
80860         getPropertyValue: getPropertyValue,
80861         addPropertyValueChangeListener: addPropertyValueChangeListener,
80862         removePropertyValueChangeListener: removePropertyValueChangeListener,
80863         handleSubFeatures: handleSubFeatures
80864     };
80865
80866     return systeminfo;
80867 };
80868
80869 SystemInfoDeviceCapability = function () {
80870     this.__defineGetter__("bluetooth", function () {
80871         return true;
80872     });
80873     this.__defineGetter__("nfc", function () {
80874         return true;
80875     });
80876     this.__defineGetter__("nfcReservedPush", function () {
80877         return false;
80878     });
80879     this.__defineGetter__("multiTouchCount", function () {
80880         return 5;
80881     });
80882     this.__defineGetter__("inputKeyboard", function () {
80883         return false;
80884     });
80885     this.__defineGetter__("inputKeyboardLayout", function () {
80886         return false;
80887     });
80888     this.__defineGetter__("wifi", function () {
80889         return true;
80890     });
80891     this.__defineGetter__("wifiDirect", function () {
80892         return true;
80893     });
80894     this.__defineGetter__("opengles", function () {
80895         return false;
80896     });
80897     this.__defineGetter__("openglestextureFormat", function () {
80898         return "";
80899     });
80900     this.__defineGetter__("openglesVersion1_1", function () {
80901         return false;
80902     });
80903     this.__defineGetter__("openglesVersion2_0", function () {
80904         return false;
80905     });
80906     this.__defineGetter__("fmRadio", function () {
80907         return false;
80908     });
80909     this.__defineGetter__("platformVersion", function () {
80910         if (!_security.platformVersion) {
80911             throw new WebAPIException(errorcode.SECURITY_ERR);
80912         }
80913         return "2.2.0";
80914     });
80915     this.__defineGetter__("webApiVersion", function () {
80916         if (!_security.webApiVersion) {
80917             throw new WebAPIException(errorcode.SECURITY_ERR);
80918         }
80919         return "2.2";
80920     });
80921     this.__defineGetter__("nativeApiVersion", function () {
80922         if (!_security.nativeApiVersion) {
80923             throw new WebAPIException(errorcode.SECURITY_ERR);
80924         }
80925         return "2.2";
80926     });
80927     this.__defineGetter__("platformName", function () {
80928         return "Tizen";
80929     });
80930     this.__defineGetter__("camera", function () {
80931         return false;
80932     });
80933     this.__defineGetter__("cameraFront", function () {
80934         return false;
80935     });
80936     this.__defineGetter__("cameraFrontFlash", function () {
80937         return false;
80938     });
80939     this.__defineGetter__("cameraBack", function () {
80940         return false;
80941     });
80942     this.__defineGetter__("cameraBackFlash", function () {
80943         return false;
80944     });
80945     this.__defineGetter__("location", function () {
80946         return true;
80947     });
80948     this.__defineGetter__("locationGps", function () {
80949         return true;
80950     });
80951     this.__defineGetter__("locationWps", function () {
80952         return false;
80953     });
80954     this.__defineGetter__("microphone", function () {
80955         return false;
80956     });
80957     this.__defineGetter__("usbHost", function () {
80958         return true;
80959     });
80960     this.__defineGetter__("usbAccessory", function () {
80961         return false;
80962     });
80963     this.__defineGetter__("screenOutputRca", function () {
80964         return false;
80965     });
80966     this.__defineGetter__("screenOutputHdmi", function () {
80967         return false;
80968     });
80969     this.__defineGetter__("platformCoreCpuArch", function () {
80970         return "x86";
80971     });
80972     this.__defineGetter__("platformCoreFpuArch", function () {
80973         return "ssse3";
80974     });
80975     this.__defineGetter__("sipVoip", function () {
80976         return false;
80977     });
80978     this.__defineGetter__("duid", function () {
80979         return "device unique ID";
80980     });
80981     this.__defineGetter__("speechRecognition", function () {
80982         return false;
80983     });
80984     this.__defineGetter__("speechSynthesis", function () {
80985         return false;
80986     });
80987     this.__defineGetter__("accelerometer", function () {
80988         return true;
80989     });
80990     this.__defineGetter__("accelerometerWakeup", function () {
80991         return false;
80992     });
80993     this.__defineGetter__("barometer", function () {
80994         return false;
80995     });
80996     this.__defineGetter__("barometerWakeup", function () {
80997         return false;
80998     });
80999     this.__defineGetter__("gyroscope", function () {
81000         return true;
81001     });
81002     this.__defineGetter__("gyroscopeWakeup", function () {
81003         return false;
81004     });
81005     this.__defineGetter__("magnetometer", function () {
81006         return false;
81007     });
81008     this.__defineGetter__("magnetometerWakeup", function () {
81009         return false;
81010     });
81011     this.__defineGetter__("photometer", function () {
81012         return false;
81013     });
81014     this.__defineGetter__("photometerWakeup", function () {
81015         return false;
81016     });
81017     this.__defineGetter__("proximity", function () {
81018         return false;
81019     });
81020     this.__defineGetter__("proximityWakeup", function () {
81021         return false;
81022     });
81023     this.__defineGetter__("tiltmeter", function () {
81024         return false;
81025     });
81026     this.__defineGetter__("tiltmeterWakeup", function () {
81027         return false;
81028     });
81029     this.__defineGetter__("dataEncryption", function () {
81030         return false;
81031     });
81032     this.__defineGetter__("graphicsAcceleration", function () {
81033         return false;
81034     });
81035     this.__defineGetter__("push", function () {
81036         return true;
81037     });
81038     this.__defineGetter__("telephony", function () {
81039         return true;
81040     });
81041     this.__defineGetter__("telephonyMms", function () {
81042         return true;
81043     });
81044     this.__defineGetter__("telephonySms", function () {
81045         return true;
81046     });
81047     this.__defineGetter__("screenSizeNormal", function () {
81048         return true;
81049     });
81050     this.__defineGetter__("screenSize480_800", function () {
81051         return true;
81052     });
81053     this.__defineGetter__("screenSize720_1280", function () {
81054         return true;
81055     });
81056     this.__defineGetter__("autoRotation", function () {
81057         return true;
81058     });
81059     this.__defineGetter__("shellAppWidget", function () {
81060         return false;
81061     });
81062     this.__defineGetter__("visionImageRecognition", function () {
81063         return false;
81064     });
81065     this.__defineGetter__("visionQrcodeGeneration", function () {
81066         return false;
81067     });
81068     this.__defineGetter__("visionQrcodeRecognition", function () {
81069         return false;
81070     });
81071     this.__defineGetter__("visionFaceRecognition", function () {
81072         return false;
81073     });
81074     this.__defineGetter__("secureElement", function () {
81075         return true;
81076     });
81077     this.__defineGetter__("nativeOspCompatible", function () {
81078         return false;
81079     });
81080     this.__defineGetter__("profile", function () {
81081         return "MOBILE_WEB";
81082     });
81083 };
81084
81085 module.exports = _self;
81086
81087 });
81088 define('ripple/platform/tizen/2.0/map', function (require, exports, module) {
81089 /*
81090  *  Copyright 2012 Intel Corporation
81091  *
81092  * Licensed under the Apache License, Version 2.0 (the "License");
81093  * you may not use this file except in compliance with the License.
81094  * You may obtain a copy of the License at
81095  *
81096  * http://www.apache.org/licenses/LICENSE-2.0
81097  *
81098  * Unless required by applicable law or agreed to in writing, software
81099  * distributed under the License is distributed on an "AS IS" BASIS,
81100  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81101  * See the License for the specific language governing permissions and
81102  * limitations under the License.
81103  */
81104
81105 var lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
81106     mapProviders = [],
81107     MapStyle,
81108     MapProvider,
81109     _self;
81110
81111 function _initialize() {
81112     // EPSG:3857 is a Spherical Mercator projection coordinate system popularized by web services such as Google and later OpenStreetMap
81113     // mapStyles are from http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
81114     var projection = "EPSG:3857",
81115         mapStyle1 = new MapStyle("Mapnik", "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png"),
81116         mapStyle2 = new MapStyle("Cycle", "http://b.tile.opencyclemap.org/cycle/${z}/${x}/${y}.png");
81117
81118     mapProviders = [new MapProvider({name: "OpenStreetMap", connectivity: "ONLINE"}, projection, [mapStyle1, mapStyle2])];
81119 }
81120
81121 _self = {
81122     getDefaultProvider: function () {
81123         return mapProviders[0];
81124     },
81125     getProviders: function () {
81126         return mapProviders;
81127     }
81128 };
81129
81130 MapStyle = function (name, url) {
81131     return {
81132         name: name,
81133         url: url
81134     };
81135 };
81136
81137 MapProvider = function (prop, projection, mapStyles) {
81138     var mapProvider = new lbs.LocationServiceProvider(prop);
81139
81140     mapProvider.__defineGetter__("projection", function () {
81141         return projection;
81142     });
81143
81144     mapProvider.__defineGetter__("mapStyles", function () {
81145         return mapStyles;
81146     });
81147
81148     return mapProvider;
81149 };
81150
81151 _initialize();
81152
81153 module.exports = _self;
81154
81155 });
81156 define('ripple/platform/tizen/2.0/datasync', function (require, exports, module) {
81157 /*
81158  *  Copyright 2013 Intel Corporation
81159  *
81160  * Licensed under the Apache License, Version 2.0 (the "License");
81161  * you may not use this file except in compliance with the License.
81162  * You may obtain a copy of the License at
81163  *
81164  * http://www.apache.org/licenses/LICENSE-2.0
81165  *
81166  * Unless required by applicable law or agreed to in writing, software
81167  * distributed under the License is distributed on an "AS IS" BASIS,
81168  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81169  * See the License for the specific language governing permissions and
81170  * limitations under the License.
81171  */
81172
81173 var db = require('ripple/db'),
81174     utils = require('ripple/utils'),
81175     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'),
81176     t = require('ripple/platform/tizen/2.0/typecast'),
81177     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
81178     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
81179     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
81180     SyncInfoMod = require('ripple/platform/tizen/2.0/SyncInfo'),
81181     SyncServiceInfoMod = require('ripple/platform/tizen/2.0/SyncServiceInfo'),
81182     SyncProfileInfoMod = require('ripple/platform/tizen/2.0/SyncProfileInfo'),
81183     SyncStatistics = require('ripple/platform/tizen/2.0/SyncStatistics'),
81184     _data = {
81185         DB_DATASYNC_ITEMS: "tizen1-db-datasync-items",
81186         DB_DATASYNC_COUNTER: "tizen1-db-datasync-counter",
81187         MAX_PROFILE_NUMBER: 5,
81188         profile_num: 0,
81189         profiles: {},
81190         sync_accounts: {},
81191         service_accounts: {},
81192         item_counter: 1000,
81193         type_table: {
81194             "TWO_WAY":             1,
81195             "SLOW":                2,
81196             "ONE_WAY_FROM_CLIENT": 3,
81197             "REFRESH_FROM_CLIENT": 4,
81198             "ONE_WAY_FROM_SERVER": 5,
81199             "REFRESH_FROM_SERVER": 6
81200         },
81201         mode_table: {
81202             "TWO_WAY":             200,
81203             "SLOW":                201,
81204             "ONE_WAY_FROM_CLIENT": 202,
81205             "REFRESH_FROM_CLIENT": 203,
81206             "ONE_WAY_FROM_SERVER": 204,
81207             "REFRESH_FROM_SERVER": 205
81208         },
81209         items: {}
81210     },
81211     _security = {
81212         "http://tizen.org/privilege/datasync":
81213             ["add", "update", "remove", "getMaxProfilesNum", "getProfilesNum",
81214              "get", "getAll", "startSync", "stopSync", "getLastSyncStatistics"]
81215     },
81216     _self,
81217     syncml = {
81218         adapter: require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'),
81219         agent: require('ripple/platform/tizen/2.0/syncml-js-lib/agent'),
81220         base64: require('ripple/platform/tizen/2.0/syncml-js-lib/base64'),
81221         codec:  require('ripple/platform/tizen/2.0/syncml-js-lib/codec'),
81222         common: require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
81223         constant: require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
81224         context: require('ripple/platform/tizen/2.0/syncml-js-lib/context'),
81225         ctype: require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'),
81226         devinfo: require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'),
81227         item: require('ripple/platform/tizen/2.0/syncml-js-lib/item'),
81228         localadapter: require('ripple/platform/tizen/2.0/syncml-js-lib/localadapter'),
81229         matcher: require('ripple/platform/tizen/2.0/syncml-js-lib/matcher'),
81230         protocol: require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'),
81231         remoteadapter: require('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter'),
81232         router: require('ripple/platform/tizen/2.0/syncml-js-lib/router'),
81233         state: require('ripple/platform/tizen/2.0/syncml-js-lib/state'),
81234         storage: require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
81235         store: require('ripple/platform/tizen/2.0/syncml-js-lib/store'),
81236         synchronizer: require('ripple/platform/tizen/2.0/syncml-js-lib/synchronizer'),
81237         useragent: require('ripple/platform/tizen/2.0/syncml-js-lib/useragent')
81238     },
81239     TizenAgent;
81240
81241 function _get() {
81242     _data.item_counter = db.retrieveObject(_data.DB_DATASYNC_COUNTER) || 1000;
81243     _data.items = db.retrieveObject(_data.DB_DATASYNC_ITEMS) || {};
81244 }
81245
81246 function _save() {
81247     db.saveObject(_data.DB_DATASYNC_COUNTER, _data.item_counter);
81248     db.saveObject(_data.DB_DATASYNC_ITEMS, _data.items);
81249 }
81250
81251 TizenAgent = syncml.agent.Agent.extend({
81252     constructor: function() {
81253     },
81254     getContentTypes: function() {
81255         return [
81256             new syncml.ctype.ContentTypeInfo('text/x-vcard', '2.1',{preferred: true})
81257         ];
81258     },
81259     dumpsItem: function(item, contentType, version, cb) {
81260         var cdata = new ET.CdataElement(item.item);
81261         cb(null, cdata);
81262     },
81263     loadsItem: function(data, contentType, version, cb) {
81264         return cb(null, {item: data._node.textContent});
81265     },
81266     getAllItems: function(cb) {
81267         var items = [];
81268         utils.forEach(_data.items, function(contact) {
81269             items.push(contact);
81270         });
81271         return cb(null, items);
81272     },
81273     addItem: function(item, cb) {
81274         _data.item_counter++;
81275         item.id = _data.item_counter.toString();
81276         _data.items[item.id] = item;
81277         _save();
81278         return cb(null, item);
81279     },
81280     getItem: function(itemID, cb) {
81281         return cb(null, _data.items[itemID]);
81282     },
81283     replaceItem: function(item, reportChanges, cb) {
81284         _data.items[item.id] = item;
81285         _save();
81286         return cb(null, null);
81287     },
81288     deleteItem: function(itemID, cb) {
81289         delete _data.items[itemID];
81290         _save();
81291         return cb(null);
81292     }
81293 });
81294
81295 function _initialize() {
81296     _data.agent = new TizenAgent();
81297     _get();
81298 }
81299
81300 _self = function () {
81301     var datasync;
81302
81303     // private
81304     function createInternalProfile(profile) {
81305         var _profile, sync_account, service_accounts;
81306
81307         sync_account = db.retrieveObject("save-syncinfo")[profile.syncInfo.__syncInfoID__];
81308
81309         _profile = {
81310             profileName: profile.profileName,
81311             syncInfo: {
81312                 url:        profile.syncInfo.url,
81313                 id:         sync_account.id,
81314                 password:   sync_account.password,
81315                 mode:       profile.syncInfo.mode
81316             },
81317             serviceInfo: []
81318         };
81319
81320         switch (_profile.syncInfo.mode) {
81321         case "MANUAL":
81322             _profile.syncInfo.type = profile.syncInfo.type || "TWO_WAY";
81323             break;
81324         case "PERIODIC":
81325             //TODO: set 1_HOUR as default value
81326             _profile.interval = profile.syncInfo.interval || "1_HOUR";
81327             _profile.syncInfo.type = "TWO_WAY";
81328             break;
81329         case "PUSH":
81330             _profile.syncInfo.type = "TWO_WAY";
81331             break;
81332         }
81333
81334         if (profile.serviceInfo) {
81335             service_accounts = db.retrieveObject("save-syncserviceinfo");
81336             utils.forEach(profile.serviceInfo, function (service) {
81337                 _profile.serviceInfo.push({
81338                     enable:             service.enable,
81339                     serviceType:        service.serviceType,
81340                     serverDatabaseUri:  service.serverDatabaseUri,
81341                     id:                 service_accounts[service.__syncServiceInfoID__].id,
81342                     password:           service_accounts[service.__syncServiceInfoID__].password
81343                 });
81344             });
81345         }
81346
81347         return _profile;
81348     }
81349
81350     function createExternalProfile(profileId) {
81351         var profile, i, _syncinfo, _serviceinfo, p;
81352
81353         p = _data.profiles[profileId];
81354
81355         switch (p.syncInfo.mode) {
81356         case "MANUAL":
81357             _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "MANUAL", p.syncInfo.type);
81358             _syncinfo.interval = null;
81359             break;
81360         case "PERIODIC":
81361             _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "PERIODIC", p.syncInfo.interval);
81362             break;
81363         case "PUSH":
81364             _syncinfo = new SyncInfoMod(p.syncInfo.url, p.syncInfo.id, p.syncInfo.password, "PUSH");
81365             break;
81366         }
81367
81368         if (p.serviceInfo) {
81369             _serviceinfo = [];
81370             for (i in p.serviceInfo) {
81371                 var info;
81372                 info = new SyncServiceInfoMod(p.serviceInfo[i].enable,
81373                         p.serviceInfo[i].serviceType, p.serviceInfo[i].serverDatabaseUri,
81374                         p.serviceInfo[i].id || null, p.serviceInfo[i].password || null);
81375                 _serviceinfo.push(info);
81376             }
81377         }
81378
81379         profile = new SyncProfileInfoMod(p.profileName, _syncinfo, _serviceinfo);
81380         Object.defineProperty(profile, "profileId", {value: p.profileId, writable: false});
81381
81382         return profile;
81383     }
81384
81385     // public
81386     function add(profile) {
81387         var _profile;
81388
81389         if (!_security.add) {
81390             throw new WebAPIException(errorcode.SECURITY_ERR);
81391         }
81392
81393         t.DataSynchronizationManager("add", arguments);
81394
81395         _profile = createInternalProfile(profile);
81396
81397         if (_data.profile_num > _data.MAX_PROFILE_NUMBER) {
81398             throw new WebAPIException(errorcode.QUOTA_EXCEEDED_ERR);
81399         }
81400
81401         _profile.profileId = Math.uuid(null, 16);
81402         _data.profiles[_profile.profileId] = _profile;
81403         _data.profile_num++;
81404
81405         Object.defineProperty(profile, "profileId", {value: _profile.profileId, writable: false});
81406     }
81407
81408     function update(profile) {
81409         var _profile;
81410
81411         if (!_security.update) {
81412             throw new WebAPIException(errorcode.SECURITY_ERR);
81413         }
81414
81415         t.DataSynchronizationManager("update", arguments);
81416
81417         _profile = createInternalProfile(profile);
81418
81419         if (!profile.profileId || !_data.profiles[profile.profileId]) {
81420             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81421         }
81422
81423         _profile.profileId = profile.profileId;
81424         _data.profiles[_profile.profileId] = _profile;
81425     }
81426
81427     function remove(profileId) {
81428         if (!_security.remove) {
81429             throw new WebAPIException(errorcode.SECURITY_ERR);
81430         }
81431
81432         t.DataSynchronizationManager("remove", arguments);
81433
81434         if (!_data.profiles[profileId]) {
81435             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81436         }
81437
81438         delete _data.profiles[profileId];
81439         _data.profile_num--;
81440     }
81441
81442     function getMaxProfilesNum() {
81443         if (!_security.getMaxProfilesNum) {
81444             throw new WebAPIException(errorcode.SECURITY_ERR);
81445         }
81446
81447         return _data.MAX_PROFILE_NUMBER;
81448     }
81449
81450     function getProfilesNum() {
81451         if (!_security.getProfilesNum) {
81452             throw new WebAPIException(errorcode.SECURITY_ERR);
81453         }
81454
81455         return _data.profile_num;
81456     }
81457
81458     function get(profileId) {
81459         var profile;
81460
81461         if (!_security.get) {
81462             throw new WebAPIException(errorcode.SECURITY_ERR);
81463         }
81464
81465         t.DataSynchronizationManager("get", arguments);
81466
81467         if (!_data.profiles[profileId]) {
81468             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81469         }
81470
81471         profile = createExternalProfile(profileId);
81472
81473         return profile;
81474     }
81475
81476     function getAll() {
81477         var profiles = [], i;
81478
81479         if (!_security.getAll) {
81480             throw new WebAPIException(errorcode.SECURITY_ERR);
81481         }
81482
81483         for (i in _data.profiles) {
81484             profiles.push(createExternalProfile(_data.profiles[i].profileId));
81485         }
81486
81487         return profiles;
81488     }
81489
81490     function startSync(profileId, progressCallback) {
81491         var _profile, _stores, _routes, sync_peer;
81492
81493         if (!_security.startSync) {
81494             throw new WebAPIException(errorcode.SECURITY_ERR);
81495         }
81496
81497         t.DataSynchronizationManager("startSync", arguments);
81498
81499         if (!_data.profiles[profileId]) {
81500             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81501         }
81502         _data.profiles[profileId].stop_flag = false;
81503
81504         sync_peer = function(adapter, store, peer, type) {
81505             adapter.sync(peer, type, function(err, stats) {
81506                 var p, name, hereTotal, peerTotal;
81507                 p = _data.profiles[profileId];
81508                 if (p.stop_flag === true) {
81509                     p.syncStatistics =[{
81510                         syncStatus: "STOP",
81511                         serviceType:            p.serviceInfo[0].serviceType,
81512                         lastSyncTime:           new Date(),
81513                         serverToClientTotal:    0,
81514                         serverToClientAdded:    0,
81515                         serverToClientUpdated:  0,
81516                         serverToClientRemoved:  0,
81517                         clientToServerTotal:    0,
81518                         clientToServerAdded:    0,
81519                         clientToServerUpdated:  0,
81520                         clientToServerRemoved:  0
81521                     }];
81522                     p.stop_flag = false;
81523                     return;
81524                 }
81525                 if (err) {
81526                     if (progressCallback) {
81527                         if (progressCallback.onfailed) {
81528                             progressCallback.onfailed(profileId, new WebAPIError(errorcode.UNKNOWN_ERR));
81529                         }
81530                     }
81531                     p.syncStatistics =[{
81532                         syncStatus: "FAIL",
81533                         serviceType:            p.serviceInfo[0].serviceType,
81534                         lastSyncTime:           new Date(),
81535                         serverToClientTotal:    0,
81536                         serverToClientAdded:    0,
81537                         serverToClientUpdated:  0,
81538                         serverToClientRemoved:  0,
81539                         clientToServerTotal:    0,
81540                         clientToServerAdded:    0,
81541                         clientToServerUpdated:  0,
81542                         clientToServerRemoved:  0
81543                     }];
81544                     p.stop_flag = false;
81545                     return;
81546                 }
81547                 name = p.profileName + "-" + p.serviceInfo[0].serviceType;
81548                 hereTotal = stats[name].hereAdd + stats[name].hereDel + stats[name].hereMod;
81549                 peerTotal = stats[name].peerAdd + stats[name].peerDel + stats[name].peerMod;
81550                 p.syncStatistics =[{
81551                     syncStatus: "SUCCESS",
81552                     serviceType:            p.serviceInfo[0].serviceType,
81553                     lastSyncTime:           new Date(),
81554                     serverToClientTotal:    hereTotal,
81555                     serverToClientAdded:    stats[name].hereAdd,
81556                     serverToClientUpdated:  stats[name].hereMod,
81557                     serverToClientRemoved:  stats[name].hereDel,
81558                     clientToServerTotal:    peerTotal,
81559                     clientToServerAdded:    stats[name].peerAdd,
81560                     clientToServerUpdated:  stats[name].peerMod,
81561                     clientToServerRemoved:  stats[name].peerDel
81562                 }];
81563                 p.stop_flag = false;
81564
81565                 if (progressCallback) {
81566                     if (progressCallback.oncompleted) {
81567                         progressCallback.oncompleted(profileId);
81568                     }
81569                 }
81570             });
81571         };
81572         _profile = _data.profiles[profileId];
81573         _profile.context = new syncml.context.Context({prefix: "tizen-"});
81574         _stores = [];
81575         _routes = [];
81576         utils.forEach(_profile.serviceInfo, function(service) {
81577             var name = _profile.profileName + "-" + service.serviceType;
81578             _stores.push({
81579                 uri:            name,
81580                 displayName:    name,
81581                 maxGuidSize:    64,
81582                 maxObjSize:     4000000,
81583                 agent:          _data.agent
81584             });
81585             _routes.push([name, service.serverDatabaseUri]);
81586         });
81587         _profile.context.getEasyClientAdapter({
81588             displayName: "Tizen syncML adapter",
81589             devInfo: {
81590                 devID: "tizen-syncml-03",
81591                 devType: syncml.constant.DEVTYPE_WORKSTATION,
81592                 manufacturerName: "Tizen",
81593                 modelName: "tizen.syncml.client",
81594                 hierarchicalSync: false
81595             },
81596             stores: _stores,
81597             peer: {
81598                 url:        _profile.syncInfo.url,
81599                 username:   _profile.syncInfo.id,
81600                 password:   _profile.syncInfo.password
81601             },
81602             routes: _routes
81603         }, function(err, adapter, stores, peer) {
81604             if (err) {
81605                 console.log("[datasync.syncml] getEasyClientAdapter fail:", err);
81606                 return;
81607             }
81608             utils.forEach(stores, function(store) {
81609                 var args = {
81610                     data:       _data.mode_table[_profile.syncInfo.type],
81611                     source:     store.uri,
81612                     target:     _profile.serviceInfo[0].serverDatabaseUri,
81613                     nextAnchor: syncml.common.ts()
81614                 };
81615                 if (args.data === _data.mode_table["SLOW"]) {
81616                     args.lastAnchor = null;
81617                 } else if (peer.getStore(args.target)) {
81618                     args.lastAnchor = peer.getStore(args.target)._getBinding().localAnchor;
81619                 }
81620
81621                 db.saveObject("syncml-alert-args", args);
81622                 db.saveObject("syncml-first-flag", false);
81623                 sync_peer(adapter, store, peer, _data.type_table[_profile.syncInfo.type]);
81624             });
81625         });
81626
81627     }
81628
81629     function stopSync(profileId) {
81630         if (!_security.stopSync) {
81631             throw new WebAPIException(errorcode.SECURITY_ERR);
81632         }
81633
81634         t.DataSynchronizationManager("stopSync", arguments);
81635
81636         if (!_data.profiles[profileId]) {
81637             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81638         }
81639
81640         _data.profiles[profileId].stop_flag = true;
81641     }
81642
81643     function getLastSyncStatistics(profileId) {
81644         var s, statistics = [], i;
81645
81646         if (!_security.getLastSyncStatistics) {
81647             throw new WebAPIException(errorcode.SECURITY_ERR);
81648         }
81649
81650         t.DataSynchronizationManager("getLastSyncStatistics", arguments);
81651
81652         if (!_data.profiles[profileId]) {
81653             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81654         }
81655
81656         s = _data.profiles[profileId].syncStatistics;
81657
81658         for (i in s) {
81659             statistics.push(
81660                 new SyncStatistics(s[i].syncStatus, s[i].serviceType, s[i].lastSyncTime,
81661                     s[i].serverToClientTotal, s[i].serverToClientAdded,
81662                     s[i].serverToClientUpdated, s[i].serverToClientRemoved,
81663                     s[i].clientToServerTotal, s[i].clientToServerAdded,
81664                     s[i].clientToServerUpdated, s[i].clientToServerRemoved)
81665             );
81666         }
81667
81668         return statistics;
81669     }
81670
81671     function handleSubFeatures(subFeatures) {
81672         var i, subFeature;
81673
81674         for (subFeature in subFeatures) {
81675             for (i in _security[subFeature]) {
81676                 _security[_security[subFeature][i]] = true;
81677             }
81678         }
81679     }
81680
81681     datasync = {
81682         add:                    add,
81683         update:                 update,
81684         remove:                 remove,
81685         getMaxProfilesNum:      getMaxProfilesNum,
81686         getProfilesNum:         getProfilesNum,
81687         get:                    get,
81688         getAll:                 getAll,
81689         startSync:              startSync,
81690         stopSync:               stopSync,
81691         getLastSyncStatistics:  getLastSyncStatistics,
81692         handleSubFeatures:      handleSubFeatures
81693     };
81694
81695     return datasync;
81696 };
81697
81698 _initialize();
81699
81700 module.exports = _self;
81701
81702 });
81703 define('ripple/platform/tizen/2.0/messageport', function (require, exports, module) {
81704 /*
81705  *  Copyright 2014 Intel Corporation.
81706  *
81707  * Licensed under the Apache License, Version 2.0 (the "License");
81708  * you may not use this file except in compliance with the License.
81709  * You may obtain a copy of the License at
81710  *
81711  * http://www.apache.org/licenses/LICENSE-2.0
81712  *
81713  * Unless required by applicable law or agreed to in writing, software
81714  * distributed under the License is distributed on an "AS IS" BASIS,
81715  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81716  * See the License for the specific language governing permissions and
81717  * limitations under the License.
81718  */
81719
81720 var db = require('ripple/db'),
81721     event = require('ripple/event'),
81722     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
81723     t = require('ripple/platform/tizen/2.0/typecast'),
81724     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
81725     LocalMessagePort,
81726     RemoteMessagePort,
81727     MessagePortInternal,
81728     _data = {
81729         messagePorts: {},
81730         nListener: 0
81731     },
81732     _self;
81733
81734 function _get() {
81735     return db.retrieveObject("tizen-messageport");
81736 }
81737
81738 function _registerApplication(appId, certificate) {
81739     if (_data.messagePorts[appId])
81740         return;
81741
81742     _data.messagePorts[appId] = {
81743         local: {},
81744         remote: {},
81745         certificate: certificate
81746     };
81747 }
81748
81749 function _initialize() {
81750     var appId, app, port, database = _get();
81751
81752     for (appId in database) {
81753         app = database[appId];
81754
81755         _registerApplication(appId, app.certificate);
81756
81757         for (port in app.ports) {
81758             _setMessagePort(appId, port, app.ports[port], false);
81759             _data.messagePorts[appId].local[port].listeners
81760                     [++_data.nListener] = _remoteListener(appId, port);
81761         }
81762     }
81763
81764     event.on("LocalMessagePortReceived", function (data, remotePort) {
81765         var currentAppId = _getCurrentAppId(), appId, messagePortName, isTrusted;
81766
81767         appId = remotePort.appId;
81768         messagePortName = remotePort.messagePortName;
81769         isTrusted = remotePort.isTrusted;
81770
81771         if (!_getMessagePort(appId, messagePortName, true)) {
81772             if (!_data.messagePorts[appId].remote[currentAppId]) {
81773                 _data.messagePorts[appId].remote[currentAppId] = {};
81774             }
81775             _data.messagePorts[appId].remote[currentAppId][messagePortName] =
81776                     new MessagePortInternal(currentAppId, appId, messagePortName,
81777                     true, isTrusted);
81778         }
81779
81780         remotePort.appId = currentAppId;
81781         _dispatchMessage(appId, remotePort, data, null);
81782     });
81783 }
81784
81785 function _getCurrentAppId() {
81786     return tizen.application.getCurrentApplication().appInfo.id;
81787 }
81788
81789 function _remoteListener(appId, port) {
81790     var remotePort = {
81791         appId: appId,
81792         messagePortName: port
81793     };
81794
81795     return function (data, localMessagePort) {
81796         event.trigger("RemoteMessagePortSent", [remotePort, data,
81797                 localMessagePort]);
81798     };
81799 }
81800
81801 function _setMessagePort(appId, messagePortName, isTrusted, isRemote) {
81802     var messagePort, ports, currentAppId = "";
81803
81804     if (!isRemote) {
81805         messagePort = new MessagePortInternal(currentAppId, appId,
81806                 messagePortName, isRemote, isTrusted);
81807         ports = _data.messagePorts[appId].local;
81808     } else {
81809         currentAppId = _getCurrentAppId();
81810         messagePort = new MessagePortInternal(currentAppId, appId,
81811             messagePortName, isRemote, isTrusted);
81812
81813         if (!_data.messagePorts[currentAppId].remote[appId]) {
81814             _data.messagePorts[currentAppId].remote[appId] = {};
81815         }
81816         ports = _data.messagePorts[currentAppId].remote[appId];
81817     }
81818
81819     ports[messagePortName] = messagePort;
81820
81821     return messagePort.external;
81822 }
81823
81824 function _getMessagePort(appId, messagePortName, isRemote) {
81825     var messagePort, currentAppId = _getCurrentAppId(),
81826         app = _data.messagePorts[currentAppId];
81827
81828     messagePort = !isRemote ? app.local[messagePortName] :
81829             (app.remote[appId] ? app.remote[appId][messagePortName] : null);
81830
81831     return !messagePort ? null : messagePort.external;
81832 }
81833
81834 function _dispatchMessage(selfId, dest, data, repliedMessagePort) {
81835     var app, watchId, listener, localPort, messagePort = null,
81836         messagePortName = dest.messagePortName,
81837         appId = dest.appId,
81838         repliedName;
81839
81840     app = _data.messagePorts[appId];
81841     localPort = app.local[messagePortName];
81842
81843     if (repliedMessagePort) {
81844         repliedName = repliedMessagePort.messagePortName;
81845         if (_data.messagePorts[appId].remote[selfId] &&
81846                 _data.messagePorts[appId].remote[selfId][repliedName]) {
81847             messagePort = _data.messagePorts[appId].remote[selfId]
81848                     [repliedName].external;
81849         }
81850     }
81851
81852     for (watchId in localPort.listeners) {
81853         listener = localPort.listeners[watchId];
81854         listener(data, messagePort);
81855     }
81856 }
81857
81858 _self = {
81859     requestLocalMessagePort: function (localMessagePortName) {
81860         var currentAppId, localMessagePort;
81861
81862         t.MessagePortManager("requestLocalMessagePort", arguments);
81863
81864         currentAppId = _getCurrentAppId();
81865         _registerApplication(currentAppId, true);
81866
81867         localMessagePort = _getMessagePort(currentAppId,
81868                 localMessagePortName, false);
81869
81870         if (localMessagePort) {
81871             if (localMessagePort.isTrusted) {
81872                 throw new WebAPIException(errorcode.UNKNOWN_ERR);
81873             }
81874         } else {
81875             localMessagePort = _setMessagePort(currentAppId,
81876                     localMessagePortName, false, false);
81877
81878             event.trigger("LocalMessagePortAdded", [localMessagePortName,
81879                     false]);
81880         }
81881
81882         return localMessagePort;
81883     },
81884
81885     requestTrustedLocalMessagePort: function (localMessagePortName) {
81886         var currentAppId, localMessagePort;
81887
81888         t.MessagePortManager("requestTrustedLocalMessagePort", arguments);
81889
81890         currentAppId = _getCurrentAppId();
81891         _registerApplication(currentAppId, true);
81892
81893         localMessagePort = _getMessagePort(currentAppId,
81894                 localMessagePortName, false);
81895
81896         if (localMessagePort) {
81897             if (!localMessagePort.isTrusted) {
81898                 throw new WebAPIException(errorcode.UNKNOWN_ERR);
81899             }
81900         } else {
81901             localMessagePort = _setMessagePort(currentAppId,
81902                     localMessagePortName, true, false);
81903
81904             event.trigger("LocalMessagePortAdded", [localMessagePortName,
81905                     true]);
81906         }
81907
81908         return localMessagePort;
81909     },
81910
81911     requestRemoteMessagePort: function (appId, remoteMessagePortName) {
81912         var remoteMessagePort, app, currentAppId;
81913
81914         t.MessagePortManager("requestRemoteMessagePort", arguments);
81915
81916         currentAppId = _getCurrentAppId();
81917         _registerApplication(currentAppId, true);
81918
81919         app = _data.messagePorts[appId];
81920
81921         if (!app || !app.local[remoteMessagePortName]) {
81922             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81923         }
81924         if (app.local[remoteMessagePortName].isTrusted) {
81925             throw new WebAPIException(errorcode.INVALID_ACCESS_ERR);
81926         }
81927
81928         remoteMessagePort = _getMessagePort(appId,
81929                 remoteMessagePortName, true);
81930
81931         if (remoteMessagePort) {
81932             if (remoteMessagePort.isTrusted) {
81933                 throw new WebAPIException(errorcode.UNKNOWN_ERR);
81934             }
81935         } else {
81936             remoteMessagePort = _setMessagePort(appId,
81937                     remoteMessagePortName, false, true);
81938
81939             event.trigger("RemoteMessagePortAdded", [appId,
81940                     remoteMessagePortName, false]);
81941         }
81942
81943         return remoteMessagePort;
81944     },
81945
81946     requestTrustedRemoteMessagePort: function (appId, remoteMessagePortName) {
81947         var remoteMessagePort, app, currentAppId;
81948
81949         t.MessagePortManager("requestTrustedRemoteMessagePort", arguments);
81950
81951         currentAppId = _getCurrentAppId();
81952         _registerApplication(currentAppId, true);
81953
81954         app = _data.messagePorts[appId];
81955
81956         if (!app) {
81957             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81958         }
81959         if (!app.certificate) {
81960             throw new WebAPIException(errorcode.INVALID_ACCESS_ERR);
81961         }
81962         if (!app.local[remoteMessagePortName]) {
81963             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
81964         }
81965         if (!app.local[remoteMessagePortName].isTrusted) {
81966             throw new WebAPIException(errorcode.INVALID_ACCESS_ERR);
81967         }
81968
81969         remoteMessagePort = _getMessagePort(appId,
81970                 remoteMessagePortName, true);
81971
81972         if (remoteMessagePort) {
81973             if (!remoteMessagePort.isTrusted) {
81974                 throw new WebAPIException(errorcode.UNKNOWN_ERR);
81975             }
81976         } else {
81977             remoteMessagePort = _setMessagePort(appId,
81978                     remoteMessagePortName, true, true);
81979
81980             event.trigger("RemoteMessagePortAdded", [appId,
81981                     remoteMessagePortName, true]);
81982         }
81983
81984         return remoteMessagePort;
81985     }
81986 };
81987
81988 LocalMessagePort = function (messagePortName, isTrusted, listeners) {
81989     var messagePort = {};
81990
81991     messagePort.messagePortName = messagePortName || "";
81992     messagePort.isTrusted = isTrusted || false;
81993
81994     this.__defineGetter__("messagePortName", function () {
81995         return messagePort.messagePortName;
81996     });
81997
81998     this.__defineGetter__("isTrusted", function () {
81999         return messagePort.isTrusted;
82000     });
82001
82002     this.addMessagePortListener = function (listener) {
82003         var watchId;
82004
82005         t.LocalMessagePort("addMessagePortListener", arguments);
82006
82007         watchId = ++_data.nListener;
82008         listeners[watchId] = listener;
82009
82010         return watchId;
82011     };
82012
82013     this.removeMessagePortListener = function (watchId) {
82014         t.LocalMessagePort("removeMessagePortListener", arguments);
82015
82016         if (!listeners[watchId]) {
82017             // throw new WebAPIException(errorcode.NOT_FOUND_ERR);
82018             return;
82019         }
82020
82021         delete listeners[watchId];
82022     };
82023 };
82024
82025 RemoteMessagePort = function (selfId, appId, messagePortName, isTrusted) {
82026     var messagePort = {};
82027
82028     messagePort.appId = appId || "";
82029     messagePort.messagePortName = messagePortName || "";
82030     messagePort.isTrusted = isTrusted || false;
82031
82032     this.__defineGetter__("appId", function () {
82033         return messagePort.appId;
82034     });
82035
82036     this.__defineGetter__("messagePortName", function () {
82037         return messagePort.messagePortName;
82038     });
82039
82040     this.__defineGetter__("isTrusted", function () {
82041         return messagePort.isTrusted;
82042     });
82043
82044     this.sendMessage = function (data, localMessagePort) {
82045         t.RemoteMessagePort("sendMessage", arguments);
82046
82047         window.setTimeout(function () {
82048             _dispatchMessage(selfId, messagePort, data, localMessagePort);
82049         }, 1);
82050     };
82051 };
82052
82053 MessagePortInternal = function (selfId, appId, messagePortName, isRemote,
82054         isTrusted) {
82055     this.isTrusted = isTrusted;
82056
82057     if (isRemote) {
82058         this.external = new RemoteMessagePort(selfId, appId, messagePortName,
82059                 isTrusted);
82060     } else {
82061         this.listeners = {};
82062         this.external = new LocalMessagePort(messagePortName, isTrusted,
82063                 this.listeners);
82064     }
82065 };
82066
82067 _initialize();
82068
82069 module.exports = _self;
82070
82071 });
82072 define('ripple/platform/tizen/2.0/errorcode', function (require, exports, module) {
82073 /*
82074  *  Copyright 2011 Intel Corporation.
82075  *
82076  * Licensed under the Apache License, Version 2.0 (the "License"),
82077  * you may not use this file except in compliance with the License.
82078  * You may obtain a copy of the License at
82079  *
82080  * http://www.apache.org/licenses/LICENSE-2.0
82081  *
82082  * Unless required by applicable law or agreed to in writing, software
82083  * distributed under the License is distributed on an "AS IS" BASIS,
82084  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82085  * See the License for the specific language governing permissions and
82086  * limitations under the License.
82087  */
82088
82089 var _self = {};
82090
82091 _self.__defineGetter__("UNKNOWN_ERR", function () {
82092     return 0;
82093 });
82094
82095 _self.__defineGetter__("INDEX_SIZE_ERR", function () {
82096     return 1;
82097 });
82098
82099 _self.__defineGetter__("DOMSTRING_SIZE_ERR", function () {
82100     return 2;
82101 });
82102
82103 _self.__defineGetter__("HIERARCHY_REQUEST_ERR", function () {
82104     return 3;
82105 });
82106
82107 _self.__defineGetter__("WRONG_DOCUMENT_ERR", function () {
82108     return 4;
82109 });
82110
82111 _self.__defineGetter__("INVALID_CHARACTER_ERR", function () {
82112     return 5;
82113 });
82114
82115 _self.__defineGetter__("NO_DATA_ALLOWED_ERR", function () {
82116     return 6;
82117 });
82118
82119 _self.__defineGetter__("NO_MODIFICATION_ALLOWED_ERR", function () {
82120     return 7;
82121 });
82122
82123 _self.__defineGetter__("NOT_FOUND_ERR", function () {
82124     return 8;
82125 });
82126
82127 _self.__defineGetter__("NOT_SUPPORTED_ERR", function () {
82128     return 9;
82129 });
82130
82131 _self.__defineGetter__("INUSE_ATTRIBUTE_ERR", function () {
82132     return 10;
82133 });
82134
82135 _self.__defineGetter__("INVALID_STATE_ERR", function () {
82136     return 11;
82137 });
82138
82139 _self.__defineGetter__("SYNTAX_ERR", function () {
82140     return 12;
82141 });
82142
82143 _self.__defineGetter__("INVALID_MODIFICATION_ERR", function () {
82144     return 13;
82145 });
82146
82147 _self.__defineGetter__("NAMESPACE_ERR", function () {
82148     return 14;
82149 });
82150
82151 _self.__defineGetter__("INVALID_ACCESS_ERR", function () {
82152     return 15;
82153 });
82154
82155 _self.__defineGetter__("VALIDATION_ERR", function () {
82156     return 16;
82157 });
82158
82159 _self.__defineGetter__("TYPE_MISMATCH_ERR", function () {
82160     return 17;
82161 });
82162
82163 _self.__defineGetter__("SECURITY_ERR", function () {
82164     return 18;
82165 });
82166
82167 _self.__defineGetter__("NETWORK_ERR", function () {
82168     return 19;
82169 });
82170
82171 _self.__defineGetter__("ABORT_ERR", function () {
82172     return 20;
82173 });
82174
82175 _self.__defineGetter__("URL_MISMATCH_ERR", function () {
82176     return 21;
82177 });
82178
82179 _self.__defineGetter__("QUOTA_EXCEEDED_ERR", function () {
82180     return 22;
82181 });
82182
82183 _self.__defineGetter__("TIMEOUT_ERR", function () {
82184     return 23;
82185 });
82186
82187 _self.__defineGetter__("INVALID_NODE_TYPE_ERR", function () {
82188     return 24;
82189 });
82190
82191 _self.__defineGetter__("DATA_CLONE_ERR", function () {
82192     return 25;
82193 });
82194
82195 _self.__defineGetter__("INVALID_VALUES_ERR", function () {
82196     return 99;
82197 });
82198
82199 _self.__defineGetter__("IO_ERR", function () {
82200     return 100;
82201 });
82202
82203 _self.__defineGetter__("SERVICE_NOT_AVAILABLE_ERR", function () {
82204     return 111;
82205 });
82206
82207 module.exports = _self;
82208
82209
82210 });
82211 define('ripple/platform/tizen/2.0/POIBase', function (require, exports, module) {
82212 /*
82213  *  Copyright 2012 Intel Corporation.
82214  *
82215  * Licensed under the Apache License, Version 2.0 (the "License");
82216  * you may not use this file except in compliance with the License.
82217  * You may obtain a copy of the License at
82218  *
82219  * http://www.apache.org/licenses/LICENSE-2.0
82220  *
82221  * Unless required by applicable law or agreed to in writing, software
82222  * distributed under the License is distributed on an "AS IS" BASIS,
82223  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82224  * See the License for the specific language governing permissions and
82225  * limitations under the License.
82226  */
82227
82228 var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
82229     POIGeometry = require('ripple/platform/tizen/2.0/POIGeometry'),
82230     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
82231     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError');
82232
82233
82234 module.exports = function (prop) {
82235     var _self, i, copy, attr;
82236     _self = {
82237         name : null,
82238         categories : [],
82239         address : null,
82240         phoneNumbers : [],
82241         geometry : null,
82242         urls : [],
82243         rating : null,
82244         tags : null,
82245         toGeoJSON : function () {
82246             throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
82247         }
82248     };
82249
82250     _self.__defineGetter__("id", function () {
82251         return null;
82252     });
82253
82254     _self.__defineGetter__("providerName", function () {
82255         return null;
82256     });
82257
82258     if (prop) {
82259         if (prop.name) {
82260             _self.name = String(prop.name);
82261         }
82262         if (tizen1_utils.isValidArray(prop.categories)) {
82263             _self.categories = [];
82264             for (i in prop.categories) {
82265                 _self.categories.push(String(prop.categories[i]));
82266             }
82267         }
82268         if (prop.address) {
82269             if (typeof prop.address === "string") {
82270                 _self.address = String(prop.address);
82271             } else if (Object.prototype.toString.call(prop.address) === "[object Object]") {
82272                 copy = prop.address.constructor();
82273                 for (attr in prop.address) {
82274                     if (prop.address.hasOwnProperty(attr)) {
82275                         copy[attr] = prop.address[attr];
82276                     }
82277                 }
82278                 _self.address = copy;
82279             }
82280         }
82281         if (tizen1_utils.isValidArray(prop.phoneNumbers)) {
82282             _self.phoneNumbers = [];
82283             for (i in prop.phoneNumbers) {
82284                 _self.phoneNumbers.push(String(prop.phoneNumbers[i]));
82285             }
82286         }
82287         if (prop.geometry) {
82288             _self.geometry = new POIGeometry(prop.geometry.position, prop.geometry.viewport, prop.geometry.wkt);
82289         }
82290         if (tizen1_utils.isValidArray(prop.urls)) {
82291             _self.urls = [];
82292             for (i in prop.urls) {
82293                 _self.urls.push(String(prop.urls[i]));
82294             }
82295         }
82296         if (typeof prop.rating === "number") {
82297             _self.rating = prop.rating;
82298         }
82299         if (Object.prototype.toString.call(prop.tags) === "[object Object]") {
82300             copy = prop.tags.constructor();
82301             for (attr in prop.tags) {
82302                 if (prop.tags.hasOwnProperty(attr)) {
82303                     copy[attr] = prop.tags[attr];
82304                 }
82305             }
82306             _self.tags = copy;
82307         }
82308     }
82309
82310     return _self;
82311 };
82312
82313 });
82314 define('ripple/platform/tizen/2.0/NDEFRecordInternal', function (require, exports, module) {
82315 /*
82316  *  Copyright 2013 Intel Corporation
82317  *
82318  * Licensed under the Apache License, Version 2.0 (the "License");
82319  * you may not use this file except in compliance with the License.
82320  * You may obtain a copy of the License at
82321  *
82322  * http://www.apache.org/licenses/LICENSE-2.0
82323  *
82324  * Unless required by applicable law or agreed to in writing, software
82325  * distributed under the License is distributed on an "AS IS" BASIS,
82326  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82327  * See the License for the specific language governing permissions and
82328  * limitations under the License.
82329  */
82330
82331 module.exports = function (tnf, type, payload, id) {
82332     this.__defineGetter__("tnf", function () {
82333         return tnf;
82334     });
82335
82336     this.__defineGetter__("type", function () {
82337         return type;
82338     });
82339
82340     this.__defineGetter__("id", function () {
82341         return id;
82342     });
82343
82344     this.__defineGetter__("payload", function () {
82345         return payload;
82346     });
82347 };
82348
82349 });
82350 define('ripple/platform/tizen/2.0/EventBase', function (require, exports, module) {
82351 /*
82352  *  Copyright 2012 Intel Corporation.
82353  *
82354  * Licensed under the Apache License, Version 2.0 (the "License");
82355  * you may not use this file except in compliance with the License.
82356  * You may obtain a copy of the License at
82357  *
82358  * http://www.apache.org/licenses/LICENSE-2.0
82359  *
82360  * Unless required by applicable law or agreed to in writing, software
82361  * distributed under the License is distributed on an "AS IS" BASIS,
82362  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82363  * See the License for the specific language governing permissions and
82364  * limitations under the License.
82365  */
82366
82367 module.exports = function () {
82368     var _self = {
82369         CAPTURING_PHASE: 1,
82370         AT_TARGET:  2,
82371         BUBBLING_PHASE: 3,
82372
82373         type: '',
82374         target: null, //new EventTarget(),
82375         currentTarget: null, //new EventTarget(),
82376         eventPhase: 0,
82377         bubbles: false,
82378         cancelable: false,
82379         timeStamp: 0
82380     };
82381
82382     this.__defineGetter__("type", function () {
82383         return _self.type;
82384     });
82385
82386     this.__defineGetter__("target", function () {
82387         return _self.target;
82388     });
82389
82390     this.__defineGetter__("currentTarget", function () {
82391         return _self.currentTarget;
82392     });
82393
82394     this.__defineGetter__("eventPhase", function () {
82395         return _self.eventPhase;
82396     });
82397
82398     this.__defineGetter__("bubbles", function () {
82399         return _self.bubbles;
82400     });
82401
82402     this.__defineGetter__("cancelable", function () {
82403         return _self.cancelable;
82404     });
82405
82406     this.__defineGetter__("timeStamp", function () {
82407         return _self.timeStamp;
82408     });
82409
82410     this.stopPropagation = function () {};
82411
82412     this.preventDefault = function () {};
82413
82414     this.initEvent = function (eventTypeArg, canBubbleArg, cancelableArg) {
82415         _self.type = eventTypeArg;
82416         _self.bubbles = canBubbleArg;
82417         _self.cancelable = cancelableArg;
82418
82419         _self.timeStamp = (new Date()).getTime();
82420     };
82421
82422     return _self;
82423 };
82424
82425
82426 });
82427 define('ripple/platform/tizen/2.0/messaging', function (require, exports, module) {
82428 /*
82429  *  Copyright 2012 Intel Corporation.
82430  *
82431  * Licensed under the Apache License, Version 2.0 (the "License");
82432  * you may not use this file except in compliance with the License.
82433  * You may obtain a copy of the License at
82434  *
82435  * http://www.apache.org/licenses/LICENSE-2.0
82436  *
82437  * Unless required by applicable law or agreed to in writing, software
82438  * distributed under the License is distributed on an "AS IS" BASIS,
82439  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82440  * See the License for the specific language governing permissions and
82441  * limitations under the License.
82442  */
82443
82444 var _self,
82445     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
82446     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
82447     MessagingService = require('ripple/platform/tizen/2.0/MessagingService'),
82448     t = require('ripple/platform/tizen/2.0/typedef'),
82449     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
82450     TIZEN_MESSAGING_SMS = "messaging.sms",
82451     TIZEN_MESSAGING_MMS = "messaging.mms",
82452     TIZEN_MESSAGING_EMAIL = "messaging.email",
82453     _security_check = {read: false, write: false},
82454     _sms_service = null,
82455     _mms_service = null,
82456     _email_service = null;
82457
82458 _self = function () {
82459     this.getMessageServices = function (messageServiceType, onSuccess, onError) {
82460         var service;
82461
82462         if (!(new TypeCoerce(t.MessageServiceTag)).match(messageServiceType)) {
82463             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82464         }
82465         if (!(new TypeCoerce(t.MessageServiceArraySuccessCallback)).match(onSuccess)) {
82466             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82467         }
82468         if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
82469             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82470         }
82471
82472         switch (messageServiceType) {
82473         case "messaging.sms":
82474             if (_sms_service === null) {
82475                 _sms_service = [new MessagingService("Tizen SMS Service 1", TIZEN_MESSAGING_SMS, _security_check), new MessagingService("Tizen SMS Service 2", TIZEN_MESSAGING_SMS, _security_check)];
82476             }
82477             service = _sms_service;
82478             break;
82479         case "messaging.mms":
82480             if (_mms_service === null) {
82481                 _mms_service = [new MessagingService("Tizen MMS Service", TIZEN_MESSAGING_MMS, _security_check)];
82482             }
82483             service = _mms_service;
82484             break;
82485         case "messaging.email":
82486             if (_email_service === null) {
82487                 _email_service = [new MessagingService("Tizen Email Service", TIZEN_MESSAGING_EMAIL, _security_check)];
82488             }
82489             service = _email_service;
82490             break;
82491         default:
82492             throw (new WebAPIException(errorcode.INVALID_VALUES_ERR));
82493         }
82494         setTimeout(function () {
82495             onSuccess(service);
82496         }, 1);
82497     };
82498     this.handleSubFeatures = function (subFeatures) {
82499         if (subFeatures.hasOwnProperty('http://tizen.org/privilege/messaging.read')) {
82500             _security_check.read = true;
82501         }
82502         if (subFeatures.hasOwnProperty('http://tizen.org/privilege/messaging.write')) {
82503             _security_check.write = true;
82504         }
82505     };
82506 };
82507
82508 module.exports = _self;
82509
82510 });
82511 define('ripple/platform/tizen/2.0/NDEFRecord', function (require, exports, module) {
82512 /*
82513  *  Copyright 2013 Intel Corporation
82514  *
82515  * Licensed under the Apache License, Version 2.0 (the "License");
82516  * you may not use this file except in compliance with the License.
82517  * You may obtain a copy of the License at
82518  *
82519  * http://www.apache.org/licenses/LICENSE-2.0
82520  *
82521  * Unless required by applicable law or agreed to in writing, software
82522  * distributed under the License is distributed on an "AS IS" BASIS,
82523  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82524  * See the License for the specific language governing permissions and
82525  * limitations under the License.
82526  */
82527
82528 var t = require('ripple/platform/tizen/2.0/typecast'),
82529     NDEFRecordInternal = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
82530     NDEFRecord;
82531
82532 NDEFRecord = function () {
82533     var voc = [
82534         function (tnf, type, payload, id) {
82535             NDEFRecordInternal.call(this, tnf, type, payload, id || []);
82536         },
82537         function (raw_data) {
82538             NDEFRecordInternal.call(this, 0, [], [], []);
82539         }
82540     ];
82541
82542     t.NDEFRecord(arguments, this, voc);
82543 };
82544
82545 module.exports = NDEFRecord;
82546
82547 });
82548 define('ripple/platform/tizen/2.0/MessageStorage', function (require, exports, module) {
82549 /*
82550  *  Copyright 2012 Intel Corporation.
82551  *
82552  * Licensed under the Apache License, Version 2.0 (the "License");
82553  * you may not use this file except in compliance with the License.
82554  * You may obtain a copy of the License at
82555  *
82556  * http://www.apache.org/licenses/LICENSE-2.0
82557  *
82558  * Unless required by applicable law or agreed to in writing, software
82559  * distributed under the License is distributed on an "AS IS" BASIS,
82560  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
82561  * See the License for the specific language governing permissions and
82562  * limitations under the License.
82563  */
82564 var _self,
82565     utils = require('ripple/utils'),
82566     event = require('ripple/event'),
82567     Message = require('ripple/platform/tizen/2.0/Message'),
82568     Conversation = require('ripple/platform/tizen/2.0/Conversation'),
82569     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
82570     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
82571     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
82572     PrivMessage = require('ripple/platform/tizen/2.0/PrivMessage'),
82573     MessageFolder = require('ripple/platform/tizen/2.0/MessageFolder'),
82574     msg_utils = require('ripple/platform/tizen/2.0/msg_utils'),
82575     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
82576     t = require('ripple/platform/tizen/2.0/typedef'),
82577     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
82578     TIZEN_DEFAULT_MSG_FROM = {"messaging.sms": "13572468",
82579                               "messaging.mms": "13572468",
82580                               "messaging.email": "tizen.simulator@tizen.org"};
82581
82582 _self = function (messages, security_check) {
82583     var message_storage = {},
82584         _findMessage, _findConversation,
82585         _processMessageChange, _processConversationChange,
82586         _folders = {}, folderOpt = {},
82587         _msgListeners = {},
82588         _convListeners = {},
82589         _folderListeners = {},
82590         _security_check = security_check,
82591         _messages = messages;
82592
82593     // init folders
82594     folderOpt = {id: "INBOX", serviceId: _messages.id, contentType: _messages.type,
82595                  path: "inbox", type: "INBOX", synchronizable: true};
82596     _folders.INBOX = new MessageFolder(folderOpt);
82597     folderOpt = {id: "OUTBOX", serviceId: _messages.id, contentType: _messages.type,
82598                  path: "outbox", type: "OUTBOX", synchronizable: false};
82599     _folders.OUTBOX = new MessageFolder(folderOpt);
82600     folderOpt = {id: "DRAFT", serviceId: _messages.id, contentType: _messages.type,
82601                  path: "draft", type: "DRAFTS", synchronizable: false};
82602     _folders.DRAFT = new MessageFolder(folderOpt);
82603     folderOpt = {id: "SENTBOX", serviceId: _messages.id, contentType: _messages.type,
82604                  path: "sentbox", type: "SENTBOX", synchronizable: false};
82605     _folders.SENTBOX = new MessageFolder(folderOpt);
82606
82607     event.on("MsgRecv", function (msg) {
82608         // msg sent from panel to module
82609         if (msg.priv.type !== _messages.type ||
82610             msg.priv.serviceId !== _messages.id) {
82611             return;
82612         }
82613         // trigger Message add
82614         _processMessageChange([msg], "add");
82615         _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
82616
82617         if (_messages.conv[msg.priv.conversationId].messageCount === 1) {
82618             _processConversationChange([_messages.conv[msg.priv.conversationId]], "add");
82619         } else {
82620             _processConversationChange([_messages.conv[msg.priv.conversationId]], "update");
82621         }
82622     });
82623
82624     event.on("OutsideMessageReceived", function (msg) {
82625         // msg sent from module to panel
82626         if (msg.msg.priv.type !== _messages.type ||
82627             msg.msg.priv.serviceId !== _messages.id) {
82628             return;
82629         }
82630         // trigger conversation/Message add
82631         _processMessageChange([msg.msg], "add");
82632         _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
82633
82634         if (_messages.conv[msg.msg.priv.conversationId].messageCount === 1) {
82635             _processConversationChange([_messages.conv[msg.msg.priv.conversationId]], "add");
82636         } else {
82637             _processConversationChange([_messages.conv[msg.msg.priv.conversationId]], "update");
82638         }
82639     });
82640
82641     event.on("MsgSentRst", function (rst) {
82642         // ACK from panel when module sent a msg to panel
82643         if (rst.priv.type !== _messages.type ||
82644             rst.priv.serviceId !== _messages.id) {
82645             return;
82646         }
82647         // trigger conversation/Message Update
82648         _processMessageChange([rst], "update");
82649         _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
82650         _processConversationChange([_messages.conv[rst.priv.conversationId]], "update");
82651     });
82652
82653     _findMessage = function (src, filter) {
82654         var ret, foo = {};
82655         switch (filter.attributeName) {
82656         case "type":
82657             foo[filter.attributeName] = _messages.type;
82658             ret = tizen1_utils.matchAttributeFilter([foo],
82659                       filter.attributeName, filter.matchFlag, filter.matchValue);
82660             if (ret.length === 0) {
82661                 ret = [];
82662             } else {
82663                 // make an array
82664                 ret = utils.filter(src, function () { return true; });
82665             }
82666             break;
82667         case "id":
82668         case "conversationId":
82669         case "folderId":
82670         case "from":
82671         case "messageStatus":
82672             ret = tizen1_utils.matchAttributeFilter(src,
82673                       "priv." + filter.attributeName,
82674                       filter.matchFlag, filter.matchValue);
82675             break;
82676         case "hasAttachment":
82677             if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
82678                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
82679                               "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
82680             }
82681             ret = tizen1_utils.matchAttributeBooleanFilter(src,
82682                       "priv." + filter.attributeName, filter.matchValue);
82683             break;
82684         case "to":
82685         case "cc":
82686         case "bcc":
82687             ret = tizen1_utils.matchAttributeArrayFilter(src,
82688                       filter.attributeName, filter.matchFlag, filter.matchValue);
82689             break;
82690         case "body":
82691             ret = tizen1_utils.matchAttributeFilter(src,
82692                       filter.attributeName + ".plainBody",
82693                       filter.matchFlag, filter.matchValue);
82694             break;
82695         case "subject":
82696         case "inResponseTo":
82697             ret = tizen1_utils.matchAttributeFilter(src, filter.attributeName,
82698                       filter.matchFlag, filter.matchValue);
82699             break;
82700         case "isRead":
82701         case "isHighPriority":
82702             if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
82703                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
82704                               "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
82705             }
82706             ret = tizen1_utils.matchAttributeBooleanFilter(src,
82707                       filter.attributeName, filter.matchValue);
82708             break;
82709         case "timestamp":
82710             ret = tizen1_utils.matchAttributeRangeFilter(src,
82711                       "priv." + filter.attributeName,
82712                       filter.initialValue, filter.endValue);
82713             break;
82714
82715         case "attachments":
82716             throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR,
82717                                   "not support find by " + filter.attributeName));
82718         default:
82719             throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
82720                                    "invalid attributeName"));
82721         }
82722         return ret;
82723     };
82724
82725     _processMessageChange = function (messages, type) {
82726         var i, j, ret = [], tmp,
82727             operation = {"add": "messagesadded",
82728                          "remove": "messagesremoved",
82729                          "update": "messagesupdated"};
82730
82731         for (i in _msgListeners) {
82732             ret = [];
82733             if (_msgListeners[i].filter !== null) {
82734                 tmp = _findMessage(messages, _msgListeners[i].filter);
82735             } else {
82736                 tmp = messages;
82737             }
82738             if (tmp.length !== 0) {
82739                 for (j = 0; j < tmp.length; j++) {
82740                     ret.push(new Message(tmp[j].priv.type, tmp[j]));
82741                 }
82742                 _msgListeners[i].callback[operation[type]](ret);
82743             }
82744         }
82745     };
82746
82747     _findConversation = function (src, filter) {
82748         var ret, foo = {};
82749         switch (filter.attributeName) {
82750         case "type":
82751             foo[filter.attributeName] = _messages.type;
82752             ret = tizen1_utils.matchAttributeFilter([foo], filter.attributeName, filter.matchFlag, filter.matchValue);
82753             if (ret.length === 0) {
82754                 ret = [];
82755             } else {
82756                 // make an array
82757                 ret = utils.filter(_messages.conv, function () { return true; });
82758             }
82759             break;
82760         case "id":
82761         case "preview":
82762         case "subject":
82763         case "from":
82764         case "lastMessageId":
82765             ret = tizen1_utils.matchAttributeFilter(src, filter.attributeName, filter.matchFlag, filter.matchValue);
82766             break;
82767         case "to":
82768         case "cc":
82769         case "bcc":
82770             ret = tizen1_utils.matchAttributeArrayFilter(src,
82771                       filter.attributeName, filter.matchFlag, filter.matchValue);
82772             break;
82773         case "isRead":
82774             if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
82775                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
82776                               "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
82777             }
82778             ret = tizen1_utils.matchAttributeBooleanFilter(src,
82779                       filter.attributeName, filter.matchValue);
82780             break;
82781         case "timestamp":
82782         case "messageCount":
82783         case "unreadMessages":
82784             ret = tizen1_utils.matchAttributeRangeFilter(src,
82785                       filter.attributeName,
82786                       filter.initialValue, filter.endValue);
82787             break;
82788         default:
82789             throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
82790                                    "invalid attributeName"));
82791         }
82792         return ret;
82793     };
82794
82795     _processConversationChange = function (conversations, type) {
82796         var i, j, ret = [], tmp,
82797             operation = {"add": "conversationsadded",
82798                          "remove": "conversationsremoved",
82799                          "update": "conversationsupdated"};
82800
82801         for (i in _convListeners) {
82802             ret = [];
82803             if (_convListeners[i].filter !== null) {
82804                 tmp = _findConversation(conversations, _convListeners[i].filter);
82805             } else {
82806                 tmp = conversations;
82807             }
82808             if (tmp.length !== 0) {
82809                 for (j = 0; j < tmp.length; j++) {
82810                     ret.push(new Conversation(tmp[j]));
82811                 }
82812                 _convListeners[i].callback[operation[type]](ret);
82813             }
82814         }
82815     };
82816
82817     message_storage = {
82818         addDraftMessage: function (_msg, onSuccess, onError) {
82819             var m, msg = {}, opt = {};
82820
82821             if (_security_check.write === false) {
82822                 throw (new WebAPIException(errorcode.SECURITY_ERR));
82823             }
82824             if (msg_utils.setMsg(_msg, msg) === false) {
82825                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
82826             }
82827             if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
82828                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82829             }
82830             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
82831                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82832             }
82833             opt.id = Math.uuid(8, 16);
82834             opt.serviceId = _messages.id;
82835             if ((msg.inResponseTo !== null) &&
82836                 (_messages.msg[msg.inResponseTo] !== undefined)) {
82837                 opt.conversationId = _messages.msg[msg.inResponseTo].conversationId;
82838             } else {
82839                 opt.conversationId = opt.id;
82840             }
82841             opt.folderId = "DRAFTS";
82842             opt.type = _messages.type;
82843             opt.timestamp = new Date();
82844             opt.from = TIZEN_DEFAULT_MSG_FROM[_messages.type];
82845             if (msg.attachments.length === 0) {
82846                 opt.hasAttachment = false;
82847             } else {
82848                 opt.hasAttachment = true;
82849             }
82850             opt.messageStatus = "DRAFT";
82851
82852             m = new PrivMessage(msg, opt);
82853             _messages.msg[m.priv.id] = m;  // local
82854             msg_utils.saveMsg(_messages.msg[m.priv.id]);  // remote
82855             // trigger message add
82856             _processMessageChange([m], "add");
82857             if (onSuccess) {
82858                 setTimeout(function () {
82859                     onSuccess(new Message(m.priv.type, m));
82860                 }, 1);
82861             }
82862         },
82863
82864         removeMessages: function (messages, onSuccess, onError) {
82865             var i, c, na_msg = "", msgToDel = [], convToDel = {}, delConv = [], updateConv = [];
82866
82867             if (_security_check.write === false) {
82868                 throw (new WebAPIException(errorcode.SECURITY_ERR));
82869             }
82870             if (tizen1_utils.isValidArray(messages) === false) {
82871                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
82872             }
82873             if (messages.length === 0) {
82874                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR));
82875             }
82876             if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
82877                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82878             }
82879             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
82880                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82881             }
82882
82883             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
82884             for (i = 0; i < messages.length; i++) {
82885                 if (_messages.msg[messages[i].id] === undefined) {
82886                     na_msg += messages[i].id + ", ";
82887                 } else {
82888                     msgToDel.push(utils.copy(_messages.msg[messages[i].id]));
82889                 }
82890                 if (_messages.conv[messages[i].conversationId] !== undefined) {
82891                     convToDel[messages[i].conversationId] = _messages.conv[messages[i].conversationId];
82892                 }
82893             }
82894             if (na_msg === "") {
82895                 for (i = 0; i < messages.length; i++) {
82896                     // conversation updated at remote when msg is deleted
82897                     msg_utils.delMsg(_messages.msg[messages[i].id]); // remote
82898                     delete _messages.msg[messages[i].id]; // local
82899                 }
82900                 // update conversation
82901                 _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
82902                 for (c in convToDel) {
82903                     if (_messages.conv[c] === undefined) {
82904                         delConv.push(convToDel[c]);
82905                     } else {
82906                         updateConv.push(convToDel[c]);
82907                     }
82908                 }
82909                 if (onSuccess) {
82910                     setTimeout(function () {
82911                         onSuccess();
82912                     }, 1);
82913                 }
82914                 // trigger messages remove
82915                 _processMessageChange(msgToDel, "remove");
82916                 if (delConv.length > 0) {
82917                     _processConversationChange(delConv, "remove");
82918                 }
82919                 if (updateConv.length > 0) {
82920                     _processConversationChange(updateConv, "update");
82921                 }
82922             } else {
82923                 if (onError) {
82924                     setTimeout(function () {
82925                         onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
82926                                 na_msg + "not found !!"));
82927                     }, 1);
82928                 }
82929             }
82930         },
82931
82932         updateMessages: function (messages, onSuccess, onError) {
82933             var i, m, updateConv = {}, updateMsg = [], tmp,
82934                 na_msg = "", invalid_msg = "";
82935
82936             if (_security_check.write === false) {
82937                 throw (new WebAPIException(errorcode.SECURITY_ERR));
82938             }
82939             if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
82940                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82941             }
82942             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
82943                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
82944             }
82945             if (tizen1_utils.isValidArray(messages) === false) {
82946                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
82947             }
82948             if (messages.length === 0) {
82949                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR));
82950             }
82951             // update conversation
82952             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
82953             for (i = 0; i < messages.length; i++) {
82954                 m = _messages.msg[messages[i].id];
82955                 if (m === undefined) {
82956                     // msg not found
82957                     na_msg += messages[i].id + ", ";
82958                 } else {
82959                     if (m.priv.messageStatus === "DRAFT") {
82960                         tmp = {};
82961                         // allow update all writeable attr in draft
82962                         if (msg_utils.setMsg(messages[i], tmp) === false) {
82963                             invalid_msg += messages[i].id + ", ";
82964                         }
82965                     }
82966                 }
82967             }
82968             if (invalid_msg !== "") {
82969                 if (onError) {
82970                     setTimeout(function () {
82971                         onError(new WebAPIError(errorcode.INVALID_VALUES_ERR,
82972                                 invalid_msg + "invalid values"));
82973                     }, 1);
82974                 }
82975                 return;
82976             }
82977             if (na_msg !== "") {
82978                 if (onError) {
82979                     setTimeout(function () {
82980                         onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
82981                                 na_msg + "not found !!"));
82982                     }, 1);
82983                 }
82984                 return;
82985             }
82986
82987             for (i = 0; i < messages.length; i++) {
82988                 m = _messages.msg[messages[i].id];
82989                 if (m.priv.messageStatus === "DRAFT") {
82990                     msg_utils.setMsg(messages[i], m);
82991                     updateMsg.push(m);
82992                 } else {
82993                     // only allow update isRead in other folders
82994                     if (typeof messages[i].isRead === 'boolean') {
82995                         m.isRead = messages[i].isRead;
82996                         updateMsg.push(m);
82997                         updateConv[m.priv.conversationId] = _messages.conv[m.priv.conversationId];
82998                     }
82999                 }
83000                 msg_utils.saveMsg(m);
83001             }
83002             if (onSuccess) {
83003                 setTimeout(function () {
83004                     onSuccess();
83005                 }, 1);
83006             }
83007
83008             // trigger Message update
83009             _processMessageChange(updateMsg, "update");
83010
83011             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
83012             // trigger conversation update
83013             _processConversationChange(updateConv, "update");
83014         },
83015
83016         findMessages: function (filter, onSuccess, onError, sort, _limit, _offset) {
83017             var i, tmp, offset, limit, ret = [];
83018
83019             if (_security_check.read === false) {
83020                 throw (new WebAPIException(errorcode.SECURITY_ERR));
83021             }
83022             if (!(new TypeCoerce(t.MessageArraySuccessCallback)).match(onSuccess)) {
83023                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83024             }
83025             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
83026                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83027             }
83028             if (sort && !(new TypeCoerce(t.SortMode)).match(sort)) {
83029                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83030             }
83031             if (_limit && !(new TypeCoerce(t.long)).match(_limit)) {
83032                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83033             }
83034             if (_offset && !(new TypeCoerce(t.long)).match(_offset)) {
83035                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83036             }
83037             tmp = _findMessage(_messages.msg, filter);
83038
83039             if (_offset) {
83040                 offset = _offset;
83041             } else {
83042                 offset = 0;
83043             }
83044             if (_limit) {
83045                 limit = Math.min(_limit + offset, tmp.length);
83046             } else {
83047                 limit = tmp.length;
83048             }
83049             for (i = offset; i < limit; i++) {
83050                 ret.push(new Message(tmp[i].priv.type, tmp[i]));
83051             }
83052             setTimeout(function () {
83053                 onSuccess(ret);
83054             }, 1);
83055         },
83056
83057         findConversations: function (filter, onSuccess, onError, sort, _limit, _offset) {
83058             var i, tmp, offset, limit, ret = [];
83059
83060             if (_security_check.read === false) {
83061                 throw (new WebAPIException(errorcode.SECURITY_ERR));
83062             }
83063             if (!(new TypeCoerce(t.MessageConversationArraySuccessCallback)).match(onSuccess)) {
83064                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83065             }
83066             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
83067                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83068             }
83069             if (sort && !(new TypeCoerce(t.SortMode)).match(sort)) {
83070                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83071             }
83072             if (_limit && !(new TypeCoerce(t.long)).match(_limit)) {
83073                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83074             }
83075             if (_offset && !(new TypeCoerce(t.long)).match(_offset)) {
83076                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83077             }
83078             // download conversation
83079             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
83080
83081             tmp = _findConversation(_messages.conv, filter);
83082
83083             if (_offset) {
83084                 offset = _offset;
83085             } else {
83086                 offset = 0;
83087             }
83088             if (_limit) {
83089                 limit = Math.min(_limit + offset, tmp.length);
83090             } else {
83091                 limit = tmp.length;
83092             }
83093             for (i = offset; i < limit; i++) {
83094                 ret.push(new Conversation(tmp[i]));
83095             }
83096             setTimeout(function () {
83097                 onSuccess(ret);
83098             }, 1);
83099         },
83100
83101         removeConversations: function (conversations, onSuccess, onError) {
83102             var i, m, na_msg = "", retConv = [], removeMsg = [];
83103
83104             if (_security_check.write === false) {
83105                 throw (new WebAPIException(errorcode.SECURITY_ERR));
83106             }
83107             if (onSuccess && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
83108                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83109             }
83110             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
83111                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83112             }
83113             // download conversation
83114             _messages.conv = msg_utils.loadConv(_messages.type, _messages.id);
83115
83116             if (tizen1_utils.isValidArray(conversations) === false) {
83117                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
83118             }
83119             if (conversations.length === 0) {
83120                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR));
83121             }
83122             if ((onSuccess && typeof onSuccess !== "function") ||
83123                 (onError && typeof onError !== "function")) {
83124                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83125             }
83126
83127             for (i = 0; i < conversations.length; i++) {
83128                 if (_messages.conv[conversations[i].id] === undefined) {
83129                     na_msg += conversations[i].id + ", ";
83130                 } else {
83131                     retConv.push(_messages.conv[conversations[i].id]);
83132                     for (m in _messages.msg) {
83133                         if (_messages.msg[m].priv.conversationId === conversations[i].id) {
83134                             removeMsg.push(_messages.msg[m]);
83135                         }
83136                     }
83137                 }
83138             }
83139             if (na_msg === "") {
83140                 for (i = 0; i < removeMsg.length; i++) {
83141                     // conversation updated at remote
83142                     msg_utils.delMsg(removeMsg[i]);  // remote
83143                     delete _messages.msg[removeMsg[i].priv.id]; // local
83144                 }
83145                 // trigger msg(retMsg)/conv(retConv) delete update
83146                 _processMessageChange(removeMsg, "remove");
83147                 _processConversationChange(retConv, "remove");
83148                 if (onSuccess) {
83149                     setTimeout(function () {
83150                         onSuccess();
83151                     }, 1);
83152                 }
83153             } else {
83154                 if (onError) {
83155                     setTimeout(function () {
83156                         onError(new WebAPIError(errorcode.NOT_FOUND_ERR,
83157                                 na_msg + "not found !!"));
83158                     }, 1);
83159                 }
83160             }
83161         },
83162
83163         findFolders: function (filter, onSuccess, onError) {
83164             var ret = [], tmp, i;
83165
83166             if (_security_check.read === false) {
83167                 throw (new WebAPIException(errorcode.SECURITY_ERR));
83168             }
83169             if (!(new TypeCoerce(t.MessageFolderArraySuccessCallback)).match(onSuccess)) {
83170                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83171             }
83172             if (onError && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
83173                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83174             }
83175             switch (filter.attributeName) {
83176             case "id":
83177             case "serviceId":
83178             case "contentType":
83179             case "name":
83180             case "path":
83181             case "type":
83182                 tmp = tizen1_utils.matchAttributeFilter(_folders,
83183                           filter.attributeName, filter.matchFlag,
83184                           filter.matchValue);
83185                 break;
83186             case "synchronizable":
83187                 if (filter.matchFlag !== "EXACTLY" ||
83188                     typeof filter.matchValue !== "boolean") {
83189                     throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
83190                                   "Support only matchFlag === 'EXACTLY' and typeof matchValue === 'boolean'"));
83191                 }
83192                 tmp = tizen1_utils.matchAttributeBooleanFilter(_folders,
83193                           filter.attributeName, filter.matchValue);
83194                 break;
83195             case "parentId":
83196                 if (filter.matchValue === null) {
83197                     tmp = utils.filter(_folders, function (o) { return o.parentId === null; });
83198                 } else {
83199                     tmp = tizen1_utils.matchAttributeFilter(_folders,
83200                               filter.attributeName, filter.matchValue);
83201                 }
83202                 break;
83203             default:
83204                 throw (new WebAPIException(errorcode.INVALID_VALUES_ERR,
83205                                        "invalid attributeName"));
83206             }
83207             for (i = 0; i < tmp.length; i++) {
83208                 ret.push(new MessageFolder(tmp[i]));
83209             }
83210             setTimeout(function () {
83211                 onSuccess(ret);
83212             }, 1);
83213         },
83214
83215         addMessagesChangeListener: function (msgCallback, filter) {
83216             var watchId, msgListener = {};
83217
83218             if (_security_check.read === false) {
83219                 throw (new WebAPIException(errorcode.SECURITY_ERR));
83220             }
83221             if (!(new TypeCoerce(t.MessagesChangeCallback)).match(msgCallback)) {
83222                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83223             }
83224             if (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) {
83225                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83226             }
83227
83228             watchId = Number(Math.uuid(8, 10));
83229             msgListener.callback = msgCallback;
83230             msgListener.filter = filter || null;
83231             _msgListeners[watchId] = msgListener;
83232             return watchId;
83233         },
83234
83235         addConversationsChangeListener: function (convCallback, filter) {
83236             var watchId, convListener = {};
83237
83238             if (_security_check.read === false) {
83239                 throw (new WebAPIException(errorcode.SECURITY_ERR));
83240             }
83241             if (!(new TypeCoerce(t.MessageConversationsChangeCallback)).match(convCallback)) {
83242                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83243             }
83244             if (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) {
83245                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83246             }
83247
83248             watchId = Number(Math.uuid(8, 10));
83249             convListener.callback = convCallback;
83250             convListener.filter = filter || null;
83251             _convListeners[watchId] = convListener;
83252             return watchId;
83253         },
83254
83255         addFoldersChangeListener: function (callback, filter) {
83256             var watchId, folderListener = {};
83257
83258             if (_security_check.read === false) {
83259                 throw (new WebAPIException(errorcode.SECURITY_ERR));
83260             }
83261             if (!(new TypeCoerce(t.MessageFoldersChangeCallback)).match(callback)) {
83262                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83263             }
83264             if (filter && !(new TypeCoerce(t.AbstractFilter)).match(filter)) {
83265                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
83266             }
83267
83268             watchId = Number(Math.uuid(8, 10));
83269             folderListener.callback = callback;
83270             folderListener.filter = filter || null;
83271             _folderListeners[watchId] = folderListener;
83272             return watchId;
83273         },
83274
83275         removeChangeListener: function (watchid) {
83276             if (_security_check.read === false) {
83277                 throw (new WebAPIException(errorcode.SECURITY_ERR));
83278             }
83279             if (_msgListeners[watchid] !== undefined) {
83280                 delete _msgListeners[watchid];
83281                 return;
83282             }
83283             if (_convListeners[watchid] !== undefined) {
83284                 delete _convListeners[watchid];
83285                 return;
83286             }
83287             if (_folderListeners[watchid] !== undefined) {
83288                 delete _folderListeners[watchid];
83289                 return;
83290             }
83291         }
83292
83293     };
83294     return message_storage;
83295 };
83296
83297 module.exports = _self;
83298
83299 });
83300 define('ripple/platform/tizen/2.0/datacontrol', function (require, exports, module) {
83301 /*
83302  *  Copyright 2013 Intel Corporation
83303  *
83304  * Licensed under the Apache License, Version 2.0 (the "License");
83305  * you may not use this file except in compliance with the License.
83306  * You may obtain a copy of the License at
83307  *
83308  * http://www.apache.org/licenses/LICENSE-2.0
83309  *
83310  * Unless required by applicable law or agreed to in writing, software
83311  * distributed under the License is distributed on an "AS IS" BASIS,
83312  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
83313  * See the License for the specific language governing permissions and
83314  * limitations under the License.
83315  */
83316
83317 var db = require('ripple/db'),
83318     utils = require('ripple/utils'),
83319     t = require('ripple/platform/tizen/2.0/typecast'),
83320     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
83321     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
83322     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
83323     DataControlConsumerFactory,
83324     DataControlConsumerObject,
83325     SQLDataControlConsumer,
83326     MappedDataControlConsumer,
83327     SQLData,
83328     MappedData,
83329     _data = {
83330         DB_DATACONTROL_KEY: "tizen1-db-datacontrol",
83331         IDS_PROVIDER:       ["http://tizen.org/datacontrol/provider/DictionaryDataControlProvider"],
83332         IDS_DATA:           ["Dictionary"],
83333         PERSIST_DELAY:      1000,
83334         SQL:                null,
83335         MAP:                null,
83336         dbStorage:          null
83337     },
83338     _security = {
83339         "http://tizen.org/privilege/datacontrol.consumer":
83340             ["getDataControlConsumer", "insert", "update", "remove", "select",
83341             "addValue", "removeValue", "getValue", "updateValue"]
83342     },
83343     _self;
83344
83345 function _get() {
83346     _data.dbStorage = db.retrieveObject(_data.DB_DATACONTROL_KEY) || {};
83347 }
83348
83349 function _save() {
83350     db.saveObject(_data.DB_DATACONTROL_KEY, _data.dbStorage);
83351 }
83352
83353 function _load(type) {
83354     if (!_data.dbStorage[type])
83355         return;
83356
83357     _data[type] = {};
83358
83359     utils.forEach(_data.dbStorage[type], function (provider, id) {
83360         var dataId;
83361
83362         _data[type][id] = {};
83363
83364         for (dataId in provider) {
83365             _data[type][id][dataId] = new DataControlConsumerFactory(type,
83366                     id, dataId, provider[dataId]);
83367         }
83368     });
83369 }
83370
83371 function _initialize() {
83372     _get();
83373
83374     _load("SQL");
83375     _load("MAP");
83376 }
83377
83378 _self = function () {
83379     var datacontrol;
83380
83381     // private
83382     function initConsumer(type) {
83383         var providers;
83384
83385         _data.dbStorage[type] = {};
83386         providers = _data.dbStorage[type];
83387
83388         _data.IDS_PROVIDER.forEach(function (id) {
83389             providers[id] = {};
83390
83391             _data.IDS_DATA.forEach(function (dataId) {
83392                 providers[id][dataId] = {};
83393             });
83394         });
83395
83396         _load(type);
83397     }
83398
83399     // public
83400     function getDataControlConsumer(providerId, dataId, type) {
83401         if (!_security.getDataControlConsumer) {
83402             throw new WebAPIException(errorcode.SECURITY_ERR);
83403         }
83404
83405         t.DataControlManager("getDataControlConsumer", arguments);
83406
83407         if (_data[type] === null) {
83408             initConsumer(type);
83409         }
83410         if (!_data[type][providerId] || !_data[type][providerId][dataId]) {
83411             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
83412         }
83413
83414         return _data[type][providerId][dataId];
83415     }
83416
83417     function handleSubFeatures(subFeatures) {
83418         var i, subFeature;
83419
83420         for (subFeature in subFeatures) {
83421             for (i in _security[subFeature]) {
83422                 _security[_security[subFeature][i]] = true;
83423             }
83424         }
83425     }
83426
83427     datacontrol = {
83428         getDataControlConsumer: getDataControlConsumer,
83429         handleSubFeatures:      handleSubFeatures
83430     };
83431
83432     return datacontrol;
83433 };
83434
83435 DataControlConsumerObject = function (type, providerId, dataId) {
83436     this.__defineGetter__("type", function () {
83437         return type;
83438     });
83439
83440     this.__defineGetter__("providerId", function () {
83441         return providerId;
83442     });
83443
83444     this.__defineGetter__("dataId", function () {
83445         return dataId;
83446     });
83447 };
83448
83449 SQLDataControlConsumer = function (providerId, dataId, dc) {
83450     var self, privateData = new SQLData(dc);
83451
83452     // public
83453     function insert(reqId, insertionData, successCallback, errorCallback) {
83454         if (!_security.insert) {
83455             throw new WebAPIException(errorcode.SECURITY_ERR);
83456         }
83457
83458         t.SQLDataControlConsumer("insert", arguments, true);
83459
83460         privateData.insert(insertionData, function (rowId) {
83461             if (successCallback) {
83462                 successCallback(reqId, rowId);
83463             }
83464         }, function (error) {
83465             if (errorCallback) {
83466                 errorCallback(reqId, error);
83467             }
83468         });
83469     }
83470
83471     function update(reqId, updateData, where, successCallback, errorCallback) {
83472         if (!_security.update) {
83473             throw new WebAPIException(errorcode.SECURITY_ERR);
83474         }
83475
83476         t.SQLDataControlConsumer("update", arguments, true);
83477
83478         privateData.update(updateData, where, function () {
83479             if (successCallback) {
83480                 successCallback(reqId);
83481             }
83482         }, function (error) {
83483             if (errorCallback) {
83484                 errorCallback(reqId, error);
83485             }
83486         });
83487     }
83488
83489     function remove(reqId, where, successCallback, errorCallback) {
83490         if (!_security.remove) {
83491             throw new WebAPIException(errorcode.SECURITY_ERR);
83492         }
83493
83494         t.SQLDataControlConsumer("remove", arguments, true);
83495
83496         privateData.remove(where, function () {
83497             if (successCallback) {
83498                 successCallback(reqId);
83499             }
83500         }, function (error) {
83501             if (errorCallback) {
83502                 errorCallback(reqId, error);
83503             }
83504         });
83505     }
83506
83507     function select(reqId, columns, where, successCallback, errorCallback, page,
83508             maxNumberPerPage) {
83509         if (!_security.select) {
83510             throw new WebAPIException(errorcode.SECURITY_ERR);
83511         }
83512
83513         t.SQLDataControlConsumer("select", arguments, true);
83514
83515         privateData.select(columns, where, function (rows) {
83516             successCallback(rows, reqId);
83517         }, function (error) {
83518             if (errorCallback) {
83519                 errorCallback(reqId, error);
83520             }
83521         }, page, maxNumberPerPage);
83522     }
83523
83524     self = new DataControlConsumerObject("SQL", providerId, dataId);
83525
83526     self.insert = insert;
83527     self.update = update;
83528     self.remove = remove;
83529     self.select = select;
83530
83531     return self;
83532 };
83533
83534 MappedDataControlConsumer = function (providerId, dataId, dc) {
83535     var self, privateData = new MappedData(dc);
83536
83537     function addValue(reqId, key, value, successCallback, errorCallback) {
83538         if (!_security.addValue) {
83539             throw new WebAPIException(errorcode.SECURITY_ERR);
83540         }
83541
83542         t.MappedDataControlConsumer("addValue", arguments);
83543
83544         window.setTimeout(function () {
83545             if (privateData.insert(key, value)) {
83546                 if (successCallback) {
83547                     successCallback(reqId);
83548                 }
83549             } else if (errorCallback) {
83550                 errorCallback(reqId, new WebAPIError(errorcode.UNKNOWN_ERR));
83551             }
83552         }, 1);
83553     }
83554
83555     function removeValue(reqId, key, value, successCallback, errorCallback) {
83556         if (!_security.removeValue) {
83557             throw new WebAPIException(errorcode.SECURITY_ERR);
83558         }
83559
83560         t.MappedDataControlConsumer("removeValue", arguments);
83561
83562         window.setTimeout(function () {
83563             if (privateData.remove(key, value)) {
83564                 successCallback(reqId);
83565             } else if (errorCallback) {
83566                 errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR));
83567             }
83568         }, 1);
83569     }
83570
83571     function getValue(reqId, key, successCallback, errorCallback) {
83572         if (!_security.getValue) {
83573             throw new WebAPIException(errorcode.SECURITY_ERR);
83574         }
83575
83576         t.MappedDataControlConsumer("getValue", arguments);
83577
83578         window.setTimeout(function () {
83579             var values;
83580
83581             values = privateData.search(key);
83582
83583             if (values !== null) {
83584                 successCallback(values, reqId);
83585             } else if (errorCallback) {
83586                 errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR));
83587             }
83588         }, 1);
83589     }
83590
83591     function updateValue(reqId, key, oldValue, newValue, successCallback,
83592             errorCallback) {
83593         if (!_security.updateValue) {
83594             throw new WebAPIException(errorcode.SECURITY_ERR);
83595         }
83596
83597         t.MappedDataControlConsumer("updateValue", arguments);
83598
83599         window.setTimeout(function () {
83600             if (privateData.update(key, oldValue, newValue)) {
83601                 successCallback(reqId);
83602             } else if (errorCallback) {
83603                 errorCallback(reqId, new WebAPIError(errorcode.NOT_FOUND_ERR));
83604             }
83605         }, 1);
83606     }
83607
83608     self = new DataControlConsumerObject("MAP", providerId, dataId);
83609
83610     self.addValue    = addValue;
83611     self.removeValue = removeValue;
83612     self.getValue    = getValue;
83613     self.updateValue = updateValue;
83614
83615     return self;
83616 };
83617
83618 DataControlConsumerFactory = function (type, providerId, dataId, dc) {
83619     var self;
83620
83621     switch (type) {
83622     case "SQL":
83623         self = new SQLDataControlConsumer(providerId, dataId, dc);
83624         break;
83625
83626     case "MAP":
83627         self = new MappedDataControlConsumer(providerId, dataId, dc);
83628         break;
83629     }
83630
83631     return self;
83632 };
83633
83634 SQLData = function (dc) {
83635     var self, data, columnNames, SQLErr2WebAPIErr;
83636
83637     // private
83638     function getDBTableName() {
83639         return "DC_" + Math.uuid(8, 16);
83640     }
83641
83642     function getColumnNames(tx, results) {
83643         columnNames = results.rows.item(0).sql
83644                 .replace(/^[^\(]+\(([^\)]+)\)/g, "$1")
83645                 .replace(/(^|(,) )([^ ,]+)([^,]*|$)/g, "$2$3")
83646                 .split(",");
83647     }
83648
83649     function queryColumns(columns) {
83650         return columns.join("=?,") + "=?";
83651     }
83652
83653     function queryValues(n) {
83654         return (new Array(n)).join("?,") + "?";
83655     }
83656
83657     function shedQuotes(values) {
83658         return values.every(function (value, i, arr) {
83659             arr[i] = value.replace(/^('|")(.*)\1$/g, "$2");
83660
83661             return (arr[i] !== value);
83662         });
83663     }
83664
83665     function isNull(p) {
83666         return ((p === undefined) || (p === null));
83667     }
83668
83669     function initialize() {
83670         SQLErr2WebAPIErr = [
83671             0,      // 0: UNKNOWN_ERR         0: UNKNOWN_ERR
83672             100,    // 1: DATABASE_ERR      100: IO_ERR
83673             100,    // 2: VERSION_ERR       100: IO_ERR
83674             100,    // 3: TOO_LARGE_ERR     100: IO_ERR
83675             22,     // 4: QUOTA_ERR          22: QUOTA_EXCEEDED_ERR
83676             12,     // 5: SYNTAX_ERR         12: SYNTAX_ERR
83677             100,    // 6: CONSTRAINT_ERR    100: IO_ERR
83678             23      // 7: TIMEOUT_ERR        23: TIMEOUT_ERR
83679         ];
83680
83681         if (!("table" in dc)) {
83682             dc.table = getDBTableName();
83683             columnNames = ["id"];
83684             _save();
83685         }
83686
83687         data = openDatabase('tinyHippos', '1.0', 'tiny Hippos persistence',
83688                 2 * 1024 * 1024);
83689
83690         data.transaction(function (tx) {
83691             tx.executeSql('CREATE TABLE IF NOT EXISTS ' + dc.table +
83692                     ' (id unique)');
83693             tx.executeSql('SELECT sql FROM sqlite_master WHERE type="table" AND name=?',
83694                     [dc.table], getColumnNames);
83695         });
83696     }
83697
83698     // public
83699     function insert(rowData, onSuccess, onError) {
83700         if (rowData.columns.length > rowData.values.length) {
83701             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
83702         }
83703         if (!shedQuotes(rowData.values)) {
83704             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
83705         }
83706
83707         data.transaction(function (tx) {
83708             rowData.columns.forEach(function (column) {
83709                 if (columnNames.indexOf(column) !== -1)
83710                     return;
83711
83712                 tx.executeSql('ALTER TABLE ' + dc.table + ' ADD ' + column +
83713                         ' TEXT', [], function () {
83714                             columnNames.push(column);
83715                         }, function (tx, error) {
83716                             onError(new WebAPIError(
83717                                     SQLErr2WebAPIErr[error.code],
83718                                     error.message));
83719                         });
83720             });
83721
83722             tx.executeSql('INSERT INTO ' + dc.table + ' (' +
83723                     rowData.columns.join() + ') VALUES (' +
83724                     queryValues(rowData.values.length) + ')', rowData.values,
83725                     function (tx, results) {
83726                         onSuccess(results.insertId);
83727                     }, function (tx, error) {
83728                         onError(new WebAPIError(SQLErr2WebAPIErr[error.code],
83729                                 error.message));
83730                     });
83731         });
83732     }
83733
83734     function update(rowData, where, onSuccess, onError) {
83735         if (rowData.columns.length > rowData.values.length) {
83736             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
83737         }
83738         if (!shedQuotes(rowData.values)) {
83739             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
83740         }
83741
83742         data.transaction(function (tx) {
83743             tx.executeSql('UPDATE ' + dc.table + ' SET ' +
83744                     queryColumns(rowData.columns) + ' WHERE ' + where,
83745                     rowData.values, onSuccess, function (tx, error) {
83746                         onError(new WebAPIError(SQLErr2WebAPIErr[error.code],
83747                                 error.message));
83748                     });
83749         });
83750     }
83751
83752     function remove(where, onSuccess, onError) {
83753         data.transaction(function (tx) {
83754             tx.executeSql('DELETE FROM ' + dc.table + ' WHERE ' + where, [],
83755                     onSuccess, function (tx, error) {
83756                         onError(new WebAPIError(SQLErr2WebAPIErr[error.code],
83757                                 error.message));
83758                     });
83759         });
83760     }
83761
83762     function select(columns, where, onSuccess, onError, page, maxNumberPerPage) {
83763         if (isNull(page)) {
83764             page = 1;
83765         } else {
83766             if (page <= 0) {
83767                 throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
83768             }
83769             page = parseInt(page, 10);
83770         }
83771
83772         if (isNull(maxNumberPerPage)) {
83773             if (page > 1) {
83774                 throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
83775             }
83776         } else {
83777             if (maxNumberPerPage <= 0) {
83778                 throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
83779             }
83780             maxNumberPerPage = parseInt(maxNumberPerPage, 10);
83781         }
83782
83783         data.transaction(function (tx) {
83784             tx.executeSql('SELECT ' + columns.join() + ' FROM ' + dc.table +
83785                     ' WHERE ' + where, [], function (tx, results) {
83786                         var rows = [], rowStart, rowData, r, c;
83787
83788                         rowStart = maxNumberPerPage ?
83789                             (page - 1) * maxNumberPerPage : 0;
83790
83791                         for (r = rowStart; r < results.rows.length; ++r) {
83792                             rowData = {
83793                                 columns: columns,
83794                                 values: []
83795                             };
83796                             for (c in columns) {
83797                                 rowData.values.push(results.rows
83798                                     .item(r)[columns[c]]);
83799                             }
83800                             rows.push(rowData);
83801
83802                             if (maxNumberPerPage && (--maxNumberPerPage === 0))
83803                                 break;
83804                         }
83805
83806                         onSuccess(rows);
83807                     }, function (tx, error) {
83808                         onError(new WebAPIError(SQLErr2WebAPIErr[error.code],
83809                                 error.message));
83810                     });
83811         });
83812     }
83813
83814     initialize();
83815
83816     self = {
83817         insert: insert,
83818         update: update,
83819         remove: remove,
83820         select: select
83821     };
83822
83823     return self;
83824 };
83825
83826 MappedData = function (dc) {
83827     var self, data = {}, ioStamp = 0;
83828
83829     // private
83830     function addNode(tree, arr, i) {
83831         var key, value;
83832
83833         if (typeof arr[i] === "string") {
83834             key = arr[i];
83835             value = 1;
83836         } else {
83837             key = arr[i][0];
83838             value = arr[i][1];
83839         }
83840         tree.insert(key, value);
83841     }
83842
83843     function bisearch(tree, arr, queue) {
83844         var start, end, mid;
83845
83846         if (queue.length === 0)
83847             return;
83848
83849         start = queue.shift();
83850         end = queue.shift();
83851
83852         if (start > end)
83853             return;
83854
83855         mid = start + parseInt((end - start) / 2, 10);
83856         addNode(tree, arr, mid);
83857         queue.push(start, mid - 1);
83858         queue.push(mid + 1, end);
83859     }
83860
83861     function build(arr) {
83862         var tree, mid, lTree = [], rTree = [];
83863
83864         tree = redblack.tree();
83865         mid = parseInt(arr.length / 2, 10);
83866         addNode(tree, arr, mid);
83867
83868         lTree.push(0, mid - 1);
83869         rTree.push(mid + 1, arr.length - 1);
83870
83871         while ((lTree.length > 0) || (rTree.length > 0)) {
83872             bisearch(tree, arr, lTree);
83873             bisearch(tree, arr, rTree);
83874         }
83875
83876         return tree;
83877     }
83878
83879     function initialize() {
83880         for (var key in dc) {
83881             data[key] = build(dc[key]);
83882         }
83883     }
83884
83885     function traverse(tree, key) {
83886         dc[key] = [];
83887         tree.forEach(function (count, value) {
83888             dc[key].push((count === 1) ? value : [value, count]);
83889         });
83890     }
83891
83892     function persist() {
83893         if (ioStamp !== 0) {
83894             window.clearTimeout(ioStamp);
83895         }
83896         ioStamp = window.setTimeout(function () {
83897             var key;
83898
83899             for (key in data) {
83900                 traverse(data[key], key);
83901             }
83902
83903             _save();
83904
83905             ioStamp = 0;
83906         }, _data.PERSIST_DELAY);
83907     }
83908
83909     // public
83910     function insert(key, value) {
83911         var tree, count;
83912
83913         if (!(key in data)) {
83914             data[key] = redblack.tree();
83915         }
83916
83917         tree = data[key];
83918
83919         if (!tree)
83920             return false;
83921
83922         count = tree.get(value);
83923         tree.insert(value, count ? (count + 1) : 1);
83924         persist();
83925
83926         return true;
83927     }
83928
83929     function remove(key, value) {
83930         var tree, count;
83931
83932         if (!(key in data))
83933             return false;
83934
83935         tree = data[key];
83936         count = tree.get(value);
83937         if (count === null)
83938             return false;
83939
83940         tree.delete(value);
83941
83942         if (tree.root === null) {
83943             delete data[key];
83944             if (key in dc) {
83945                 delete dc[key];
83946             }
83947         }
83948
83949         persist();
83950
83951         return true;
83952     }
83953
83954     function search(key) {
83955         var values = [], tree;
83956
83957         if (!(key in data))
83958             return null;
83959
83960         tree = data[key];
83961         tree.forEach(function (count, value) {
83962             while (count--) {
83963                 values.push(value);
83964             }
83965         });
83966
83967         return values;
83968     }
83969
83970     function update(key, oldValue, newValue) {
83971         var tree, count, countNew;
83972
83973         if (!(key in data))
83974             return false;
83975
83976         tree = data[key];
83977         count = tree.get(oldValue);
83978         if (count === null)
83979             return false;
83980
83981         countNew = tree.get(newValue);
83982         count += (countNew === null) ? 0 : countNew;
83983         tree.delete(oldValue);
83984         tree.insert(newValue, count);
83985         persist();
83986
83987         return true;
83988     }
83989
83990     initialize();
83991
83992     self = {
83993         insert: insert,
83994         remove: remove,
83995         search: search,
83996         update: update
83997     };
83998
83999     return self;
84000 };
84001
84002 _initialize();
84003
84004 module.exports = _self;
84005
84006 });
84007 define('ripple/platform/tizen/2.0/CalendarAlarm', function (require, exports, module) {
84008 /*
84009  *  Copyright 2013 Intel Corporation.
84010  *
84011  * Licensed under the Apache License, Version 2.0 (the "License");
84012  * you may not use this file except in compliance with the License.
84013  * You may obtain a copy of the License at
84014  *
84015  * http://www.apache.org/licenses/LICENSE-2.0
84016  *
84017  * Unless required by applicable law or agreed to in writing, software
84018  * distributed under the License is distributed on an "AS IS" BASIS,
84019  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84020  * See the License for the specific language governing permissions and
84021  * limitations under the License.
84022  */
84023
84024 var t = require('ripple/platform/tizen/2.0/typecast'),
84025     CalendarAlarm;
84026
84027 CalendarAlarm = function () {
84028     var voc, calendarAlarm = {};
84029
84030     // private
84031     function construct() {
84032         this.__defineGetter__("absoluteDate", function () {
84033             return calendarAlarm.absoluteDate;
84034         });
84035         this.__defineSetter__("absoluteDate", function (val) {
84036             try {
84037                 calendarAlarm.absoluteDate = t.TZDate(val, "?");
84038             } catch (e) {
84039             }
84040         });
84041
84042         this.__defineGetter__("before", function () {
84043             return calendarAlarm.before;
84044         });
84045         this.__defineSetter__("before", function (val) {
84046             try {
84047                 calendarAlarm.before = t.TimeDuration(val, "?");
84048             } catch (e) {
84049             }
84050         });
84051
84052         this.__defineGetter__("method", function () {
84053             return calendarAlarm.method;
84054         });
84055         this.__defineSetter__("method", function (val) {
84056             try {
84057                 calendarAlarm.method = t.AlarmMethod(val);
84058             } catch (e) {
84059             }
84060         });
84061
84062         this.__defineGetter__("description", function () {
84063             return calendarAlarm.description;
84064         });
84065         this.__defineSetter__("description", function (val) {
84066             try {
84067                 calendarAlarm.description = t.DOMString(val, "?");
84068             } catch (e) {
84069             }
84070         });
84071     }
84072
84073     // Constructor
84074     function CalendarAlarm_TZDate_AlarmMethod_DOMString(absoluteDate, method,
84075             description) {
84076         construct.call(this);
84077
84078         calendarAlarm.absoluteDate = absoluteDate;
84079         calendarAlarm.before       = null;
84080         calendarAlarm.method       = method;
84081         calendarAlarm.description  = description || "";
84082     }
84083
84084     function CalendarAlarm_TimeDuration_AlarmMethod_DOMString(before, method,
84085             description) {
84086         construct.call(this);
84087
84088         calendarAlarm.absoluteDate = null;
84089         calendarAlarm.before       = before;
84090         calendarAlarm.method       = method;
84091         calendarAlarm.description  = description || "";
84092     }
84093
84094     voc = [CalendarAlarm_TZDate_AlarmMethod_DOMString,
84095            CalendarAlarm_TimeDuration_AlarmMethod_DOMString];
84096     t.CalendarAlarm(arguments, this, voc);
84097 };
84098
84099 module.exports = CalendarAlarm;
84100
84101 });
84102 define('ripple/platform/tizen/2.0/TZDate', function (require, exports, module) {
84103 /*
84104  *  Copyright 2012 Intel Corporation.
84105  *
84106  * Licensed under the Apache License, Version 2.0 (the "License");
84107  * you may not use this file except in compliance with the License.
84108  * You may obtain a copy of the License at
84109  *
84110  * http://www.apache.org/licenses/LICENSE-2.0
84111  *
84112  * Unless required by applicable law or agreed to in writing, software
84113  * distributed under the License is distributed on an "AS IS" BASIS,
84114  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84115  * See the License for the specific language governing permissions and
84116  * limitations under the License.
84117  */
84118
84119 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
84120     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
84121     tz = require('ripple/platform/tizen/2.0/timezone_info'),
84122     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
84123     _Month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
84124     _Day = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
84125
84126 function TZDate (dt) {
84127     var d, UTCd, UTC_diff, tzid = "", target_diff, temp_date, localeTime_fmt = 'h:m:s', localeDate_fmt = 'D, d M y',
84128     time = require('ripple/platform/tizen/2.0/time'),
84129         hour = arguments[3] || 0, min = arguments[4] || 0,
84130         sec = arguments[5] || 0, msec = arguments[6] || 0,
84131
84132     _checkTZDate = function (dat) {
84133         var Tzdate = require('ripple/platform/tizen/2.0/TZDate'),
84134             i, tzd;
84135         if (typeof dat !== 'object' || dat === undefined || dat === null) {
84136             return false;
84137         }
84138         tzd = new Tzdate();
84139         for (i in tzd) {
84140             if (dat.hasOwnProperty(i) === false) {
84141                 return false;
84142             }
84143         }
84144         return true;
84145     },
84146     _d2UTCd_sync = function () {
84147         UTCd = new Date(d.valueOf() - (UTC_diff * 1000 * 60 * 60));
84148     },
84149     _UTCd2d_sync = function () {
84150         d = new Date(UTCd.valueOf() + (UTC_diff * 1000 * 60 * 60));
84151     },
84152     _getValue = function (o) {
84153         var other;
84154         other = new Date(o.getUTCFullYear(), o.getUTCMonth(), o.getUTCDate(),
84155                     o.getUTCHours(), o.getUTCMinutes(), o.getUTCSeconds(), o.getUTCMilliseconds());
84156         return other.valueOf();
84157     },
84158     _formatDateString = function (fmt) {
84159         var i, ret = '';
84160         for (i = 0; i < fmt.length; i++) {
84161             switch (fmt.charAt(i)) {
84162             case 'd':
84163                 ret = ret + d.getDate();
84164                 break;
84165             case 'y':
84166                 ret = ret + d.getFullYear();
84167                 break;
84168             case 'm':
84169                 ret = ret + (d.getMonth() + 1);
84170                 break;
84171             case 'M':
84172                 ret = ret + _Month[d.getMonth()];
84173                 break;
84174             case 'D':
84175                 ret = ret + _Day[d.getDay()];
84176                 break;
84177             default:
84178                 ret = ret + fmt.charAt(i);
84179             }
84180         }
84181         return ret;
84182     },
84183     _formatTimeString = function (fmt) {
84184         var i, hh, mm, ss, AP, ret = "";
84185         if (fmt.search(/ap/) === -1) {
84186             AP = false;
84187         } else {
84188             AP = true;
84189             if (d.getHours() > 11) {
84190                 fmt = fmt.replace("ap", "PM");
84191             } else {
84192                 fmt = fmt.replace("ap", "AM");
84193             }
84194         }
84195         for (i = 0; i < fmt.length; i++) {
84196             switch (fmt.charAt(i)) {
84197             case 'h':
84198                 hh = d.getHours();
84199                 if (AP) {
84200                     hh = (hh > 12) ? hh - 12 : hh;
84201                 }
84202                 ret = ret + hh;
84203                 break;
84204             case 'm':
84205                 mm = d.getMinutes();
84206                 mm = (mm < 10 ? "0" : "") + mm;
84207                 ret = ret + mm;
84208                 break;
84209             case 's':
84210                 ss = d.getSeconds();
84211                 ss = (ss < 10 ? "0" : "") + ss;
84212                 ret = ret + ss;
84213                 break;
84214             default:
84215                 ret = ret + fmt.charAt(i);
84216             }
84217         }
84218         return ret;
84219     };
84220
84221     if (arguments[7] !== undefined) {
84222         tzid = arguments[7];
84223     }
84224
84225     if (dt === null || dt === undefined) {
84226         temp_date = new Date();
84227         if (arguments[1] !== undefined) {
84228             if (typeof arguments[1] !== 'string') {
84229                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84230             }
84231             if (tz.isValidTimezone(arguments[1]) === false) {
84232                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84233             }
84234             tzid = arguments[1];
84235         } else {
84236             tzid = time.getLocalTimezone();
84237         }
84238         target_diff = tz.getTimezoneDiff(tzid);
84239         d = new Date(temp_date.valueOf() + (target_diff + temp_date.getTimezoneOffset() / 60) * 1000 * 60 * 60);
84240     } else {
84241         if (tizen1_utils.isValidDate(dt)) {
84242             d = new Date(dt);
84243             if (arguments[1] !== undefined) {
84244                 tzid = arguments[1];
84245             } else {
84246                 tzid = time.getLocalTimezone();
84247             }
84248         } else {
84249             if (arguments.length === 1) {
84250                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84251             } else {
84252                 d = new Date(arguments[0], arguments[1], arguments[2], hour, min, sec, msec);
84253             }
84254         }
84255     }
84256
84257     if (tz.isValidTimezone(tzid) === false) {
84258         tzid = 'UTC';
84259     }
84260     UTC_diff = tz.getTimezoneDiff(tzid);
84261     _d2UTCd_sync();
84262
84263     this.getDate = function () {
84264         return d.getDate();
84265     };
84266     this.setDate = function (dt) {
84267         d.setDate(dt);
84268         _d2UTCd_sync();
84269     };
84270     this.getDay = function () {
84271         return d.getDay();
84272     };
84273     this.getFullYear = function () {
84274         return d.getFullYear();
84275     };
84276     this.setFullYear = function (yr) {
84277         d.setFullYear(yr);
84278         _d2UTCd_sync();
84279     };
84280     this.getHours = function () {
84281         return d.getHours();
84282     };
84283     this.setHours = function (hr) {
84284         d.setHours(hr);
84285         _d2UTCd_sync();
84286     };
84287     this.getMilliseconds = function () {
84288         return d.getMilliseconds();
84289     };
84290     this.setMilliseconds = function (msec) {
84291         d.setMilliseconds(msec);
84292         _d2UTCd_sync();
84293     };
84294     this.getMinutes = function () {
84295         return d.getMinutes();
84296     };
84297     this.setMinutes = function (min) {
84298         d.setMinutes(min);
84299         _d2UTCd_sync();
84300     };
84301     this.getMonth = function () {
84302         return d.getMonth();
84303     };
84304     this.setMonth = function (m) {
84305         d.setMonth(m);
84306         _d2UTCd_sync();
84307     };
84308     this.getSeconds = function () {
84309         return d.getSeconds();
84310     };
84311     this.setSeconds = function (s) {
84312         d.setSeconds(s);
84313         _d2UTCd_sync();
84314     };
84315     this.getUTCDate = function () {
84316         return UTCd.getDate();
84317     };
84318     this.setUTCDate = function (dt) {
84319         UTCd.setDate(dt);
84320         _UTCd2d_sync();
84321     };
84322     this.getUTCDay = function () {
84323         return UTCd.getDay();
84324     };
84325     this.getUTCFullYear = function () {
84326         return UTCd.getFullYear();
84327     };
84328     this.setUTCFullYear = function (yr) {
84329         UTCd.setFullYear(yr);
84330         _UTCd2d_sync();
84331     };
84332     this.getUTCHours = function () {
84333         return UTCd.getHours();
84334     };
84335     this.setUTCHours = function (hr) {
84336         UTCd.setHours(hr);
84337         _UTCd2d_sync();
84338     };
84339     this.getUTCMilliseconds = function () {
84340         return UTCd.getMilliseconds();
84341     };
84342     this.setUTCMilliseconds = function (msec) {
84343         UTCd.setMilliseconds(msec);
84344         _UTCd2d_sync();
84345     };
84346     this.getUTCMinutes = function () {
84347         return UTCd.getMinutes();
84348     };
84349     this.setUTCMinutes = function (min) {
84350         UTCd.setMinutes(min);
84351         _UTCd2d_sync();
84352     };
84353     this.getUTCMonth = function () {
84354         return UTCd.getMonth();
84355     };
84356     this.setUTCMonth = function (m) {
84357         UTCd.setMonth(m);
84358         _UTCd2d_sync();
84359     };
84360     this.getUTCSeconds = function () {
84361         return UTCd.getSeconds();
84362     };
84363     this.setUTCSeconds = function (s) {
84364         UTCd.setSeconds(s);
84365         _UTCd2d_sync();
84366     };
84367     this.getTimezone = function () {
84368         return tzid;
84369     };
84370     this.toTimezone = function (new_tzid) {
84371         var diff,
84372             Tzdate = require('ripple/platform/tizen/2.0/TZDate');
84373         if (tz.isValidTimezone(String(new_tzid)) === true) {
84374             diff = tz.getTimezoneDiff(new_tzid) - UTC_diff;
84375             return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), new_tzid);
84376         } else {
84377             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
84378         }
84379     };
84380     this.toLocalTimezone = function () {
84381         var diff,
84382             localTzid,
84383             Tzdate = require('ripple/platform/tizen/2.0/TZDate');
84384         localTzid = time.getLocalTimezone();
84385
84386         diff = tz.getTimezoneDiff(localTzid) - UTC_diff;
84387         return new Tzdate(new Date(d.valueOf() + (diff * 1000 * 60 * 60)), localTzid);
84388     };
84389     this.toUTC = function () {
84390         var Tzdate = require('ripple/platform/tizen/2.0/TZDate');
84391         return new Tzdate(UTCd, "UTC");
84392     };
84393     this.difference = function (other) {
84394         var diff,
84395             TDur = require('ripple/platform/tizen/2.0/TimeDuration');
84396         if (_checkTZDate(other) === false) {
84397             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84398         }
84399         diff = (UTCd.valueOf() - _getValue(other));
84400         if (diff % 86400000 === 0) {
84401             return new TDur(diff/86400000, 'DAYS');
84402         } else {
84403             return new TDur(diff);
84404         }
84405     };
84406     this.equalsTo = function (other) {
84407         if (_checkTZDate(other) === false) {
84408             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84409         }
84410         return (UTCd.valueOf() === _getValue(other));
84411     };
84412     this.earlierThan = function (other) {
84413         if (_checkTZDate(other) === false) {
84414             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84415         }
84416         return (UTCd.valueOf() < _getValue(other));
84417     };
84418     this.laterThan = function (other) {
84419         if (_checkTZDate(other) === false) {
84420             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84421         }
84422         return (UTCd.valueOf() > _getValue(other));
84423     };
84424     this.addDuration = function (dur) {
84425         var Tzdate = require('ripple/platform/tizen/2.0/TZDate'),
84426             Tunit = {"MSECS": 1,
84427                 "SECS": 1000,
84428                 "MINS": 60 * 1000,
84429                 "HOURS": 60 * 60 * 1000,
84430                 "DAYS": 24 * 60 * 60 * 1000
84431             };
84432         if (typeof dur !== 'object' || dur === undefined || dur === null) {
84433             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84434         }
84435         if (dur.length === undefined || dur.length === null ||
84436                 dur.unit === undefined || dur.unit === null) {
84437             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84438         }
84439         if ((typeof dur.length) !== 'number') {
84440             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84441         }
84442         if (Tunit[dur.unit] === undefined) {
84443             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
84444         }
84445         return new Tzdate(new Date(d.valueOf() + (parseInt(dur.length, 10) * Tunit[dur.unit])), tzid);
84446     };
84447     this.toLocaleDateString = function () {
84448         if (d.toString() === "Invalid Date") {
84449             return d.toString();
84450         } else {
84451             return _formatDateString(localeDate_fmt);
84452         }
84453     };
84454     this.toLocaleTimeString = function () {
84455         if (d.toString() === "Invalid Date") {
84456             return d.toString();
84457         } else {
84458             return _formatTimeString(localeTime_fmt);
84459         }
84460     };
84461     this.toLocaleString = function () {
84462         if (d.toString() === "Invalid Date") {
84463             return d.toString();
84464         } else {
84465             return (this.toLocaleDateString() + " " + this.toLocaleTimeString());
84466         }
84467     };
84468     this.toDateString = function () {
84469         var ret = "", fmt = time.getDateFormat();
84470         if (d.toString() === "Invalid Date") {
84471             return d.toString();
84472         }
84473         ret = _formatDateString(fmt);
84474         return ret;
84475     };
84476     this.toTimeString = function () {
84477         var ret, fmt = time.getTimeFormat();
84478
84479         if (d.toString() === "Invalid Date") {
84480             return d.toString();
84481         }
84482
84483         ret = _formatTimeString(fmt);
84484         if (tz.getTimezoneDesc(tzid) !== null) {
84485             return ret + " " + tz.getTimezoneDesc(tzid);
84486         } else {
84487             return ret + " " + tz.getTimezoneAbbr(tzid);
84488         }
84489         return ret;
84490     };
84491     this.toString = function () {
84492         if (d.toString() === "Invalid Date") {
84493             return d.toString();
84494         } else {
84495             return (this.toDateString() + " " + this.toTimeString());
84496         }
84497     };
84498     this.getTimezoneAbbreviation = function () {
84499         return tz.getTimezoneAbbr(tzid);
84500     };
84501     this.secondsFromUTC = function () {
84502         return (-1 * UTC_diff * 60 * 60);
84503     };
84504     this.isDST = function () {
84505         throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR));
84506     };
84507     this.getPreviousDSTTransition = function () {
84508         throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR));
84509     };
84510     this.getNextDSTTransition = function () {
84511         throw (new WebAPIException(errorcode.NOT_SUPPORTED_ERR));
84512     };
84513     return this;
84514 }
84515
84516 module.exports = TZDate;
84517
84518 });
84519 define('ripple/platform/tizen/2.0/NotificationBase', function (require, exports, module) {
84520 /*
84521  *  Copyright 2013 Intel Corporation.
84522  *
84523  * Licensed under the Apache License, Version 2.0 (the "License");
84524  * you may not use this file except in compliance with the License.
84525  * You may obtain a copy of the License at
84526  *
84527  * http://www.apache.org/licenses/LICENSE-2.0
84528  *
84529  * Unless required by applicable law or agreed to in writing, software
84530  * distributed under the License is distributed on an "AS IS" BASIS,
84531  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84532  * See the License for the specific language governing permissions and
84533  * limitations under the License.
84534  */
84535
84536 var t = require('ripple/platform/tizen/2.0/typecast'),
84537     Notification;
84538
84539 Notification = function (title, content) {
84540     var notification = {};
84541
84542     notification.title = title;
84543     notification.content = content || null;
84544
84545     this.__defineGetter__("id", function () {
84546         return undefined;
84547     });
84548
84549     this.__defineGetter__("type", function () {
84550         return "STATUS";
84551     });
84552
84553     this.__defineGetter__("postedTime", function () {
84554         return undefined;
84555     });
84556
84557     this.__defineGetter__("title", function () {
84558         return notification.title;
84559     });
84560     this.__defineSetter__("title", function (val) {
84561         try {
84562             notification.title = t.DOMString(val);
84563         } catch (e) {
84564         }
84565     });
84566
84567     this.__defineGetter__("content", function () {
84568         return notification.content;
84569     });
84570     this.__defineSetter__("content", function (val) {
84571         try {
84572             notification.content = t.DOMString(val, "?");
84573         } catch (e) {
84574         }
84575     });
84576 };
84577
84578 module.exports = Notification;
84579
84580 });
84581 define('ripple/platform/tizen/2.0/spec', function (require, exports, module) {
84582 /*
84583  *  Copyright 2012 Intel Corporation.
84584  *
84585  * Licensed under the Apache License, Version 2.0 (the "License");
84586  * you may not use this file except in compliance with the License.
84587  * You may obtain a copy of the License at
84588  *
84589  * http://www.apache.org/licenses/LICENSE-2.0
84590  *
84591  * Unless required by applicable law or agreed to in writing, software
84592  * distributed under the License is distributed on an "AS IS" BASIS,
84593  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84594  * See the License for the specific language governing permissions and
84595  * limitations under the License.
84596  */
84597
84598 module.exports = {
84599
84600     id: "tizen",
84601     version: "2.2",
84602     name: "TIZEN",
84603
84604     persistencePrefix: "tizen1-",
84605
84606     config: require('ripple/platform/tizen/2.0/spec/config'),
84607     ui: require('ripple/platform/tizen/2.0/spec/ui'),
84608     device: require('ripple/platform/tizen/2.0/spec/device'),
84609     sensor: require('ripple/platform/tizen/2.0/spec/sensor'),
84610     DeviceMotionEvent: require('ripple/platform/tizen/2.0/DeviceMotionEvent'),
84611     DeviceOrientationEvent: require('ripple/platform/tizen/2.0/DeviceOrientationEvent'),
84612
84613     objects: {
84614         Coordinates: {
84615             path: "w3c/1.0/Coordinates"
84616         },
84617         Position: {
84618             path: "w3c/1.0/Position"
84619         },
84620         PositionError: {
84621             path: "w3c/1.0/PositionError"
84622         },
84623         SensorConnection: {
84624             path: "w3c/1.0/SensorConnection"
84625         },
84626         navigator: {
84627             path: "tizen/2.0/navigator",
84628             children: {
84629                 geolocation: {
84630                     path: "wac/2.0/geolocation"
84631                 },
84632                 battery: {
84633                     path: "tizen/2.0/battery"
84634                 }
84635             }
84636         },
84637         tizen: {
84638             feature: "http://tizen.org/privilege/tizen",
84639             children: {
84640                 AlarmAbsolute: {
84641                     path: "tizen/2.0/AlarmAbsolute"
84642                 },
84643                 AlarmRelative: {
84644                     path: "tizen/2.0/AlarmRelative"
84645                 },
84646                 ApplicationControl: {
84647                     path: "tizen/2.0/ApplicationControl"
84648                 },
84649                 ApplicationControlData: {
84650                     path: "tizen/2.0/ApplicationControlData"
84651                 },
84652                 AttributeFilter: {
84653                     path: "tizen/2.0/AttributeFilter"
84654                 },
84655                 AttributeRangeFilter: {
84656                     path: "tizen/2.0/AttributeRangeFilter"
84657                 },
84658                 BookmarkFolder: {
84659                     path: "tizen/2.0/BookmarkFolder"
84660                 },
84661                 BookmarkItem: {
84662                     path: "tizen/2.0/BookmarkItem"
84663                 },
84664                 CalendarAlarm: {
84665                     path: "tizen/2.0/CalendarAlarm"
84666                 },
84667                 CalendarAttendee: {
84668                     path: "tizen/2.0/CalendarAttendee"
84669                 },
84670                 CalendarEvent: {
84671                     path: "tizen/2.0/CalendarEvent"
84672                 },
84673                 CalendarEventId: {
84674                     path: "tizen/2.0/CalendarEventId"
84675                 },
84676                 CalendarRecurrenceRule: {
84677                     path: "tizen/2.0/CalendarRecurrenceRule"
84678                 },
84679                 CalendarTask: {
84680                     path: "tizen/2.0/CalendarTask"
84681                 },
84682                 CompositeFilter: {
84683                     path: "tizen/2.0/CompositeFilter"
84684                 },
84685                 Contact: {
84686                     path: "tizen/2.0/ContactBase"
84687                 },
84688                 ContactAddress: {
84689                     path: "tizen/2.0/ContactAddress"
84690                 },
84691                 ContactAnniversary: {
84692                     path: "tizen/2.0/ContactAnniversary"
84693                 },
84694                 ContactEmailAddress: {
84695                     path: "tizen/2.0/ContactEmailAddress"
84696                 },
84697                 ContactGroup: {
84698                     path: "tizen/2.0/ContactGroup"
84699                 },
84700                 ContactName: {
84701                     path: "tizen/2.0/ContactName"
84702                 },
84703                 ContactOrganization: {
84704                     path: "tizen/2.0/ContactOrganization"
84705                 },
84706                 ContactPhoneNumber: {
84707                     path: "tizen/2.0/ContactPhoneNumber"
84708                 },
84709                 ContactRef: {
84710                     path: "tizen/2.0/ContactRef"
84711                 },
84712                 ContactWebSite: {
84713                     path: "tizen/2.0/ContactWebSite"
84714                 },
84715                 DownloadRequest: {
84716                     path: "tizen/2.0/DownloadRequest"
84717                 },
84718                 Message: {
84719                     path: "tizen/2.0/Message"
84720                 },
84721                 NDEFMessage: {
84722                     path: "tizen/2.0/NDEFMessage"
84723                 },
84724                 NDEFRecord: {
84725                     path: "tizen/2.0/NDEFRecord"
84726                 },
84727                 NDEFRecordMedia: {
84728                     path: "tizen/2.0/NDEFRecordMedia"
84729                 },
84730                 NDEFRecordText: {
84731                     path: "tizen/2.0/NDEFRecordText"
84732                 },
84733                 NDEFRecordURI: {
84734                     path: "tizen/2.0/NDEFRecordURI"
84735                 },
84736                 NotificationDetailInfo: {
84737                     path: "tizen/2.0/NotificationDetailInfo"
84738                 },
84739                 SimpleCoordinates: {
84740                     path: "tizen/2.0/SimpleCoordinates"
84741                 },
84742                 SortMode: {
84743                     path: "tizen/2.0/SortMode"
84744                 },
84745                 StatusNotification: {
84746                     path: "tizen/2.0/StatusNotification"
84747                 },
84748                 SyncInfo: {
84749                     path: "tizen/2.0/SyncInfo"
84750                 },
84751                 SyncServiceInfo: {
84752                     path: "tizen/2.0/SyncServiceInfo"
84753                 },
84754                 SyncProfileInfo: {
84755                     path: "tizen/2.0/SyncProfileInfo"
84756                 },
84757                 TZDate: {
84758                     path: "tizen/2.0/TZDate"
84759                 },
84760                 TimeDuration: {
84761                     path: "tizen/2.0/TimeDuration"
84762                 },
84763                 alarm: {
84764                     path: "tizen/2.0/alarm",
84765                     feature: "http://tizen.org/privilege/alarm",
84766                     handleSubfeatures: true
84767                 },
84768                 application: {
84769                     path: "tizen/2.0/application",
84770                     feature: "http://tizen.org/privilege/application.launch|http://tizen.org/privilege/appmanager.kill|http://tizen.org/privilege/appmanager.certificate",
84771                     handleSubfeatures: true
84772                 },
84773                 bluetooth: {
84774                     path: "tizen/2.0/bluetooth",
84775                     feature: "http://tizen.org/privilege/bluetoothmanager|http://tizen.org/privilege/bluetooth.admin|http://tizen.org/privilege/bluetooth.gap|http://tizen.org/privilege/bluetooth.spp",
84776                     handleSubfeatures: true
84777                 },
84778                 bookmark: {
84779                     path: "tizen/2.0/bookmark",
84780                     feature: "http://tizen.org/privilege/bookmark.read|http://tizen.org/privilege/bookmark.write",
84781                     handleSubfeatures: true
84782                 },
84783                 callhistory: {
84784                     path: "tizen/2.0/callHistory",
84785                     feature: "http://tizen.org/privilege/callhistory|http://tizen.org/privilege/callhistory.read|http://tizen.org/privilege/callhistory.write",
84786                     handleSubfeatures: true
84787                 },
84788                 calendar: {
84789                     path: "tizen/2.0/calendar",
84790                     feature: "http://tizen.org/privilege/calendar.read|http://tizen.org/privilege/calendar.write",
84791                     handleSubfeatures: true
84792                 },
84793                 contact: {
84794                     path: "tizen/2.0/contact",
84795                     feature: "http://tizen.org/privilege/contact.read|http://tizen.org/privilege/contact.write",
84796                     handleSubfeatures: true
84797                 },
84798                 content: {
84799                     path: "tizen/2.0/content",
84800                     feature: "http://tizen.org/privilege/content.read|http://tizen.org/privilege/content.write",
84801                     handleSubfeatures: true
84802                 },
84803                 datacontrol: {
84804                     path: "tizen/2.0/datacontrol",
84805                     feature: "http://tizen.org/privilege/datacontrol.consumer",
84806                     handleSubfeatures: true
84807                 },
84808                 datasync: {
84809                     path: "tizen/2.0/datasync",
84810                     feature: "http://tizen.org/privilege/datasync",
84811                     handleSubfeatures: true
84812                 },
84813                 download: {
84814                     path: "tizen/2.0/download",
84815                     feature: "http://tizen.org/privilege/download",
84816                     handleSubfeatures: true
84817                 },
84818                 filesystem: {
84819                     path: "tizen/2.0/filesystem",
84820                     feature: "http://tizen.org/privilege/filesystem.read|http://tizen.org/privilege/filesystem.write"
84821                 },
84822                 messageport: {
84823                     path: "tizen/2.0/messageport"
84824                 },
84825                 messaging: {
84826                     path: "tizen/2.0/messaging",
84827                     feature: "http://tizen.org/privilege/messaging.send|http://tizen.org/privilege/messaging.read|http://tizen.org/privilege/messaging.write",
84828                     handleSubfeatures: true
84829                 },
84830                 networkbearerselection: {
84831                     path: "tizen/2.0/networkbearerselection",
84832                     feature: "http://tizen.org/privilege/networkbearerselection",
84833                     handleSubfeatures: true
84834                 },
84835                 nfc: {
84836                     path: "tizen/2.0/nfc",
84837                     feature: "http://tizen.org/privilege/nfc.common|http://tizen.org/privilege/nfc.admin|http://tizen.org/privilege/nfc.tag|http://tizen.org/privilege/nfc.p2p",
84838                     handleSubfeatures: true
84839                 },
84840                 notification: {
84841                     path: "tizen/2.0/notification",
84842                     feature: "http://tizen.org/privilege/notification",
84843                     handleSubfeatures: true
84844                 },
84845                 package: {
84846                     path: "tizen/2.0/package",
84847                     feature: "http://tizen.org/privilege/packagemanager.install|http://tizen.org/privilege/package.info",
84848                     handleSubfeatures: true
84849                 },
84850                 power: {
84851                     path: "tizen/2.0/power",
84852                     feature: "http://tizen.org/privilege/power",
84853                     handleSubfeatures: true
84854                 },
84855                 push: {
84856                     path: "tizen/2.0/push",
84857                     feature: "http://tizen.org/privilege/push",
84858                     handleSubfeatures: true
84859                 },
84860                 seService: {
84861                     path: "tizen/2.0/secureelement",
84862                     feature: "http://tizen.org/privilege/secureelement",
84863                     handleSubfeatures: true
84864                 },
84865                 systeminfo: {
84866                     path: "tizen/2.0/systeminfo",
84867                     feature: "http://tizen.org/privilege/system|http://tizen.org/privilege/systemmanager",
84868                     handleSubfeatures: true
84869                 },
84870                 systemsetting: {
84871                     path: "tizen/2.0/systemsetting",
84872                     feature: "http://tizen.org/privilege/setting",
84873                     handleSubfeatures: true
84874                 },
84875                 time: {
84876                     path: "tizen/2.0/time",
84877                     feature: "http://tizen.org/privilege/time",
84878                     handleSubfeatures: true
84879                 },
84880                 websetting: {
84881                     path: "tizen/2.0/websetting",
84882                     feature: "http://tizen.org/privilege/websetting",
84883                     handleSubfeatures: true
84884                 }
84885             }
84886         }
84887     }
84888 };
84889
84890 });
84891 define('ripple/platform/tizen/2.0/routeBackend_local', function (require, exports, module) {
84892 /*
84893  *  Copyright 2012 Intel Corporation.
84894  *
84895  * Licensed under the Apache License, Version 2.0 (the "License");
84896  * you may not use this file except in compliance with the License.
84897  * You may obtain a copy of the License at
84898  *
84899  * http://www.apache.org/licenses/LICENSE-2.0
84900  *
84901  * Unless required by applicable law or agreed to in writing, software
84902  * distributed under the License is distributed on an "AS IS" BASIS,
84903  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
84904  * See the License for the specific language governing permissions and
84905  * limitations under the License.
84906  */
84907
84908 var db = require('ripple/db'),
84909     utils = require('ripple/utils'),
84910     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
84911     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
84912     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
84913     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
84914     lbs = require('ripple/platform/tizen/2.0/lbs'),
84915     LocationServiceProvider = {},
84916     RouteWaypoint,
84917     RouteDistance,
84918     RouteDuration,
84919     RouteStep,
84920     RouteSegment,
84921     RouteRequestOptions,
84922     RouteResultSummary,
84923     RouteResult,
84924     _data = {
84925         DB_ROUTE_LOCATION_KEY: "tizen1-db-route",
84926         DB_ROUTE_COLLEAGE_KEY: "tizen2-db-route",
84927         routeProvider: {},
84928         routes: [],
84929         RouteDistanceUnit: ["M", "KM", "MI", "FT"],
84930         providers: [],
84931         path: []
84932     },
84933     _self;
84934
84935 // The RouteWaypoint object
84936 RouteWaypoint = function () {
84937     return {
84938         position: {
84939             latitude: 0,
84940             longitude: 0
84941         },
84942         isStopover: true
84943     };
84944 };
84945
84946 // The RouteDistance object
84947 RouteDistance = function () {
84948     return {
84949         text: "",
84950         value: 0,
84951         unit: "KM"
84952     };
84953 };
84954
84955 // The RouteDuration object
84956 RouteDuration = function () {
84957     return {
84958         text: "",
84959         value: 0 // The duration in a seconds
84960     };
84961 };
84962
84963 // The RouteStep object
84964 RouteStep = function () {
84965     var _self = {
84966         mode: "",        // The way of the travel, for example: car, bike, foot
84967         instruction: "", // The instruction of this step
84968         points: []       // The points of this step
84969     };
84970
84971     _self.origin      = new SimpleCoordinates(0, 0);
84972     _self.destination = new SimpleCoordinates(0, 0);
84973     _self.distance    = new RouteDistance();
84974     _self.duration    = new RouteDuration();
84975
84976     return _self;
84977 };
84978
84979 // The RouteSegment object
84980 RouteSegment = function () {
84981     var _self = {
84982         steps: []
84983     };
84984
84985     _self.origin      = new SimpleCoordinates(0, 0);
84986     _self.destination = new SimpleCoordinates(0, 0);
84987     _self.distance    = new RouteDistance();
84988     _self.duration    = new RouteDuration();
84989
84990     return _self;
84991 };
84992
84993 // The RouteRequestOptions object
84994 RouteRequestOptions = function () {
84995     return {
84996         mode: "", // CAR, BIKE
84997         unit: "KM",
84998         routeGoal: "SHORTEST",
84999         constraints: ["HIGHWAY", "TOLL", "UNPAVED"],
85000         wayPoints: [],
85001         maxResults: 1
85002     };
85003 };
85004
85005 // The RouteResultSummary object
85006 RouteResultSummary = function () {
85007     var _self = {};
85008
85009     _self.origin        = new SimpleCoordinates(0, 0);
85010     _self.destination   = new SimpleCoordinates(0, 0);
85011     _self.totalDistance = new RouteDistance();
85012     _self.totalDuration = new RouteDuration();
85013
85014     return _self;
85015 };
85016
85017 // The RouteResult object
85018 RouteResult = function () {
85019     var _self = {
85020         segments: []
85021     };
85022
85023     _self.summary = new RouteResultSummary();
85024
85025     return _self;
85026 };
85027
85028 // Floyd arithmetic in Mathematics, solving the optimal way
85029 function floyd(e, n, startIndex, endIndex) {
85030     var MAX = Infinity,
85031         a = new Array(n), i, j, k, p = new Array(n),
85032         paths, pathWay = [];
85033
85034     for (i = 1; i < n + 1; i++) {
85035         a[i] = new Array(n);
85036     }
85037     for (i = 1; i < n + 1; i++) {
85038         p[i] = new Array(n);
85039     }
85040     for (i = 1; i < n + 1; i++) {
85041         for (j = 1; j < n + 1; j++) {
85042             if (i === j || e[i][j] === "MIN") {
85043                 a[i][j] = 0;
85044             } else if (e[i][j] !== 0 && e[i][j] !== "MIN") {
85045                 a[i][j] = e[i][j];
85046             } else {
85047                 a[i][j] = MAX;
85048             }
85049             p[i][j] = 0;
85050         }
85051     }
85052     for (i = 1; i < n + 1; i++) {
85053         a[i][i] = 0;
85054     }
85055     for (k = 1; k < n + 1; k++) {
85056         for (i = 1; i < n + 1; i++) {
85057             for (j = 1; j < n + 1; j++) {
85058                 if (parseInt(a[i][k], 10) + parseInt(a[k][j], 10) < a[i][j]) {
85059                     a[i][j] = parseInt(a[i][k], 10) + parseInt(a[k][j], 10);
85060                     p[i][j] = k;
85061                 }
85062             }
85063         }
85064     }
85065     _data.path = [];
85066     paths = findPath(startIndex, endIndex, p);
85067     pathWay = [];
85068     pathWay.push(startIndex);
85069     for (i = 0; i < paths.length; i++) {
85070         pathWay.push(paths[i]);
85071     }
85072     pathWay.push(endIndex);
85073
85074     return pathWay;
85075 }
85076
85077 // Find the best way in the locations
85078 function findPath(i, j, p) {
85079     var k = p[i][j];
85080
85081     if (k === 0 || i === j) {
85082         return _data.path;
85083     }
85084     findPath(i, k, p);
85085     _data.path.push(k);
85086
85087     return findPath(k, j, p);
85088 }
85089
85090 // Find the index in the locations by string
85091 function findIndexByStr(str, locations) {
85092     for (var i in locations) {
85093         if (locations[i].name === str) {
85094             return parseInt(i, 10) + 1;
85095         }
85096     }
85097     return -1;
85098 }
85099
85100 // Find the index in the colleages by name1 and name2
85101 function findValueByStr(start, end, locations, colleages) {
85102     for (var i in colleages) {
85103         if (colleages[i].name1 === locations[start - 1].name && colleages[i].name2 === locations[end - 1].name) {
85104             return parseInt(i, 10);
85105         } else if (colleages[i].name2 === locations[start - 1].name && colleages[i].name1 === locations[end - 1].name) {
85106             return parseInt(i, 10);
85107         }
85108     }
85109     return -1;
85110 }
85111
85112 // Find the index in the locations by latitude and longitude
85113 function searchIndexBycoodinates(latitude, longitude, locations) {
85114     if (latitude !== null && longitude !== null) {
85115         for (var i in locations) {
85116             if (locations[i].latitude === latitude && locations[i].longitude === longitude) {
85117                 return parseInt(i, 10) + 1;
85118             }
85119         }
85120     }
85121     return -1;
85122 }
85123
85124 // Get the relation among the locations
85125 function getRelation(n, colleages, locations, goal) {
85126     var i, j, start, end, relation = new Array(n + 1);
85127     for (i = 1; i < n + 2; i++) {
85128         relation[i] = new Array(n + 1);
85129     }
85130     for (i = 1; i < n + 1; i++) {
85131         for (j = 1; j < n + 1; j++) {
85132             relation[i][j] = 0;
85133         }
85134     }
85135     for (i in colleages) {
85136         start = findIndexByStr(colleages[i].name1, locations);
85137         end = findIndexByStr(colleages[i].name2, locations);
85138         if (start !== -1 && end !== -1 && start !== end) {
85139             switch (goal) {
85140             case "distance":
85141                 relation[start][end] = colleages[i].distance;
85142                 relation[end][start] = colleages[i].distance;
85143                 break;
85144
85145             case "duration":
85146                 relation[start][end] = colleages[i].duration;
85147                 relation[end][start] = colleages[i].duration;
85148                 break;
85149
85150             case "simple":
85151                 relation[start][end] = 1;
85152                 relation[end][start] = 1;
85153                 break;
85154
85155             case "scenic":
85156                 if (colleages[i].addition.scenic === "SCENIC") {
85157                     relation[start][end] = 1;
85158                     relation[start][end] = 1;
85159                 } else if (colleages[i].addition.scenic === "") {
85160                     relation[start][end] = "MIN";
85161                     relation[start][end] = "MIN";
85162                 }
85163                 break;
85164
85165             case "cheap":
85166                 if (colleages[i].addition.toll === "TOLL") {
85167                     relation[start][end] = 1;
85168                     relation[end][start] = 1;
85169                 } else if (colleages[i].addition.toll === "") {
85170                     relation[start][end] = "MIN";
85171                     relation[start][end] = "MIN";
85172                 }
85173                 break;
85174
85175             case "safe":
85176                 if (colleages[i].addition.hazardous === "HAZARDOUS") {
85177                     relation[start][end] = 1;
85178                     relation[end][start] = 1;
85179                 } else if (colleages[i].addition.hazardous === "") {
85180                     relation[start][end] = "MIN";
85181                     relation[end][start] = "MIN";
85182                 }
85183                 break;
85184
85185             default:
85186                 return null;
85187             }
85188         }
85189     }
85190
85191     return relation;
85192 }
85193
85194 // Get the distance relationship among the locations
85195 function distanceRelation(n, colleages, locations) {
85196     return getRelation(n, colleages, locations, "distance");
85197 }
85198
85199 // Get the duration relationship among the locations
85200 function durationRelation(n, colleages, locations) {
85201     return getRelation(n, colleages, locations, "duration");
85202 }
85203
85204 // Get the simple relationship among the locations
85205 function simpleRelation(n, colleages, locations) {
85206     return getRelation(n, colleages, locations, "simple");
85207 }
85208
85209 // Get the cheap relationship among the locations
85210 function cheapRelation(n, colleages, locations) {
85211     return getRelation(n, colleages, locations, "cheap");
85212 }
85213
85214 // Get the safe relationship among the locations
85215 function safeRelation(n, colleages, locations) {
85216     return getRelation(n, colleages, locations, "safe");
85217 }
85218
85219 // Get the scenic relationship among the locations
85220 function scenicRelation(n, colleages, locations) {
85221     return getRelation(n, colleages, locations, "scenic");
85222 }
85223
85224 // Get the shortest way by origin, destination, locations and colleages
85225 function optimalWay(origin, destination, locations, colleages, relation) {
85226     var n = locations.length, i, steps = [], step, relations, routeLocations,
85227         originIndex, destinationIndex, startIndex, endIndex, colleageIndex,
85228         originLatitude, originLongitude, destinationLatitude, destinationLongitude,
85229         startLatitude, startLongitude, endLatitude, endLongitude,
85230         originLocation, destinationLocation, segment, result;
85231
85232     originLatitude = origin.latitude;
85233     originLongitude = origin.longitude;
85234     originIndex = searchIndexBycoodinates(originLatitude, originLongitude, locations);
85235
85236     destinationLatitude = destination.latitude;
85237     destinationLongitude = destination.longitude;
85238     destinationIndex = searchIndexBycoodinates(destinationLatitude, destinationLongitude, locations);
85239
85240     relations = relation(n, colleages, locations);
85241
85242     if (originIndex !== -1 && destinationIndex !== -1) {
85243         routeLocations = floyd(relations, n, parseInt(originIndex, 10), parseInt(destinationIndex, 10));
85244
85245         for (i = 0; i < routeLocations.length - 1; i++) {
85246             colleageIndex = findValueByStr(routeLocations[i], routeLocations[i + 1], locations, colleages);
85247
85248             if (colleageIndex !== -1) {
85249                 step = new RouteStep();
85250                 startIndex = parseInt(routeLocations[i], 10) - 1;
85251                 endIndex = parseInt(routeLocations[i + 1], 10) - 1;
85252
85253                 startLatitude = locations[startIndex].latitude;
85254                 startLongitude = locations[startIndex].longitude;
85255                 originLocation = new SimpleCoordinates(startLatitude, startLongitude);
85256
85257                 endLatitude = locations[endIndex].latitude;
85258                 endLongitude = locations[endIndex].longitude;
85259                 destinationLocation = new SimpleCoordinates(endLatitude, endLongitude);
85260
85261                 step.origin = originLocation;
85262                 step.destination = destinationLocation;
85263                 step.distance = colleages[colleageIndex].distance;
85264                 step.duration = colleages[colleageIndex].duration;
85265                 step.mode = colleages[colleageIndex].mode;
85266                 step.addition = colleages[colleageIndex].addition;
85267
85268                 steps.push(step);
85269             } else if (colleageIndex === -1) {
85270                 return null;
85271             }
85272         }
85273
85274         segment = new RouteSegment();
85275         segment.steps = steps;
85276         result = new RouteResult();
85277         result.segments[0] = segment;
85278
85279         return result;
85280     }
85281     return null;
85282 }
85283
85284 // Get the shortest way by origin, destination, locations and colleages
85285 function shortestWay(origin, destination, locations, colleages) {
85286     return optimalWay(origin, destination, locations, colleages, distanceRelation);
85287 }
85288
85289 // Get the fastest way by origin, destination, locations and colleages
85290 function fastestWay(origin, destination, locations, colleages) {
85291     return optimalWay(origin, destination, locations, colleages, durationRelation);
85292 }
85293
85294 // Get the simplest way by origin, destination, locations and colleages
85295 function simplestWay(origin, destination, locations, colleages) {
85296     return optimalWay(origin, destination, locations, colleages, simpleRelation);
85297 }
85298
85299 // Get the most scenic way by origin, destination, locations and colleages
85300 function mostScenicWay(origin, destination, locations, colleages) {
85301     return optimalWay(origin, destination, locations, colleages, scenicRelation);
85302 }
85303
85304 // Get the cheapest way by origin, destination, locations and colleages
85305 function cheapestWay(origin, destination, locations, colleages) {
85306     return optimalWay(origin, destination, locations, colleages, cheapRelation);
85307 }
85308
85309 // Get the safest way by origin, destination, locations and colleages
85310 function safestWay(origin, destination, locations, colleages) {
85311     return optimalWay(origin, destination, locations, colleages, safeRelation);
85312 }
85313
85314 // Uniquelize the array
85315 function uniquelize(array) {
85316     var temp = {}, result = [], i;
85317     for (i = array.length; i--;) {
85318         temp[array[i]] = array[i];
85319     }
85320     for (i in temp) {
85321         result.push(temp[i]);
85322     }
85323     return result;
85324 }
85325
85326 // Is it intersect between the Array a and b
85327 function intersect(a, b) {
85328     var i, j;
85329
85330     a = uniquelize(a);
85331     if (a.length === 0 && b.length === 0) {
85332         return true;
85333     }
85334     for (i in a) {
85335         for (j in b) {
85336             if (a[i] === b[j])
85337                 return true;
85338         }
85339     }
85340     return false;
85341 }
85342
85343 function getConstrains(result) {
85344     var steps = result.segments[0].steps, constrains = [];
85345
85346     utils.forEach(steps, function (item, index) {
85347         if (item.addition.highway === "HIGHWAY") {
85348             constrains.push("HIGHWAY");
85349         }
85350         if (item.addition.toll === "TOLL") {
85351             constrains.push("TOLL");
85352         }
85353         if (item.addition.bridge === "BRIDGE") {
85354             constrains.push("BRIDGE");
85355         }
85356         if (item.addition.hazardous === "HAZARDOUS") {
85357             constrains.push("HAZARDOUS");
85358         }
85359         if (item.addition.scenic === "SCENIC") {
85360             constrains.push("SCENIC");
85361         }
85362     });
85363     if (constrains.length > 0) {
85364         return uniquelize(constrains);
85365     }
85366     return constrains;
85367 }
85368
85369 module.exports = function (prop) {
85370     var _self = new lbs.LocationServiceProvider(prop);
85371     _self.find = function (origin, destination, successCallback, errorCallback, options) {
85372         function _find() {
85373             var locations, colleages, i, result = {}, emptyResult = [], modes = [], resultModes = [], constrains = [], resultconstrains = [];
85374
85375             locations = db.retrieveObject(_data.DB_ROUTE_LOCATION_KEY);
85376             colleages = db.retrieveObject(_data.DB_ROUTE_COLLEAGE_KEY);
85377
85378             modes = options.modes;
85379             constrains = options.constrains;
85380             if (locations.length > 0 && colleages.length > 0) {
85381                 switch (options.routeGoal) {
85382                 case "SHORTEST":
85383                     result = shortestWay(origin, destination, locations, colleages);
85384                     break;
85385
85386                 case "FASTEST":
85387                     result = fastestWay(origin, destination, locations, colleages);
85388                     break;
85389
85390                 case "SIMPLEST":
85391                     result = simplestWay(origin, destination, locations, colleages);
85392                     break;
85393
85394                 case "MOST_SCENIC":
85395                     result = mostScenicWay(origin, destination, locations, colleages);
85396                     break;
85397
85398                 case "CHEAPEST":
85399                     result = cheapestWay(origin, destination, locations, colleages);
85400                     break;
85401
85402                 case "SAFEST":
85403                     result = safestWay(origin, destination, locations, colleages);
85404                     break;
85405
85406                 default:
85407                     result = shortestWay(origin, destination, locations, colleages);
85408                     break;
85409                 }
85410                 if (result !== null) {
85411                     for (i in result.segments[0].steps) {
85412                         resultModes.push(result.segments[0].steps[i].mode);
85413                     }
85414                     resultconstrains = getConstrains(result);
85415                     if (intersect(resultModes, modes) && intersect(resultconstrains, constrains)) {
85416                         successCallback(result);
85417                     } else {
85418                         successCallback(null);
85419                     }
85420                 }
85421             } else {
85422                 successCallback(emptyResult);
85423             }
85424         }
85425         tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
85426     };
85427     return _self;
85428 };
85429
85430 });
85431 define('ripple/platform/tizen/2.0/ReverseGeocodeOptions', function (require, exports, module) {
85432 /*      
85433  *  Copyright 2012 Intel Corporation.
85434  *  
85435  * Licensed under the Apache License, Version 2.0 (the "License");
85436  * you may not use this file except in compliance with the License.
85437  * You may obtain a copy of the License at
85438  *  
85439  * http://www.apache.org/licenses/LICENSE-2.0
85440  *  
85441  * Unless required by applicable law or agreed to in writing, software
85442  * distributed under the License is distributed on an "AS IS" BASIS,
85443  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85444  * See the License for the specific language governing permissions and
85445  * limitations under the License.
85446  */
85447 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
85448     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
85449     SortMode = require('ripple/platform/tizen/2.0/SortMode');
85450
85451 module.exports = function (_sortMode, _resultType, _maxResults) {
85452     var _self;
85453     if (_sortMode !== null && _sortMode !== undefined) {
85454         if (typeof _sortMode !== "object") {
85455             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
85456         }
85457         try {
85458             new SortMode(_sortMode.attributeName, _sortMode.order);
85459         } catch (e) {
85460             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
85461         }
85462     }
85463     if (_resultType !== null && _resultType !== undefined) {
85464         if (_resultType !== "FORMATTED" && _resultType !== "STRUCTURED") {
85465             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
85466         }
85467     }
85468     if (_maxResults !== null && _maxResults !== undefined) {
85469         if (typeof _maxResults !== "number") {
85470             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
85471         }
85472     }
85473     _self = {
85474         sortMode : _sortMode,
85475         resultType : _resultType || "FORMATTED",
85476         maxResults : _maxResults || 0
85477     };
85478
85479     return _self;
85480 };
85481
85482
85483 });
85484 define('ripple/platform/tizen/2.0/BookmarkFolder', function (require, exports, module) {
85485 /*
85486  *  Copyright 2013 Intel Corporation.
85487  *
85488  * Licensed under the Apache License, Version 2.0 (the "License");
85489  * you may not use this file except in compliance with the License.
85490  * You may obtain a copy of the License at
85491  *
85492  * http://www.apache.org/licenses/LICENSE-2.0
85493  *
85494  * Unless required by applicable law or agreed to in writing, software
85495  * distributed under the License is distributed on an "AS IS" BASIS,
85496  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85497  * See the License for the specific language governing permissions and
85498  * limitations under the License.
85499  */
85500
85501 var t = require('ripple/platform/tizen/2.0/typecast'),
85502     BookmarkFolder;
85503
85504 BookmarkFolder = function (title) {
85505     t.BookmarkFolder(arguments, this);
85506
85507     this.__defineGetter__("parent", function () {
85508         return undefined;
85509     });
85510
85511     this.__defineGetter__("title", function () {
85512         return title;
85513     });
85514 };
85515
85516 module.exports = BookmarkFolder;
85517
85518 });
85519 define('ripple/platform/tizen/2.0/dbinit', function (require, exports, module) {
85520 /*
85521  *  Copyright 2013 Intel Corporation.
85522  *
85523  * Licensed under the Apache License, Version 2.0 (the "License");
85524  * you may not use this file except in compliance with the License.
85525  * You may obtain a copy of the License at
85526  *
85527  * http://www.apache.org/licenses/LICENSE-2.0
85528  *
85529  * Unless required by applicable law or agreed to in writing, software
85530  * distributed under the License is distributed on an "AS IS" BASIS,
85531  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85532  * See the License for the specific language governing permissions and
85533  * limitations under the License.
85534  */
85535
85536 var utils = require('ripple/utils'),
85537     exception = require('ripple/exception'),
85538     dbfs = require('ripple/platform/tizen/2.0/dbfs'),
85539     filesystem = require('ripple/platform/tizen/2.0/filesystem'),
85540     DBBuilder,
85541     Content,
85542     FileSystem,
85543     _data = {
85544         dbBuilder: null
85545     },
85546     _self = {};
85547
85548 function _initialize() {
85549     _data.dbBuilder = new DBBuilder();
85550
85551     _data.dbBuilder.register("FileSystem", "", FileSystem);
85552     _data.dbBuilder.register("Content", "dbcontent.xml", Content);
85553     _data.dbBuilder.register("Package", "dbpackage.xml");
85554     _data.dbBuilder.register("Application", "dbapplication.xml");
85555     _data.dbBuilder.register("Bluetooth", "dbbluetooth.xml");
85556     _data.dbBuilder.register("MessagePort", "dbmessageport.json");
85557
85558     _data.FileSystem.initdb();
85559 }
85560
85561 DBBuilder = function () {
85562     var self;
85563
85564     // private
85565     function formatString(str) {
85566         return str.replace(/^\s+|[\t\n\r\v]+|\s+$/g, "").replace(/\s+/g, " ");
85567     }
85568
85569     function getType(node) {
85570         var type, reNum, reHexNum, reDate;
85571
85572         if (node.childNodes) {
85573             return (node.childNodes[0].nodeName === "i") ? "Array" : "Object";
85574         }
85575
85576         // Special case
85577         if (node.nodeName === "version") {
85578             return "DOMString";
85579         }
85580
85581         reNum = /^(-?\d+)(\.\d+)?$/;
85582         reHexNum = /^0[Xx][0-9A-Fa-f]+$/;
85583         reDate = /^(\d{4})\-(\d{2})\-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/;
85584
85585         if (reNum.test(node.textContent)) {
85586             type = "Number";
85587         } else if (reHexNum.test(node.textContent)) {
85588             type = "Number";
85589         } else if (reDate.test(node.textContent)) {
85590             type = "Date";
85591         } else if (node.textContent === "true" || node.textContent === "false") {
85592             type = "Boolean";
85593         } else {
85594             type = "DOMString";
85595         }
85596
85597         return type;
85598     }
85599
85600     function build(node) {
85601         var i, value;
85602
85603         switch (getType(node)) {
85604         case "Boolean":
85605             value = (formatString(node.textContent) === "true");
85606             break;
85607
85608         case "Date":
85609             value = new Date(formatString(node.textContent));
85610             break;
85611
85612         case "Number":
85613             value = Number(formatString(node.textContent));
85614             break;
85615
85616         case "Object":
85617             value = {};
85618             for (i in node.childNodes) {
85619                 value[node.childNodes[i].nodeName] = build(node.childNodes[i]);
85620             }
85621             break;
85622
85623         case "Array":
85624             value = [];
85625             for (i in node.childNodes) {
85626                 value.push(build(node.childNodes[i]));
85627             }
85628             break;
85629
85630         default:  // "DOMString"
85631             value = formatString(node.textContent);
85632             break;
85633         }
85634
85635         return value;
85636     }
85637
85638     function parse(obj) {
85639         var i, res = {};
85640
85641         res.nodeName = ("name" in obj.attributes) ?
85642                 obj.attributes["name"].value : obj.nodeName;
85643
85644         if (obj.childElementCount === 0) {
85645             res.textContent = obj.textContent;
85646         } else {
85647             res.childNodes = [];
85648
85649             for (i in obj.childNodes) {
85650                 if (obj.childNodes[i].attributes) {
85651                     res.childNodes.push(parse(obj.childNodes[i]));
85652                 }
85653             }
85654         }
85655
85656         return res;
85657     }
85658
85659     // public
85660     function register(type, dbXml, Extension) {
85661         _data[type] = Extension ? new Extension() : {};
85662
85663         if (!dbXml)
85664             return;
85665
85666         _self.__defineGetter__(type, function () {
85667             var fnInit;
85668
85669             if (!_data[type].db) {
85670                 fnInit = _data[type].initdb || initdb;
85671                 _data[type].db = fnInit(dbXml);
85672             }
85673
85674             return _data[type].db;
85675         });
85676     }
85677
85678     function initdb(dbXml) {
85679         var db = {}, xmlHttp, res;
85680
85681         try {
85682             xmlHttp = new XMLHttpRequest();
85683             xmlHttp.open("GET", "dbsamples/" + dbXml, false);
85684             xmlHttp.send();
85685         } catch (e) {
85686             exception.handle(e);
85687         }
85688
85689         if (/^(.+)\.json$/.test(dbXml)) {
85690             if (!xmlHttp.responseText) {
85691                 return null;
85692             }
85693
85694             db = JSON.parse(formatString(xmlHttp.responseText));
85695         } else {
85696             if (!xmlHttp.responseXML) {
85697                 return null;
85698             }
85699
85700             res = parse(xmlHttp.responseXML.documentElement);
85701             res.childNodes.forEach(function (node) {
85702                 db[node.nodeName] = build(node);
85703             });
85704         }
85705
85706         return db;
85707     }
85708
85709     self = {
85710         register: register,
85711         initdb:   initdb
85712     };
85713
85714     return self;
85715 };
85716
85717 /*
85718  * FileSystem
85719  */
85720
85721 FileSystem = function () {
85722     var self;
85723
85724     // private
85725     function createPath(path) {
85726         var parts = path.replace(/^\//, "").split("/"),
85727             workflow = jWorkflow.order();
85728
85729         parts.forEach(function (part, index) {
85730             var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/");
85731
85732             workflow.andThen(function (prev, baton) {
85733                 baton.take();
85734                 dbfs.mkdir(dir, baton.pass, baton.pass);
85735             });
85736         });
85737
85738         workflow.start();
85739     }
85740
85741     // public
85742     function initdb() {
85743         filesystem.resolve("images", function () {});
85744         filesystem.resolve("videos", function () {});
85745         filesystem.resolve("music", function () {});
85746     }
85747
85748     function createFile(uri) {
85749         var directoryURI;
85750
85751         directoryURI = uri.slice(0, uri.lastIndexOf("/") + 1)
85752                 .replace(/file:\/\//, "");
85753
85754         dbfs.stat(directoryURI, function () {}, function () {
85755             createPath(directoryURI);
85756         });
85757
85758         uri = uri.replace(/file:\/\//, "");
85759         dbfs.touch(uri, function () {});
85760     }
85761
85762     self = {
85763         initdb: initdb,
85764         createFile: createFile
85765     };
85766
85767     return self;
85768 };
85769
85770 /*
85771  * Content
85772  */
85773
85774 Content = function () {
85775     var self, ContentStorage;
85776
85777     ContentStorage = function (contents, directories) {
85778         var i, parentURI;
85779
85780         for (i in directories) {
85781             directories[i].contents = {};
85782             this[directories[i].directoryURI] = directories[i];
85783         }
85784
85785         for (i in contents) {
85786             parentURI = contents[i].contentURI.slice(0,
85787                     contents[i].contentURI.lastIndexOf("/") + 1)
85788                     .replace(/file:\/\//, "");
85789
85790             if (parentURI in this) {
85791                 this[parentURI].contents[contents[i].contentURI] = contents[i];
85792             }
85793         }
85794     };
85795
85796     // public
85797     function initdb(dbXml) {
85798         var i, db;
85799
85800         db = _data.dbBuilder.initdb(dbXml);
85801
85802         if (!db)
85803             return null;
85804
85805         for (i in db.contents) {
85806             _data.FileSystem.createFile(db.contents[i].contentURI);
85807         }
85808
85809         return new ContentStorage(db.contents, db.directories);
85810     }
85811
85812     self = {
85813         initdb: initdb
85814     };
85815
85816     return self;
85817 };
85818
85819 _initialize();
85820
85821 module.exports = _self;
85822
85823 });
85824 define('ripple/platform/tizen/2.0/pendingoperation', function (require, exports, module) {
85825 /*
85826  *  Copyright 2011 Intel Corporation.
85827  *
85828  * Licensed under the Apache License, Version 2.0 (the "License");
85829  * you may not use this file except in compliance with the License.
85830  * You may obtain a copy of the License at
85831  *
85832  * http://www.apache.org/licenses/LICENSE-2.0
85833  *
85834  * Unless required by applicable law or agreed to in writing, software
85835  * distributed under the License is distributed on an "AS IS" BASIS,
85836  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85837  * See the License for the specific language governing permissions and
85838  * limitations under the License.
85839  */
85840
85841 module.exports = function (pendingObj) {
85842     var pending = true;
85843     this.cancel = function () {
85844         if (pending === true) {
85845             if (typeof (pendingObj.getCancelFlag) === "function" && pendingObj.getCancelFlag() === false) {
85846                 pending = false;
85847                 // this clearTimeout is for the case when a 3rd party is invoked to do the task, and it's finished sooner than the intended timeout. therefore, the 3rd party set CancelFlag false, and this cancel is called before timeout
85848                 clearTimeout(pendingObj.pendingID);
85849                 return false;
85850             }
85851             if (typeof (pendingObj.userCancel) === "function") {
85852                 pendingObj.userCancel();
85853             }
85854             clearTimeout(pendingObj.pendingID);
85855             pending = false;
85856             return true;
85857         } else {
85858             return false;
85859         }
85860     };
85861 };
85862
85863
85864 });
85865 define('ripple/platform/tizen/2.0/navigator', function (require, exports, module) {
85866 /*
85867  *  Copyright 2011 Research In Motion Limited.
85868  *  Copyright 2012 Intel Corporation.
85869  *
85870  * Licensed under the Apache License, Version 2.0 (the "License");
85871  * you may not use this file except in compliance with the License.
85872  * You may obtain a copy of the License at
85873  *
85874  * http://www.apache.org/licenses/LICENSE-2.0
85875  *
85876  * Unless required by applicable law or agreed to in writing, software
85877  * distributed under the License is distributed on an "AS IS" BASIS,
85878  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85879  * See the License for the specific language governing permissions and
85880  * limitations under the License.
85881  */
85882 var _original = window.navigator,
85883     utils = require('ripple/utils'),
85884     devices = require('ripple/devices'),
85885     constants = require('ripple/constants'),
85886     vibration = require('ripple/platform/tizen/2.0/vibration'),
85887     _self = {};
85888
85889 (function () {
85890     var key,
85891         nav = window.navigator;
85892
85893     function _handle(obj, key) {
85894         return typeof obj[key] !== "function" ? obj[key] : function () {
85895             return obj[key].apply(obj, Array.prototype.slice.call(arguments));
85896         };
85897     }
85898
85899     for (key in nav) {
85900         _self[key] = _handle(nav, key);
85901     }
85902 }());
85903
85904 _self.__defineGetter__('userAgent', function () {
85905     var currentUserAgent = devices.getCurrentDevice().userAgent;
85906
85907     return currentUserAgent === constants.COMMON.USER_AGENT_DEFAULT ?
85908         _original.userAgent : currentUserAgent;
85909 });
85910
85911 _self.__defineGetter__('vibrate', function () {
85912     return vibration.vibrate;
85913 });
85914
85915 module.exports = _self;
85916
85917 });
85918 define('ripple/platform/tizen/2.0/BluetoothDevice', function (require, exports, module) {
85919 /*
85920  *  Copyright 2013 Intel Corporation.
85921  *
85922  * Licensed under the Apache License, Version 2.0 (the "License");
85923  * you may not use this file except in compliance with the License.
85924  * You may obtain a copy of the License at
85925  *
85926  * http://www.apache.org/licenses/LICENSE-2.0
85927  *
85928  * Unless required by applicable law or agreed to in writing, software
85929  * distributed under the License is distributed on an "AS IS" BASIS,
85930  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
85931  * See the License for the specific language governing permissions and
85932  * limitations under the License.
85933  */
85934
85935 var utils = require('ripple/utils'),
85936     event = require('ripple/event'),
85937     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
85938     t = require('ripple/platform/tizen/2.0/typecast'),
85939     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
85940     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
85941     BluetoothClass = require('ripple/platform/tizen/2.0/BluetoothClass'),
85942     BluetoothSocket = require('ripple/platform/tizen/2.0/BluetoothSocket'),
85943     BluetoothDevice,
85944     _security;
85945
85946 BluetoothDevice = function (prop) {
85947     var bluetoothDevice = {}, sockets = {}, self;
85948
85949     bluetoothDevice.name        = prop.name || "";
85950     bluetoothDevice.address     = prop.address || "";
85951     bluetoothDevice.deviceClass = new BluetoothClass(prop.deviceClass,
85952             prop.metaData) || {};
85953     bluetoothDevice.isBonded    = prop.isBonded || false;
85954     bluetoothDevice.isTrusted   = prop.isTrusted || false;
85955     bluetoothDevice.isConnected = prop.isConnected || false;
85956     bluetoothDevice.services    = prop.services;
85957     bluetoothDevice.uuids       = [];
85958
85959     this.__defineGetter__("name", function () {
85960         return bluetoothDevice.name;
85961     });
85962
85963     this.__defineGetter__("address", function () {
85964         return bluetoothDevice.address;
85965     });
85966
85967     this.__defineGetter__("deviceClass", function () {
85968         return bluetoothDevice.deviceClass;
85969     });
85970
85971     this.__defineGetter__("isBonded", function () {
85972         return bluetoothDevice.isBonded;
85973     });
85974
85975     this.__defineGetter__("isTrusted", function () {
85976         return bluetoothDevice.isTrusted;
85977     });
85978
85979     this.__defineGetter__("isConnected", function () {
85980         return bluetoothDevice.isConnected;
85981     });
85982
85983     this.__defineGetter__("uuids", function () {
85984         return bluetoothDevice.uuids;
85985     });
85986
85987     this.connectToServiceByUUID = function (uuid, successCallback,
85988             errorCallback) {
85989         if (!_security.all && !_security.connectToServiceByUUID) {
85990             throw new WebAPIException(errorcode.SECURITY_ERR);
85991         }
85992
85993         t.BluetoothDevice("connectToServiceByUUID", arguments);
85994
85995         window.setTimeout(function () {
85996             if (bluetoothDevice.uuids.join(",").indexOf(uuid) === -1) {
85997                 if (errorCallback) {
85998                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
85999                 }
86000                 return;
86001             }
86002
86003             bluetoothDevice.isConnected = true;
86004             event.trigger("bt-device-connected-changed", [bluetoothDevice.address,
86005                     true]);
86006             event.trigger("bt-service-state-changed", [bluetoothDevice.address,
86007                     uuid, true]);
86008
86009             window.setTimeout(function () {
86010                 successCallback(sockets[uuid]);
86011             }, 1);
86012         }, 1);
86013     };
86014
86015     event.on("bt-device-connected-update", function (addr, isConnected) {
86016         if (addr !== bluetoothDevice.address)
86017             return;
86018
86019         bluetoothDevice.isConnected = isConnected;
86020         event.trigger("bt-device-connected-changed",
86021                 [bluetoothDevice.address, bluetoothDevice.isConnected]);
86022     });
86023
86024     event.on("bt-device-bonded-changed", function (addr, isBonded) {
86025         if (addr !== bluetoothDevice.address)
86026             return;
86027
86028         bluetoothDevice.isBonded = isBonded;
86029     });
86030
86031     _security = prop.metaData;
86032     self = this;
86033
86034     utils.forEach(bluetoothDevice.services, function (service) {
86035         bluetoothDevice.uuids.push(service.uuid);
86036         sockets[service.uuid] = new BluetoothSocket({
86037             uuid: service.uuid,
86038             protocol: service.protocol,
86039             state: "CLOSED",
86040             peer: self,
86041             metaData: _security
86042         });
86043     });
86044 };
86045
86046 module.exports = BluetoothDevice;
86047
86048 });
86049 define('ripple/platform/tizen/2.0/dbfs', function (require, exports, module) {
86050 /*
86051  *  Copyright 2011 Research In Motion Limited.
86052  *  Copyright 2012 Intel Corporation.
86053  *
86054  * Licensed under the Apache License, Version 2.0 (the "License");
86055  * you may not use this file except in compliance with the License.
86056  * You may obtain a copy of the License at
86057  *
86058  * http://www.apache.org/licenses/LICENSE-2.0
86059  *
86060  * Unless required by applicable law or agreed to in writing, software
86061  * distributed under the License is distributed on an "AS IS" BASIS,
86062  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86063  * See the License for the specific language governing permissions and
86064  * limitations under the License.
86065  */
86066
86067 var db = require('ripple/db'),
86068     utils = require('ripple/utils'),
86069     _console = require('ripple/console'),
86070     _cache = {},
86071     _self;
86072
86073 function _get(path) {
86074     return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
86075         return token === "" ? obj : ((obj && obj.children) ? obj.children[token] || null : null);
86076     }, _cache);
86077 }
86078
86079 function _getInfo(path) {
86080     var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
86081         name = parent.splice(parent.length - 1, 1).join("");
86082
86083     return {
86084         name: name,
86085         parent: parent.join("/") || "/"
86086     };
86087 }
86088
86089 function _set(path, obj) {
86090     var parent = _cache,
86091         tokens = path.replace(/^\//, '').split("/"),
86092         child = tokens.splice(tokens.length - 1, 1).join("");
86093
86094     tokens.forEach(function (token) {
86095         parent = parent.children[token];
86096     });
86097
86098     parent.children = parent.children || {};
86099     parent.children[child] = obj;
86100 }
86101
86102 function _delete(path) {
86103     var parent = _cache,
86104         tokens = path.replace(/^\//, '').split("/"),
86105         child = tokens.splice(tokens.length - 1, 1).join("");
86106
86107     tokens.forEach(function (token) {
86108         parent = parent.children[token];
86109     });
86110
86111     delete parent.children[child];
86112 }
86113
86114 function _save() {
86115     db.saveObject("tizen1-db-filesystem", _cache);
86116 }
86117
86118 function _walk(path, parent) {
86119     _self.ls(path, function (entries) {
86120         parent.children = parent.children || {};
86121
86122         entries.forEach(function (entry) {
86123             parent.children[entry.name] = entry;
86124
86125             if (entry.isDirectory) {
86126                 _walk(entry.fullPath, entry);
86127             } else {
86128                 /* after getting Date out of DB, Date will become
86129                    a string, so need to recast it back to Date */
86130                 if (entry.lastModifiedDate !== null && entry.lastModifiedDate !== undefined)
86131                     entry.lastModifiedDate = new Date(entry.lastModifiedDate);
86132                 if (entry.createdDate !== null && entry.createdDate !== undefined)
86133                     entry.createdDate = new Date(entry.createdDate);
86134
86135                 _self.read(entry.fullPath, function (data) {
86136                     parent.children[entry.name].data = data;
86137                 }, function (e) {
86138                     _console.error(e);
86139                 });
86140             }
86141         });
86142     }, function (e) {
86143         _console.error(e);
86144     });
86145 }
86146
86147 function _createPath(path) {
86148     var parts = path.replace(/^\//, '').split("/"),
86149         workflow = jWorkflow.order();
86150
86151     parts.forEach(function (part, index) {
86152         var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/");
86153
86154         workflow.andThen(function (prev, baton) {
86155             baton.take();
86156             _self.mkdir(dir, baton.pass, baton.pass);
86157         });
86158     });
86159
86160     workflow.start();
86161 }
86162
86163 _self = {
86164     // The order is consistent with _virtualRoots in filesystem.js
86165     roots: ["/opt/documents", "/opt/images", "/opt/music", "/opt/videos", "/opt/downloads", "/home/user/appdata/simulatedapp/wgt-package", "/home/user/appdata/simulatedapp/wgt-private", "/home/user/appdata/simulatedapp/wgt-private-tmp", "/SDCard", "/opt/attachments"],
86166     initialize: function () {
86167         // TODO: Initialize at bootstrap and emulatorBridge.link
86168         _cache = db.retrieveObject("tizen1-db-filesystem") || {};
86169         // create real root paths if empty
86170         _self.roots.every(function (root) {
86171             _createPath(root);
86172             return true;
86173         });
86174         // build the file system cache so that we could access information synchronously
86175         _walk("/", _cache);
86176     },
86177     ls: function (path, success, error) {
86178         try {
86179             var dir = _get(path),
86180                 items = [];
86181
86182             if (dir) {
86183                 utils.forEach(dir.children, function (item) {
86184                     items.push(item);
86185                 });
86186             }
86187             else {
86188                 items = {};
86189             }
86190
86191             success(items);
86192         }
86193         catch (e) {
86194             e.code = 1;
86195             error(e);
86196         }
86197     },
86198     rm: function (path, success, error, options) {
86199         _delete(path);
86200         _save();
86201         success();
86202     },
86203     rmdir: function (path, success, error, options) {
86204         _delete(path);
86205         _save();
86206         success();
86207     },
86208     mkdir: function (path, success, error) {
86209         var entry = _get(path),
86210             info = _getInfo(path);
86211
86212         if (!entry) {
86213             _set(path, {
86214                 lastModifiedDate: new Date(),
86215                 createdDate: new Date(),
86216                 name: info.name,
86217                 isDirectory: true,
86218                 fullPath: path
86219             });
86220             entry = _get(path);
86221             _save();
86222         }
86223
86224         if (entry) {
86225             success(entry);
86226         }
86227         else {
86228             error({code: 1});
86229         }
86230     },
86231     mv: function (from, to, success, error) {
86232         try {
86233             var fromEntry = _get(from),
86234                 toInfo = _getInfo(to);
86235
86236             fromEntry.fullPath = to;
86237             fromEntry.name = toInfo.name;
86238
86239             _set(to, fromEntry);
86240             _delete(from);
86241             _save();
86242             success();
86243         }
86244         catch (e) {
86245             e.code = 1;
86246             error(e);
86247         }
86248     },
86249     touch: function (path, success, error) {
86250         var entry = _get(path),
86251             info  = _getInfo(path);
86252
86253         if (!entry) {
86254             _set(path, {
86255                 lastModifiedDate: new Date(),
86256                 createdDate: new Date(),
86257                 name: info.name,
86258                 isDirectory: false,
86259                 fullPath: path,
86260                 data: ""
86261             });
86262             entry = _get(path);
86263         }
86264         _save();
86265         success(entry);
86266     },
86267     cp: function (from, to, success, error) {
86268         try {
86269             var fromEntry = _get(from),
86270                 copied = utils.copy(fromEntry);
86271
86272             copied.name  = _getInfo(to).name;
86273             copied.fullPath = to;
86274             _set(to, copied);
86275             _save();
86276             success();
86277         }
86278         catch (e) {
86279             e.code = 1;
86280             error(e);
86281         }
86282     },
86283     stat: function (path, success, error) {
86284         var entry = _get(path);
86285
86286         if (entry) {
86287             success(entry);
86288         } else {
86289             error({code: 1});
86290         }
86291     },
86292     write: function (path, contents, success, error, options) {
86293         var entry = _get(path);
86294
86295         if (entry) {
86296             entry.lastModifiedDate = new Date();
86297             entry.data = contents;
86298             _save();
86299             success();
86300         } else {
86301             error({code: 1});
86302         }
86303
86304     },
86305     read: function (path, success, error) {
86306         var entry = _get(path);
86307
86308         if (entry) {
86309             success(utils.copy(entry.data));
86310         }
86311         else {
86312             error({code: 1});
86313         }
86314     }
86315 };
86316
86317 module.exports = _self;
86318
86319 });
86320 define('ripple/platform/tizen/2.0/spec/config', function (require, exports, module) {
86321 /*
86322  *  Copyright 2011 Research In Motion Limited.
86323  *  Copyright 2011 Intel Corporation.
86324  *
86325  * Licensed under the Apache License, Version 2.0 (the "License");
86326  * you may not use this file except in compliance with the License.
86327  * You may obtain a copy of the License at
86328  *
86329  * http://www.apache.org/licenses/LICENSE-2.0
86330  *
86331  * Unless required by applicable law or agreed to in writing, software
86332  * distributed under the License is distributed on an "AS IS" BASIS,
86333  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
86334  * See the License for the specific language governing permissions and
86335  * limitations under the License.
86336  */
86337 var utils = require('ripple/utils'),
86338     db = require('ripple/db'),
86339     constants = require('ripple/constants');
86340
86341 module.exports = {
86342     fileName: "config.xml",
86343     validateVersion: function (configValidationObject) {
86344         var valid = true;
86345         // no xmlns:JIL in wac 2.0 spec
86346         valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid;
86347
86348         return valid;
86349     },
86350     extractInfo: function (configValidationObject) {
86351         if (!configValidationObject) {
86352             return null;
86353         }
86354
86355         var widgetInfo = {},
86356             configFeatures,
86357             configPreferences,
86358             preferenceName,
86359             platform, rst, i, j,
86360             settingRst = {
86361                 'screen-orientation': 'portrait',
86362                 'context-menu': 'enable',
86363                 'background-support': 'disable',
86364                 encryption: 'disable',
86365                 'install-location': 'auto',
86366                 'hwkey-event': 'enable'
86367             };
86368
86369         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
86370         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
86371         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
86372         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
86373         if (configValidationObject.widget.children.application.validationResult[0].valid) {
86374             widgetInfo.tizenAppId = configValidationObject.widget.children.application.validationResult[0].attributes.id.value;
86375             widgetInfo.tizenPackageId = configValidationObject.widget.children.application.validationResult[0].attributes.package.value;
86376         }
86377
86378         widgetInfo.features = {};
86379
86380         if (configValidationObject.widget.children.setting.hasOwnProperty('validationResult') === true) {
86381             rst = configValidationObject.widget.children.setting.validationResult;
86382             // the first one has higher priority per platform implementation
86383             for (i = rst.length -1 ; i >= 0; i--) {
86384                 if (rst[i].valid === true) {
86385                     for (j in rst[i].attributes) {
86386                         if (rst[i].attributes[j].value !== undefined) {
86387                             settingRst[j] = rst[i].attributes[j].value;
86388                         }
86389                     }
86390                 }
86391             }
86392             db.save("layout", settingRst["screen-orientation"]);
86393         }
86394
86395         configFeatures = configValidationObject.widget.children.feature.validationResult;
86396         utils.forEach(configFeatures, function (f) {
86397             if (f.valid === true) {
86398                 var feature = {id: f.attributes.name.value,
86399                          required: f.attributes.required.valid};
86400                 widgetInfo.features[feature.id] = feature;
86401             }
86402         });
86403
86404         widgetInfo.preferences = {};
86405
86406         configPreferences = configValidationObject.widget.children.preference.validationResult;
86407
86408         platform = require('ripple/platform');
86409         utils.forEach(configPreferences, function (preference) {
86410             preferenceName = preference.attributes.name.value;
86411             if (preferenceName) {
86412                 widgetInfo.preferences[preferenceName] = {
86413                     "key": preferenceName,
86414                     "value": preference.attributes.value.value || "",
86415                     "readonly": preference.attributes.readonly.value === "true"
86416                 };
86417
86418                 db.save(preferenceName,
86419                         widgetInfo.preferences[preferenceName].value,
86420                         platform.getPersistencePrefix(widgetInfo.id));
86421             }
86422         });
86423
86424         return widgetInfo;
86425     },
86426     schema: {
86427         rootElement: "widget",
86428         widget: {
86429             nodeName: "widget",
86430             required: true,
86431             occurrence: 1,
86432             helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in the configuration document and may have the following child elments: name,description,icon,author,license,content,feature and preference.The \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir",
86433             attributes: {
86434                 xmlns: {
86435                     attributeName: "xmlns",
86436                     required: true,
86437                     type: "list",
86438                     listValues: ["http://www.w3.org/ns/widgets"]
86439                 },
86440                 "xmlns:tizen": {
86441                     attributeName: "xmlns:tizen",
86442                     required: false,
86443                     type: "list",
86444                     listValues: ["http://tizen.org/ns/widgets"]
86445                 },
86446                 "xml:lang": {
86447                     attributeName: "xml:lang",
86448                     required: false,
86449                     type: "iso-language"
86450                 },
86451                 dir: {
86452                     attributeName: "dir",
86453                     required: false,
86454                     type: "list",
86455                     listValues: ["ltr", "rtl", "lro", "rlo"]
86456                 },
86457                 id: {
86458                     attributeName: "id",
86459                     required: false,
86460                     type: "string"
86461                 },
86462                 version: {
86463                     attributeName: "version",
86464                     required: false,
86465                     type: "string"
86466                 },
86467                 height: {
86468                     attributeName: "height",
86469                     required: false,
86470                     type: "integer"
86471                 },
86472                 width: {
86473                     attributeName: "width",
86474                     required: false,
86475                     type: "integer"
86476                 },
86477                 viewmodes: {
86478                     attributeName: "viewmodes",
86479                     required: false,
86480                     type: "list",
86481                     listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"]
86482                 },
86483                 defaultlocale: {
86484                     attributeName: "defaultlocale",
86485                     required: false,
86486                     type: "iso-language"
86487                 }
86488             },
86489             children: {
86490                 name: {
86491                     nodeName: "name",
86492                     required: false,
86493                     occurrence: 0,
86494                     type: "string",
86495                     attributes: {
86496                         "xml:lang": {
86497                             attributeName: "xml:lang",
86498                             required: false,
86499                             type: "iso-language",
86500                             unique: true
86501                         },
86502                         dir: {
86503                             attributeName: "dir",
86504                             required: false,
86505                             type: "list",
86506                             listValues: ["ltr", "rtl", "lro", "rlo"]
86507                         },
86508                         "short": {
86509                             attributeName: "short",
86510                             required: false,
86511                             type: "string"
86512                         }
86513                     },
86514                     children: {
86515                         span: {
86516                             nodeName: "span",
86517                             required: false,
86518                             type: "string",
86519                             attributes: {
86520                                 "xml:lang": {
86521                                     attributeName: "xml:lang",
86522                                     required: false,
86523                                     type: "iso-language",
86524                                     unique: true
86525                                 },
86526                                 dir: {
86527                                     attributeName: "dir",
86528                                     required: false,
86529                                     type: "list",
86530                                     listValues: ["ltr", "rtl", "lro", "rlo"]
86531                                 }
86532                             }
86533                         }
86534                     }
86535                 },
86536                 description: {
86537                     nodeName: "description",
86538                     required: false,
86539                     occurrence: 0,
86540                     type: "string",
86541                     attributes: {
86542                         "xml:lang": {
86543                             attributeName: "xml:lang",
86544                             required: false,
86545                             type: "iso-language",
86546                             unique: true
86547                         },
86548                         dir: {
86549                             attributeName: "dir",
86550                             required: false,
86551                             type: "list",
86552                             listValues: ["ltr", "rtl", "lro", "rlo"]
86553                         }
86554                     },
86555                     children: {
86556                         span: {
86557                             nodeName: "span",
86558                             required: false,
86559                             type: "string",
86560                             attributes: {
86561                                 "xml:lang": {
86562                                     attributeName: "xml:lang",
86563                                     required: false,
86564                                     type: "iso-language",
86565                                     unique: true
86566                                 },
86567                                 dir: {
86568                                     attributeName: "dir",
86569                                     required: false,
86570                                     type: "list",
86571                                     listValues: ["ltr", "rtl", "lro", "rlo"]
86572                                 }
86573                             }
86574                         }
86575                     }
86576                 },
86577                 author: {
86578                     nodeName: "author",
86579                     required: false,
86580                     occurrence: 0,
86581                     type: "string",
86582                     attributes: {
86583                         "xml:lang": {
86584                             attributeName: "xml:lang",
86585                             required: false,
86586                             type: "iso-language"
86587                         },
86588                         dir: {
86589                             attributeName: "dir",
86590                             required: false,
86591                             type: "list",
86592                             listValues: ["ltr", "rtl", "lro", "rlo"]
86593                         },
86594                         href: {
86595                             attributeName: "href",
86596                             required: false,
86597                             type: "regex",
86598                             regex: constants.REGEX.URL
86599                         },
86600                         email: {
86601                             attributeName: "email",
86602                             required: false,
86603                             type: "regex",
86604                             regex: constants.REGEX.EMAIL
86605                         }
86606                     },
86607                     children: {
86608                         span: {
86609                             nodeName: "span",
86610                             required: false,
86611                             type: "string",
86612                             attributes: {
86613                                 "xml:lang": {
86614                                     attributeName: "xml:lang",
86615                                     required: false,
86616                                     type: "iso-language",
86617                                     unique: true
86618                                 },
86619                                 dir: {
86620                                     attributeName: "dir",
86621                                     required: false,
86622                                     type: "list",
86623                                     listValues: ["ltr", "rtl", "lro", "rlo"]
86624                                 }
86625                             }
86626                         }
86627                     }
86628                 },
86629                 license: {
86630                     nodeName: "license",
86631                     required: false,
86632                     occurrence: 0,
86633                     type: "string",
86634                     attributes: {
86635                         "xml:lang": {
86636                             attributeName: "xml:lang",
86637                             required: false,
86638                             type: "iso-language"
86639                         },
86640                         dir: {
86641                             attributeName: "dir",
86642                             required: false,
86643                             type: "list",
86644                             listValues: ["ltr", "rtl", "lro", "rlo"]
86645                         },
86646                         href: {
86647                             attributeName: "href",
86648                             type: "regex",
86649                             required: false,
86650                             regex: constants.REGEX.URL
86651                         }
86652                     },
86653                     children: {
86654                         span: {
86655                             nodeName: "span",
86656                             required: false,
86657                             type: "string",
86658                             attributes: {
86659                                 "xml:lang": {
86660                                     attributeName: "xml:lang",
86661                                     required: false,
86662                                     type: "iso-language",
86663                                     unique: true
86664                                 },
86665                                 dir: {
86666                                     attributeName: "dir",
86667                                     required: false,
86668                                     type: "list",
86669                                     listValues: ["ltr", "rtl", "lro", "rlo"]
86670                                 }
86671                             }
86672                         }
86673                     }
86674                 },
86675                 icon: {
86676                     nodeName: "icon",
86677                     required: false,
86678                     occurrence: 0,
86679                     attributes: {
86680                         "xml:lang": {
86681                             attributeName: "xml:lang",
86682                             required: false,
86683                             type: "iso-language"
86684                         },
86685                         dir: {
86686                             attributeName: "dir",
86687                             required: false,
86688                             type: "list",
86689                             listValues: ["ltr", "rtl", "lro", "rlo"]
86690                         },
86691                         src: {
86692                             attributeName: "src",
86693                             required: true,
86694                             type: "string"
86695                         },
86696                         width: {
86697                             attributeName: "width",
86698                             required: false,
86699                             type: "integer"
86700                         },
86701                         height: {
86702                             attributeName: "height",
86703                             required: false,
86704                             type: "integer"
86705                         }
86706                     }
86707                 },
86708                 content: {
86709                     nodeName: "content",
86710                     required: false,
86711                     occurrence: 1,
86712                     attributes: {
86713                         "xml:lang": {
86714                             attributeName: "xml:lang",
86715                             required: false,
86716                             type: "iso-language",
86717                             unique: true
86718                         },
86719                         dir: {
86720                             attributeName: "dir",
86721                             required: false,
86722                             type: "list",
86723                             listValues: ["ltr", "rtl", "lro", "rlo"]
86724                         },
86725                         src: {
86726                             attributeName: "src",
86727                             required: true,
86728                             type: "string"
86729                         },
86730                         encoding: {
86731                             attributeName: "encoding",
86732                             required: false,
86733                             type: "string"
86734                         },
86735                         type: {
86736                             attributeName: "type",
86737                             required: false,
86738                             type: "string"
86739                         }
86740                     }
86741                 },
86742                 setting: {
86743                     nodeName: "tizen:setting",
86744                     required: false,
86745                     occurrence: 0,
86746                     attributes: {
86747                         'screen-orientation': {
86748                             attributeName: "screen-orientation",
86749                             required: false,
86750                             type: "list",
86751                             listValues: ['portrait', 'landscape', 'auto']
86752                         },
86753                         'context-menu': {
86754                             attributeName: "context-menu",
86755                             required: false,
86756                             type: "list",
86757                             listValues: ['enable', 'disable']
86758                         },
86759                         'background-support': {
86760                             attributeName: "background-support",
86761                             required: false,
86762                             type: "list",
86763                             listValues: ['enable', 'disable']
86764                         },
86765                         'encryption': {
86766                             attributeName: "encryption",
86767                             required: false,
86768                             type: "list",
86769                             listValues: ['enable', 'disable']
86770                         },
86771                         'install-location': {
86772                             attributeName: "install-location",
86773                             required: false,
86774                             type: "list",
86775                             listValues: ['auto', 'internal-only', 'perfer-external']
86776                         },
86777                         'hwkey-event': {
86778                             attributeName: "hwkey-event",
86779                             required: false,
86780                             type: "list",
86781                             listValues: ['enable', 'disable']
86782                         }
86783                     }
86784                 },
86785                 application: {
86786                     nodeName: "tizen:application",
86787                     required: true,
86788                     occurrence: 1,
86789                     attributes: {
86790                         id: {
86791                             attributeName: "id",
86792                             required: true,
86793                             type: "string"
86794                         },
86795                         required_version: {
86796                             attributeName: "required_version",
86797                             required: true,
86798                             type: "list",
86799                             listValues: ['1.0', '2.0', '2.1', '2.2']
86800                         },
86801                         package: {
86802                             attributeName: "package",
86803                             required: false,
86804                             type: "string"
86805                         }
86806                     }
86807                 },
86808                 "tizen:content": {
86809                     nodeName: "tizen:content",
86810                     required: false,
86811                     occurrence: 1,
86812                     attributes: {
86813                         src: {
86814                             attributeName: "src",
86815                             required: true,
86816                             type: "string"
86817                         }
86818                     }
86819                 },
86820                 control: {
86821                     nodeName: "tizen:app-control",
86822                     required: false,
86823                     occurrence: 0,
86824                     children: {
86825                         src: {
86826                             nodeName: "tizen:src",
86827                             required: true,
86828                             occurence: 0,
86829                             attributes: {
86830                                 name: {
86831                                     attributeName: "name",
86832                                     required: false,
86833                                     type: "string"
86834                                 }
86835                             }
86836                         },
86837                         operation: {
86838                             nodeName: "tizen:operation",
86839                             required: true,
86840                             occurence: 0,
86841                             attributes: {
86842                                 name: {
86843                                     attributeName: "name",
86844                                     required: false,
86845                                     type: "string"
86846                                 }
86847                             }
86848                         },
86849                         uri: {
86850                             nodeName: "tizen:uri",
86851                             required: false,
86852                             occurence: 0,
86853                             attributes: {
86854                                 name: {
86855                                     attributeName: "name",
86856                                     required: false,
86857                                     type: "string"
86858                                 }
86859                             }
86860                         },
86861                         mime: {
86862                             nodeName: "tizen:mime",
86863                             required: false,
86864                             occurence: 0,
86865                             attributes: {
86866                                 name: {
86867                                     attributeName: "name",
86868                                     required: false,
86869                                     type: "string"
86870                                 }
86871                             }
86872                         }
86873                     }
86874                 },
86875                 "app-widget": {
86876                     nodeName: "tizen:app-widget",
86877                     required: false,
86878                     occurrence: 0,
86879                     attributes: {
86880                         id: {
86881                             attributeName: "id",
86882                             required: true,
86883                             type: "string"
86884                         },
86885                         primary: {
86886                             attributeName: "primary",
86887                             required: true,
86888                             type: "list",
86889                             listValues: ['true', 'false']
86890                         },
86891                         "auto-launch": {
86892                             attributeName: "auto-launch",
86893                             required: false,
86894                             type: "list",
86895                             listValues: ['true', 'false']
86896                         },
86897                         "update-period": {
86898                             attributeName: "update-period",
86899                             required: false,
86900                             type: "integer"
86901                         }
86902                     },
86903                     children: {
86904                         "box-label": {
86905                             nodeName: "tizen:box-label",
86906                             required: true,
86907                             occurence: 1
86908                         },
86909                         "box-icon": {
86910                             nodeName: "tizen:box-icon",
86911                             required: true,
86912                             occurence: 1,
86913                             attributes: {
86914                                 src: {
86915                                     attributeName: "src",
86916                                     required: true,
86917                                     type: "string"
86918                                 }
86919                             }
86920                         },
86921                         "box-content": {
86922                             nodeName: "tizen:box-content",
86923                             required: true,
86924                             occurence: 1,
86925                             attributes: {
86926                                 src: {
86927                                     attributeName: "src",
86928                                     required: true,
86929                                     type: "string"
86930                                 },
86931                                 "mouse-event": {
86932                                     attributeName: "mouse-event",
86933                                     required: false,
86934                                     type: "string"
86935                                 },
86936                                 "touch-event": {
86937                                     attributeName: "touch-event",
86938                                     required: false,
86939                                     type: "string"
86940                                 }
86941                             },
86942                             children: {
86943                                 "box-size": {
86944                                     nodeName: "tizen:box-size",
86945                                     required: false,
86946                                     occurence: 1,
86947                                     attributes: {
86948                                         "preview": {
86949                                             attributeName: "preview",
86950                                             required: false,
86951                                             type: "string"
86952                                         }
86953                                     }
86954                                 },
86955                                 pd: {
86956                                     nodeName: "tizen:pd",
86957                                     required: false,
86958                                     occurence: 1,
86959                                     attributes: {
86960                                         "src": {
86961                                             attributeName: "src",
86962                                             required: true,
86963                                             type: "string"
86964                                         },
86965                                         "width": {
86966                                             attributeName: "width",
86967                                             required: true,
86968                                             type: "integer"
86969                                         },
86970                                         "height": {
86971                                             attributeName: "height",
86972                                             required: true,
86973                                             type: "integer"
86974                                         }
86975                                     }
86976                                 }
86977                             }
86978                         }
86979                     }
86980                 },
86981                 account: {
86982                     nodeName: "tizen:account",
86983                     required: false,
86984                     occurrence: 0,
86985                     attributes: {
86986                         "multiple-account-support": {
86987                             attributeName: "multiple-account-support",
86988                             required: true,
86989                             type: "list",
86990                             listValues: ['true', 'false']
86991                         }
86992                     },
86993                     children: {
86994                         icon: {
86995                             nodeName: "tizen:icon",
86996                             required: false,
86997                             occurence: 1,
86998                             attributes: {
86999                                 section: {
87000                                     attributeName: "section",
87001                                     required: true,
87002                                     type: "string"
87003                                 }
87004                             }
87005                         },
87006                         "display-name": {
87007                             nodeName: "tizen:display-name",
87008                             required: false,
87009                             occurence: 1,
87010                             attributes: {
87011                                 "xml:lang": {
87012                                     attributeName: "xml:lang",
87013                                     required: false,
87014                                     type: "string"
87015                                 }
87016                             }
87017                         },
87018                         capability: {
87019                             nodeName: "capability",
87020                             required: false,
87021                             occurence: 1
87022                         }
87023                     }
87024                 },
87025                 feature: {
87026                     nodeName: "tizen:privilege",
87027                     required: false,
87028                     occurrence: 0,
87029                     attributes: {
87030                         "xml:lang": {
87031                             attributeName: "xml:lang",
87032                             required: false,
87033                             type: "iso-language"
87034                         },
87035                         dir: {
87036                             attributeName: "dir",
87037                             required: false,
87038                             type: "list",
87039                             listValues: ["ltr", "rtl", "lro", "rlo"]
87040                         },
87041                         name: {
87042                             attributeName: "name",
87043                             required: true,
87044                             type: "list",
87045                             listValues: ["http://www.w3.org/TR/battery-status/",
87046                                          "http://www.w3.org/TR/geolocation-API/",
87047                                          "http://www.w3.org/TR/touch-events/",
87048                                          "http://www.w3.org/TR/vibration/",
87049                                          "http://tizen.org/privilege/tizen",
87050                                          "http://tizen.org/privilege/alarm",
87051                                          "http://tizen.org/privilege/application.launch",
87052                                          "http://tizen.org/privilege/appmanager.kill", "http://tizen.org/privilege/appmanager.certificate",
87053                                          "http://tizen.org/privilege/bluetoothmanager", "http://tizen.org/privilege/bluetooth.admin",
87054                                          "http://tizen.org/privilege/bluetooth.gap", "http://tizen.org/privilege/bluetooth.spp",
87055                                          "http://tizen.org/privilege/bookmark.read", "http://tizen.org/privilege/bookmark.write",
87056                                          "http://tizen.org/privilege/calendar.read", "http://tizen.org/privilege/calendar.write",
87057                                          "http://tizen.org/privilege/callhistory.read", "http://tizen.org/privilege/callhistory.write",
87058                                          "http://tizen.org/privilege/contact.read", "http://tizen.org/privilege/contact.write",
87059                                          "http://tizen.org/privilege/content.read", "http://tizen.org/privilege/content.write",
87060                                          "http://tizen.org/privilege/datacontrol.consumer",
87061                                          "http://tizen.org/privilege/datasync",
87062                                          "http://tizen.org/privilege/download",
87063                                          "http://tizen.org/privilege/filesystem.read", "http://tizen.org/privilege/filesystem.write",
87064                                          "http://tizen.org/privilege/messaging.read", "http://tizen.org/privilege/messaging.write",
87065                                          "http://tizen.org/privilege/networkbearerselection",
87066                                          "http://tizen.org/privilege/nfc.common", "http://tizen.org/privilege/nfc.admin",
87067                                          "http://tizen.org/privilege/nfc.tag", "http://tizen.org/privilege/nfc.p2p",
87068                                          "http://tizen.org/privilege/notification",
87069                                          "http://tizen.org/privilege/packagemanager.install", "http://tizen.org/privilege/package.info",
87070                                          "http://tizen.org/privilege/power",
87071                                          "http://tizen.org/privilege/push",
87072                                          "http://tizen.org/privilege/secureelement",
87073                                          "http://tizen.org/privilege/setting",
87074                                          "http://tizen.org/privilege/system", "http://tizen.org/privilege/systemmanager",
87075                                          "http://tizen.org/privilege/time",
87076                                          "http://tizen.org/privilege/websetting"]
87077                         },
87078                         required: {
87079                             attributeName: "required",
87080                             type: "boolean",
87081                             required: false
87082                         }
87083                     },
87084                     children: {
87085                         param: {
87086                             nodeName: "param",
87087                             required: false,
87088                             occurrence: 0,
87089                             attributes: {
87090                                 "xml:lang": {
87091                                     attributeName: "xml:lang",
87092                                     required: false,
87093                                     type: "iso-language"
87094                                 },
87095                                 dir: {
87096                                     attributeName: "dir",
87097                                     required: false,
87098                                     type: "list",
87099                                     listValues: ["ltr", "rtl", "lro", "rlo"]
87100                                 },
87101                                 name: {
87102                                     attributeName: "name",
87103                                     required: true,
87104                                     type: "string"
87105                                 },
87106                                 value: {
87107                                     attributeName: "value",
87108                                     required: true,
87109                                     type: "string"
87110                                 }
87111                             }
87112                         }
87113                     }
87114                 },
87115                 preference: {
87116                     nodeName: "preference",
87117                     required: false,
87118                     occurrence: 0,
87119                     attributes: {
87120                         "xml:lang": {
87121                             attributeName: "xml:lang",
87122                             required: false,
87123                             type: "iso-language"
87124                         },
87125                         dir: {
87126                             attributeName: "dir",
87127                             required: false,
87128                             type: "list",
87129                             listValues: ["ltr", "rtl", "lro", "rlo"]
87130                         },
87131                         name: {
87132                             attributeName: "name",
87133                             required: true,
87134                             type: "string"
87135                         },
87136                         value: {
87137                             type: "string",
87138                             required: false,
87139                             attributeName: "value"
87140                         },
87141                         readonly: {
87142                             attributeName: "readonly",
87143                             type: "boolean",
87144                             required: false
87145                         }
87146                     }
87147                 }
87148             }
87149         }
87150     }
87151 };
87152
87153 });
87154 define('ripple/platform/tizen/2.0/spec/device', function (require, exports, module) {
87155 /*
87156  *  Copyright 2011 Intel Corporation.
87157  *
87158  * Licensed under the Apache License, Version 2.0 (the "License");
87159  * you may not use this file except in compliance with the License.
87160  * You may obtain a copy of the License at
87161  *
87162  * http://www.apache.org/licenses/LICENSE-2.0
87163  *
87164  * Unless required by applicable law or agreed to in writing, software
87165  * distributed under the License is distributed on an "AS IS" BASIS,
87166  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87167  * See the License for the specific language governing permissions and
87168  * limitations under the License.
87169  */
87170 var event = require('ripple/event'),
87171     utils = require('ripple/utils'),
87172     StorageTypeTable = {
87173         "UNKNOWN": "UNKNOWN",
87174         "INTERNAL": "INTERNAL",
87175         "MMC": "MMC",
87176         "USB_HOST": "USB_HOST"
87177     },
87178     NetworkTypeTable = {
87179         "NONE": "NONE",
87180         "2G": "2G",
87181         "2.5G": "2.5G",
87182         "3G": "3G",
87183         "4G": "4G",
87184         "WIFI": "WIFI",
87185         "ETHERNET": "ETHERNET",
87186         "UNKNOWN": "UNKNOWN"
87187     },
87188     LocaleTable = {
87189         "eng_USA": "eng_USA",
87190         "eng_CAN": "eng_CAN",
87191         "deu_DEU": "deu_DEU",
87192         "jpn_JPN": "jpn_JPN",
87193         "zho_CHN": "zho_CHN",
87194         "UNKNOWN": "UNKNOWN"
87195     },
87196     SimStateTable = {
87197         "ABSENT": "ABSENT",
87198         "INITIALIZING": "INITIALIZING",
87199         "READY": "READY",
87200         "PIN_REQUIRED": "PIN_REQUIRED",
87201         "PUK_REQUIRED":"PUK_REQUIRED",
87202         "NETWORK_LOCKED": "NETWORK_LOCKED",
87203         "SIM_LOCKED": "SIM_LOCKED",
87204         "UNKNOWN": "UNKNOWN"
87205     };
87206
87207 function deviceStatusEventTrigger(setting) {
87208     event.trigger("DeviceStatusChanged", [setting]);
87209 }
87210
87211 module.exports = {
87212     "Config": {
87213         "vibratingMode": {
87214             "name": "Vibrator",
87215             "control": {
87216                 "type": "checkbox",
87217                 "value": true
87218             },
87219             "callback": function (setting) {
87220                 event.trigger("VibratingModeChanged", [setting]);
87221             }
87222         },
87223         "lockScreen": {
87224             "name": "Lock Screen",
87225             "control": {
87226                 "type": "checkbox",
87227                 "value": false
87228             },
87229             "callback": function (setting) {
87230                 event.trigger("LockScreenChanged", [setting]);
87231             }
87232         }
87233     },
87234     "DEVICE_ORIENTATION": {
87235         "status": {
87236             "name": "Status",
87237             "control": {
87238                 "type": "label",
87239                 "innertext": "PORTRAIT_PRIMARY",
87240                 "value": "PORTRAIT_PRIMARY"
87241             },
87242             "event": "LayoutChanged"
87243         },
87244         "isAutoRotation": {
87245             "name": "Is Auto Rotation",
87246             "control": {
87247                 "type": "label",
87248                 "value": false
87249             }
87250         }
87251     },
87252     "CPU": {
87253         "load": {
87254             "name": "Load",
87255             "control": {
87256                 "type": "number",
87257                 "value": 0.1
87258             },
87259             "event": "CpuLoadChanged",
87260             "callback": function (setting) {
87261                 if (setting > 1) setting = 1;
87262                 if (setting < 0) setting = 0;
87263                 event.trigger("CpuLoadChanged", [setting]);
87264             }
87265         }
87266     },
87267     "STORAGE": {
87268         "type": {
87269             "name": "Type",
87270             "control": {
87271                 "type": "select",
87272                 "value": StorageTypeTable["INTERNAL"]
87273             },
87274             "options": (function () {
87275                 var optionList = {};
87276                 utils.forEach(StorageTypeTable, function (key, value) {
87277                     optionList[key] = StorageTypeTable[value];
87278                 });
87279
87280                 return optionList;
87281             }())
87282         },
87283         "capacity": {
87284             "name": "Capacity(bytes)",
87285             "control": {
87286                 "type": "label",
87287                 "value": 16000000000
87288             },
87289         },
87290         "availableCapacity": {
87291             "name": "AvailableCapacity(bytes)",
87292             "control": {
87293                 "type": "number",
87294                 "value": 12000000000
87295             },
87296             "callback": function (setting) {
87297                 event.trigger("AvailCapacityChanged", [setting]);
87298             }
87299         },
87300         "isRemovable": {
87301             "name": "IsRemovable",
87302             "control": {
87303                 "type": "checkbox",
87304                 "value": true
87305             }
87306         }
87307     },
87308     "BUILD": {
87309         "model": {
87310             "name": "Model",
87311             "control": {
87312                 "type": "label",
87313                 "innertext": "tizen-2.2 build",
87314                 "value": "tizen-2.2 build"
87315             }
87316         },
87317         "manufacturer": {
87318             "name": "Manufacturer",
87319             "control": {
87320                 "type": "label",
87321                 "innertext": "Tizen",
87322                 "value": "Tizen"
87323             }
87324         },
87325         "buildVersion": {
87326             "name": "Build Version",
87327             "control": {
87328                 "type": "label",
87329                 "innertext": "TIZEN_WEB_SIMULATOR_000001",
87330                 "value": "TIZEN_WEB_SIMULATOR_000001"
87331             }
87332         }
87333     },
87334     "LOCALE": {
87335         "language": {
87336             "name": "Language",
87337             "control": {
87338                 "type": "select",
87339                 "value": LocaleTable["eng_USA"]
87340             },
87341             "options": (function () {
87342                 var optionList = {};
87343                 utils.forEach(LocaleTable, function (key, value) {
87344                     optionList[key] = LocaleTable[value];
87345                 });
87346
87347                 return optionList;
87348             }())
87349         },
87350         "country": {
87351             "name": "Country",
87352             "control": {
87353                 "type": "select",
87354                 "value": LocaleTable["eng_USA"]
87355             },
87356             "options": (function () {
87357                 var optionList = {};
87358                 utils.forEach(LocaleTable, function (key, value) {
87359                     optionList[key] = LocaleTable[value];
87360                 });
87361
87362                 return optionList;
87363             }())
87364         }
87365     },
87366     "DISPLAY": {
87367         "resolutionWidth": {
87368             "name": "Resolution Width(pixels)",
87369             "control": {
87370                 "type": "label",
87371                 "value": 0
87372             }
87373         },
87374         "resolutionHeight": {
87375             "name": "Resolution Height(pixels)",
87376             "control": {
87377                 "type": "label",
87378                 "value": 0
87379             }
87380         },
87381         "dotsPerInchWidth": {
87382             "name": "DPI-X",
87383             "control": {
87384                 "type": "label",
87385                 "value": 0
87386             }
87387         },
87388         "dotsPerInchHeight": {
87389             "name": "DPI-Y",
87390             "control": {
87391                 "type": "label",
87392                 "value": 0
87393             }
87394         },
87395         "physicalWidth": {
87396             "name": "Physical Width(millimeters)",
87397             "control": {
87398                 "type": "label",
87399                 "value": 0
87400             }
87401         },
87402         "physicalHeight": {
87403             "name": "Physical Height(millimeters)",
87404             "control": {
87405                 "type": "label",
87406                 "value": 0
87407             }
87408         },
87409         "brightness": {
87410             "name": "Brightness",
87411             "control": {
87412                 "type": "number",
87413                 "value": 1
87414             },
87415             "event": "DisplayBrightnessChanged",
87416             "callback": function (setting) {
87417                 if (setting > 1) setting = 1;
87418                 if (setting < 0) setting = 0;
87419                 event.trigger("DisplayBrightnessChanged", [setting]);
87420             }
87421         }
87422     },
87423     "NETWORK": {
87424         "networkType": {
87425             "name": "Network Type",
87426             "control" : {
87427                 "type": "select",
87428                 "value": NetworkTypeTable["NONE"]
87429             },
87430             "options": (function () {
87431                 var optionList = {};
87432                 utils.forEach(NetworkTypeTable, function (key, value) {
87433                     optionList[key] = NetworkTypeTable[value];
87434                 });
87435
87436                 return optionList;
87437             }())
87438         }
87439     },
87440     "WIFI_NETWORK": {
87441         "status": {
87442             "name": "Status",
87443             "control": {
87444                 "type": "checkbox",
87445                 "value": false
87446             },
87447             "event": "WiFiNetworkStatusChanged",
87448             "callback": function (setting) {
87449                 event.trigger("WiFiNetworkStatusChanged", [setting]);
87450             }
87451         },
87452         "ssid": {
87453             "name": "SSID",
87454             "control": {
87455                 "type": "text",
87456                 "value": "Tizen WiFi"
87457             }
87458         },
87459         "ipAddress": {
87460             "name": "IP Address",
87461             "control": {
87462                 "type": "text",
87463                 "value": "192.168.0.1"
87464             }
87465         },
87466         "ipv6Address": {
87467             "name": "IPv6 Address",
87468             "control": {
87469                 "type": "text",
87470                 "value": "2001:db8:85a3:0:0:0:70:7334"
87471             }
87472         },
87473         "signalStrength": {
87474             "name": "Signal Strength",
87475             "control": {
87476                 "type": "select",
87477                 "value": 0
87478             },
87479             "options": (function () {
87480                 var i,
87481                     optionList = {};
87482
87483                 for (i = 0; i <= 10; i++) {
87484                     optionList[i] = i;
87485                 }
87486
87487                 return optionList;
87488             }())
87489         }
87490     },
87491     "CELLULAR_NETWORK": {
87492         "status": {
87493             "name": "Status",
87494             "control": {
87495                 "type": "checkbox",
87496                 "value": true
87497             },
87498             "event": "CellularNetworkStatusChanged",
87499             "callback": function (setting) {
87500                 event.trigger("CellularNetworkStatusChanged", [setting]);
87501             }
87502         },
87503         "apn": {
87504             "name": "APN",
87505             "control": {
87506                 "type": "text",
87507                 "value": "Tizen"
87508             }
87509         },
87510         "ipAddress": {
87511             "name": "IP Address",
87512             "control": {
87513                 "type": "text",
87514                 "value": "10.0.2.16"
87515             }
87516         },
87517         "ipv6Address": {
87518             "name": "IPv6 Address",
87519             "control": {
87520                 "type": "text",
87521                 "value": "2001:db8:85a3:0:0:0:70:7334"
87522             }
87523         },
87524         "mcc": {
87525             "name": "MCC",
87526             "control": {
87527                 "type": "number",
87528                 "value": 460
87529             }
87530         },
87531         "mnc": {
87532             "name": "MNC",
87533             "control": {
87534                 "type": "number",
87535                 "value": 0
87536             }
87537         },
87538         "cellId": {
87539             "name": "Cell ID",
87540             "control": {
87541                 "type": "number",
87542                 "value": 0
87543             }
87544         },
87545         "lac": {
87546             "name": "LAC",
87547             "control": {
87548                 "type": "number",
87549                 "value": 0
87550             }
87551         },
87552         "isRoaming": {
87553             "name": "Roaming",
87554             "control": {
87555                 "type": "checkbox",
87556                 "value": true
87557             }
87558         },
87559         "isFlightMode": {
87560             "name": "Flight Mode",
87561             "control": {
87562                 "type": "checkbox",
87563                 "value": false
87564             },
87565             "callback": function (setting) {
87566                 event.trigger("FlightModeChanged", [setting]);
87567             }
87568         },
87569         "imei": {
87570             "name": "IMEI",
87571             "control": {
87572                 "type": "text",
87573                 "value": "012417005203000"
87574             }
87575         }
87576     },
87577     "SIM": {
87578         "state": {
87579             "name": "State",
87580             "control": {
87581                 "type": "select",
87582                 "value": SimStateTable["READY"]
87583             },
87584             "options": (function () {
87585                 var optionList = {};
87586                 utils.forEach(SimStateTable, function (key, value) {
87587                     optionList[key] = SimStateTable[value];
87588                 });
87589
87590                 return optionList;
87591             }())
87592         },
87593         "operatorName": {
87594             "name": "Operator Name",
87595             "control": {
87596                 "type": "text",
87597                 "value": "Tizen"
87598             }
87599         },
87600         "msisdn": {
87601             "name": "MSISDN",
87602             "control": {
87603                 "type": "text",
87604                 "value": "088123456789"
87605             }
87606         },
87607         "iccid": {
87608             "name": "ICCID",
87609             "control": {
87610                 "type": "text",
87611                 "value": "123000MFSSYYGXXXXXXP"
87612             }
87613         },
87614         "mcc": {
87615             "name": "MCC",
87616             "control": {
87617                 "type": "number",
87618                 "value": 460
87619             }
87620         },
87621         "mnc": {
87622             "name": "MNC",
87623             "control": {
87624                 "type": "number",
87625                 "value": 0
87626             }
87627         },
87628         "msin": {
87629             "name": "MSIN",
87630             "control": {
87631                 "type": "text",
87632                 "value": "H1 H2 H3 S 12345"
87633             }
87634         },
87635         "spn": {
87636             "name": "SPN",
87637             "control": {
87638                 "type": "text",
87639                 "value": "TizenSPN"
87640             }
87641         }
87642     },
87643     "PERIPHERAL": {
87644         "isVideoOutputOn": {
87645             "name": "Video Output",
87646             "control": {
87647                 "type": "checkbox",
87648                 "value": false
87649             }
87650         }
87651     }
87652 };
87653
87654
87655 });
87656 define('ripple/platform/tizen/2.0/spec/sensor', function (require, exports, module) {
87657 /*
87658  *  Copyright 2012 Intel Corporation.
87659  *
87660  * Licensed under the Apache License, Version 2.0 (the "License");
87661  * you may not use this file except in compliance with the License.
87662  * You may obtain a copy of the License at
87663  *
87664  * http://www.apache.org/licenses/LICENSE-2.0
87665  *
87666  * Unless required by applicable law or agreed to in writing, software
87667  * distributed under the License is distributed on an "AS IS" BASIS,
87668  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87669  * See the License for the specific language governing permissions and
87670  * limitations under the License.
87671  */
87672 var event = require('ripple/event');
87673
87674 function sensorStatusEventTrigger(setting) {
87675     event.trigger("SensorStatusChanged", [setting]);
87676 }
87677
87678 module.exports = {
87679     "Accelerometer": {
87680         "resolution": 0.039239998906850815,
87681         "minDelay": 20,
87682         "range": 20.051639556884766,
87683         "name": "Accelerometer",
87684         "type": "Accelerometer"
87685     },
87686     "MagneticField": {
87687         "x": {
87688             "name": "X",
87689             "control": {
87690                 "type": "range",
87691                 "value": 100.0000000000000000,
87692                 "min": 0.0000000000000000,
87693                 "max": 200.0000000000000000,
87694                 "step": 0.0000000000000001
87695             },
87696             "callback": function (setting) {
87697                 event.trigger("MagneticField-xChanged", [setting]);
87698             }
87699         },
87700
87701         "y": {
87702             "name": "Y",
87703             "control": {
87704                 "type": "range",
87705                 "value": 100.0000000000000000,
87706                 "min": 0.0000000000000000,
87707                 "max": 200.0000000000000000,
87708                 "step": 0.0000000000000001
87709             },
87710             "callback": function (setting) {
87711                 event.trigger("MagneticField-yChanged", [setting]);
87712             }
87713         },
87714
87715         "z": {
87716             "name": "Z",
87717             "control": {
87718                 "type": "range",
87719                 "value": 100.0000000000000000,
87720                 "min": 0.0000000000000000,
87721                 "max": 200.0000000000000000,
87722                 "step": 0.0000000000000001
87723             },
87724             "callback": function (setting) {
87725                 event.trigger("MagneticField-zChanged", [setting]);
87726             }
87727         },
87728
87729         "resolution": 1,
87730         "minDelay": 20,
87731         "range": 359,
87732         "name": "MagneticField",
87733         "type": "MagneticField"
87734     },
87735     "Rotation": {
87736         "resolution": 1,
87737         "minDelay": 20,
87738         "range": 359,
87739         "name": "Rotation",
87740         "type": "Rotation"
87741     },
87742     "Orientation": {
87743         "resolution": 1,
87744         "minDelay": 20,
87745         "range": 359,
87746         "name": "Orientation",
87747         "type": "Orientation"
87748     }
87749 };
87750
87751 });
87752 define('ripple/platform/tizen/2.0/spec/ui', function (require, exports, module) {
87753 /*
87754  *  Copyright 2011 Intel Corporation.
87755  *
87756  * Licensed under the Apache License, Version 2.0 (the "License");
87757  * you may not use this file except in compliance with the License.
87758  * You may obtain a copy of the License at
87759  *
87760  * http://www.apache.org/licenses/LICENSE-2.0
87761  *
87762  * Unless required by applicable law or agreed to in writing, software
87763  * distributed under the License is distributed on an "AS IS" BASIS,
87764  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87765  * See the License for the specific language governing permissions and
87766  * limitations under the License.
87767  */
87768 module.exports = {
87769     plugins: [
87770         "sensors",
87771         "communication",
87772         "geoView",
87773         "widgetConfig",
87774         "deviceSettings",
87775         "application",
87776         "network",
87777         "power",
87778         "download",
87779         "notifications",
87780         "package",
87781         "messagePort",
87782         "secureElement"
87783     ]
87784 };
87785
87786 });
87787 define('ripple/platform/tizen/2.0/AlarmBase', function (require, exports, module) {
87788 /*
87789  *  Copyright 2012 Intel Corporation.
87790  *
87791  * Licensed under the Apache License, Version 2.0 (the "License");
87792  * you may not use this file except in compliance with the License.
87793  * You may obtain a copy of the License at
87794  *
87795  * http://www.apache.org/licenses/LICENSE-2.0
87796  *
87797  * Unless required by applicable law or agreed to in writing, software
87798  * distributed under the License is distributed on an "AS IS" BASIS,
87799  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87800  * See the License for the specific language governing permissions and
87801  * limitations under the License.
87802  */
87803
87804 module.exports = function (self) {
87805     self = self || this;
87806
87807     self.__defineGetter__("id", function () {
87808         return null;
87809     });
87810 };
87811
87812 });
87813 define('ripple/platform/tizen/2.0/CalendarRecurrenceRule', function (require, exports, module) {
87814 /*
87815  *  Copyright 2013 Intel Corporation.
87816  *
87817  * Licensed under the Apache License, Version 2.0 (the "License");
87818  * you may not use this file except in compliance with the License.
87819  * You may obtain a copy of the License at
87820  *
87821  * http://www.apache.org/licenses/LICENSE-2.0
87822  *
87823  * Unless required by applicable law or agreed to in writing, software
87824  * distributed under the License is distributed on an "AS IS" BASIS,
87825  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87826  * See the License for the specific language governing permissions and
87827  * limitations under the License.
87828  */
87829
87830 var t = require('ripple/platform/tizen/2.0/typecast'),
87831     CalendarRecurrenceRule;
87832
87833 CalendarRecurrenceRule = function (frequency, ruleInitDict) {
87834     var calendarRecurrenceRule = {}, attr;
87835
87836     t.CalendarRecurrenceRule(arguments, this);
87837
87838     calendarRecurrenceRule.frequency       = frequency;
87839     calendarRecurrenceRule.interval        = 1;
87840     calendarRecurrenceRule.untilDate       = null;
87841     calendarRecurrenceRule.occurrenceCount = -1;
87842     calendarRecurrenceRule.daysOfTheWeek   = [];
87843     calendarRecurrenceRule.setPositions    = [];
87844     calendarRecurrenceRule.exceptions      = [];
87845
87846     if (ruleInitDict) {
87847         for (attr in ruleInitDict) {
87848             switch (attr) {
87849             case "daysOfTheWeek":
87850                 calendarRecurrenceRule.daysOfTheWeek = t.ByDayValue(
87851                         ruleInitDict.daysOfTheWeek, "[]+");
87852                 break;
87853
87854             case "setPositions":
87855                 calendarRecurrenceRule.setPositions = t.short(
87856                         ruleInitDict.setPositions, "[]+");
87857                 break;
87858
87859             case "exceptions":
87860                 calendarRecurrenceRule.exceptions = t.TZDate(
87861                         ruleInitDict.exceptions, "[]+");
87862                 break;
87863
87864             default:
87865                 calendarRecurrenceRule[attr] = ruleInitDict[attr];
87866                 break;
87867             }
87868         }
87869     }
87870
87871     this.__defineGetter__("frequency", function () {
87872         return calendarRecurrenceRule.frequency;
87873     });
87874     this.__defineSetter__("frequency", function (val) {
87875         try {
87876             calendarRecurrenceRule.frequency = t.RecurrenceRuleFrequency(val);
87877         } catch (e) {
87878         }
87879     });
87880
87881     this.__defineGetter__("interval", function () {
87882         return calendarRecurrenceRule.interval;
87883     });
87884     this.__defineSetter__("interval", function (val) {
87885         try {
87886             calendarRecurrenceRule.interval = t.unsigned_short(val);
87887         } catch (e) {
87888         }
87889     });
87890
87891     this.__defineGetter__("untilDate", function () {
87892         return calendarRecurrenceRule.untilDate;
87893     });
87894     this.__defineSetter__("untilDate", function (val) {
87895         try {
87896             calendarRecurrenceRule.untilDate = t.TZDate(val, "?");
87897         } catch (e) {
87898         }
87899     });
87900
87901     this.__defineGetter__("occurrenceCount", function () {
87902         return calendarRecurrenceRule.occurrenceCount;
87903     });
87904     this.__defineSetter__("occurrenceCount", function (val) {
87905         try {
87906             calendarRecurrenceRule.occurrenceCount = t.long(val);
87907         } catch (e) {
87908         }
87909     });
87910
87911     this.__defineGetter__("daysOfTheWeek", function () {
87912         return calendarRecurrenceRule.daysOfTheWeek;
87913     });
87914     this.__defineSetter__("daysOfTheWeek", function (val) {
87915         try {
87916             calendarRecurrenceRule.daysOfTheWeek = t.ByDayValue(val, "[]");
87917         } catch (e) {
87918         }
87919     });
87920
87921     this.__defineGetter__("setPositions", function () {
87922         return calendarRecurrenceRule.setPositions;
87923     });
87924     this.__defineSetter__("setPositions", function (val) {
87925         try {
87926             calendarRecurrenceRule.setPositions = t.short(val, "[]");
87927         } catch (e) {
87928         }
87929     });
87930
87931     this.__defineGetter__("exceptions", function () {
87932         return calendarRecurrenceRule.exceptions;
87933     });
87934     this.__defineSetter__("exceptions", function (val) {
87935         try {
87936             calendarRecurrenceRule.exceptions = t.TZDate(val, "[]");
87937         } catch (e) {
87938         }
87939     });
87940 };
87941
87942 module.exports = CalendarRecurrenceRule;
87943
87944 });
87945 define('ripple/platform/tizen/2.0/systemsetting', function (require, exports, module) {
87946 /*
87947  *  Copyright 2013 Intel Corporation.
87948  *
87949  * Licensed under the Apache License, Version 2.0 (the "License");
87950  * you may not use this file except in compliance with the License.
87951  * You may obtain a copy of the License at
87952  *
87953  * http://www.apache.org/licenses/LICENSE-2.0
87954  *
87955  * Unless required by applicable law or agreed to in writing, software
87956  * distributed under the License is distributed on an "AS IS" BASIS,
87957  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87958  * See the License for the specific language governing permissions and
87959  * limitations under the License.
87960  */
87961
87962 var db = require('ripple/db'),
87963     event = require('ripple/event'),
87964     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
87965     t = require('ripple/platform/tizen/2.0/typecast'),
87966     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
87967     _systemSettings = null,
87968     DBSYSTEMSETTING_KEY = "tizen2-systemsetting",
87969     _security = {
87970         "http://tizen.org/privilege/setting": ["setProperty"]
87971     },
87972     _self;
87973
87974 function _initialize() {
87975     _systemSettings = db.retrieveObject(DBSYSTEMSETTING_KEY);
87976     if (!_systemSettings) {
87977         _systemSettings = {"HOME_SCREEN": "images/home_screen.jpg", "LOCK_SCREEN": "images/lock_screen.jpg", "INCOMING_CALL": "sounds/incoming.wav", "NOTIFICATION_EMAIL": "sounds/notification.wav"};
87978         db.saveObject(DBSYSTEMSETTING_KEY, _systemSettings);
87979         event.trigger("SystemSettingChanged");
87980     }
87981 }
87982
87983 _self = function () {
87984     var systemSetting;
87985
87986     function setProperty(type, value, successCallback, errorCallback) {
87987         if (!_security.setProperty) {
87988             throw new WebAPIException(errorcode.SECURITY_ERR);
87989         }
87990
87991         t.SystemSettingManager("setProperty", arguments);
87992
87993         _systemSettings = db.retrieveObject(DBSYSTEMSETTING_KEY);
87994         _systemSettings[type] = value;
87995         db.saveObject(DBSYSTEMSETTING_KEY, _systemSettings);
87996         event.trigger("SystemSettingChanged");
87997         window.setTimeout(function () {
87998             successCallback();
87999         }, 1);
88000     }
88001
88002     function getProperty(type, successCallback, errorCallback) {
88003         t.SystemSettingManager("getProperty", arguments);
88004
88005         _systemSettings = db.retrieveObject(DBSYSTEMSETTING_KEY);
88006         window.setTimeout(function () {
88007             successCallback(_systemSettings[type]);
88008         }, 1);
88009     }
88010
88011     function handleSubFeatures(subFeatures) {
88012         var i, subFeature;
88013
88014         for (subFeature in subFeatures) {
88015             for (i in _security[subFeature]) {
88016                 _security[_security[subFeature][i]] = true;
88017             }
88018         }
88019     }
88020
88021     systemSetting = {
88022         setProperty:       setProperty,
88023         getProperty:       getProperty,
88024         handleSubFeatures: handleSubFeatures
88025     };
88026
88027     return systemSetting;
88028 };
88029
88030 _initialize();
88031
88032 module.exports = _self;
88033
88034 });
88035 define('ripple/platform/tizen/2.0/battery', function (require, exports, module) {
88036 /*
88037  *  Copyright 2012 Intel Corporation
88038  *
88039  * Licensed under the Apache License, Version 2.0 (the "License");
88040  * you may not use this file except in compliance with the License.
88041  * You may obtain a copy of the License at
88042  *
88043  * http://www.apache.org/licenses/LICENSE-2.0
88044  *
88045  * Unless required by applicable law or agreed to in writing, software
88046  * distributed under the License is distributed on an "AS IS" BASIS,
88047  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88048  * See the License for the specific language governing permissions and
88049  * limitations under the License.
88050  */
88051
88052 var event = require('ripple/event'),
88053     utils = require('ripple/utils'),
88054     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
88055     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
88056     _data = {
88057         charging: true,
88058         chargingTime: 0,
88059         level: 1.0,
88060         dischargingTime: Infinity,
88061         chargingchange: {},
88062         chargingtimechange: {},
88063         levelchange: {},
88064         dischargingtimechange: {}
88065     },
88066     _self;
88067
88068 _self = {
88069     addEventListener: function (event, callback, capture) {
88070         if (typeof callback !== "function" || event === undefined) {
88071             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
88072         }
88073         switch (event) {
88074         case "chargingchange":
88075         case "chargingtimechange":
88076         case "levelchange":
88077         case "dischargingtimechange":
88078             var isExist = false, item;
88079             for (item in _data[event]) {
88080                 if (callback === item) {
88081                     isExist = true;
88082                     break;
88083                 }
88084             }
88085             if (!isExist) {
88086                 _data[event].add(callback);
88087             }
88088             break;
88089
88090         default:
88091             break;
88092         }
88093     },
88094
88095     removeEventListener: function (event, callback, capture) {
88096         if (typeof callback !== "function" || event === undefined) {
88097             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
88098         }
88099         _data[event].unbind(callback);
88100     },
88101
88102     dispatchEvent: function (event) {
88103         if (event === undefined) {
88104             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
88105         }
88106         return _data[event].exec(event);
88107     }
88108 };
88109
88110 _self.__defineGetter__("charging", function () {
88111     return _data.charging;
88112 });
88113
88114 _self.__defineGetter__("chargingTime", function () {
88115     return _data.chargingTime;
88116 });
88117
88118 _self.__defineGetter__("level", function () {
88119     return _data.level;
88120 });
88121
88122 _self.__defineGetter__("dischargingTime", function () {
88123     return _data.dischargingTime;
88124 });
88125
88126 function _initialize() {
88127     var callback = [];
88128
88129     function bind(name) {
88130         _self.__defineGetter__(name, function () {
88131             return callback;
88132         });
88133
88134         _self.__defineSetter__(name, function (cb) {
88135             callback = cb;
88136         });
88137
88138         return {
88139             get: function () {
88140                 return callback;
88141             },
88142
88143             set: function (value) {
88144                 callback = value;
88145             },
88146
88147             add: function (value) {
88148                 callback.push(value);
88149             },
88150
88151             exec: function (arg) {
88152                 callback.forEach(function (callback) {
88153                     return !callback || callback(arg);
88154                 });
88155             },
88156
88157             unbind: function (value) {
88158                 if (value === undefined) {
88159                     callback = [];
88160                 } else {
88161                     utils.forEach(callback, function (callback, index) {
88162                         if (callback === value) {
88163                             callback.splice(index, 1);
88164                         }
88165                     });
88166                 }
88167             }
88168         };
88169     }
88170
88171     _data.chargingchange        = bind("onchargingchange");
88172     _data.chargingtimechange    = bind("onchargingtimechange");
88173     _data.levelchange           = bind("onlevelchange");
88174     _data.dischargingtimechange = bind("ondischargingtimechange");
88175
88176     event.on("BatteryEvent", function (status) {
88177         for (var ev in status) {
88178             if ((status[ev] !== undefined) && (status[ev] !== _data[ev])) {
88179                 _data[ev] = status[ev];
88180             }
88181         }
88182         _data[status.type].exec();
88183     });
88184 }
88185
88186 _initialize();
88187
88188 module.exports = _self;
88189
88190 });
88191 define('ripple/platform/tizen/2.0/CalendarTask', function (require, exports, module) {
88192 /*
88193  *  Copyright 2013 Intel Corporation.
88194  *
88195  * Licensed under the Apache License, Version 2.0 (the "License");
88196  * you may not use this file except in compliance with the License.
88197  * You may obtain a copy of the License at
88198  *
88199  * http://www.apache.org/licenses/LICENSE-2.0
88200  *
88201  * Unless required by applicable law or agreed to in writing, software
88202  * distributed under the License is distributed on an "AS IS" BASIS,
88203  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88204  * See the License for the specific language governing permissions and
88205  * limitations under the License.
88206  */
88207
88208 var t = require('ripple/platform/tizen/2.0/typecast'),
88209     typedef = require('ripple/platform/tizen/2.0/typedef'),
88210     CalendarItem = require('ripple/platform/tizen/2.0/CalendarItem'),
88211     CalendarTask;
88212
88213 CalendarTask = function () {
88214     var voc, calendarTask = {};
88215
88216     // private
88217     function construct(taskInitDict) {
88218         CalendarItem.call(this, taskInitDict);
88219
88220         this.status = "NEEDS_ACTION";
88221
88222         calendarTask.convertToString = this.convertToString;
88223         calendarTask.dueDate         = null;
88224         calendarTask.completedDate   = null;
88225         calendarTask.progress        = 0;
88226
88227         this.__defineGetter__("dueDate", function () {
88228             return calendarTask.dueDate;
88229         });
88230         this.__defineSetter__("dueDate", function (val) {
88231             try {
88232                 calendarTask.dueDate = t.TZDate(val, "?");
88233             } catch (e) {
88234             }
88235         });
88236
88237         this.__defineGetter__("completedDate", function () {
88238             return calendarTask.completedDate;
88239         });
88240         this.__defineSetter__("completedDate", function (val) {
88241             try {
88242                 calendarTask.completedDate = t.TZDate(val, "?");
88243             } catch (e) {
88244             }
88245         });
88246
88247         this.__defineGetter__("progress", function () {
88248             return calendarTask.progress;
88249         });
88250         this.__defineSetter__("progress", function (val) {
88251             try {
88252                 calendarTask.progress = t.unsigned_short(val);
88253             } catch (e) {
88254             }
88255         });
88256
88257         this.convertToString = convertToString;
88258         this.clone           = clone(this);
88259     }
88260
88261     function clone(self) {
88262         return function () {
88263             return new CalendarTask(self);
88264         };
88265     }
88266
88267     // public
88268     function convertToString(format) {
88269         var str;
88270
88271         str = calendarTask.convertToString.call(this, format);
88272         str = str.replace(/#TYPE#/g, "VTASK");
88273
88274         // TODO: dueDate is not supported
88275         // TODO: completedDate is not supported
88276         if (this.progress) {
88277             str = str.replace(/#PROGRESS#/g, "PERCENT-COMPLETE:" +
88278                     this.progress + "\r\n");
88279         }
88280
88281         str = str.replace(/#AVAILABILITY#.*\r\n/g, "");
88282         str = str.replace(/#[^#]*#/g, "");
88283
88284         return str;
88285     }
88286
88287     // Constructor
88288     function CalendarTask_CalendarTaskInit(taskInitDict) {
88289         var attr;
88290
88291         construct.call(this, taskInitDict);
88292
88293         if (taskInitDict) {
88294             for (attr in taskInitDict) {
88295                 if (attr in typedef.CalendarTaskInit) {
88296                     calendarTask[attr] = taskInitDict[attr];
88297                 }
88298             }
88299         }
88300     }
88301
88302     function CalendarTask_DOMString_CalendarTextFormat(stringRepresentation,
88303             format) {
88304     }
88305
88306     voc = [CalendarTask_CalendarTaskInit,
88307            CalendarTask_DOMString_CalendarTextFormat];
88308     t.CalendarTask(arguments, this, voc);
88309 };
88310
88311 module.exports = CalendarTask;
88312
88313 });
88314 define('ripple/platform/tizen/2.0/pendingObject', function (require, exports, module) {
88315 /*
88316  *  Copyright 2011 Intel Corporation.
88317  *
88318  * Licensed under the Apache License, Version 2.0 (the "License");
88319  * you may not use this file except in compliance with the License.
88320  * You may obtain a copy of the License at
88321  *
88322  * http://www.apache.org/licenses/LICENSE-2.0
88323  *
88324  * Unless required by applicable law or agreed to in writing, software
88325  * distributed under the License is distributed on an "AS IS" BASIS,
88326  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88327  * See the License for the specific language governing permissions and
88328  * limitations under the License.
88329  */
88330
88331 module.exports = function (pendingObj) {
88332     var cancelFlag = true;
88333     this.setCancelFlag = function (flag) {
88334         cancelFlag = flag;
88335     };
88336     this.getCancelFlag = function () {
88337         return cancelFlag;
88338     };
88339     this.userCancel = null;
88340     this.pendingID = null;
88341 };
88342
88343 });
88344 define('ripple/platform/tizen/2.0/PackageInformation', function (require, exports, module) {
88345 /*
88346  *  Copyright 2013 Intel Corporation.
88347  *
88348  * Licensed under the Apache License, Version 2.0 (the "License");
88349  * you may not use this file except in compliance with the License.
88350  * You may obtain a copy of the License at
88351  *
88352  * http://www.apache.org/licenses/LICENSE-2.0
88353  *
88354  * Unless required by applicable law or agreed to in writing, software
88355  * distributed under the License is distributed on an "AS IS" BASIS,
88356  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88357  * See the License for the specific language governing permissions and
88358  * limitations under the License.
88359  */
88360 module.exports = function (id, name, iconPath, version, totalSize,
88361         dataSize, lastModified, author, description, appIds) {
88362     var packageInformation = {}, _date = new Date(lastModified);
88363
88364     packageInformation.__defineGetter__("id", function () {
88365         return id;
88366     });
88367     packageInformation.__defineGetter__("name", function () {
88368         return name;
88369     });
88370     packageInformation.__defineGetter__("iconPath", function () {
88371         return iconPath;
88372     });
88373     packageInformation.__defineGetter__("version", function () {
88374         return version;
88375     });
88376     packageInformation.__defineGetter__("totalSize", function () {
88377         return totalSize;
88378     });
88379     packageInformation.__defineGetter__("dataSize", function () {
88380         return dataSize;
88381     });
88382     packageInformation.__defineGetter__("lastModified", function () {
88383         return _date;
88384     });
88385     packageInformation.__defineGetter__("author", function () {
88386         return author;
88387     });
88388     packageInformation.__defineGetter__("description", function () {
88389         return description;
88390     });
88391     packageInformation.__defineGetter__("appIds", function () {
88392         return appIds;
88393     });
88394
88395     return packageInformation;
88396 };
88397
88398 });
88399 define('ripple/platform/tizen/2.0/POIFilter', function (require, exports, module) {
88400 /*
88401  *  Copyright 2012 Intel Corporation.
88402  *
88403  * Licensed under the Apache License, Version 2.0 (the "License");
88404  * you may not use this file except in compliance with the License.
88405  * You may obtain a copy of the License at
88406  *
88407  * http://www.apache.org/licenses/LICENSE-2.0
88408  *
88409  * Unless required by applicable law or agreed to in writing, software
88410  * distributed under the License is distributed on an "AS IS" BASIS,
88411  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88412  * See the License for the specific language governing permissions and
88413  * limitations under the License.
88414  */
88415
88416 module.exports = function (attributeName, value) {
88417     var _self;
88418
88419     _self = {
88420         attributeName: attributeName,
88421         value: value
88422     };
88423
88424     return _self;
88425 };
88426
88427 });
88428 define('ripple/platform/tizen/2.0/GeoPolyBounds', function (require, exports, module) {
88429 /*
88430  *  Copyright 2012 Intel Corporation.
88431  *
88432  * Licensed under the Apache License, Version 2.0 (the "License");
88433  * you may not use this file except in compliance with the License.
88434  * You may obtain a copy of the License at
88435  *
88436  * http://www.apache.org/licenses/LICENSE-2.0
88437  *
88438  * Unless required by applicable law or agreed to in writing, software
88439  * distributed under the License is distributed on an "AS IS" BASIS,
88440  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88441  * See the License for the specific language governing permissions and
88442  * limitations under the License.
88443  */
88444
88445 module.exports = function (_points) {
88446     var points = _points || [];
88447
88448     this.__defineGetter__("points", function () {
88449         return points;
88450     });
88451 };
88452
88453 });
88454 define('ripple/platform/tizen/2.0/POIGeometry', function (require, exports, module) {
88455 /*
88456  *  Copyright 2012 Intel Corporation.
88457  *
88458  * Licensed under the Apache License, Version 2.0 (the "License");
88459  * you may not use this file except in compliance with the License.
88460  * You may obtain a copy of the License at
88461  *
88462  * http://www.apache.org/licenses/LICENSE-2.0
88463  *
88464  * Unless required by applicable law or agreed to in writing, software
88465  * distributed under the License is distributed on an "AS IS" BASIS,
88466  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88467  * See the License for the specific language governing permissions and
88468  * limitations under the License.
88469  */
88470
88471 var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
88472     GeoRectBounds = require('ripple/platform/tizen/2.0/GeoRectBounds');
88473
88474 module.exports = function (position, viewport, wkt) {
88475     var _self, _position = null, _viewport = null, _wkt = "";
88476
88477     if (position) {
88478         _position = new SimpleCoordinates(position.latitude, position.longitude);
88479     }
88480
88481     if (viewport) {
88482         _viewport = new GeoRectBounds(viewport.southWest, viewport.northEast);
88483     }
88484
88485     if (wkt) {
88486         _wkt = String(wkt);
88487     }
88488
88489     _self = {
88490         position : _position,
88491         viewport: _viewport,
88492         wkt: _wkt
88493     };
88494
88495     return _self;
88496 };
88497
88498 });
88499 define('ripple/platform/tizen/2.0/BluetoothClass', function (require, exports, module) {
88500 /*
88501  *  Copyright 2013 Intel Corporation.
88502  *
88503  * Licensed under the Apache License, Version 2.0 (the "License");
88504  * you may not use this file except in compliance with the License.
88505  * You may obtain a copy of the License at
88506  *
88507  * http://www.apache.org/licenses/LICENSE-2.0
88508  *
88509  * Unless required by applicable law or agreed to in writing, software
88510  * distributed under the License is distributed on an "AS IS" BASIS,
88511  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88512  * See the License for the specific language governing permissions and
88513  * limitations under the License.
88514  */
88515
88516 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
88517     t = require('ripple/platform/tizen/2.0/typecast'),
88518     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
88519     BluetoothClass,
88520     _security;
88521
88522 BluetoothClass = function (prop, metaData) {
88523     var bluetoothClass = {};
88524
88525     _security = metaData;
88526
88527     bluetoothClass.major    = prop.major || 0;
88528     bluetoothClass.minor    = prop.minor || 0;
88529     bluetoothClass.services = prop.services || [];
88530
88531     this.__defineGetter__("major", function () {
88532         return bluetoothClass.major;
88533     });
88534
88535     this.__defineGetter__("minor", function () {
88536         return bluetoothClass.minor;
88537     });
88538
88539     this.__defineGetter__("services", function () {
88540         return bluetoothClass.services;
88541     });
88542
88543     bluetoothClass.services.forEach(function (service, i) {
88544         bluetoothClass.services.__defineGetter__(i, function () {
88545             return service;
88546         });
88547     });
88548
88549     this.hasService = function (service) {
88550         if (!_security.hasService) {
88551             throw new WebAPIException(errorcode.SECURITY_ERR);
88552         }
88553
88554         t.BluetoothClass("hasService", arguments);
88555
88556         return (bluetoothClass.services.join(",").indexOf(service) !== -1);
88557     };
88558 };
88559
88560 module.exports = BluetoothClass;
88561
88562 });
88563 define('ripple/platform/tizen/2.0/NDEFRecordURI', function (require, exports, module) {
88564 /*
88565  *  Copyright 2013 Intel Corporation
88566  *
88567  * Licensed under the Apache License, Version 2.0 (the "License");
88568  * you may not use this file except in compliance with the License.
88569  * You may obtain a copy of the License at
88570  *
88571  * http://www.apache.org/licenses/LICENSE-2.0
88572  *
88573  * Unless required by applicable law or agreed to in writing, software
88574  * distributed under the License is distributed on an "AS IS" BASIS,
88575  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88576  * See the License for the specific language governing permissions and
88577  * limitations under the License.
88578  */
88579
88580 var t = require('ripple/platform/tizen/2.0/typecast'),
88581     NDEFRecordInternal = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
88582     NDEFRecordURI;
88583
88584 NDEFRecordURI = function (uri) {
88585     var payload = [], i;
88586
88587     t.NDEFRecordURI(arguments, this);
88588
88589     // Store uri in payload
88590     payload.push(0);
88591     for (i = 0; i < uri.length; i++) {
88592         payload.push(uri.charCodeAt(i));
88593     }
88594
88595     NDEFRecordInternal.call(this, tizen.nfc.NFC_RECORD_TNF_WELL_KNOWN,
88596             ["U".charCodeAt(0)], payload, []);
88597
88598     this.__defineGetter__("uri", function () {
88599         return uri;
88600     });
88601 };
88602
88603 module.exports = NDEFRecordURI;
88604
88605 });
88606 define('ripple/platform/tizen/2.0/StatusNotification', function (require, exports, module) {
88607 /*
88608  *  Copyright 2013 Intel Corporation.
88609  *
88610  * Licensed under the Apache License, Version 2.0 (the "License");
88611  * you may not use this file except in compliance with the License.
88612  * You may obtain a copy of the License at
88613  *
88614  * http://www.apache.org/licenses/LICENSE-2.0
88615  *
88616  * Unless required by applicable law or agreed to in writing, software
88617  * distributed under the License is distributed on an "AS IS" BASIS,
88618  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88619  * See the License for the specific language governing permissions and
88620  * limitations under the License.
88621  */
88622
88623 var t = require('ripple/platform/tizen/2.0/typecast'),
88624     ApplicationControl = require('ripple/platform/tizen/2.0/ApplicationControl'),
88625     Notification = require('ripple/platform/tizen/2.0/NotificationBase'),
88626     NotificationDetailInfo = require('ripple/platform/tizen/2.0/NotificationDetailInfo'),
88627     StatusNotification;
88628
88629 StatusNotification = function (statusType, title, notificationInitDict) {
88630     var statusNotification = {}, attr, i, info;
88631
88632     t.StatusNotification(arguments, this);
88633
88634     Notification.call(this, title, notificationInitDict ?
88635             notificationInitDict.content : null);
88636
88637     statusNotification.statusType          = statusType;
88638     statusNotification.iconPath            = null;
88639     statusNotification.subIconPath         = null;
88640     statusNotification.number              = null;
88641     statusNotification.detailInfo          = [];
88642     statusNotification.ledColor            = null;
88643     statusNotification.ledOnPeriod         = 0;
88644     statusNotification.ledOffPeriod        = 0;
88645     statusNotification.backgroundImagePath = null;
88646     statusNotification.thumbnails          = [];
88647     statusNotification.soundPath           = null;
88648     statusNotification.vibration           = false;
88649     statusNotification.appControl          = null;
88650     statusNotification.appId               = null;
88651     statusNotification.progressType        = "PERCENTAGE";
88652     statusNotification.progressValue       = null;
88653
88654     for (attr in notificationInitDict) {
88655         switch (attr) {
88656         case "appControl":
88657             statusNotification.appControl = new ApplicationControl(
88658                     notificationInitDict.appControl.operation,
88659                     notificationInitDict.appControl.uri || null,
88660                     notificationInitDict.appControl.mime || null,
88661                     notificationInitDict.appControl.category || null,
88662                     notificationInitDict.appControl.data || null);
88663             break;
88664
88665         case "detailInfo":
88666             for (i in notificationInitDict.detailInfo) {
88667                 info = notificationInitDict.detailInfo[i];
88668                 info = new NotificationDetailInfo(info.mainText,
88669                         info.subText);
88670
88671                 statusNotification.detailInfo.push(info);
88672             }
88673             break;
88674
88675         default:
88676             statusNotification[attr] = notificationInitDict[attr];
88677             break;
88678         }
88679     }
88680
88681     this.__defineGetter__("statusType", function () {
88682         return statusNotification.statusType;
88683     });
88684
88685     this.__defineGetter__("iconPath", function () {
88686         return statusNotification.iconPath;
88687     });
88688     this.__defineSetter__("iconPath", function (val) {
88689         try {
88690             statusNotification.iconPath = t.DOMString(val, "?");
88691         } catch (e) {
88692         }
88693     });
88694
88695     this.__defineGetter__("subIconPath", function () {
88696         return statusNotification.subIconPath;
88697     });
88698     this.__defineSetter__("subIconPath", function (val) {
88699         try {
88700             statusNotification.subIconPath = t.DOMString(val, "?");
88701         } catch (e) {
88702         }
88703     });
88704
88705     this.__defineGetter__("number", function () {
88706         return statusNotification.number;
88707     });
88708     this.__defineSetter__("number", function (val) {
88709         try {
88710             statusNotification.number = t.long(val, "?");
88711         } catch (e) {
88712         }
88713     });
88714
88715     this.__defineGetter__("detailInfo", function () {
88716         return statusNotification.detailInfo;
88717     });
88718     this.__defineSetter__("detailInfo", function (val) {
88719         try {
88720             statusNotification.detailInfo = t.NotificationDetailInfo(val, "[]?");
88721         } catch (e) {
88722         }
88723     });
88724
88725     this.__defineGetter__("ledColor", function () {
88726         return statusNotification.ledColor;
88727     });
88728     this.__defineSetter__("ledColor", function (val) {
88729         try {
88730             statusNotification.ledColor = t.DOMString(val, "?");
88731         } catch (e) {
88732         }
88733     });
88734
88735     this.__defineGetter__("ledOnPeriod", function () {
88736         return statusNotification.ledOnPeriod;
88737     });
88738     this.__defineSetter__("ledOnPeriod", function (val) {
88739         try {
88740             statusNotification.ledOnPeriod = t.unsigned_long(val);
88741         } catch (e) {
88742         }
88743     });
88744
88745     this.__defineGetter__("ledOffPeriod", function () {
88746         return statusNotification.ledOffPeriod;
88747     });
88748     this.__defineSetter__("ledOffPeriod", function (val) {
88749         try {
88750             statusNotification.ledOffPeriod = t.unsigned_long(val);
88751         } catch (e) {
88752         }
88753     });
88754
88755     this.__defineGetter__("backgroundImagePath", function () {
88756         return statusNotification.backgroundImagePath;
88757     });
88758     this.__defineSetter__("backgroundImagePath", function (val) {
88759         try {
88760             statusNotification.backgroundImagePath = t.DOMString(val, "?");
88761         } catch (e) {
88762         }
88763     });
88764
88765     this.__defineGetter__("thumbnails", function () {
88766         return statusNotification.thumbnails;
88767     });
88768     this.__defineSetter__("thumbnails", function (val) {
88769         try {
88770             statusNotification.thumbnails = t.DOMString(val, "[]?");
88771         } catch (e) {
88772         }
88773     });
88774
88775     this.__defineGetter__("soundPath", function () {
88776         return statusNotification.soundPath;
88777     });
88778     this.__defineSetter__("soundPath", function (val) {
88779         try {
88780             statusNotification.soundPath = t.DOMString(val, "?");
88781         } catch (e) {
88782         }
88783     });
88784
88785     this.__defineGetter__("vibration", function () {
88786         return statusNotification.vibration;
88787     });
88788     this.__defineSetter__("vibration", function (val) {
88789         try {
88790             statusNotification.vibration = t.boolean(val);
88791         } catch (e) {
88792         }
88793     });
88794
88795     this.__defineGetter__("appControl", function () {
88796         return statusNotification.appControl;
88797     });
88798     this.__defineSetter__("appControl", function (val) {
88799         try {
88800             statusNotification.appControl = t.ApplicationControl(val, "?");
88801         } catch (e) {
88802         }
88803     });
88804
88805     this.__defineGetter__("appId", function () {
88806         return statusNotification.appId;
88807     });
88808     this.__defineSetter__("appId", function (val) {
88809         try {
88810             statusNotification.appId = t.ApplicationId(val, "?");
88811         } catch (e) {
88812         }
88813     });
88814
88815     this.__defineGetter__("progressType", function () {
88816         return statusNotification.progressType;
88817     });
88818     this.__defineSetter__("progressType", function (val) {
88819         try {
88820             statusNotification.progressType = t.NotificationProgressType(val);
88821         } catch (e) {
88822         }
88823     });
88824
88825     this.__defineGetter__("progressValue", function () {
88826         return statusNotification.progressValue;
88827     });
88828     this.__defineSetter__("progressValue", function (val) {
88829         try {
88830             val = t.unsigned_long(val, '?');
88831
88832             if ((statusNotification.progressType === "PERCENTAGE") &&
88833                     (val > 100))
88834                 return;
88835
88836             statusNotification.progressValue = val;
88837         } catch (e) {
88838         }
88839     });
88840 };
88841
88842 module.exports = StatusNotification;
88843
88844 });
88845 define('ripple/platform/tizen/2.0/WebAPIError', function (require, exports, module) {
88846 /*
88847  *  Copyright 2012 Intel Corporation.
88848  *
88849  * Licensed under the Apache License, Version 2.0 (the "License");
88850  * you may not use this file except in compliance with the License.
88851  * You may obtain a copy of the License at
88852  *
88853  * http://www.apache.org/licenses/LICENSE-2.0
88854  *
88855  * Unless required by applicable law or agreed to in writing, software
88856  * distributed under the License is distributed on an "AS IS" BASIS,
88857  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88858  * See the License for the specific language governing permissions and
88859  * limitations under the License.
88860  */
88861
88862 var errorcode = require('ripple/platform/tizen/2.0/errorcode');
88863
88864 var msg = {
88865     0: "Generic Error",
88866     1: "Index or size is negative, or greater than the allowed value.",
88867     2: "Specified range of text does not fit into a DOMString.",
88868     3: "Node is inserted somewhere it doesn't belong.",
88869     4: "Node is used in a different document than the one that created it (that doesn't support it).",
88870     5: "An invalid or illegal character is specified.",
88871     6: "Data is specified for a Node which does not support data.",
88872     7: "An attempt is made to modify an object where modifications are not allowed.",
88873     8: "An attempt is made to reference a Node in a context where it does not exist.",
88874     9: "The implementation does not support the requested type of object or operation.",
88875     10: "An attempt is made to add an attribute that is already in use elsewhere.",
88876     11: "An attempt is made to use an object that is not, or is no longer, usable.",
88877     12: "An invalid or illegal string is specified.",
88878     13: "An attempt is made to modify the type of the underlying object.",
88879     14: "An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.",
88880     15: "A parameter or an operation is not supported by the underlying object.",
88881     16: "A call to a method such as insertBefore or removeChild would make the Node invalid with respect to \"partial validity\", this exception would be raised and the operation would not be done.",
88882     17: "The type of an object is incompatible with the expected type of the parameter associated to the object.",
88883     18: "An attempt is made to perform an operation or access some data in a way that would be a security risk or a violation of the user agent's security policy.",
88884     19: "A network error occurs in synchronous requests.",
88885     20: "The abort error occurs in asynchronous requests by user prompt.",
88886     21: "The operation could not be completed because the URL does not match.",
88887     22: "The quota has been exceeded.",
88888     23: "The operation timed out.",
88889     24: "The supplied node is incorrect or has an incorrect ancestor for this operation.",
88890     25: "The object can not be cloned.",
88891     99: "The content of an object does not include valid values.",
88892     100: "Error occurred in communication with the underlying implementation that meant the requested method could not complete.",
88893     111: "Requested service is not available."
88894 },
88895     errType = {
88896     0: "UnknownError",
88897     1: "IndexSizeError",
88898     2: "DOMStringSizeError",
88899     3: "HierarchyRequestError",
88900     4: "WrongDocumentError",
88901     5: "InvalidCharacterError",
88902     6: "NoDataAllowedError",
88903     7: "NoModificationAllowedError",
88904     8: "NotFoundError",
88905     9: "NotSupportedError",
88906     10: "InuseAttributeError",
88907     11: "InvalidStateError",
88908     12: "SyntaxError",
88909     13: "InvalidModificationError",
88910     14: "NamespaceError",
88911     15: "InvalidAccessError",
88912     16: "ValidationError",
88913     17: "TypeMismatchError",
88914     18: "SecurityError",
88915     19: "NetworkError",
88916     20: "AbortError",
88917     21: "URLMismatchError",
88918     22: "QuotaExceededError",
88919     23: "TimeoutError",
88920     24: "InvalidNodeTypeError",
88921     25: "DataCloneError",
88922     99: "InvalidValuesError",
88923     100: "IOError",
88924     111: "ServiceNotAvailableError"
88925 };
88926
88927 /*
88928   support 3 types of error:
88929   - WebAPIError()
88930       code = errorcode.UNKNOWN_ERR
88931       message = errorcode.message[UNKNOWN_ERR]
88932   - WebAPIError(errorcode."TYPE_MISMATCH_ERR")
88933       code = 17
88934       message = errorcode.message[17]
88935   - WebAPIError(my_own_error_code, "This is my error message.")
88936       code = my_own_error_code(number)
88937       message = "This is my error message."
88938 */
88939
88940 module.exports = function (code, message, name) {
88941     var _code, _message, _name;
88942
88943     if (typeof code !== 'number') {
88944         _code = errorcode.UNKNOWN_ERR;
88945         _message = msg[_code];
88946         _name = errType[_code];
88947     } else {
88948         _code = code;
88949         if (typeof message === 'string') {
88950             _message = message;
88951         } else {
88952             _message = msg[_code];
88953         }
88954         if (typeof name === 'string') {
88955             _name = name;
88956         } else {
88957             _name = errType[_code];
88958         }
88959     }
88960
88961     this.__defineGetter__("code", function () {
88962         return _code;
88963     });
88964     this.__defineGetter__("message", function () {
88965         return _message;
88966     });
88967     this.__defineGetter__("name", function () {
88968         return _name;
88969     });
88970 };
88971
88972 });
88973 define('ripple/platform/tizen/2.0/notification', function (require, exports, module) {
88974 /*
88975  *  Copyright 2013 Intel Corporation.
88976  *
88977  * Licensed under the Apache License, Version 2.0 (the "License");
88978  * you may not use this file except in compliance with the License.
88979  * You may obtain a copy of the License at
88980  *
88981  * http://www.apache.org/licenses/LICENSE-2.0
88982  *
88983  * Unless required by applicable law or agreed to in writing, software
88984  * distributed under the License is distributed on an "AS IS" BASIS,
88985  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
88986  * See the License for the specific language governing permissions and
88987  * limitations under the License.
88988  */
88989
88990 var db = require('ripple/db'),
88991     utils = require('ripple/utils'),
88992     event = require('ripple/event'),
88993     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
88994     t = require('ripple/platform/tizen/2.0/typecast'),
88995     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
88996     StatusNotification = require('ripple/platform/tizen/2.0/StatusNotification'),
88997     _notificationStack,
88998     _security = {
88999         "http://tizen.org/privilege/notification": ["post", "update", "remove",
89000                 "removeAll"]
89001     },
89002     _self;
89003
89004 _self = function () {
89005     function post(notification) {
89006         var posted = {};
89007
89008         if (!_security.post) {
89009             throw new WebAPIException(errorcode.SECURITY_ERR);
89010         }
89011
89012         t.NotificationManager("post", arguments);
89013
89014         if (notification.id !== undefined) {
89015             return;
89016         }
89017         posted.id = Math.uuid(null, 16);
89018
89019         notification.__defineGetter__("id", function () {
89020             return posted.id;
89021         });
89022
89023         if (!_notificationStack[notification.id]) {
89024             posted.postedTime = new Date();
89025
89026             notification.__defineGetter__("postedTime", function () {
89027                 return posted.postedTime;
89028             });
89029
89030             _notificationStack[notification.id] = t.Notification(notification,
89031                     "+");
89032             db.saveObject("posted-notifications", _notificationStack);
89033             event.trigger("refreshNotificationUI", [], true);
89034         }
89035     }
89036
89037     function update(notification) {
89038         if (!_security.update) {
89039             throw new WebAPIException(errorcode.SECURITY_ERR);
89040         }
89041
89042         t.NotificationManager("update", arguments);
89043
89044         if (!_notificationStack[notification.id]) {
89045             throw new WebAPIException(errorcode.UNKNOWN_ERR);
89046         }
89047         _notificationStack[notification.id] = t.Notification(notification,
89048                 "+");
89049         db.saveObject("posted-notifications", _notificationStack);
89050         event.trigger("refreshNotificationUI", [], true);
89051     }
89052
89053     function remove(id) {
89054         if (!_security.remove) {
89055             throw new WebAPIException(errorcode.SECURITY_ERR);
89056         }
89057
89058         t.NotificationManager("remove", arguments);
89059
89060         if (!_notificationStack[id]) {
89061             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
89062         }
89063         delete _notificationStack[id];
89064         db.saveObject("posted-notifications", _notificationStack);
89065         event.trigger('refreshNotificationUI', [], true);
89066     }
89067
89068     function removeAll() {
89069         if (!_security.removeAll) {
89070             throw new WebAPIException(errorcode.SECURITY_ERR);
89071         }
89072
89073         _notificationStack = {};
89074         db.saveObject("posted-notifications", _notificationStack);
89075         event.trigger('refreshNotificationUI', [], true);
89076     }
89077
89078     function get(id) {
89079         var n, notification;
89080
89081         t.NotificationManager("get", arguments);
89082
89083         if (!_notificationStack[id]) {
89084             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
89085         }
89086         n = _notificationStack[id];
89087         notification = new StatusNotification(n.statusType, n.title, n);
89088
89089         notification.__defineGetter__("id", function () {
89090             return n.id;
89091         });
89092
89093         notification.__defineGetter__("postedTime", function () {
89094             return n.postedTime;
89095         });
89096
89097         return notification;
89098     }
89099
89100     function getAll() {
89101         var notifications = [];
89102
89103         utils.forEach(_notificationStack, function (n) {
89104             var notification;
89105
89106             notification = new StatusNotification(n.statusType, n.title, n);
89107
89108             notification.__defineGetter__("id", function () {
89109                 return n.id;
89110             });
89111
89112             notification.__defineGetter__("postedTime", function () {
89113                 return n.postedTime;
89114             });
89115
89116             notifications.push(notification);
89117         });
89118
89119         return notifications;
89120     }
89121
89122     function handleSubFeatures(subFeatures) {
89123         var i, subFeature;
89124
89125         for (subFeature in subFeatures) {
89126             for (i in _security[subFeature]) {
89127                 _security[_security[subFeature][i]] = true;
89128             }
89129         }
89130     }
89131
89132     var notification = {
89133         post:              post,
89134         update:            update,
89135         remove:            remove,
89136         removeAll:         removeAll,
89137         get:               get,
89138         getAll:            getAll,
89139         handleSubFeatures: handleSubFeatures
89140     };
89141
89142     return notification;
89143 };
89144
89145 function _initilize() {
89146     _notificationStack = db.retrieveObject("posted-notifications") || {};
89147
89148     utils.forEach(_notificationStack, function (n) {
89149         n.postedTime = new Date(n.postedTime);
89150     });
89151
89152     event.on("refreshNotificationStack", function () {
89153         _notificationStack = db.retrieveObject("posted-notifications");
89154     });
89155 }
89156
89157 _initilize();
89158
89159 module.exports = _self;
89160
89161 });
89162 define('ripple/platform/tizen/2.0/AttributeRangeFilter', function (require, exports, module) {
89163 /*
89164  *  Copyright 2013 Intel Corporation.
89165  *
89166  * Licensed under the Apache License, Version 2.0 (the "License");
89167  * you may not use this file except in compliance with the License.
89168  * You may obtain a copy of the License at
89169  *
89170  * http://www.apache.org/licenses/LICENSE-2.0
89171  *
89172  * Unless required by applicable law or agreed to in writing, software
89173  * distributed under the License is distributed on an "AS IS" BASIS,
89174  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89175  * See the License for the specific language governing permissions and
89176  * limitations under the License.
89177  */
89178
89179 var t = require('ripple/platform/tizen/2.0/typecast'),
89180     AttributeRangeFilter;
89181
89182 AttributeRangeFilter = function (attributeName, initialValue, endValue) {
89183     var attributeRangeFilter = {};
89184
89185     t.AttributeRangeFilter(arguments, this);
89186
89187     this.__defineGetter__("attributeName", function () {
89188         return attributeRangeFilter.attributeName;
89189     });
89190     this.__defineSetter__("attributeName", function (val) {
89191         try {
89192             attributeRangeFilter.attributeName = t.DOMString(val);
89193         } catch (e) {
89194         }
89195     });
89196
89197     attributeRangeFilter.attributeName = attributeName;
89198
89199     this.initialValue = initialValue || null;
89200     this.endValue     = endValue || null;
89201 };
89202
89203 module.exports = AttributeRangeFilter;
89204
89205 });
89206 define('ripple/platform/tizen/2.0/SyncStatistics', function (require, exports, module) {
89207 /*
89208  *  Copyright 2013 Intel Corporation.
89209  *
89210  * Licensed under the Apache License, Version 2.0 (the "License");
89211  * you may not use this file except in compliance with the License.
89212  * You may obtain a copy of the License at
89213  *
89214  * http://www.apache.org/licenses/LICENSE-2.0
89215  *
89216  * Unless required by applicable law or agreed to in writing, software
89217  * distributed under the License is distributed on an "AS IS" BASIS,
89218  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89219  * See the License for the specific language governing permissions and
89220  * limitations under the License.
89221  */
89222
89223 var SyncStatistics = function (syncStatus, serviceType, lastSyncTime,
89224         serverToClientTotal, serverToClientAdded, serverToClientUpdated,
89225         serverToClientRemoved, clientToServerTotal, clientToServerAdded,
89226         clientToServerUpdated, clientToServerRemoved) {
89227     this.__defineGetter__("syncStatus", function () {
89228         return syncStatus;
89229     });
89230
89231     this.__defineGetter__("serviceType", function () {
89232         return serviceType;
89233     });
89234
89235     this.__defineGetter__("lastSyncTime", function () {
89236         return lastSyncTime;
89237     });
89238
89239     this.__defineGetter__("serverToClientTotal", function () {
89240         return serverToClientTotal;
89241     });
89242
89243     this.__defineGetter__("serverToClientAdded", function () {
89244         return serverToClientAdded;
89245     });
89246
89247     this.__defineGetter__("serverToClientUpdated", function () {
89248         return serverToClientUpdated;
89249     });
89250
89251     this.__defineGetter__("serverToClientRemoved", function () {
89252         return serverToClientRemoved;
89253     });
89254
89255     this.__defineGetter__("clientToServerTotal", function () {
89256         return clientToServerTotal;
89257     });
89258
89259     this.__defineGetter__("clientToServerAdded", function () {
89260         return clientToServerAdded;
89261     });
89262
89263     this.__defineGetter__("clientToServerUpdated", function () {
89264         return clientToServerUpdated;
89265     });
89266
89267     this.__defineGetter__("clientToServerRemoved", function () {
89268         return clientToServerRemoved;
89269     });
89270 };
89271
89272 module.exports = SyncStatistics;
89273
89274 });
89275 define('ripple/platform/tizen/2.0/typedef', function (require, exports, module) {
89276 /*
89277  *  Copyright 2013 Intel Corporation.
89278  *
89279  * Licensed under the Apache License, Version 2.0 (the "License");
89280  * you may not use this file except in compliance with the License.
89281  * You may obtain a copy of the License at
89282  *
89283  * http://www.apache.org/licenses/LICENSE-2.0
89284  *
89285  * Unless required by applicable law or agreed to in writing, software
89286  * distributed under the License is distributed on an "AS IS" BASIS,
89287  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
89288  * See the License for the specific language governing permissions and
89289  * limitations under the License.
89290  */
89291
89292 var _t, _c, _i;
89293
89294 /*
89295  * Primitive type definition
89296  */
89297
89298 _t = {
89299     // Basic
89300     Callback:                           "Callback",
89301     DOMString:                          "",
89302     Date:                               new Date(),
89303     Function:                           function () {},
89304     TZDate:                             "TZDate",
89305     any:                                "any",
89306     boolean:                            false,
89307     byte:                               "byte",
89308     double:                             "double",
89309     float:                              "float",
89310     long:                               "long",
89311     octet:                              "octet",
89312     short:                              "short",
89313     long_long:                          "long long",
89314     unsigned_long:                      "unsigned long",
89315     unsigned_long_long:                 "unsigned long long",
89316     unsigned_short:                     "unsigned short",
89317
89318     // Common
89319     FilterMatchFlag:                    ["EXACTLY", "FULLSTRING", "CONTAINS",
89320                                          "STARTSWITH", "ENDSWITH", "EXISTS"],
89321     SortModeOrder:                      ["ASC", "DESC"],
89322     CompositeFilterType:                ["UNION", "INTERSECTION"],
89323
89324     // Bluetooth
89325     BluetoothSocketState:               ["CLOSED", "OPEN"],
89326     BluetoothProfileType:               ["HEALTH", "HEALTH"],
89327     BluetoothHealthChannelType:         ["RELIABLE", "STREAMING"],
89328
89329     // Calendar
89330     CalendarType:                       ["EVENT", "TASK"],
89331     CalendarTextFormat:                 ["ICALENDAR_20", "VCALENDAR_10"],
89332     AlarmMethod:                        ["SOUND", "DISPLAY"],
89333     RecurrenceRuleFrequency:            ["DAILY", "WEEKLY", "MONTHLY",
89334                                          "YEARLY"],
89335     ByDayValue:                         ["MO", "TU", "WE", "TH", "FR", "SA",
89336                                          "SU"],
89337     EventAvailability:                  ["BUSY", "FREE"],
89338     AttendeeType:                       ["INDIVIDUAL", "GROUP", "RESOURCE",
89339                                          "ROOM", "UNKNOWN"],
89340     AttendeeStatus:                     ["PENDING", "ACCEPTED", "DECLINED",
89341                                          "TENTATIVE", "DELEGATED", "COMPLETED",
89342                                          "IN_PROCESS"],
89343     AttendeeRole:                       ["REQ_PARTICIPANT", "OPT_PARTICIPANT",
89344                                          "NON_PARTICIPANT", "CHAIR"],
89345     CalendarItemPriority:               ["HIGH", "MEDIUM", "LOW"],
89346     CalendarItemVisibility:             ["PUBLIC", "PRIVATE", "CONFIDENTIAL"],
89347     CalendarItemStatus:                 ["TENTATIVE", "CONFIRMED", "CANCELLED",
89348                                          "NEEDS_ACTION", "IN_PROCESS",
89349                                          "COMPLETED"],
89350
89351     // Contact
89352     ContactTextFormat:                  ["VCARD_30", "VCARD_30"],    // Enum must has more than one value
89353
89354     // Content
89355     ContentDirectoryStorageType:        ["INTERNAL", "EXTERNAL"],
89356     ContentType:                        ["IMAGE", "VIDEO", "AUDIO", "OTHER"],
89357     AudioContentLyricsType:             ["SYNCHRONIZED", "UNSYNCHRONIZED"],
89358     ImageContentOrientation:            ["NORMAL", "FLIP_HORIZONTAL",
89359                                          "ROTATE_180", "FLIP_VERTICAL",
89360                                          "TRANSPOSE", "ROTATE_90", "TRANSVERSE",
89361                                          "ROTATE_270"],
89362
89363     // Data Control
89364     DataType:                           ["MAP", "SQL"],
89365
89366     // Data Synchronization
89367     SyncMode:                           ["MANUAL", "PERIODIC", "PUSH"],
89368     SyncType:                           ["TWO_WAY", "SLOW",
89369                                          "ONE_WAY_FROM_CLIENT",
89370                                          "REFRESH_FROM_CLIENT",
89371                                          "ONE_WAY_FROM_SERVER",
89372                                          "REFRESH_FROM_SERVER"],
89373     SyncInterval:                       ["5_MINUTES", "15_MINUTES", "1_HOUR",
89374                                          "4_HOURS", "12_HOURS", "1_DAY",
89375                                          "1_WEEK", "1_MONTH"],
89376     SyncServiceType:                    ["CONTACT", "EVENT"],
89377     SyncStatus:                         ["SUCCESS", "FAIL", "STOP", "NONE"],
89378
89379     // Download
89380     DownloadState:                      ["QUEUED", "DOWNLOADING", "PAUSED",
89381                                          "CANCELED", "COMPLETED", "FAILED"],
89382     DownloadNetworkType:                ["CELLULAR", "WIFI", "ALL"],
89383
89384     // Messaging
89385     MessageServiceTag:                  ["messaging.sms", "messaging.mms",
89386                                          "messaging.email"],
89387
89388     // Network Bearer Selection
89389     NetworkType:                        ["CELLULAR", "UNKNOWN"],
89390
89391     // NFC
89392     NDEFRecordTextEncoding:             ["UTF8", "UTF16"],
89393     NFCTagType:                         ["GENERIC_TARGET", "ISO14443_A",
89394                                          "ISO14443_4A", "ISO14443_3A",
89395                                          "MIFARE_MINI", "MIFARE_1K",
89396                                          "MIFARE_4K", "MIFARE_ULTRA",
89397                                          "MIFARE_DESFIRE", "ISO14443_B",
89398                                          "ISO14443_4B", "ISO14443_BPRIME",
89399                                          "FELICA", "JEWEL", "ISO15693",
89400                                          "UNKNOWN_TARGET"],
89401
89402     // Notification
89403     NotificationType:                   ["STATUS", "STATUS"],
89404     StatusNotificationType:             ["SIMPLE", "THUMBNAIL", "ONGOING",
89405                                          "PROGRESS"],
89406     NotificationProgressType:           ["PERCENTAGE", "BYTE"],
89407
89408     // System Info
89409     SystemInfoPropertyId:               ["BATTERY", "CPU", "STORAGE", "DISPLAY",
89410                                          "DEVICE_ORIENTATION", "BUILD",
89411                                          "LOCALE", "NETWORK", "WIFI_NETWORK",
89412                                          "CELLULAR_NETWORK", "SIM",
89413                                          "PERIPHERAL"],
89414     SystemInfoNetworkType:              ["NONE", "2G", "2.5G", "3G", "4G",
89415                                          "WIFI", "ETHERNET", "UNKNOWN"],
89416     SystemInfoDeviceOrientationStatus:  ["PORTRAIT_PRIMARY",
89417                                          "PORTRAIT_SECONDARY",
89418                                          "LANDSCAPE_PRIMARY",
89419                                          "LANDSCAPE_SECONDARY"],
89420     SystemInfoSimState:                 ["ABSENT", "INITIALIZING", "READY",
89421                                          "PIN_REQUIRED", "PUK_REQUIRED",
89422                                          "NETWORK_LOCKED", "SIM_LOCKED",
89423                                          "UNKNOWN"],
89424     SystemInfoProfile:                  ["MOBILE_FULL", "MOBILE_WEB"],
89425
89426     // System Setting
89427     SystemSettingType:                  ["HOME_SCREEN", "LOCK_SCREEN",
89428                                          "INCOMING_CALL", "NOTIFICATION_EMAIL"],
89429
89430     // Time
89431     TimeDurationUnit:                   ["MSECS", "SECS", "MINS", "HOURS",
89432                                          "DAYS"]
89433 };
89434
89435 /*
89436  * Derivative type definition
89437  */
89438
89439 /*
89440  * Object
89441  *
89442  * attributes
89443  *     Specify a type for each attribute.
89444  *
89445  * _optional
89446  *     Optional attributes table, which consists of two types of attributes,
89447  *
89448  *     nullable
89449  *         Nullable attributes, marked as '?' in IDL.
89450  *
89451  *     undefined
89452  *         Array type attributes, that not definitely specified to be
89453  *         initialized as an empty array, i.e., undefined-initialized array.
89454  *
89455  * _derived
89456  *     Subtype list, which consists of derived subtypes. It exists in the
89457  *     definition of a base type.
89458  *
89459  * _dictionary
89460  *     Dictionary type, which indicates that the object is a dictionary type.
89461  */
89462
89463 /*
89464  * Union types
89465  *     An array consists of two or more other types.
89466  */
89467
89468 /*
89469  * Common
89470  */
89471
89472 _t.AttributeFilter = {
89473     attributeName: _t.DOMString,
89474     matchFlag:     _t.FilterMatchFlag,
89475     matchValue:    _t.any,
89476
89477     _optional: {
89478         // nullable
89479         matchValue: true
89480     }
89481 };
89482
89483 _t.AttributeRangeFilter = {
89484     attributeName: _t.DOMString,
89485     initialValue:  _t.any,
89486     endValue:      _t.any,
89487
89488     _optional: {
89489         // nullable
89490         initialValue: true,
89491         endValue:     true
89492     }
89493 };
89494
89495 _t.CompositeFilter = {
89496     type:    _t.CompositeFilterType,
89497     filters: ["AbstractFilter"]     // Recursive expansion
89498 };
89499
89500 _t.AbstractFilter = {
89501     _derived: [_t.AttributeFilter, _t.AttributeRangeFilter, _t.CompositeFilter]
89502 };
89503
89504 _t.SortMode = {
89505     attributeName: _t.DOMString,
89506     order:         _t.SortModeOrder
89507 };
89508
89509 _t.SimpleCoordinates = {
89510     latitude:  _t.double,
89511     longitude: _t.double
89512 };
89513
89514 _t.SuccessCallback = _t.Function;
89515 _t.ErrorCallback   = _t.Function;
89516
89517 /*
89518  * Time
89519  */
89520
89521 _t.TimeDuration = {
89522     length:      _t.long_long,
89523     unit:        _t.TimeDurationUnit,
89524     difference:  _t.Function,
89525     equalsTo:    _t.Function,
89526     lessThan:    _t.Function,
89527     greaterThan: _t.Function
89528 };
89529
89530 /*
89531  * Alarm
89532  */
89533
89534 _t.AlarmId = _t.DOMString;
89535
89536 _t.AlarmRelative = {
89537     delay:               _t.unsigned_long_long,
89538     period:              _t.unsigned_long_long,
89539     getRemainingSeconds: _t.Function,
89540
89541     _optional: {
89542         // nullable
89543         period:              true,
89544         getRemainingSeconds: true
89545     }
89546 };
89547
89548 _t.AlarmAbsolute = {
89549     date:                 _t.Date,
89550     period:               _t.unsigned_long_long,
89551     daysOfTheWeek:        [_t.ByDayValue],
89552     getNextScheduledDate: _t.Function,
89553
89554     _optional: {
89555         // nullable
89556         period:               true,
89557         getNextScheduledDate: true
89558     }
89559 };
89560
89561 _t.Alarm = {
89562     id: _t.AlarmId,
89563
89564     _optional: {
89565         // nullable
89566         id: true
89567     },
89568
89569     _derived: [_t.AlarmRelative, _t.AlarmAbsolute]
89570 };
89571
89572 /*
89573  * Application
89574  */
89575
89576 _t.ApplicationId                              = _t.DOMString;
89577 _t.ApplicationContextId                       = _t.DOMString;
89578 _t.ApplicationInformationArraySuccessCallback = _t.Function;
89579 _t.FindAppControlSuccessCallback              = _t.Function;
89580 _t.ApplicationContextArraySuccessCallback     = _t.Function;
89581
89582 _t.ApplicationControlData = {
89583     key:   _t.DOMString,
89584     value: [_t.DOMString]
89585 };
89586
89587 _t.ApplicationControl = {
89588     operation: _t.DOMString,
89589     uri:       _t.DOMString,
89590     mime:      _t.DOMString,
89591     category:  _t.DOMString,
89592     data:      [_t.ApplicationControlData],
89593
89594     _optional: {
89595         // nullable
89596         uri:      true,
89597         mime:     true,
89598         category: true
89599     }
89600 };
89601
89602 _t.ApplicationControlDataArrayReplyCallback = {
89603     onsuccess: _t.Callback,
89604     onfailure: _t.Callback
89605 };
89606
89607 _t.ApplicationInformationEventCallback = {
89608     oninstalled:   _t.Callback,
89609     onupdated:     _t.Callback,
89610     onuninstalled: _t.Callback
89611 };
89612
89613 /*
89614  * Bluetooth
89615  */
89616
89617 _t.BluetoothAddress                          = _t.DOMString;
89618 _t.BluetoothUUID                             = _t.DOMString;
89619 _t.BluetoothDeviceSuccessCallback            = _t.Function;
89620 _t.BluetoothDeviceArraySuccessCallback       = _t.Function;
89621 _t.BluetoothSocketSuccessCallback            = _t.Function;
89622 _t.BluetoothServiceSuccessCallback           = _t.Function;
89623 _t.BluetoothHealthApplicationSuccessCallback = _t.Function;
89624 _t.BluetoothHealthChannelSuccessCallback     = _t.Function;
89625
89626 _t.BluetoothClass = {
89627     major:      _t.octet,
89628     minor:      _t.octet,
89629     services:   [_t.unsigned_short],
89630     hasService: _t.Function
89631 };
89632
89633 _t.BluetoothDevice = {
89634     name:                   _t.DOMString,
89635     address:                _t.BluetoothAddress,
89636     deviceClass:            _t.BluetoothClass,
89637     isBonded:               _t.boolean,
89638     isTrusted:              _t.boolean,
89639     isConnected:            _t.boolean,
89640     uuids:                  [_t.BluetoothUUID],
89641     connectToServiceByUUID: _t.Function
89642 };
89643
89644 _t.BluetoothHealthApplication = {
89645     dataType:   _t.unsigned_short,
89646     name:       _t.DOMString,
89647     onconnect:  _t.BluetoothHealthChannelSuccessCallback,
89648     unregister: _t.Function,
89649
89650     _optional: {
89651         onconnect: true
89652     }
89653 };
89654
89655 _t.BluetoothAdapterChangeCallback = {
89656     onstatechanged:      _t.Callback,
89657     onnamechanged:       _t.Callback,
89658     onvisibilitychanged: _t.Callback
89659 };
89660
89661 _t.BluetoothDiscoverDevicesSuccessCallback = {
89662     onstarted:           _t.Callback,
89663     ondevicefound:       _t.Callback,
89664     ondevicedisappeared: _t.Callback,
89665     onfinished:          _t.Callback
89666 };
89667
89668 _t.BluetoothHealthChannelChangeCallback = {
89669     onmessage: _t.Callback,
89670     onclose:   _t.Callback
89671 };
89672
89673 /*
89674  * Bookmark
89675  */
89676
89677 _t.BookmarkFolder = {
89678     parent: "BookmarkFolder",
89679     title:  _t.DOMString,
89680
89681     _optional: {
89682         // nullable
89683         parent: true
89684     }
89685 };
89686
89687 _t.BookmarkItem = {
89688     parent: _t.BookmarkFolder,
89689     title:  _t.DOMString,
89690     url:    _t.DOMString,
89691
89692     _optional: {
89693         // nullable
89694         parent: true
89695     }
89696 };
89697
89698 _t.Bookmark = [_t.BookmarkItem, _t.BookmarkFolder];
89699
89700 /*
89701  * Contact
89702  */
89703
89704 _t.AddressBookId  = _t.DOMString;
89705 _t.ContactId      = _t.DOMString;
89706 _t.PersonId       = _t.DOMString;
89707 _t.ContactGroupId = _t.DOMString;
89708
89709 _t.Person = {
89710     id:               _t.PersonId,
89711     displayName:      _t.DOMString,
89712     contactCount:     _t.long,
89713     hasPhoneNumber:   _t.boolean,
89714     hasEmail:         _t.boolean,
89715     isFavorite:       _t.boolean,
89716     photoURI:         _t.DOMString,
89717     ringtoneURI:      _t.DOMString,
89718     displayContactId: _t.ContactId,
89719
89720     _optional: {
89721         // nullable
89722         photoURI:    true,
89723         ringtoneURI: true
89724     }
89725 };
89726
89727 _t.ContactRef = {
89728     addressBookId: _t.AddressBookId,
89729     contactId:     _t.ContactId
89730 };
89731
89732 _t.ContactName = {
89733     prefix:            _t.DOMString,
89734     suffix:            _t.DOMString,
89735     firstName:         _t.DOMString,
89736     middleName:        _t.DOMString,
89737     lastName:          _t.DOMString,
89738     nicknames:         [_t.DOMString],
89739     phoneticFirstName: _t.DOMString,
89740     phoneticLastName:  _t.DOMString,
89741     displayName:       _t.DOMString,
89742
89743     _optional: {
89744         // nullable
89745         prefix:            true,
89746         suffix:            true,
89747         firstName:         true,
89748         middleName:        true,
89749         lastName:          true,
89750         phoneticFirstName: true,
89751         phoneticLastName:  true,
89752         displayName:       true
89753     }
89754 };
89755
89756 _t.ContactOrganization = {
89757     name:       _t.DOMString,
89758     department: _t.DOMString,
89759     title:      _t.DOMString,
89760     role:       _t.DOMString,
89761     logoURI:    _t.DOMString,
89762
89763     _optional: {
89764         // nullable
89765         name:       true,
89766         department: true,
89767         title:      true,
89768         role:       true,
89769         logoURI:    true
89770     }
89771 };
89772
89773 _t.ContactWebSite = {
89774     url:  _t.DOMString,
89775     type: _t.DOMString,
89776
89777     _optional: {
89778         // nullable
89779         type: true
89780     }
89781 };
89782
89783 _t.ContactAnniversary = {
89784     date:  _t.Date,
89785     label: _t.DOMString,
89786
89787     _optional: {
89788         // nullable
89789         label: true
89790     }
89791 };
89792
89793 _t.ContactAddress = {
89794     country:               _t.DOMString,
89795     region:                _t.DOMString,
89796     city:                  _t.DOMString,
89797     streetAddress:         _t.DOMString,
89798     additionalInformation: _t.DOMString,
89799     postalCode:            _t.DOMString,
89800     isDefault:             _t.boolean,
89801     types:                 [_t.DOMString],
89802
89803     _optional: {
89804         // nullable
89805         country:               true,
89806         region:                true,
89807         city:                  true,
89808         streetAddress:         true,
89809         additionalInformation: true,
89810         postalCode:            true,
89811         // undefined
89812         types:                 true
89813     }
89814 };
89815
89816 _t.ContactPhoneNumber = {
89817     number:    _t.DOMString,
89818     isDefault: _t.boolean,
89819     types:     [_t.DOMString],
89820
89821     _optional: {
89822         // undefined
89823         types: true
89824     }
89825 };
89826
89827 _t.ContactEmailAddress = {
89828     email:     _t.DOMString,
89829     isDefault: _t.boolean,
89830     types:     [_t.DOMString],
89831
89832     _optional: {
89833         // undefined
89834         types: true
89835     }
89836 };
89837
89838 _t.Contact = {
89839     id:              _t.ContactId,
89840     personId:        _t.PersonId,
89841     addressBookId:   _t.AddressBookId,
89842     lastUpdated:     _t.Date,
89843     isFavorite:      _t.boolean,
89844     name:            _t.ContactName,
89845     addresses:       [_t.ContactAddress],
89846     photoURI:        _t.DOMString,
89847     phoneNumbers:    [_t.ContactPhoneNumber],
89848     emails:          [_t.ContactEmailAddress],
89849     birthday:        _t.Date,
89850     anniversaries:   [_t.ContactAnniversary],
89851     organizations:   [_t.ContactOrganization],
89852     notes:           [_t.DOMString],
89853     urls:            [_t.ContactWebSite],
89854     ringtoneURI:     _t.DOMString,
89855     groupIds:        [_t.ContactGroupId],
89856     convertToString: _t.Function,
89857     clone:           _t.Function,
89858
89859     _optional: {
89860         // nullable
89861         id:            true,
89862         personId:      true,
89863         addressBookId: true,
89864         lastUpdated:   true,
89865         name:          true,
89866         photoURI:      true,
89867         birthday:      true,
89868         ringtoneURI:   true
89869     }
89870 };
89871
89872 _t.ContactGroup = {
89873     id:            _t.ContactGroupId,
89874     addressBookId: _t.AddressBookId,
89875     name:          _t.DOMString,
89876     ringtoneURI:   _t.DOMString,
89877     photoURI:      _t.DOMString,
89878     readOnly:      _t.boolean,
89879
89880     _optional: {
89881         // nullable
89882         id:            true,
89883         addressBookId: true,
89884         ringtoneURI:   true,
89885         photoURI:      true
89886     }
89887 };
89888
89889 _t.PersonArraySuccessCallback      = _t.Function;
89890 _t.ContactArraySuccessCallback     = _t.Function;
89891 _t.AddressBookArraySuccessCallback = _t.Function;
89892
89893 _t.AddressBookChangeCallback = {
89894     oncontactsadded:   _t.Callback,
89895     oncontactsupdated: _t.Callback,
89896     oncontactsremoved: _t.Callback
89897 };
89898
89899 _t.PersonsChangeCallback = {
89900     onpersonsadded:   _t.Callback,
89901     onpersonsupdated: _t.Callback,
89902     onpersonsremoved: _t.Callback
89903 };
89904
89905 _t.ContactInit = {
89906     name:          _t.ContactName,
89907     addresses:     [_t.ContactAddress],
89908     photoURI:      _t.DOMString,
89909     phoneNumbers:  [_t.ContactPhoneNumber],
89910     emails:        [_t.ContactEmailAddress],
89911     birthday:      _t.Date,
89912     anniversaries: [_t.ContactAnniversary],
89913     organizations: [_t.ContactOrganization],
89914     notes:         [_t.DOMString],
89915     urls:          [_t.ContactWebSite],
89916     ringtoneURI:   _t.DOMString,
89917     groupIds:      [_t.ContactGroupId],
89918
89919     _dictionary: null
89920 };
89921
89922 _t.ContactNameInit = {
89923     prefix:            _t.DOMString,
89924     suffix:            _t.DOMString,
89925     firstName:         _t.DOMString,
89926     middleName:        _t.DOMString,
89927     lastName:          _t.DOMString,
89928     nicknames:         [_t.DOMString],
89929     phoneticFirstName: _t.DOMString,
89930     phoneticLastName:  _t.DOMString,
89931
89932     _dictionary: null
89933 };
89934
89935 _t.ContactOrganizationInit = {
89936     name:       _t.DOMString,
89937     department: _t.DOMString,
89938     title:      _t.DOMString,
89939     role:       _t.DOMString,
89940     logoURI:    _t.DOMString,
89941
89942     _dictionary: null
89943 };
89944
89945 _t.ContactAddressInit = {
89946     country:               _t.DOMString,
89947     region:                _t.DOMString,
89948     city:                  _t.DOMString,
89949     streetAddress:         _t.DOMString,
89950     additionalInformation: _t.DOMString,
89951     postalCode:            _t.DOMString,
89952     isDefault:             _t.boolean,
89953     types:                 [_t.DOMString],
89954
89955     _dictionary: null
89956 };
89957
89958 /*
89959  * Calendar
89960  */
89961
89962 _t.CalendarId                        = _t.DOMString;
89963 _t.CalendarTaskId                    = _t.DOMString;
89964 _t.CalendarEventArraySuccessCallback = _t.Function;
89965 _t.CalendarItemArraySuccessCallback  = _t.Function;
89966 _t.CalendarArraySuccessCallback      = _t.Function;
89967
89968 _t.CalendarEventId = {
89969     uid: _t.DOMString,
89970     rid: _t.DOMString,
89971
89972     _optional: {
89973         // nullable
89974         rid: true
89975     }
89976 };
89977
89978 _t.CalendarItemId = [_t.CalendarEventId, _t.CalendarTaskId];
89979
89980 _t.CalendarAlarm = {
89981     absoluteDate: _t.TZDate,
89982     before:       _t.TimeDuration,
89983     method:       _t.AlarmMethod,
89984     description:  _t.DOMString,
89985
89986     _optional: {
89987         // nullable
89988         absoluteDate: true,
89989         before:       true,
89990         description:  true
89991     }
89992 };
89993
89994 _t.CalendarAttendee = {
89995     uri:          _t.DOMString,
89996     name:         _t.DOMString,
89997     role:         _t.AttendeeRole,
89998     status:       _t.AttendeeStatus,
89999     RSVP:         _t.boolean,
90000     type:         _t.AttendeeType,
90001     group:        _t.DOMString,
90002     delegatorURI: _t.DOMString,
90003     delegateURI:  _t.DOMString,
90004     contactRef:   _t.ContactRef,
90005
90006     _optional: {
90007         // nullable
90008         name:         true,
90009         group:        true,
90010         delegatorURI: true,
90011         delegateURI:  true,
90012         contactRef:   true
90013     }
90014 };
90015
90016 _t.CalendarRecurrenceRule = {
90017     frequency:       _t.RecurrenceRuleFrequency,
90018     interval:        _t.unsigned_short,
90019     untilDate:       _t.TZDate,
90020     occurrenceCount: _t.long,
90021     daysOfTheWeek:   [_t.ByDayValue],
90022     setPositions:    [_t.short],
90023     exceptions:      [_t.TZDate],
90024
90025     _optional: {
90026         // nullable
90027         untilDate: true
90028     }
90029 };
90030
90031 _t.CalendarTask = {
90032     dueDate:       _t.TZDate,
90033     completedDate: _t.TZDate,
90034     progress:      _t.unsigned_short,
90035
90036     _optional: {
90037         // nullable
90038         dueDate:       true,
90039         completedDate: true
90040     }
90041 };
90042
90043 _t.CalendarEvent = {
90044     isDetached:       _t.boolean,
90045     endDate:          _t.TZDate,
90046     availability:     _t.EventAvailability,
90047     recurrenceRule:   _t.CalendarRecurrenceRule,
90048     expandRecurrence: _t.Function,
90049
90050     _optional: {
90051         // nullable
90052         endDate:        true,
90053         recurrenceRule: true
90054     }
90055 };
90056
90057 _t.CalendarItem = {
90058     id:                   _t.CalendarItemId,
90059     calendarId:           _t.CalendarId,
90060     lastModificationDate: _t.TZDate,
90061     description:          _t.DOMString,
90062     summary:              _t.DOMString,
90063     isAllDay:             _t.boolean,
90064     startDate:            _t.TZDate,
90065     duration:             _t.TimeDuration,
90066     location:             _t.DOMString,
90067     geolocation:          _t.SimpleCoordinates,
90068     organizer:            _t.DOMString,
90069     visibility:           _t.CalendarItemVisibility,
90070     status:               _t.CalendarItemStatus,
90071     priority:             _t.CalendarItemPriority,
90072     alarms:               [_t.CalendarAlarm],
90073     categories:           [_t.DOMString],
90074     attendees:            [_t.CalendarAttendee],
90075     convertToString:      _t.Function,
90076     clone:                _t.Function,
90077
90078     _optional: {
90079         // nullable
90080         id:                   true,
90081         calendarId:           true,
90082         lastModificationDate: true,
90083         description:          true,
90084         summary:              true,
90085         startDate:            true,
90086         duration:             true,
90087         location:             true,
90088         geolocation:          true,
90089         organizer:            true
90090     },
90091
90092     _derived: [_t.CalendarTask, _t.CalendarEvent]
90093 };
90094
90095 _t.CalendarItemInit = {
90096     description: _t.DOMString,
90097     summary:     _t.DOMString,
90098     isAllDay:    _t.boolean,
90099     startDate:   _t.TZDate,
90100     duration:    _t.TimeDuration,
90101     location:    _t.DOMString,
90102     geolocation: _t.SimpleCoordinates,
90103     organizer:   _t.DOMString,
90104     visibility:  _t.CalendarItemVisibility,
90105     status:      _t.CalendarItemStatus,
90106     priority:    _t.CalendarItemPriority,
90107     alarms:      [_t.CalendarAlarm],
90108     categories:  [_t.DOMString],
90109     attendees:   [_t.CalendarAttendee],
90110
90111     _dictionary: null
90112 };
90113
90114 _t.CalendarTaskInit = {
90115     dueDate:       _t.TZDate,
90116     completedDate: _t.TZDate,
90117     progress:      _t.short,
90118
90119     _dictionary: _t.CalendarItemInit
90120 };
90121
90122 _t.CalendarEventInit = {
90123     endDate:        _t.TZDate,
90124     availability:   _t.EventAvailability,
90125     recurrenceRule: _t.CalendarRecurrenceRule,
90126
90127     _dictionary: _t.CalendarItemInit
90128 };
90129
90130 _t.CalendarAttendeeInit = {
90131     name:         _t.DOMString,
90132     role:         _t.AttendeeRole,
90133     status:       _t.AttendeeStatus,
90134     RSVP:         _t.boolean,
90135     type:         _t.AttendeeType,
90136     group:        _t.DOMString,
90137     delegatorURI: _t.DOMString,
90138     delegateURI:  _t.DOMString,
90139     contactRef:   _t.ContactRef,
90140
90141     _dictionary: null
90142 };
90143
90144 _t.CalendarRecurrenceRuleInit = {
90145     interval:        _t.short,
90146     untilDate:       _t.TZDate,
90147     occurrenceCount: _t.long,
90148     daysOfTheWeek:   [_t.ByDayValue],
90149     setPositions:    [_t.short],
90150     exceptions:      [_t.TZDate],
90151
90152     _dictionary: null
90153 };
90154
90155 _t.CalendarChangeCallback = {
90156     onitemsadded:   _t.Callback,
90157     onitemsupdated: _t.Callback,
90158     onitemsremoved: _t.Callback
90159 };
90160
90161 /*
90162  * CallHistory
90163  */
90164
90165 _t.CallHistoryEntryArraySuccessCallback = _t.Function;
90166
90167 _t.RemoteParty = {
90168     remoteParty: _t.DOMString,
90169     personId:    _t.PersonId,
90170
90171     _optional: {
90172         // nullable
90173         remoteParty: true,
90174         personId:    true
90175     }
90176 };
90177
90178 _t.CallHistoryEntry = {
90179     uid:           _t.DOMString,
90180     type:          _t.DOMString,
90181     features:      [_t.DOMString],
90182     remoteParties: [_t.RemoteParty],
90183     startTime:     _t.Date,
90184     duration:      _t.unsigned_long,
90185     direction:     _t.DOMString,
90186
90187     _optional: {
90188         // nullable
90189         features: true
90190     }
90191 };
90192
90193 _t.CallHistoryChangeCallback = {
90194     onadded:   _t.Callback,
90195     onchanged: _t.Callback,
90196     onremoved: _t.Callback
90197 };
90198
90199 /*
90200  * Content
90201  */
90202
90203 _t.ContentId                            = _t.DOMString;
90204 _t.ContentDirectoryId                   = _t.DOMString;
90205 _t.ContentArraySuccessCallback          = _t.Function;
90206 _t.ContentDirectoryArraySuccessCallback = _t.Function;
90207 _t.ContentScanSuccessCallback           = _t.Function;
90208
90209 _t.ContentChangeCallback = {
90210     oncontentadded:   _t.Callback,
90211     oncontentupdated: _t.Callback,
90212     oncontentremoved: _t.Callback
90213 };
90214
90215 _t.VideoContent = {
90216     geolocation: _t.SimpleCoordinates,
90217     album:       _t.DOMString,
90218     artists:     [_t.DOMString],
90219     duration:    _t.unsigned_long,
90220     width:       _t.unsigned_long,
90221     height:      _t.unsigned_long,
90222
90223     _optional: {
90224         // nullable
90225         geolocation: true,
90226         album:       true,
90227         artists:     true
90228     }
90229 };
90230
90231 _t.AudioContentLyrics = {
90232     type:       _t.AudioContentLyricsType,
90233     timestamps: [_t.unsigned_long],
90234     texts:      [_t.DOMString],
90235
90236     _optional: {
90237         // undefined
90238         timestamps: true
90239     }
90240 };
90241
90242 _t.AudioContent = {
90243     album:       _t.DOMString,
90244     genres:      [_t.DOMString],
90245     artists:     [_t.DOMString],
90246     composers:   [_t.DOMString],
90247     lyrics:      _t.AudioContentLyrics,
90248     copyright:   _t.DOMString,
90249     bitrate:     _t.unsigned_long,
90250     trackNumber: _t.unsigned_short,
90251     duration:    _t.unsigned_long,
90252
90253     _optional: {
90254         // nullable
90255         album:       true,
90256         genres:      true,
90257         artists:     true,
90258         composers:   true,
90259         lyrics:      true,
90260         copyright:   true,
90261         trackNumber: true
90262     }
90263 };
90264
90265 _t.ImageContent = {
90266     geolocation: _t.SimpleCoordinates,
90267     width:       _t.unsigned_long,
90268     height:      _t.unsigned_long,
90269     orientation: _t.ImageContentOrientation,
90270
90271     _optional: {
90272         // nullable
90273         geolocation: true
90274     }
90275 };
90276
90277 _t.Content = {
90278     editableAttributes: [_t.DOMString],
90279     id:                 _t.ContentId,
90280     name:               _t.DOMString,
90281     type:               _t.ContentType,
90282     mimeType:           _t.DOMString,
90283     title:              _t.DOMString,
90284     contentURI:         _t.DOMString,
90285     thumbnailURIs:      [_t.DOMString],
90286     releaseDate:        _t.Date,
90287     modifiedDate:       _t.Date,
90288     size:               _t.unsigned_long,
90289     description:        _t.DOMString,
90290     rating:             _t.float,
90291
90292     _optional: {
90293         // nullable
90294         thumbnailURIs: true,
90295         releaseDate:   true,
90296         modifiedDate:  true,
90297         description:   true
90298     },
90299
90300     _derived: [_t.VideoContent, _t.AudioContent, _t.ImageContent]
90301 };
90302
90303 /*
90304  * Data Control
90305  */
90306
90307 _t.DataControlSuccessCallback         = _t.Function;
90308 _t.DataControlErrorCallback           = _t.Function;
90309 _t.DataControlInsertSuccessCallback   = _t.Function;
90310 _t.DataControlSelectSuccessCallback   = _t.Function;
90311 _t.DataControlGetValueSuccessCallback = _t.Function;
90312
90313 _t.RowData = {
90314     columns: [_t.DOMString],
90315     values:  [_t.DOMString]
90316 };
90317
90318 /*
90319  * Data Synchronization
90320  */
90321
90322 _t.SyncProfileId = _t.DOMString;
90323
90324 _t.SyncInfo = {
90325     url:      _t.DOMString,
90326     id:       _t.DOMString,
90327     password: _t.DOMString,
90328     mode:     _t.SyncMode,
90329     type:     _t.SyncType,
90330     interval: _t.SyncInterval,
90331
90332     _optional: {
90333         // nullable
90334         id:       true,
90335         password: true,
90336         type:     true,
90337         interval: true
90338     }
90339 };
90340
90341 _t.SyncServiceInfo = {
90342     enable:            _t.boolean,
90343     serviceType:       _t.SyncServiceType,
90344     serverDatabaseUri: _t.DOMString,
90345     id:                _t.DOMString,
90346     password:          _t.DOMString,
90347
90348     _optional: {
90349         // nullable
90350         id:       true,
90351         password: true
90352     }
90353 };
90354
90355 _t.SyncProfileInfo = {
90356     profileId:   _t.SyncProfileId,
90357     profileName: _t.DOMString,
90358     syncInfo:    _t.SyncInfo,
90359     serviceInfo: [_t.SyncServiceInfo],
90360
90361     _optional: {
90362         // nullable
90363         profileId:   true,
90364         serviceInfo: true
90365     }
90366 };
90367
90368 _t.SyncProgressCallback = {
90369     onprogress:  _t.Callback,
90370     oncompleted: _t.Callback,
90371     onstopped:   _t.Callback,
90372     onfailed:    _t.Callback
90373 };
90374
90375 /*
90376  * Download
90377  */
90378
90379 _t.DownloadHTTPHeaderFields = {};
90380
90381 _t.DownloadRequest = {
90382     url:         _t.DOMString,
90383     destination: _t.DOMString,
90384     fileName:    _t.DOMString,
90385     networkType: _t.DownloadNetworkType,
90386     httpHeader:  _t.DownloadHTTPHeaderFields,
90387
90388     _optional: {
90389         destination: true,
90390         fileName:    true,
90391         networkType: true,
90392         httpHeader:  true
90393     }
90394 };
90395
90396 _t.DownloadCallback = {
90397     onprogress:  _t.Callback,
90398     onpaused:    _t.Callback,
90399     oncanceled:  _t.Callback,
90400     oncompleted: _t.Callback,
90401     onfailed:    _t.Callback
90402 };
90403
90404 /*
90405  * Messaging
90406  */
90407
90408 _t.MessageId                               = _t.DOMString;
90409 _t.MessageAttachmentId                     = _t.DOMString;
90410 _t.MessageConvId                           = _t.DOMString;
90411 _t.MessageFolderId                         = _t.DOMString;
90412 _t.MessageServiceArraySuccessCallback      = _t.Function;
90413 _t.MessageRecipientsCallback               = _t.Function;
90414 _t.MessageBodySuccessCallback              = _t.Function;
90415 _t.MessageAttachmentSuccessCallback        = _t.Function;
90416 _t.MessageArraySuccessCallback             = _t.Function;
90417 _t.MessageConversationArraySuccessCallback = _t.Function;
90418 _t.MessageFolderArraySuccessCallback       = _t.Function;
90419
90420 _t.MessageFolder = {
90421     id:             _t.MessageFolderId,
90422     parentId:       _t.MessageFolderId,
90423     serviceId:      _t.DOMString,
90424     contentType:    _t.MessageServiceTag,
90425     name:           _t.DOMString,
90426     path:           _t.DOMString,
90427     type:           _t.DOMString,
90428     synchronizable: _t.boolean,
90429
90430     _optional: {
90431         // nullable
90432         parentId: true
90433     }
90434 };
90435
90436 _t.MessagesChangeCallback = {
90437     messagesadded:   _t.Callback,
90438     messagesupdated: _t.Callback,
90439     messagesremoved: _t.Callback
90440 };
90441
90442 _t.MessageConversationsChangeCallback = {
90443     conversationsadded:   _t.Callback,
90444     conversationsupdated: _t.Callback,
90445     conversationsremoved: _t.Callback
90446 };
90447
90448 _t.MessageFoldersChangeCallback = {
90449     foldersadded:   _t.Callback,
90450     foldersupdated: _t.Callback,
90451     foldersremoved: _t.Callback
90452 };
90453
90454 /*
90455  * Message Port
90456  */
90457
90458 _t.MessagePortCallback = _t.Function;
90459
90460 _t.LocalMessagePort = {
90461     messagePortName:           _t.DOMString,
90462     isTrusted:                 _t.boolean,
90463     addMessagePortListener:    _t.Function,
90464     removeMessagePortListener: _t.Function
90465 };
90466
90467 _t.MessagePortDataItem = {
90468     key:   _t.DOMString,
90469     value: _t.DOMString,
90470
90471     _dictionary: null
90472 };
90473
90474 /*
90475  * Network Bearer Selection
90476  */
90477
90478 _t.NetworkSuccessCallback = {
90479     onsuccess:      _t.Callback,
90480     ondisconnected: _t.Callback
90481 };
90482
90483 /*
90484  * NFC
90485  */
90486
90487 _t.NDEFMessageReadCallback  = _t.Function;
90488 _t.ByteArraySuccessCallback = _t.Function;
90489
90490 _t.NFCTagDetectCallback = {
90491     onattach: _t.Callback,
90492     ondetach: _t.Callback
90493 };
90494
90495 _t.NFCPeerDetectCallback = {
90496     onattach: _t.Callback,
90497     ondetach: _t.Callback
90498 };
90499
90500 _t.NDEFRecordText = {
90501     text:         _t.DOMString,
90502     languageCode: _t.DOMString,
90503     encoding:     _t.NDEFRecordTextEncoding
90504 };
90505
90506 _t.NDEFRecordURI = {
90507     uri: _t.DOMString
90508 };
90509
90510 _t.NDEFRecordMedia = {
90511     mimeType: _t.DOMString
90512 };
90513
90514 _t.NDEFRecord = {
90515     tnf:     _t.short,
90516     type:    [_t.byte],
90517     id:      [_t.byte],
90518     payload: [_t.byte],
90519
90520     _derived: [_t.NDEFRecordText, _t.NDEFRecordURI, _t.NDEFRecordMedia]
90521 };
90522
90523 _t.NDEFMessage = {
90524     recordCount: _t.long,
90525     records:     [_t.NDEFRecord],
90526     toByte:      _t.Function
90527 };
90528
90529 /*
90530  * Notification
90531  */
90532
90533 _t.NotificationId = _t.DOMString;
90534
90535 _t.NotificationDetailInfo = {
90536     mainText: _t.DOMString,
90537     subText:  _t.DOMString,
90538
90539     _optional: {
90540         // nullable
90541         subText: true
90542     }
90543 };
90544
90545 _t.StatusNotificationInit = {
90546     content:             _t.DOMString,
90547     iconPath:            _t.DOMString,
90548     soundPath:           _t.DOMString,
90549     vibration:           _t.boolean,
90550     appControl:          _t.ApplicationControl,
90551     appId:               _t.ApplicationId,
90552     progressType:        _t.NotificationProgressType,
90553     progressValue:       _t.unsigned_long,
90554     number:              _t.long,
90555     subIconPath:         _t.DOMString,
90556     detailInfo:          [_t.NotificationDetailInfo],
90557     ledColor:            _t.DOMString,
90558     ledOnPeriod:         _t.unsigned_long,
90559     ledOffPeriod:        _t.unsigned_long,
90560     backgroundImagePath: _t.DOMString,
90561     thumbnails:          [_t.DOMString],
90562
90563     _dictionary: null
90564 };
90565
90566 _t.StatusNotification = {
90567     statusType:          _t.StatusNotificationType,
90568     iconPath:            _t.DOMString,
90569     subIconPath:         _t.DOMString,
90570     number:              _t.long,
90571     detailInfo:          [_t.NotificationDetailInfo],
90572     ledColor:            _t.DOMString,
90573     ledOnPeriod:         _t.unsigned_long,
90574     ledOffPeriod:        _t.unsigned_long,
90575     backgroundImagePath: _t.DOMString,
90576     thumbnails:          [_t.DOMString],
90577     soundPath:           _t.DOMString,
90578     vibration:           _t.boolean,
90579     appControl:          _t.ApplicationControl,
90580     appId:               _t.ApplicationId,
90581     progressType:        _t.NotificationProgressType,
90582     progressValue:       _t.unsigned_long,
90583
90584     _optional: {
90585         // nullable
90586         iconPath:            true,
90587         subIconPath:         true,
90588         number:              true,
90589         detailInfo:          true,
90590         ledColor:            true,
90591         backgroundImagePath: true,
90592         thumbnails:          true,
90593         soundPath:           true,
90594         appControl:          true,
90595         appId:               true,
90596         progressValue:       true
90597     }
90598 };
90599
90600 _t.Notification = {
90601     id:         _t.NotificationId,
90602     type:       _t.NotificationType,
90603     postedTime: _t.Date,
90604     title:      _t.DOMString,
90605     content:    _t.DOMString,
90606
90607     _optional: {
90608         // nullable
90609         id:         true,
90610         postedTime: true,
90611         content:    true
90612     },
90613
90614     _derived: [_t.StatusNotification]
90615 };
90616
90617 /*
90618  * Push
90619  */
90620
90621 _t.PushRegistrationId          = _t.DOMString;
90622 _t.PushRegisterSuccessCallback = _t.Function;
90623 _t.PushNotificationCallback    = _t.Function;
90624
90625 /*
90626  * Secure Element
90627  */
90628
90629 _t.ReaderArraySuccessCallback = _t.Function;
90630 _t.SEChangeListener = {
90631     onSEReady:    _t.Callback,
90632     onSENotReady: _t.Callback
90633 };
90634 _t.SessionSuccessCallback  = _t.Function;
90635 _t.ChannelSuccessCallback  = _t.Function;
90636 _t.TransmitSuccessCallback = _t.Function;
90637
90638 /*
90639  * Package
90640  */
90641
90642 _t.PackageId = _t.DOMString;
90643 _t.PackageInformationArraySuccessCallback = _t.Function;
90644
90645 _t.PackageProgressCallback = {
90646     onprogress: _t.Callback,
90647     oncomplete: _t.Callback
90648 };
90649
90650 _t.PackageInfomationEventCallback = {
90651     oninstalled:   _t.Callback,
90652     onupdated:     _t.Callback,
90653     onuninstalled: _t.Callback
90654 };
90655
90656 /*
90657  * System Info
90658  */
90659
90660 _t.SystemInfoPropertySuccessCallback = _t.Callback;
90661
90662 _t.SystemInfoOptions = {
90663     timeout:       _t.unsigned_long,
90664     highThreshold: _t.double,
90665     lowThreshold:  _t.double,
90666
90667     _dictionary: null
90668 };
90669
90670 /*
90671  * System Setting
90672  */
90673
90674 _t.SystemSettingSuccessCallback = _t.Function;
90675
90676 /*
90677  * Constructor list definition
90678  */
90679
90680 /*
90681  * Generic constructor
90682  *     Construct a prototype of constructor. A fake array of arguments type is
90683  *     specified for constructor.
90684  *
90685  * Overloaded constructors
90686  *     Construct an array of prototype of constructor. Each array element is
90687  *     specified for one of constructors. The constructor with extra arguments
90688  *     are recommended to be defined ahead of the one with fewer same arguments
90689  *     for exact match.
90690  */
90691
90692 _c = {
90693     // Alarm
90694     AlarmAbsolute: [],
90695
90696     // Calendar
90697     CalendarTask:  [],
90698     CalendarEvent: [],
90699     CalendarAlarm: [],
90700
90701     // Contact
90702     Contact:       [],
90703
90704     // NFC
90705     NDEFMessage:   [],
90706     NDEFRecord:    [],
90707
90708     // Data Synchronization
90709     SyncInfo:      [],
90710
90711     // Time
90712     TZDate:        []
90713 };
90714
90715 /*
90716  * Common
90717  */
90718
90719 // AttributeFilter
90720 _c.AttributeFilter = {
90721     0: _t.DOMString,
90722     1: _t.FilterMatchFlag,
90723     2: _t.any,
90724
90725     _optional: {
90726         1: true,
90727         2: true
90728     }
90729 };
90730
90731 // AttributeRangeFilter
90732 _c.AttributeRangeFilter = {
90733     0: _t.DOMString,
90734     1: _t.any,
90735     2: _t.any,
90736
90737     _optional: {
90738         1: true,
90739         2: true
90740     }
90741 };
90742
90743 // CompositeFilter
90744 _c.CompositeFilter = {
90745     0: _t.CompositeFilterType,
90746     1: [_t.AbstractFilter],
90747
90748     _optional: {
90749         1: true
90750     }
90751 };
90752
90753 // SortMode
90754 _c.SortMode = {
90755     0: _t.DOMString,
90756     1: _t.SortModeOrder,
90757
90758     _optional: {
90759         1: true
90760     }
90761 };
90762
90763 // SimpleCoordinates
90764 _c.SimpleCoordinates = {
90765     0: _t.double,
90766     1: _t.double
90767 };
90768
90769 /*
90770  * Alarm
90771  */
90772
90773 // AlarmRelative
90774 _c.AlarmRelative = {
90775     0: _t.long,
90776     1: _t.long,
90777
90778     _optional: {
90779         1: true
90780     }
90781 };
90782
90783 // AlarmAbsolute
90784 _c.AlarmAbsolute[0] = {
90785     0: _t.Date,
90786     1: [_t.ByDayValue]
90787 };
90788
90789 _c.AlarmAbsolute[1] = {
90790     0: _t.Date,
90791     1: _t.long
90792 };
90793
90794 _c.AlarmAbsolute[2] = {
90795     0: _t.Date
90796 };
90797
90798 /*
90799  * Application
90800  */
90801
90802 // ApplicationControlData
90803 _c.ApplicationControlData = {
90804     0: _t.DOMString,
90805     1: [_t.DOMString]
90806 };
90807
90808 // ApplicationControl
90809 _c.ApplicationControl = {
90810     0: _t.DOMString,
90811     1: _t.DOMString,
90812     2: _t.DOMString,
90813     3: _t.DOMString,
90814     4: [_t.ApplicationControlData],
90815
90816     _optional: {
90817         1: true,
90818         2: true,
90819         3: true,
90820         4: true
90821     }
90822 };
90823
90824 /*
90825  * Bookmark
90826  */
90827
90828 // BookmarkItem
90829 _c.BookmarkItem = {
90830     0: _t.DOMString,
90831     1: _t.DOMString
90832 };
90833
90834 // BookmarkFolder
90835 _c.BookmarkFolder = {
90836     0: _t.DOMString
90837 };
90838
90839 /*
90840  * Calendar
90841  */
90842
90843 // CalendarTask
90844 _c.CalendarTask[0] = {
90845     0: _t.CalendarTaskInit,
90846
90847     _optional: {
90848         // nullable
90849         0: true
90850     }
90851 };
90852
90853 _c.CalendarTask[1] = {
90854     0: _t.DOMString,
90855     1: _t.CalendarTextFormat
90856 };
90857
90858 // CalendarEvent
90859 _c.CalendarEvent[0] = {
90860     0: _t.CalendarEventInit,
90861
90862     _optional: {
90863         // nullable
90864         0: true
90865     }
90866 };
90867
90868 _c.CalendarEvent[1] = {
90869     0: _t.DOMString,
90870     1: _t.CalendarTextFormat
90871 };
90872
90873 // CalendarAttendee
90874 _c.CalendarAttendee = {
90875     0: _t.DOMString,
90876     1: _t.CalendarAttendeeInit,
90877
90878     _optional: {
90879         1: true
90880     }
90881 };
90882
90883 // CalendarRecurrenceRule
90884 _c.CalendarRecurrenceRule = {
90885     0: _t.RecurrenceRuleFrequency,
90886     1: _t.CalendarRecurrenceRuleInit,
90887
90888     _optional: {
90889         1: true
90890     }
90891 };
90892
90893 // CalendarEventId
90894 _c.CalendarEventId = {
90895     0: _t.DOMString,
90896     1: _t.DOMString,
90897
90898     _optional: {
90899         1: true
90900     }
90901 };
90902
90903 // CalendarAlarm
90904 _c.CalendarAlarm[0] = {
90905     0: _t.TZDate,
90906     1: _t.AlarmMethod,
90907     2: _t.DOMString,
90908
90909     _optional: {
90910         2: true
90911     }
90912 };
90913
90914 _c.CalendarAlarm[1] = {
90915     0: _t.TimeDuration,
90916     1: _t.AlarmMethod,
90917     2: _t.DOMString,
90918
90919     _optional: {
90920         2: true
90921     }
90922 };
90923
90924 /*
90925  * Contact
90926  */
90927
90928 // Contact
90929 _c.Contact[0] = {
90930     0: _t.ContactInit,
90931
90932     _optional: {
90933         0: true
90934     }
90935 };
90936
90937 _c.Contact[1] = {
90938     0: _t.DOMString
90939 };
90940
90941 // ContactRef
90942 _c.ContactRef = {
90943     0: _t.AddressBookId,
90944     1: _t.ContactId
90945 };
90946
90947 // ContactName
90948 _c.ContactName = {
90949     0: _t.ContactNameInit,
90950
90951     _optional: {
90952         0: true
90953     }
90954 };
90955
90956 // ContactOrganization
90957 _c.ContactOrganization = {
90958     0: _t.ContactOrganizationInit,
90959
90960     _optional: {
90961         0: true
90962     }
90963 };
90964
90965 // ContactWebSite
90966 _c.ContactWebSite = {
90967     0: _t.DOMString,
90968     1: _t.DOMString,
90969
90970     _optional: {
90971         1: true
90972     }
90973 };
90974
90975 // ContactAnniversary
90976 _c.ContactAnniversary = {
90977     0: _t.Date,
90978     1: _t.DOMString,
90979
90980     _optional: {
90981         1: true
90982     }
90983 };
90984
90985 // ContactAddress
90986 _c.ContactAddress = {
90987     0: _t.ContactAddressInit,
90988
90989     _optional: {
90990         0: true
90991     }
90992 };
90993
90994 // ContactPhoneNumber
90995 _c.ContactPhoneNumber = {
90996     0: _t.DOMString,
90997     1: [_t.DOMString],
90998     2: _t.boolean,
90999
91000     _optional: {
91001         1: true,
91002         2: true
91003     }
91004 };
91005
91006 // ContactEmailAddress
91007 _c.ContactEmailAddress = {
91008     0: _t.DOMString,
91009     1: [_t.DOMString],
91010     2: _t.boolean,
91011
91012     _optional: {
91013         1: true,
91014         2: true
91015     }
91016 };
91017
91018 // ContactGroup
91019 _c.ContactGroup = {
91020     0: _t.DOMString,
91021     1: _t.DOMString,
91022     2: _t.DOMString,
91023
91024     _optional: {
91025         1: true,
91026         2: true
91027     }
91028 };
91029
91030 /*
91031  * Data Synchronization
91032  */
91033
91034 // SyncInfo
91035 _c.SyncInfo[0] = {
91036     0: _t.DOMString,
91037     1: _t.DOMString,
91038     2: _t.DOMString,
91039     3: _t.SyncMode,
91040     4: _t.SyncType
91041 };
91042
91043 _c.SyncInfo[1] = {
91044     0: _t.DOMString,
91045     1: _t.DOMString,
91046     2: _t.DOMString,
91047     3: _t.SyncMode,
91048     4: _t.SyncInterval
91049 };
91050
91051 _c.SyncInfo[2] = {
91052     0: _t.DOMString,
91053     1: _t.DOMString,
91054     2: _t.DOMString,
91055     3: _t.SyncMode
91056 };
91057
91058 // SyncServiceInfo
91059 _c.SyncServiceInfo = {
91060     0: _t.boolean,
91061     1: _t.SyncServiceType,
91062     2: _t.DOMString,
91063     3: _t.DOMString,
91064     4: _t.DOMString,
91065
91066     _optional: {
91067         3: true,
91068         4: true
91069     }
91070 };
91071
91072 // SyncProfileInfo
91073 _c.SyncProfileInfo = {
91074     0: _t.DOMString,
91075     1: _t.SyncInfo,
91076     2: [_t.SyncServiceInfo],
91077
91078     _optional: {
91079         2: true
91080     }
91081 };
91082
91083 /*
91084  * Download
91085  */
91086
91087 // DownloadRequest
91088 _c.DownloadRequest = {
91089     0: _t.DOMString,
91090     1: _t.DOMString,
91091     2: _t.DOMString,
91092     3: _t.DownloadNetworkType,
91093     4: _t.DownloadHTTPHeaderFields,
91094
91095     _optional: {
91096         1: true,
91097         2: true,
91098         3: true,
91099         4: true
91100     }
91101 };
91102
91103 /*
91104  * NFC
91105  */
91106
91107 // NDEFMessage
91108 _c.NDEFMessage[0] = {
91109     0: [_t.NDEFRecord]
91110 };
91111
91112 _c.NDEFMessage[1] = {
91113     0: [_t.byte]
91114 };
91115
91116 _c.NDEFMessage[2] = null;
91117
91118 // NDEFRecord
91119 _c.NDEFRecord[0] = {
91120     0: _t.short,
91121     1: [_t.byte],
91122     2: [_t.byte],
91123     3: [_t.byte],
91124
91125     _optional: {
91126         3: true
91127     }
91128 };
91129
91130 _c.NDEFRecord[1] = {
91131     0: [_t.byte]
91132 };
91133
91134 // NDEFRecordText
91135 _c.NDEFRecordText = {
91136     0: _t.DOMString,
91137     1: _t.DOMString,
91138     2: _t.DOMString,
91139
91140     _optional: {
91141         2: true
91142     }
91143 };
91144
91145 // NDEFRecordURI
91146 _c.NDEFRecordURI = {
91147     0: _t.DOMString
91148 };
91149
91150 // NDEFRecordMedia
91151 _c.NDEFRecordMedia = {
91152     0: _t.DOMString,
91153     1: [_t.byte]
91154 };
91155
91156 /*
91157  * Notification
91158  */
91159
91160 // StatusNotification
91161 _c.StatusNotification = {
91162     0: _t.StatusNotificationType,
91163     1: _t.DOMString,
91164     2: _t.StatusNotificationInit,
91165
91166     _optional: {
91167         2: true
91168     }
91169 };
91170
91171 // NotificationDetailInfo
91172 _c.NotificationDetailInfo = {
91173     0: _t.DOMString,
91174     1: _t.DOMString,
91175
91176     _optional: {
91177         1: true
91178     }
91179 };
91180
91181 /*
91182  * Time
91183  */
91184
91185 // TZDate
91186 _c.TZDate[0] = {
91187     0: _t.Date,
91188     1: _t.DOMString,
91189
91190     _optional: {
91191         // nullable
91192         0: true,
91193         1: true
91194     }
91195 };
91196
91197 _c.TZDate[1] = {
91198     0: _t.long,
91199     1: _t.long,
91200     2: _t.long,
91201     3: _t.long,
91202     4: _t.long,
91203     5: _t.long,
91204     6: _t.long,
91205     7: _t.DOMString,
91206
91207     _optional: {
91208         // nullable
91209         3: true,
91210         4: true,
91211         5: true,
91212         6: true,
91213         7: true
91214     }
91215 };
91216
91217 // TimeDuration
91218 _c.TimeDuration = {
91219     0: _t.long_long,
91220     1: _t.TimeDurationUnit,
91221
91222     _optional: {
91223         // nullable
91224         1: true
91225     }
91226 };
91227
91228 /*
91229  * Interface prototype definition
91230  */
91231
91232 _i = {
91233     // Alarm
91234     AlarmManager:                  {},
91235
91236     // Application
91237     ApplicationManager:            {},
91238     Application:                   {},
91239     RequestedApplicationControl:   {},
91240
91241     // Bluetooth
91242     BluetoothManager:              {},
91243     BluetoothAdapter:              {},
91244     BluetoothDevice:               {},
91245     BluetoothSocket:               {},
91246     BluetoothClass:                {},
91247     BluetoothServiceHandler:       {},
91248     BluetoothHealthProfileHandler: {},
91249     BluetoothHealthApplication:    {},
91250     BluetoothHealthChannel:        {},
91251
91252     // Bookmark
91253     BookmarkManager:               {},
91254
91255     // Calendar
91256     CalendarManager:               {},
91257     Calendar:                      {},
91258     CalendarItem:                  {},
91259     CalendarEvent:                 {},
91260
91261     // Call History
91262     CallHistory:                   {},
91263
91264     // Contact
91265     ContactManager:                {},
91266     AddressBook:                   {},
91267     Person:                        {},
91268     Contact:                       {},
91269
91270     // Content
91271     ContentManager:                {},
91272
91273     // Data Control
91274     DataControlManager:            {},
91275     SQLDataControlConsumer:        {},
91276     MappedDataControlConsumer:     {},
91277
91278     // Data Synchronization
91279     DataSynchronizationManager:    {},
91280
91281     // Download
91282     DownloadManager:               {},
91283
91284     // Network Bearer Selection
91285     NetworkBearerSelection:        {},
91286
91287     // NFC
91288     NFCManager:                    {},
91289     NFCAdapter:                    {},
91290     NFCTag:                        {},
91291     NFCPeer:                       {},
91292     NDEFMessage:                   {},
91293
91294     // Notification
91295     NotificationManager:           {},
91296
91297     // Message
91298     Messaging:                     {},
91299     MessageService:                {},
91300     MessageStorage:                {},
91301
91302     // Message Port
91303     MessagePortManager:            {},
91304     LocalMessagePort:              {},
91305     RemoteMessagePort:             {},
91306
91307     // Package
91308     PackageManager:                {},
91309
91310     // Push
91311     PushManager:                   {},
91312
91313     // Secure Element
91314     SEService:                     {},
91315     Reader:                        {},
91316     Session:                       {},
91317     Channel:                       {},
91318
91319     // System Info
91320     SystemInfo:                    {},
91321
91322     // System Setting
91323     SystemSettingManager:          {},
91324
91325     // Time
91326     TimeUtil:                      {},
91327     TZDate:                        {},
91328     TimeDuration:                  {},
91329
91330     // Web Setting
91331     WebSettingManager:             {}
91332 };
91333
91334 /*
91335  * Alarm
91336  */
91337
91338 // AlarmManager
91339 _i.AlarmManager.add = {
91340     0: _t.Alarm,
91341     1: _t.ApplicationId,
91342     2: _t.ApplicationControl,
91343
91344     _optional: {
91345         2: true
91346     }
91347 };
91348
91349 _i.AlarmManager.remove = {
91350     0: _t.AlarmId
91351 };
91352
91353 _i.AlarmManager.removeAll = null;
91354
91355 _i.AlarmManager.get = {
91356     0: _t.AlarmId
91357 };
91358
91359 _i.AlarmManager.getAll = null;
91360
91361 /*
91362  * Application
91363  */
91364
91365 // ApplicationManager
91366 _i.ApplicationManager.getCurrentApplication = null;
91367
91368 _i.ApplicationManager.kill = {
91369     0: _t.ApplicationContextId,
91370     1: _t.SuccessCallback,
91371     2: _t.ErrorCallback,
91372
91373     _optional: {
91374         1: true,
91375         2: true
91376     }
91377 };
91378
91379 _i.ApplicationManager.launch = {
91380     0: _t.ApplicationId,
91381     1: _t.SuccessCallback,
91382     2: _t.ErrorCallback,
91383
91384     _optional: {
91385         1: true,
91386         2: true
91387     }
91388 };
91389
91390 _i.ApplicationManager.launchAppControl = {
91391     0: _t.ApplicationControl,
91392     1: _t.ApplicationId,
91393     2: _t.SuccessCallback,
91394     3: _t.ErrorCallback,
91395     4: _t.ApplicationControlDataArrayReplyCallback,
91396
91397     _optional: {
91398         1: true,
91399         2: true,
91400         3: true,
91401         4: true
91402     }
91403 };
91404
91405 _i.ApplicationManager.findAppControl = {
91406     0: _t.ApplicationControl,
91407     1: _t.FindAppControlSuccessCallback,
91408     2: _t.ErrorCallback,
91409
91410     _optional: {
91411         2: true
91412     }
91413 };
91414
91415 _i.ApplicationManager.getAppsContext = {
91416     0: _t.ApplicationContextArraySuccessCallback,
91417     1: _t.ErrorCallback,
91418
91419     _optional: {
91420         1: true
91421     }
91422 };
91423
91424 _i.ApplicationManager.getAppContext = {
91425     0: _t.ApplicationContextId,
91426
91427     _optional: {
91428         0: true
91429     }
91430 };
91431
91432 _i.ApplicationManager.getAppsInfo = {
91433     0: _t.ApplicationInformationArraySuccessCallback,
91434     1: _t.ErrorCallback,
91435
91436     _optional: {
91437         1: true
91438     }
91439 };
91440
91441 _i.ApplicationManager.getAppInfo = {
91442     0: _t.ApplicationId,
91443
91444     _optional: {
91445         0: true
91446     }
91447 };
91448
91449 _i.ApplicationManager.getAppCerts = {
91450     0: _t.ApplicationId,
91451
91452     _optional: {
91453         0: true
91454     }
91455 };
91456
91457 _i.ApplicationManager.getAppSharedURI = {
91458     0: _t.ApplicationId,
91459
91460     _optional: {
91461         0: true
91462     }
91463 };
91464
91465 _i.ApplicationManager.getAppMetaData = {
91466     0: _t.ApplicationId,
91467
91468     _optional: {
91469         0: true
91470     }
91471 };
91472
91473 _i.ApplicationManager.addAppInfoEventListener = {
91474     0: _t.ApplicationInformationEventCallback
91475 };
91476
91477 _i.ApplicationManager.removeAppInfoEventListener = {
91478     0: _t.long
91479 };
91480
91481 // Application
91482 _i.Application.exit = null;
91483 _i.Application.hide = null;
91484 _i.Application.getRequestedAppControl = null;
91485
91486 // RequestedApplicationControl
91487 _i.RequestedApplicationControl.replyResult = {
91488     0: [_t.ApplicationControlData],
91489
91490     _optional: {
91491         0: true
91492     }
91493 };
91494
91495 _i.RequestedApplicationControl.replyFailure = null;
91496
91497 /*
91498  * Bluetooth
91499  */
91500
91501 // BluetoothManager
91502 _i.BluetoothManager.getDefaultAdapter = null;
91503
91504 // BluetoothAdapter
91505 _i.BluetoothAdapter.setName = {
91506     0: _t.DOMString,
91507     1: _t.SuccessCallback,
91508     2: _t.ErrorCallback,
91509
91510     _optional: {
91511         1: true,
91512         2: true
91513     }
91514 };
91515
91516 _i.BluetoothAdapter.setPowered = {
91517     0: _t.boolean,
91518     1: _t.SuccessCallback,
91519     2: _t.ErrorCallback,
91520
91521     _optional: {
91522         1: true,
91523         2: true
91524     }
91525 };
91526
91527 _i.BluetoothAdapter.setVisible = {
91528     0: _t.boolean,
91529     1: _t.SuccessCallback,
91530     2: _t.ErrorCallback,
91531     3: _t.unsigned_short,
91532
91533     _optional: {
91534         1: true,
91535         2: true,
91536         3: true
91537     }
91538 };
91539
91540 _i.BluetoothAdapter.setChangeListener = {
91541     0: _t.BluetoothAdapterChangeCallback
91542 };
91543
91544 _i.BluetoothAdapter.unsetChangeListener = null;
91545
91546 _i.BluetoothAdapter.discoverDevices = {
91547     0: _t.BluetoothDiscoverDevicesSuccessCallback,
91548     1: _t.ErrorCallback,
91549
91550     _optional: {
91551         1: true
91552     }
91553 };
91554
91555 _i.BluetoothAdapter.stopDiscovery = {
91556     0: _t.SuccessCallback,
91557     1: _t.ErrorCallback,
91558
91559     _optional: {
91560         0: true,
91561         1: true
91562     }
91563 };
91564
91565 _i.BluetoothAdapter.getKnownDevices = {
91566     0: _t.BluetoothDeviceArraySuccessCallback,
91567     1: _t.ErrorCallback,
91568
91569     _optional: {
91570         1: true
91571     }
91572 };
91573
91574 _i.BluetoothAdapter.getDevice = {
91575     0: _t.BluetoothAddress,
91576     1: _t.BluetoothDeviceSuccessCallback,
91577     2: _t.ErrorCallback,
91578
91579     _optional: {
91580         2: true
91581     }
91582 };
91583
91584 _i.BluetoothAdapter.createBonding = {
91585     0: _t.BluetoothAddress,
91586     1: _t.BluetoothDeviceSuccessCallback,
91587     2: _t.ErrorCallback,
91588
91589     _optional: {
91590         2: true
91591     }
91592 };
91593
91594 _i.BluetoothAdapter.destroyBonding = {
91595     0: _t.BluetoothAddress,
91596     1: _t.SuccessCallback,
91597     2: _t.ErrorCallback,
91598
91599     _optional: {
91600         1: true,
91601         2: true
91602     }
91603 };
91604
91605 _i.BluetoothAdapter.registerRFCOMMServiceByUUID = {
91606     0: _t.BluetoothUUID,
91607     1: _t.DOMString,
91608     2: _t.BluetoothServiceSuccessCallback,
91609     3: _t.ErrorCallback,
91610
91611     _optional: {
91612         3: true
91613     }
91614 };
91615
91616 _i.BluetoothAdapter.getBluetoothProfileHandler = {
91617     0: _t.BluetoothProfileType
91618 };
91619
91620 // BluetoothDevice
91621 _i.BluetoothDevice.connectToServiceByUUID = {
91622     0: _t.BluetoothUUID,
91623     1: _t.BluetoothSocketSuccessCallback,
91624     2: _t.ErrorCallback,
91625
91626     _optional: {
91627         2: true
91628     }
91629 };
91630
91631 // BluetoothSocket
91632 _i.BluetoothSocket.readData = null;
91633 _i.BluetoothSocket.close = null;
91634
91635 _i.BluetoothSocket.writeData = {
91636     0: [_t.byte]
91637 };
91638
91639 // BluetoothClass
91640 _i.BluetoothClass.hasService = {
91641     0: _t.unsigned_short
91642 };
91643
91644 // BluetoothServiceHandler
91645 _i.BluetoothServiceHandler.unregister = {
91646     0: _t.SuccessCallback,
91647     1: _t.ErrorCallback,
91648
91649     _optional: {
91650         0: true,
91651         1: true
91652     }
91653 };
91654
91655 // BluetoothHealthProfileHandler
91656 _i.BluetoothHealthProfileHandler.registerSinkApplication = {
91657     0: _t.unsigned_short,
91658     1: _t.DOMString,
91659     2: _t.BluetoothHealthApplicationSuccessCallback,
91660     3: _t.ErrorCallback,
91661
91662     _optional: {
91663         3: true
91664     }
91665 };
91666
91667 _i.BluetoothHealthProfileHandler.connectToSource = {
91668     0: _t.BluetoothDevice,
91669     1: _t.BluetoothHealthApplication,
91670     2: _t.BluetoothHealthChannelSuccessCallback,
91671     3: _t.ErrorCallback,
91672
91673     _optional: {
91674         3: true
91675     }
91676 };
91677
91678 // BluetoothHealthApplication
91679 _i.BluetoothHealthApplication.unregister = {
91680     0: _t.SuccessCallback,
91681     1: _t.ErrorCallback,
91682
91683     _optional: {
91684         0: true,
91685         1: true
91686     }
91687 };
91688
91689 // BluetoothHealthChannel
91690 _i.BluetoothHealthChannel.close = null;
91691 _i.BluetoothHealthChannel.unsetListener = null;
91692
91693 _i.BluetoothHealthChannel.sendData = {
91694     0: [_t.byte]
91695 };
91696
91697 _i.BluetoothHealthChannel.setListener = {
91698     0: _t.BluetoothHealthChannelChangeCallback
91699 };
91700
91701 /*
91702  * Bookmark
91703  */
91704
91705 // BookmarkManager
91706 _i.BookmarkManager.get = {
91707     0: _t.BookmarkFolder,
91708     1: _t.boolean,
91709
91710     _optional: {
91711         0: true,
91712         1: true
91713     }
91714 };
91715
91716 _i.BookmarkManager.add = {
91717     0: _t.Bookmark,
91718     1: _t.BookmarkFolder,
91719
91720     _optional: {
91721         1: true
91722     }
91723 };
91724
91725 _i.BookmarkManager.remove = {
91726     0: _t.Bookmark,
91727
91728     _optional: {
91729         0: true
91730     }
91731 };
91732
91733 /*
91734  * Calendar
91735  */
91736
91737 // CalendarManager
91738 _i.CalendarManager.getCalendars = {
91739     0: _t.CalendarType,
91740     1: _t.CalendarArraySuccessCallback,
91741     2: _t.ErrorCallback,
91742
91743     _optional: {
91744         2: true
91745     }
91746 };
91747
91748 _i.CalendarManager.getUnifiedCalendar = {
91749     0: _t.CalendarType
91750 };
91751
91752 _i.CalendarManager.getDefaultCalendar = {
91753     0: _t.CalendarType
91754 };
91755
91756 _i.CalendarManager.getCalendar = {
91757     0: _t.CalendarType,
91758     1: _t.CalendarId
91759 };
91760
91761 // Calendar
91762 _i.Calendar.get = {
91763     0: _t.CalendarItemId
91764 };
91765
91766 _i.Calendar.add = {
91767     0: _t.CalendarItem
91768 };
91769
91770 _i.Calendar.addBatch = {
91771     0: [_t.CalendarItem],
91772     1: _t.CalendarItemArraySuccessCallback,
91773     2: _t.ErrorCallback,
91774
91775     _optional: {
91776         1: true,
91777         2: true
91778     }
91779 };
91780
91781 _i.Calendar.update = {
91782     0: _t.CalendarItem,
91783     1: _t.boolean,
91784
91785     _optional: {
91786         1: true
91787     }
91788 };
91789
91790 _i.Calendar.updateBatch = {
91791     0: [_t.CalendarItem],
91792     1: _t.SuccessCallback,
91793     2: _t.ErrorCallback,
91794     3: _t.boolean,
91795
91796     _optional: {
91797         1: true,
91798         2: true,
91799         3: true
91800     }
91801 };
91802
91803 _i.Calendar.remove = {
91804     0: _t.CalendarItemId
91805 };
91806
91807 _i.Calendar.removeBatch = {
91808     0: [_t.CalendarItemId],
91809     1: _t.SuccessCallback,
91810     2: _t.ErrorCallback,
91811
91812     _optional: {
91813         1: true,
91814         2: true
91815     }
91816 };
91817
91818 _i.Calendar.find = {
91819     0: _t.CalendarItemArraySuccessCallback,
91820     1: _t.ErrorCallback,
91821     2: _t.AbstractFilter,
91822     3: _t.SortMode,
91823
91824     _optional: {
91825         1: true,
91826         2: true,
91827         3: true
91828     }
91829 };
91830
91831 _i.Calendar.addChangeListener = {
91832     0: _t.CalendarChangeCallback
91833 };
91834
91835 _i.Calendar.removeChangeListener = {
91836     0: _t.long
91837 };
91838
91839 // CalendarItem
91840 _i.CalendarItem.convertToString = {
91841     0: _t.CalendarTextFormat
91842 };
91843
91844 _i.CalendarItem.clone = null;
91845
91846 // CalendarEvent
91847 _i.CalendarEvent.expandRecurrence = {
91848     0: _t.TZDate,
91849     1: _t.TZDate,
91850     2: _t.CalendarEventArraySuccessCallback,
91851     3: _t.ErrorCallback,
91852
91853     _optional: {
91854         3: true
91855     }
91856 };
91857
91858 /*
91859  * Call History
91860  */
91861
91862 // CallHistory
91863 _i.CallHistory.find = {
91864     0: _t.CallHistoryEntryArraySuccessCallback,
91865     1: _t.ErrorCallback,
91866     2: _t.AbstractFilter,
91867     3: _t.SortMode,
91868     4: _t.unsigned_long,
91869     5: _t.unsigned_long,
91870
91871     _optional: {
91872         // nullable
91873         1: true,
91874         2: true,
91875         3: true,
91876         4: true,
91877         5: true
91878     }
91879 };
91880
91881 _i.CallHistory.remove = {
91882     0: _t.CallHistoryEntry
91883 };
91884
91885 _i.CallHistory.removeBatch = {
91886     0: [_t.CallHistoryEntry],
91887     1: _t.SuccessCallback,
91888     2: _t.ErrorCallback,
91889
91890     _optional: {
91891         // nullable
91892         1: true,
91893         2: true
91894     }
91895 };
91896
91897 _i.CallHistory.removeAll = {
91898     0: _t.SuccessCallback,
91899     1: _t.ErrorCallback,
91900
91901     _optional: {
91902         // nullable
91903         0: true,
91904         1: true
91905     }
91906 };
91907
91908 _i.CallHistory.addChangeListener = {
91909     0: _t.CallHistoryChangeCallback
91910 };
91911
91912 _i.CallHistory.removeChangeListener = {
91913     0: _t.long
91914 };
91915
91916 /*
91917  * Contact
91918  */
91919
91920 // ContactManager
91921 _i.ContactManager.getAddressBooks = {
91922     0: _t.AddressBookArraySuccessCallback,
91923     1: _t.ErrorCallback,
91924
91925     _optional: {
91926         1: true
91927     }
91928 };
91929
91930 _i.ContactManager.getUnifiedAddressBook = null;
91931 _i.ContactManager.getDefaultAddressBook = null;
91932
91933 _i.ContactManager.getAddressBook = {
91934     0: _t.AddressBookId
91935 };
91936
91937 _i.ContactManager.get = {
91938     0: _t.PersonId
91939 };
91940
91941 _i.ContactManager.update = {
91942     0: _t.Person
91943 };
91944
91945 _i.ContactManager.updateBatch = {
91946     0: [_t.Person],
91947     1: _t.SuccessCallback,
91948     2: _t.ErrorCallback,
91949
91950     _optional: {
91951         1: true,
91952         2: true
91953     }
91954 };
91955
91956 _i.ContactManager.remove = {
91957     0: _t.PersonId
91958 };
91959
91960 _i.ContactManager.removeBatch = {
91961     0: [_t.PersonId],
91962     1: _t.SuccessCallback,
91963     2: _t.ErrorCallback,
91964
91965     _optional: {
91966         1: true,
91967         2: true
91968     }
91969 };
91970
91971 _i.ContactManager.find = {
91972     0: _t.PersonArraySuccessCallback,
91973     1: _t.ErrorCallback,
91974     2: _t.AbstractFilter,
91975     3: _t.SortMode,
91976
91977     _optional: {
91978         1: true,
91979         2: true,
91980         3: true
91981     }
91982 };
91983
91984 _i.ContactManager.addChangeListener = {
91985     0: _t.PersonsChangeCallback
91986 };
91987
91988 _i.ContactManager.removeChangeListener = {
91989     0: _t.long
91990 };
91991
91992 // AddressBook
91993 _i.AddressBook.get = {
91994     0: _t.ContactId
91995 };
91996
91997 _i.AddressBook.add = {
91998     0: _t.Contact
91999 };
92000
92001 _i.AddressBook.addBatch = {
92002     0: [_t.Contact],
92003     1: _t.ContactArraySuccessCallback,
92004     2: _t.ErrorCallback,
92005
92006     _optional: {
92007         1: true,
92008         2: true
92009     }
92010 };
92011
92012 _i.AddressBook.update = {
92013     0: _t.Contact
92014 };
92015
92016 _i.AddressBook.updateBatch = {
92017     0: [_t.Contact],
92018     1: _t.SuccessCallback,
92019     2: _t.ErrorCallback,
92020
92021     _optional: {
92022         1: true,
92023         2: true
92024     }
92025 };
92026
92027 _i.AddressBook.remove = {
92028     0: _t.ContactId
92029 };
92030
92031 _i.AddressBook.removeBatch = {
92032     0: [_t.ContactId],
92033     1: _t.SuccessCallback,
92034     2: _t.ErrorCallback,
92035
92036     _optional: {
92037         1: true,
92038         2: true
92039     }
92040 };
92041
92042 _i.AddressBook.find = {
92043     0: _t.ContactArraySuccessCallback,
92044     1: _t.ErrorCallback,
92045     2: _t.AbstractFilter,
92046     3: _t.SortMode,
92047
92048     _optional:{
92049         1: true,
92050         2: true,
92051         3: true
92052     }
92053 };
92054
92055 _i.AddressBook.addChangeListener = {
92056     0: _t.AddressBookChangeCallback,
92057     1: _t.ErrorCallback,
92058
92059     _optional: {
92060         1: true
92061     }
92062 };
92063
92064 _i.AddressBook.removeChangeListener = {
92065     0: _t.long
92066 };
92067
92068 _i.AddressBook.getGroup = {
92069     0: _t.ContactGroupId
92070 };
92071
92072 _i.AddressBook.addGroup = {
92073     0: _t.ContactGroup
92074 };
92075
92076 _i.AddressBook.updateGroup = {
92077     0: _t.ContactGroup
92078 };
92079
92080 _i.AddressBook.removeGroup = {
92081     0: _t.ContactGroupId
92082 };
92083
92084 _i.AddressBook.getGroups = null;
92085
92086 // Person
92087 _i.Person.link = {
92088     0: _t.PersonId
92089 };
92090
92091 _i.Person.unlink = {
92092     0: _t.ContactId
92093 };
92094
92095 // Contact
92096 _i.Contact.convertToString = {
92097     0: _t.ContactTextFormat,
92098
92099     _optional: {
92100         0: true
92101     }
92102 };
92103
92104 _i.Contact.clone = null;
92105
92106 /*
92107  * Content
92108  */
92109
92110 // ContentManager
92111 _i.ContentManager.update = {
92112     0: _t.Content
92113 };
92114
92115 _i.ContentManager.updateBatch = {
92116     0: [_t.Content],
92117     1: _t.SuccessCallback,
92118     2: _t.ErrorCallback,
92119
92120     _optional: {
92121         1: true,
92122         2: true
92123     }
92124 };
92125
92126 _i.ContentManager.getDirectories = {
92127     0: _t.ContentDirectoryArraySuccessCallback,
92128     1: _t.ErrorCallback,
92129
92130     _optional: {
92131         1: true
92132     }
92133 };
92134
92135 _i.ContentManager.find = {
92136     0: _t.ContentArraySuccessCallback,
92137     1: _t.ErrorCallback,
92138     2: _t.ContentDirectoryId,
92139     3: _t.AbstractFilter,
92140     4: _t.SortMode,
92141     5: _t.unsigned_long,
92142     6: _t.unsigned_long,
92143
92144     _optional: {
92145         1: true,
92146         2: true,
92147         3: true,
92148         4: true,
92149         5: true,
92150         6: true
92151     }
92152 };
92153
92154 _i.ContentManager.scanFile = {
92155     0: _t.DOMString,
92156     1: _t.ContentScanSuccessCallback,
92157     2: _t.ErrorCallback,
92158
92159     _optional: {
92160         1: true,
92161         2: true
92162     }
92163 };
92164
92165 _i.ContentManager.setChangeListener = {
92166     0: _t.ContentChangeCallback
92167 };
92168
92169 _i.ContentManager.unsetChangeListener = null;
92170
92171 /*
92172  * Data Control
92173  */
92174
92175 // DataControlManager
92176 _i.DataControlManager.getDataControlConsumer = {
92177     0: _t.DOMString,
92178     1: _t.DOMString,
92179     2: _t.DataType
92180 };
92181
92182 // SQLDataControlConsumer
92183 _i.SQLDataControlConsumer.insert = {
92184     0: _t.unsigned_long,
92185     1: _t.RowData,
92186     2: _t.DataControlInsertSuccessCallback,
92187     3: _t.DataControlErrorCallback,
92188
92189     _optional: {
92190         2: true,
92191         3: true
92192     }
92193 };
92194
92195 _i.SQLDataControlConsumer.update = {
92196     0: _t.unsigned_long,
92197     1: _t.RowData,
92198     2: _t.DOMString,
92199     3: _t.DataControlSuccessCallback,
92200     4: _t.DataControlErrorCallback,
92201
92202     _optional: {
92203         3: true,
92204         4: true
92205     }
92206 };
92207
92208 _i.SQLDataControlConsumer.remove = {
92209     0: _t.unsigned_long,
92210     1: _t.DOMString,
92211     2: _t.DataControlSuccessCallback,
92212     3: _t.DataControlErrorCallback,
92213
92214     _optional: {
92215         2: true,
92216         3: true
92217     }
92218 };
92219
92220 _i.SQLDataControlConsumer.select = {
92221     0: _t.unsigned_long,
92222     1: [_t.DOMString],
92223     2: _t.DOMString,
92224     3: _t.DataControlSelectSuccessCallback,
92225     4: _t.DataControlErrorCallback,
92226     5: _t.unsigned_long,
92227     6: _t.unsigned_long,
92228
92229     _optional: {
92230         4: true,
92231         5: true,
92232         6: true
92233     }
92234 };
92235
92236 // MappedDataControlConsumer
92237 _i.MappedDataControlConsumer.addValue = {
92238     0: _t.unsigned_long,
92239     1: _t.DOMString,
92240     2: _t.DOMString,
92241     3: _t.DataControlSuccessCallback,
92242     4: _t.DataControlErrorCallback,
92243
92244     _optional: {
92245         3: true,
92246         4: true
92247     }
92248 };
92249
92250 _i.MappedDataControlConsumer.removeValue = {
92251     0: _t.unsigned_long,
92252     1: _t.DOMString,
92253     2: _t.DOMString,
92254     3: _t.DataControlSuccessCallback,
92255     4: _t.DataControlErrorCallback,
92256
92257     _optional: {
92258         4: true
92259     }
92260 };
92261
92262 _i.MappedDataControlConsumer.getValue = {
92263     0: _t.unsigned_long,
92264     1: _t.DOMString,
92265     2: _t.DataControlGetValueSuccessCallback,
92266     3: _t.DataControlErrorCallback,
92267
92268     _optional: {
92269         3: true
92270     }
92271 };
92272
92273 _i.MappedDataControlConsumer.updateValue = {
92274     0: _t.unsigned_long,
92275     1: _t.DOMString,
92276     2: _t.DOMString,
92277     3: _t.DOMString,
92278     4: _t.DataControlSuccessCallback,
92279     5: _t.DataControlErrorCallback,
92280
92281     _optional: {
92282         5: true
92283     }
92284 };
92285
92286 /*
92287  * Data Synchronization
92288  */
92289
92290 // DataSynchronizationManager
92291 _i.DataSynchronizationManager.getMaxProfilesNum = null;
92292 _i.DataSynchronizationManager.getProfilesNum    = null;
92293 _i.DataSynchronizationManager.getAll            = null;
92294
92295 _i.DataSynchronizationManager.add = {
92296     0: _t.SyncProfileInfo
92297 };
92298
92299 _i.DataSynchronizationManager.update = {
92300     0: _t.SyncProfileInfo
92301 };
92302
92303 _i.DataSynchronizationManager.remove = {
92304     0: _t.SyncProfileId
92305 };
92306
92307 _i.DataSynchronizationManager.get = {
92308     0: _t.SyncProfileId
92309 };
92310
92311 _i.DataSynchronizationManager.startSync = {
92312     0: _t.SyncProfileId,
92313     1: _t.SyncProgressCallback,
92314
92315     _optional: {
92316         1: true
92317     }
92318 };
92319
92320 _i.DataSynchronizationManager.stopSync = {
92321     0: _t.SyncProfileId
92322 };
92323
92324 _i.DataSynchronizationManager.getLastSyncStatistics = {
92325     0: _t.SyncProfileId
92326 };
92327
92328 /*
92329  * Download
92330  */
92331
92332 // DownloadManager
92333 _i.DownloadManager.start = {
92334     0: _t.DownloadRequest,
92335     1: _t.DownloadCallback,
92336
92337     _optional: {
92338         1: true
92339     }
92340 };
92341
92342 _i.DownloadManager.cancel = {
92343     0: _t.long
92344 };
92345
92346 _i.DownloadManager.pause = {
92347     0: _t.long
92348 };
92349
92350 _i.DownloadManager.resume = {
92351     0: _t.long
92352 };
92353
92354 _i.DownloadManager.getState = {
92355     0: _t.long
92356 };
92357
92358 _i.DownloadManager.getDownloadRequest = {
92359     0: _t.long
92360 };
92361
92362 _i.DownloadManager.getMIMEType = {
92363     0: _t.long
92364 };
92365
92366 _i.DownloadManager.setListener = {
92367     0: _t.long,
92368     1: _t.DownloadCallback
92369 };
92370
92371 /*
92372  * Message Port
92373  */
92374
92375 // MessagePortManager
92376 _i.MessagePortManager.requestLocalMessagePort = {
92377     0: _t.DOMString
92378 };
92379
92380 _i.MessagePortManager.requestTrustedLocalMessagePort = {
92381     0: _t.DOMString
92382 };
92383
92384 _i.MessagePortManager.requestRemoteMessagePort = {
92385     0: _t.ApplicationId,
92386     1: _t.DOMString
92387 };
92388
92389 _i.MessagePortManager.requestTrustedRemoteMessagePort = {
92390     0: _t.ApplicationId,
92391     1: _t.DOMString
92392 };
92393
92394 // LocalMessagePort
92395 _i.LocalMessagePort.addMessagePortListener = {
92396     0: _t.MessagePortCallback
92397 };
92398
92399 _i.LocalMessagePort.removeMessagePortListener = {
92400     0: _t.long
92401 };
92402
92403 // RemoteMessagePort
92404 _i.RemoteMessagePort.sendMessage = {
92405     0: [_t.MessagePortDataItem],
92406     1: _t.LocalMessagePort,
92407
92408     _optional: {
92409         1: true
92410     }
92411 };
92412
92413 /*
92414  * Network Bearer Selection
92415  */
92416
92417 // NetworkBearerSelection
92418 _i.NetworkBearerSelection.requestRouteToHost = {
92419     0: _t.NetworkType,
92420     1: _t.DOMString,
92421     2: _t.NetworkSuccessCallback,
92422     3: _t.ErrorCallback,
92423
92424     _optional: {
92425         3: true
92426     }
92427 };
92428
92429 _i.NetworkBearerSelection.releaseRouteToHost = {
92430     0: _t.NetworkType,
92431     1: _t.DOMString,
92432     2: _t.SuccessCallback,
92433     3: _t.ErrorCallback,
92434
92435     _optional: {
92436         3: true
92437     }
92438 };
92439
92440 /*
92441  * NFC
92442  */
92443
92444 // NFCManager
92445 _i.NFCManager.getDefaultAdapter = null;
92446 _i.NFCManager.setExclusiveMode = {
92447     0: _t.boolean
92448 };
92449
92450 // NFCAdapter
92451 _i.NFCAdapter.setPowered = {
92452     0: _t.boolean,
92453     1: _t.SuccessCallback,
92454     2: _t.ErrorCallback,
92455
92456     _optional: {
92457         1: true,
92458         2: true
92459     }
92460 };
92461
92462 _i.NFCAdapter.setTagListener = {
92463     0: _t.NFCTagDetectCallback,
92464     1: [_t.NFCTagType],
92465
92466     _optional: {
92467         1: true
92468     }
92469 };
92470
92471 _i.NFCAdapter.setPeerListener = {
92472     0: _t.NFCPeerDetectCallback
92473 };
92474
92475 _i.NFCAdapter.unsetTagListener  = null;
92476 _i.NFCAdapter.unsetPeerListener = null;
92477 _i.NFCAdapter.getCachedMessage  = null;
92478
92479 // NFCTag
92480 _i.NFCTag.readNDEF = {
92481     0: _t.NDEFMessageReadCallback,
92482     1: _t.ErrorCallback,
92483
92484     _optional: {
92485         1: true
92486     }
92487 };
92488
92489 _i.NFCTag.writeNDEF = {
92490     0: _t.NDEFMessage,
92491     1: _t.SuccessCallback,
92492     2: _t.ErrorCallback,
92493
92494     _optional: {
92495         1: true,
92496         2: true
92497     }
92498 };
92499
92500 _i.NFCTag.transceive = {
92501     0: [_t.byte],
92502     1: _t.ByteArraySuccessCallback,
92503     2: _t.ErrorCallback,
92504
92505     _optional: {
92506         2: true
92507     }
92508 };
92509
92510 // NFCPeer
92511 _i.NFCPeer.setReceiveNDEFListener = {
92512     0: _t.NDEFMessageReadCallback
92513 };
92514
92515 _i.NFCPeer.unsetReceiveNDEFListener = null;
92516
92517 _i.NFCPeer.sendNDEF = {
92518     0: _t.NDEFMessage,
92519     1: _t.SuccessCallback,
92520     2: _t.ErrorCallback,
92521
92522     _optional: {
92523         1: true,
92524         2: true
92525     }
92526 };
92527
92528 // NDEFMessage
92529 _i.NDEFMessage.toByte = null;
92530
92531 /*
92532  * Notification
92533  */
92534
92535 // NotificationManager
92536 _i.NotificationManager.post = {
92537     0: _t.Notification
92538 };
92539
92540 _i.NotificationManager.update = {
92541     0: _t.Notification
92542 };
92543
92544 _i.NotificationManager.remove = {
92545     0: _t.NotificationId
92546 };
92547
92548 _i.NotificationManager.get = {
92549     0: _t.NotificationId
92550 };
92551
92552 _i.NotificationManager.removeAll = null;
92553 _i.NotificationManager.getAll = null;
92554
92555 /*
92556  * Package
92557  */
92558
92559 // PackageManager
92560 _i.PackageManager.install = {
92561     0: _t.DOMString,
92562     1: _t.PackageProgressCallback,
92563     2: _t.ErrorCallback,
92564
92565     _optional: {
92566         2: true
92567     }
92568 };
92569
92570 _i.PackageManager.uninstall = {
92571     0: _t.PackageId,
92572     1: _t.PackageProgressCallback,
92573     2: _t.ErrorCallback,
92574
92575     _optional: {
92576         2: true
92577     }
92578 };
92579
92580 _i.PackageManager.getPackagesInfo = {
92581     0: _t.PackageInformationArraySuccessCallback,
92582     1: _t.ErrorCallback,
92583
92584     _optional: {
92585         1: true
92586     }
92587 };
92588
92589 _i.PackageManager.getPackageInfo = {
92590     0: _t.PackageId,
92591
92592     _optional: {
92593         0: true
92594     }
92595 };
92596
92597 _i.PackageManager.setPackageInfoEventListener = {
92598     0: _t.PackageInfomationEventCallback
92599 };
92600
92601 _i.PackageManager.unsetPackageInfoEventListener = null;
92602
92603 /*
92604  * Push
92605  */
92606
92607 // PushManager
92608 _i.PushManager.registerService = {
92609     0: _t.ApplicationControl,
92610     1: _t.PushRegisterSuccessCallback,
92611     2: _t.ErrorCallback,
92612
92613     _optional: {
92614         2: true
92615     }
92616 };
92617
92618 _i.PushManager.unregisterService = {
92619     0: _t.SuccessCallback,
92620     1: _t.ErrorCallback,
92621
92622     _optional: {
92623         0: true,
92624         1: true
92625     }
92626 };
92627
92628 _i.PushManager.connectService = {
92629     0: _t.PushNotificationCallback
92630 };
92631
92632 _i.PushManager.disconnectService = null;
92633 _i.PushManager.getRegistrationId = null;
92634
92635 /*
92636  * Secure Element
92637  */
92638
92639 // SEService
92640 _i.SEService.getReaders = {
92641     0: _t.ReaderArraySuccessCallback,
92642     1: _t.ErrorCallback,
92643
92644     _optional: {
92645         // nullable
92646         1: true
92647     }
92648 };
92649
92650 _i.SEService.registerSEListener = {
92651     0: _t.SEChangeListener
92652 };
92653
92654 _i.SEService.unregisterSEListener = {
92655     0: _t.unsigned_long
92656 };
92657
92658 _i.SEService.shutdown = null;
92659
92660 // Reader
92661 _i.Reader.openSession = {
92662     0: _t.SessionSuccessCallback,
92663     1: _t.ErrorCallback,
92664
92665     _optional: {
92666         // nullable
92667         1: true
92668     }
92669 };
92670
92671 _i.Reader.getName = null;
92672 _i.Reader.closeSessions = null;
92673
92674 // Session
92675 _i.Session.openBasicChannel = {
92676     0: [_t.byte],
92677     1: _t.ChannelSuccessCallback,
92678     2: _t.ErrorCallback,
92679
92680     _optional: {
92681         // nullable
92682         2: true
92683     }
92684 };
92685
92686 _i.Session.openLogicalChannel = {
92687     0: [_t.byte],
92688     1: _t.ChannelSuccessCallback,
92689     2: _t.ErrorCallback,
92690
92691     _optional: {
92692         // nullable
92693         2: true
92694     }
92695 };
92696
92697 _i.Session.getATR = null;
92698 _i.Session.close = null;
92699 _i.Session.closeChannels = null;
92700
92701 // Channel
92702 _i.Channel.transmit = {
92703     0: [_t.byte],
92704     1: _t.TransmitSuccessCallback,
92705     2: _t.ErrorCallback,
92706
92707     _optional: {
92708         // nullable
92709         2: true
92710     }
92711 };
92712
92713 _i.Channel.close = null;
92714
92715 /*
92716  * System Info
92717  */
92718
92719 // SystemInfo
92720 _i.SystemInfo.getCapabilities = null;
92721
92722 _i.SystemInfo.getPropertyValue = {
92723     0: _t.SystemInfoPropertyId,
92724     1: _t.SystemInfoPropertySuccessCallback,
92725     2: _t.ErrorCallback,
92726
92727     _optional: {
92728         2: true
92729     }
92730 };
92731
92732 _i.SystemInfo.addPropertyValueChangeListener = {
92733     0: _t.SystemInfoPropertyId,
92734     1: _t.SystemInfoPropertySuccessCallback,
92735     2: _t.SystemInfoOptions,
92736
92737     _optional: {
92738         2: true
92739     }
92740 };
92741
92742 _i.SystemInfo.removePropertyValueChangeListener = {
92743     0: _t.unsigned_long
92744 };
92745
92746 /*
92747  * System Setting
92748  */
92749
92750 // SystemSettingManager
92751 _i.SystemSettingManager.setProperty = {
92752     0: _t.SystemSettingType,
92753     1: _t.DOMString,
92754     2: _t.SuccessCallback,
92755     3: _t.ErrorCallback,
92756
92757     _optional: {
92758         3: true
92759     }
92760 };
92761
92762 _i.SystemSettingManager.getProperty = {
92763     0: _t.SystemSettingType,
92764     1: _t.SystemSettingSuccessCallback,
92765     2: _t.ErrorCallback,
92766
92767     _optional: {
92768         2: true
92769     }
92770 };
92771
92772 /*
92773  * Time
92774  */
92775
92776 // TimeUtil
92777 _i.TimeUtil.getCurrentDateTime    = null;
92778 _i.TimeUtil.getLocalTimezone      = null;
92779 _i.TimeUtil.getAvailableTimezones = null;
92780 _i.TimeUtil.getTimeFormat         = null;
92781
92782 _i.TimeUtil.getDateFormat = {
92783     0: _t.boolean,
92784
92785     _optional: {
92786         0: true
92787     }
92788 };
92789
92790 _i.TimeUtil.isLeapYear = {
92791     0: _t.long
92792 };
92793
92794 // TimeDuration
92795 _i.TimeDuration.difference = {
92796     0: _t.TimeDuration
92797 };
92798
92799 _i.TimeDuration.equalsTo = {
92800     0: _t.TimeDuration
92801 };
92802
92803 _i.TimeDuration.lessThan = {
92804     0: _t.TimeDuration
92805 };
92806
92807 _i.TimeDuration.greaterThan = {
92808     0: _t.TimeDuration
92809 };
92810
92811 /*
92812  * Web Setting
92813  */
92814
92815 // WebSettingManager
92816 _i.WebSettingManager.setUserAgentString = {
92817     0: _t.DOMString,
92818     1: _t.SuccessCallback,
92819     2: _t.ErrorCallback,
92820
92821     _optional: {
92822         1: true,
92823         2: true
92824     }
92825 };
92826
92827 _i.WebSettingManager.removeAllCookies = {
92828     0: _t.SuccessCallback,
92829     1: _t.ErrorCallback,
92830
92831     _optional: {
92832         0: true,
92833         1: true
92834     }
92835 };
92836
92837 // Exports
92838 _t.constructor = _c;
92839 _t.interface   = _i;
92840
92841 module.exports = _t;
92842
92843 });
92844 define('ripple/platform/tizen/2.0/secureelement', function (require, exports, module) {
92845 /*
92846  *  Copyright 2014 Intel Corporation.
92847  *
92848  * Licensed under the Apache License, Version 2.0 (the "License");
92849  * you may not use this file except in compliance with the License.
92850  * You may obtain a copy of the License at
92851  *
92852  * http://www.apache.org/licenses/LICENSE-2.0
92853  *
92854  * Unless required by applicable law or agreed to in writing, software
92855  * distributed under the License is distributed on an "AS IS" BASIS,
92856  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
92857  * See the License for the specific language governing permissions and
92858  * limitations under the License.
92859  */
92860
92861 var db = require('ripple/db'),
92862     event = require('ripple/event'),
92863     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
92864     t = require('ripple/platform/tizen/2.0/typecast'),
92865     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
92866     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
92867     Reader,
92868     ReaderInternal,
92869     Session,
92870     SessionInternal,
92871     Channel,
92872     _data = {
92873         APDU_COMMANDS:        null,
92874         DB_SECUREELEMENT_KEY: "tizen-secureelement",
92875         readers:              [],
92876         listeners:            {},
92877         nListener:            0,
92878         internal:             [],
92879         dbStorage:            null
92880     },
92881     _security = {
92882         "http://tizen.org/privilege/secureelement": ["getReaders",
92883                 "registerSEListener", "unregisterSEListener", "shutdown",
92884                 "getName", "openSession", "closeSessions", "openBasicChannel",
92885                 "openLogicalChannel", "getATR", "close", "closeChannels",
92886                 "transmit"]
92887     },
92888     _self;
92889
92890 function _get() {
92891     _data.dbStorage = db.retrieveObject(_data.DB_SECUREELEMENT_KEY) || [];
92892 }
92893
92894 function _save() {
92895     db.saveObject(_data.DB_SECUREELEMENT_KEY, _data.dbStorage);
92896 }
92897
92898 function _getCurrentAppId() {
92899     return tizen.application.getCurrentApplication().appInfo.id;
92900 }
92901
92902 function _initialize() {
92903     /*
92904      *  INS   RESPONSE         COMMAND
92905      */
92906
92907     _data.APDU_COMMANDS = {
92908         0xb0: [0x90, 0x00], // READ BINARY *
92909         0xd0: [0x90, 0x00], // WRITE BINARY
92910         0xd6: [0x90, 0x00], // UPDATE BINARY
92911         0x0e: [0x90, 0x00], // ERASE BINARY
92912         0xb2: [0x90, 0x00], // READ RECORD *
92913         0xd2: [0x90, 0x00], // WRITE RECORD
92914         0xe2: [0x90, 0x00], // APPEND RECORD
92915         0xdc: [0x90, 0x00], // UPDATE RECORD
92916         0xca: [0x90, 0x00], // GET DATA *
92917         0xda: [0x90, 0x00], // PUT DATA
92918         0xa4: [0x69, 0x00], // SELECT FILE *
92919         0x20: [0x90, 0x00], // VERIFY
92920         0x88: [0x90, 0x00], // INTERNAL AUTHENTICATE *
92921         0x82: [0x90, 0x00], // EXTERNAL AUTHENTICATE
92922         0x84: [0x90, 0x00], // GET CHALLENGE *
92923         0x70: [0x69, 0x00], // MANAGE CHANNEL *
92924         0xc0: [0x90, 0x00], // GET RESPONSE *
92925         0xc2: [0x90, 0x00]  // ENVELOPE *
92926     };
92927
92928     _get();
92929
92930     _data.dbStorage.forEach(function (dbReader) {
92931         var reader;
92932
92933         reader = new ReaderInternal(dbReader);
92934         _data.internal.push(reader);
92935         _data.readers.push(new Reader(reader));
92936     });
92937
92938     event.on("ReaderChanged", function (name, isPresent) {
92939         _data.internal.some(function (reader, index) {
92940             var i;
92941
92942             if (reader.name !== name)
92943                 return false;
92944
92945             reader.isPresent = isPresent;
92946             _data.dbStorage[index].isPresent = isPresent;
92947
92948             if (isPresent) {
92949                 for (i in _data.listeners) {
92950                     _data.listeners[i].onSEReady(_data.readers[index]);
92951                 }
92952             } else {
92953                 _data.readers[index].closeSessions();
92954                 for (i in _data.listeners) {
92955                     _data.listeners[i].onSENotReady(_data.readers[index]);
92956                 }
92957             }
92958
92959             return true;
92960         });
92961
92962         _save();
92963     });
92964 }
92965
92966 _self = function () {
92967     var secureelement;
92968
92969     // public
92970     function getReaders(successCallback, errorCallback) {
92971         if (!_security.getReaders) {
92972             throw new WebAPIException(errorcode.SECURITY_ERR);
92973         }
92974
92975         t.SEService("getReaders", arguments);
92976
92977         window.setTimeout(function () {
92978             if (_data.readers.length === 0) {
92979                 if (errorCallback) {
92980                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
92981                 }
92982                 return;
92983             }
92984             successCallback(_data.readers);
92985         }, 1);
92986     }
92987
92988     function registerSEListener(listener) {
92989         var id;
92990
92991         if (!_security.registerSEListener) {
92992             throw new WebAPIException(errorcode.SECURITY_ERR);
92993         }
92994
92995         t.SEService("registerSEListener", arguments);
92996
92997         id = ++_data.nListener;
92998         _data.listeners[id] = listener;
92999
93000         return id;
93001     }
93002
93003     function unregisterSEListener(id) {
93004         if (!_security.unregisterSEListener) {
93005             throw new WebAPIException(errorcode.SECURITY_ERR);
93006         }
93007
93008         t.SEService("unregisterSEListener", arguments);
93009
93010         if (!_data.listeners[id])
93011             return;
93012
93013         delete _data.listeners[id];
93014     }
93015
93016     function shutdown() {
93017         if (!_security.shutdown) {
93018             throw new WebAPIException(errorcode.SECURITY_ERR);
93019         }
93020
93021         t.SEService("shutdown", arguments);
93022
93023         _data.readers.forEach(function (reader) {
93024             reader.closeSessions();
93025         });
93026         _data.internal.forEach(function (reader) {
93027             reader.isPresent = false;
93028         });
93029
93030         event.trigger("ReadersClosed");
93031
93032         window.setTimeout(function () {
93033             _data.readers.forEach(function (reader) {
93034                 for (var i in _data.listeners) {
93035                     _data.listeners[i].onSENotReady(reader);
93036                 }
93037             });
93038         }, 1);
93039     }
93040
93041     function handleSubFeatures(subFeatures) {
93042         var i, subFeature;
93043
93044         for (subFeature in subFeatures) {
93045             for (i in _security[subFeature]) {
93046                 _security[_security[subFeature][i]] = true;
93047             }
93048         }
93049     }
93050
93051     secureelement = {
93052         getReaders:           getReaders,
93053         registerSEListener:   registerSEListener,
93054         unregisterSEListener: unregisterSEListener,
93055         shutdown:             shutdown,
93056         handleSubFeatures:    handleSubFeatures
93057     };
93058
93059     return secureelement;
93060 };
93061
93062 Reader = function (reader) {
93063     // public
93064     function getName() {
93065         if (!_security.getName) {
93066             throw new WebAPIException(errorcode.SECURITY_ERR);
93067         }
93068
93069         t.Reader("getName", arguments);
93070
93071         return reader.name;
93072     }
93073
93074     function openSession(successCallback, errorCallback) {
93075         if (!_security.openSession) {
93076             throw new WebAPIException(errorcode.SECURITY_ERR);
93077         }
93078
93079         t.Reader("openSession", arguments);
93080
93081         window.setTimeout(function () {
93082             var session;
93083
93084             if (!reader.isPresent) {
93085                 if (errorCallback) {
93086                     errorCallback(new WebAPIError(errorcode.INVALID_STATE_ERR));
93087                 }
93088                 return;
93089             }
93090
93091             session = new SessionInternal();
93092             reader.sessions.push(session);
93093
93094             successCallback(session.external);
93095         }, 1);
93096     }
93097
93098     function closeSessions() {
93099         if (!_security.closeSessions) {
93100             throw new WebAPIException(errorcode.SECURITY_ERR);
93101         }
93102
93103         t.Reader("closeSessions", arguments);
93104
93105         if (!reader.isPresent)
93106             return;
93107
93108         if (reader.sessions.length === 0)
93109             return;
93110
93111         reader.sessions.forEach(function (session) {
93112             session.external.close();
93113         });
93114
93115         reader.sessions = [];
93116     }
93117
93118     this.__defineGetter__("isPresent", function () {
93119         return reader.isPresent;
93120     });
93121
93122     reader.sessions    = [];
93123
93124     this.getName       = getName;
93125     this.openSession   = openSession;
93126     this.closeSessions = closeSessions;
93127 };
93128
93129 Session = function (channels) {
93130     var session = {};
93131
93132     // private
93133     function openChannel(isBasic, aid, successCallback, errorCallback) {
93134         window.setTimeout(function () {
93135             var channel, peers, appId;
93136
93137             if (session.isClosed) {
93138                 if (errorCallback) {
93139                     errorCallback(new WebAPIError(errorcode.INVALID_STATE_ERR));
93140                 }
93141                 return;
93142             }
93143
93144             if ((aid.length < 5) || (aid.length > 16)) {
93145                 if (errorCallback) {
93146                     errorCallback(new WebAPIError(
93147                             errorcode.INVALID_VALUES_ERR));
93148                 }
93149                 return;
93150             }
93151
93152             if (isBasic) {
93153                 appId = _getCurrentAppId();
93154
93155                 if (session.locker !== null) {
93156                     if (session.locker === appId) {
93157                         channel = channels.basic[0];
93158                         successCallback(channel);
93159                     } else if (errorCallback) {
93160                         errorCallback(new WebAPIError(errorcode.SECURITY_ERR));
93161                     }
93162                     return;
93163                 }
93164
93165                 session.locker = appId;
93166                 peers = channels.basic;
93167             } else {
93168                 peers = channels.logical;
93169             }
93170
93171             channel = new Channel(isBasic, aid);
93172             peers.push(channel);
93173
93174             successCallback(channel);
93175         }, 1);
93176     }
93177
93178     function closeChannel(channels) {
93179         channels.forEach(function (channel) {
93180             channel.close();
93181         });
93182     }
93183
93184     // public
93185     function openBasicChannel(aid, successCallback, errorCallback) {
93186         if (!_security.openBasicChannel) {
93187             throw new WebAPIException(errorcode.SECURITY_ERR);
93188         }
93189
93190         t.Session("openBasicChannel", arguments);
93191
93192         openChannel(true, aid, successCallback, errorCallback);
93193     }
93194
93195     function openLogicalChannel(aid, successCallback, errorCallback) {
93196         if (!_security.openLogicalChannel) {
93197             throw new WebAPIException(errorcode.SECURITY_ERR);
93198         }
93199
93200         t.Session("openLogicalChannel", arguments);
93201
93202         openChannel(false, aid, successCallback, errorCallback);
93203     }
93204
93205     function getATR() {
93206         /*
93207          * +--+--+---+---+---+---+---+---+---+--------------------+---+
93208          * |TS|T0|TA1|TB1|TC1|TD1|TD2|TA3|TB3|    History Bytes   |TCK|
93209          * |3B|F7|13 |00 |00 |81 |31 |FE |45 |54 49 5A 45 4E 33 30|A0 |
93210          * ------------------------------------------------------------
93211          *  T0                Y1 = 0xF(TA1, TB1, TC1, TD1), k = 7
93212          *  TD1               Y2 = 0x8(TD2), T = 1
93213          *  TD2               Y3 = 0x3(TA3, TB3), T = 1
93214          *  History Bytes     T1 ~ Tk = 'TIZEN30'
93215          *  Tck               XOR T0 ~ Tk
93216          * +----------------------------------------------------------+
93217          */
93218
93219         var atr = [0x3B, 0xF7, 0x13, 0x00, 0x00, 0x81, 0x31, 0xFE, 0x45, 0x54,
93220                    0x49, 0x5A, 0x45, 0x4E, 0x33, 0x30, 0xA0];
93221
93222         if (!_security.getATR) {
93223             throw new WebAPIException(errorcode.SECURITY_ERR);
93224         }
93225
93226         if (session.isClosed) {
93227             throw new WebAPIException(errorcode.UNKNOWN_ERR);
93228         }
93229
93230         t.Session("getATR", arguments);
93231
93232         return atr.slice(0);
93233     }
93234
93235     function close() {
93236         if (!_security.close) {
93237             throw new WebAPIException(errorcode.SECURITY_ERR);
93238         }
93239
93240         t.Session("close", arguments);
93241
93242         if (session.isClosed)
93243             return;
93244
93245         closeChannels();
93246         session.isClosed = true;
93247     }
93248
93249     function closeChannels() {
93250         var type;
93251
93252         if (!_security.closeChannels) {
93253             throw new WebAPIException(errorcode.SECURITY_ERR);
93254         }
93255
93256         t.Session("closeChannels", arguments);
93257
93258         if (session.isClosed)
93259             return;
93260
93261         if ((channels.basic.length === 0) && (channels.logical.length === 0))
93262             return;
93263
93264         for (type in channels) {
93265             closeChannel(channels[type]);
93266             channels[type] = [];
93267         }
93268         session.locker = null;
93269     }
93270
93271     session.isClosed = false;
93272     session.locker   = null;
93273     channels.basic   = [];
93274     channels.logical = [];
93275
93276     this.__defineGetter__("isClosed", function () {
93277         return session.isClosed;
93278     });
93279
93280     this.openBasicChannel   = openBasicChannel;
93281     this.openLogicalChannel = openLogicalChannel;
93282     this.getATR             = getATR;
93283     this.close              = close;
93284     this.closeChannels      = closeChannels;
93285 };
93286
93287 Channel = function (isBasic, aid) {
93288     var channel = {};
93289
93290     // private
93291     function getResponse(command) {
93292         var response;
93293
93294         if (!command[1])
93295             return [0x67, 0x00];
93296
93297         response = _data.APDU_COMMANDS[command[1]];
93298         if (!response)
93299             return [0x6d, 0x00];
93300
93301         return response;
93302     }
93303
93304     function isTransmitted(response) {
93305         return ((response[0] === 0x90) && (response[1] === 0x00));
93306     }
93307
93308     // public
93309     function close() {
93310         if (!_security.close) {
93311             throw new WebAPIException(errorcode.SECURITY_ERR);
93312         }
93313
93314         t.Channel("close", arguments);
93315
93316         if (channel.isClosed)
93317             return;
93318
93319         channel.isClosed = true;
93320     }
93321
93322     function transmit(command, successCallback, errorCallback) {
93323         if (!_security.transmit) {
93324             throw new WebAPIException(errorcode.SECURITY_ERR);
93325         }
93326
93327         t.Channel("transmit", arguments);
93328
93329         window.setTimeout(function () {
93330             var response;
93331
93332             if (channel.isClosed) {
93333                 if (errorCallback) {
93334                     errorCallback(new WebAPIError(errorcode.INVALID_STATE_ERR));
93335                 }
93336                 return;
93337             }
93338
93339             response = getResponse(command);
93340             if (!isTransmitted((response))) {
93341                 if (errorCallback) {
93342                     errorCallback(new WebAPIError(errorcode.SECURITY_ERR));
93343                 }
93344                 return;
93345             }
93346
93347             event.trigger("SETransmitted", [aid, command]);
93348
93349             successCallback(response);
93350         }, 1);
93351     }
93352
93353     channel.isBasicChannel = !!isBasic;
93354     channel.isClosed       = false;
93355
93356     this.__defineGetter__("isBasicChannel", function () {
93357         return channel.isBasicChannel;
93358     });
93359
93360     this.close    = close;
93361     this.transmit = transmit;
93362 };
93363
93364 ReaderInternal = function (reader) {
93365     this.name      = reader.name;
93366     this.isPresent = reader.isPresent;
93367 };
93368
93369 SessionInternal = function () {
93370     this.channels = {};
93371     this.external = new Session(this.channels);
93372 };
93373
93374 _initialize();
93375
93376 module.exports = _self;
93377
93378 });
93379 define('ripple/platform/tizen/2.0/geoBackend_nominatim', function (require, exports, module) {
93380 /*
93381  *  Copyright 2012 Intel Corporation.
93382  *
93383  * Licensed under the Apache License, Version 2.0 (the "License");
93384  * you may not use this file except in compliance with the License.
93385  * You may obtain a copy of the License at
93386  *
93387  * http://www.apache.org/licenses/LICENSE-2.0
93388  *
93389  * Unless required by applicable law or agreed to in writing, software
93390  * distributed under the License is distributed on an "AS IS" BASIS,
93391  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93392  * See the License for the specific language governing permissions and
93393  * limitations under the License.
93394  */
93395
93396 var lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
93397     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
93398     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
93399     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
93400     GeocodeResult = require('ripple/platform/tizen/2.0/GeocodeResult');
93401
93402 function _concatAddrString(addr) {
93403     var ret = "", i, pieces;
93404     if (typeof addr === "string") {
93405         pieces = addr.split(" ");
93406         for (i = 0; i < pieces.length; i++) {
93407             ret = ret + pieces[i] + "+";
93408         }
93409     } else if (typeof addr === "object") {
93410         if (addr.premises !== null && addr.premises !== undefined) {
93411             ret = ret + addr.premises + "+";
93412         }
93413         if (addr.streetNumber !== null && addr.streetNumber !== undefined) {
93414             ret = ret + addr.streetNumber + "+";
93415         }
93416         if (addr.street !== null && addr.street !== undefined) {
93417             ret = ret + addr.street + "+";
93418         }
93419         if (addr.city !== null && addr.city !== undefined) {
93420             ret = ret + addr.city + "+";
93421         }
93422         if (addr.county !== null && addr.county !== undefined) {
93423             ret = ret + addr.county + "+";
93424         }
93425         if (addr.region !== null && addr.region !== undefined) {
93426             ret = ret + addr.region + "+";
93427         }
93428         if (addr.postalCode !== null && addr.postalCode !== undefined) {
93429             ret = ret + addr.postalCode + "+";
93430         }
93431         if (addr.country !== null && addr.country !== undefined) {
93432             ret = ret + addr.country + "+";
93433         }
93434     } else {
93435         return undefined;
93436     }
93437     ret = ret.slice(0, -1);
93438     return ret;
93439 }
93440
93441 module.exports = function (prop) {
93442     var _self = new lbs.LocationServiceProvider(prop);
93443
93444     _self.geocode = function (address, successCB, errorCB, options) {
93445         function _geocode() {
93446             var i, searchStr, coordinates = [], result;
93447
93448             searchStr = _concatAddrString(address);
93449             if (searchStr === undefined) {
93450                 throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
93451             }
93452             searchStr = "http://nominatim.openstreetmap.org/search?q=" + searchStr + "&format=json&polygon=1&addressdetails=1";
93453
93454             /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */
93455             $.getJSON(searchStr, function (data) {
93456                 for (i = 0; i < data.length; i++) {
93457                     result = new GeocodeResult(parseFloat(data[i].lat), parseFloat(data[i].lon));
93458                     coordinates.push(result);
93459                 }
93460                 successCB(coordinates);
93461             }).error(function () {
93462                 if (errorCB) {
93463                     setTimeout(function () {
93464                         errorCB(new WebAPIError(errorcode.NETWORK_ERR));
93465                     }, 1);
93466                 }
93467             });
93468         }
93469
93470         tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode);
93471     };
93472
93473     _self.reverseGeocode = function (coordinates, successCB, errorCB, options) {
93474         function _reverseGeocode() {
93475             var searchStr = "";
93476             if (typeof coordinates !== "object" ||
93477                 typeof coordinates.latitude !== "number" ||
93478                 typeof coordinates.longitude !== "number") {
93479                 throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
93480             }
93481             searchStr = "http://nominatim.openstreetmap.org/reverse?format=json&lat=" +
93482                         coordinates.latitude + "&lon=" + coordinates.longitude + "&zoom=18&addressdetails=1";
93483
93484             /* use nominatim online geo service. (http://nominatim.openstreetmap.org) */
93485             $.getJSON(searchStr, function (data) {
93486                 var addr;
93487
93488                 if (options && options.resultType === "STRUCTURED") {
93489                     addr = new lbs.StructuredAddress({
93490                         country : data.address.country,
93491                         region : data.address.state,
93492                         county : data.address.county,
93493                         city : data.address.city,
93494                         street : data.address.road,
93495                         streetNumber : data.address.streetNumber,
93496                         postalCode : data.address.postcode
93497                     });
93498                 } else {
93499                     addr = data.display_name;
93500                 }
93501                 successCB([addr]);
93502             }).error(function () {
93503                 if (errorCB) {
93504                     setTimeout(function () {
93505                         errorCB(new WebAPIError(errorcode.NETWORK_ERR));
93506                     }, 1);
93507                 }
93508             });
93509         }
93510
93511         tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode);
93512     };
93513
93514     return _self;
93515 };
93516
93517
93518 });
93519 define('ripple/platform/tizen/2.0/route', function (require, exports, module) {
93520 /*
93521  *  Copyright 2012 Intel Corporation.
93522  *
93523  * Licensed under the Apache License, Version 2.0 (the "License");
93524  * you may not use this file except in compliance with the License.
93525  * You may obtain a copy of the License at
93526  *
93527  * http://www.apache.org/licenses/LICENSE-2.0
93528  *
93529  * Unless required by applicable law or agreed to in writing, software
93530  * distributed under the License is distributed on an "AS IS" BASIS,
93531  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93532  * See the License for the specific language governing permissions and
93533  * limitations under the License.
93534  */
93535
93536 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
93537     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
93538     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
93539     ProviderNominatim = require('ripple/platform/tizen/2.0/routeBackend_navigation'), // navigation route service
93540     _getProviders,
93541     _providers,
93542     _self;
93543
93544 function _initialize() {
93545     _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"})];
93546 }
93547
93548 _initialize();
93549
93550 _self = {
93551     getDefaultProvider : function () {
93552         if (arguments.length !== 0) {
93553             throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
93554         }
93555         return _providers[0];
93556     },
93557     getProviders : function () {
93558         if (arguments.length !== 0) {
93559             throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
93560         }
93561         return _providers;
93562     }
93563 };
93564
93565 module.exports = _self;
93566
93567 });
93568 define('ripple/platform/tizen/2.0/time', function (require, exports, module) {
93569 /*
93570  *  Copyright 2012 Intel Corporation.
93571  *
93572  * Licensed under the Apache License, Version 2.0 (the "License");
93573  * you may not use this file except in compliance with the License.
93574  * You may obtain a copy of the License at
93575  *
93576  * http://www.apache.org/licenses/LICENSE-2.0
93577  *
93578  * Unless required by applicable law or agreed to in writing, software
93579  * distributed under the License is distributed on an "AS IS" BASIS,
93580  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93581  * See the License for the specific language governing permissions and
93582  * limitations under the License.
93583  */
93584
93585 var t = require('ripple/platform/tizen/2.0/typecast'),
93586     TZDate = require('ripple/platform/tizen/2.0/TZDate'),
93587     db = require('ripple/db'),
93588     tz = require('ripple/platform/tizen/2.0/timezone_info'),
93589     _timeFormat = "h:m:s ap", _shortDateFormat = "d/m/y",
93590     _longDateFormat = "D, M d, y", _self;
93591
93592 _self = {
93593     getCurrentDateTime: function () {
93594         t.TimeUtil("getCurrentDateTime", arguments);
93595         return new TZDate();
93596     },
93597     getLocalTimezone: function () {
93598         t.TimeUtil("getLocalTimezone", arguments);
93599         var localtz = db.retrieve("tizen-timezone") || "UTC";
93600         return localtz;
93601     },
93602     getAvailableTimezones: function () {
93603         t.TimeUtil("getAvailableTimezones", arguments);
93604         var ret = tz.getAllTimezone();
93605         return ret;
93606     },
93607     getDateFormat: function (shortformat) {
93608         t.TimeUtil("getDateFormat", arguments);
93609
93610         if (shortformat) {
93611             return _shortDateFormat;
93612         } else {
93613             return _longDateFormat;
93614         }
93615     },
93616     getTimeFormat: function () {
93617         t.TimeUtil("getTimeFormat", arguments);
93618         return _timeFormat;
93619     },
93620     isLeapYear: function (year) {
93621         t.TimeUtil("isLeapYear", arguments);
93622         return ((year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0));
93623     }
93624 };
93625
93626 module.exports = _self;
93627
93628 });
93629 define('ripple/platform/tizen/2.0/Message', function (require, exports, module) {
93630 /*
93631  *  Copyright 2012 Intel Corporation.
93632  *
93633  * Licensed under the Apache License, Version 2.0 (the "License");
93634  * you may not use this file except in compliance with the License.
93635  * You may obtain a copy of the License at
93636  *
93637  * http://www.apache.org/licenses/LICENSE-2.0
93638  *
93639  * Unless required by applicable law or agreed to in writing, software
93640  * distributed under the License is distributed on an "AS IS" BASIS,
93641  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93642  * See the License for the specific language governing permissions and
93643  * limitations under the License.
93644  */
93645
93646 var msg_utils = require('ripple/platform/tizen/2.0/msg_utils'),
93647     MessageBody = require('ripple/platform/tizen/2.0/MessageBody'),
93648     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
93649     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException');
93650
93651 module.exports = function (type, messageInit) {
93652     var _id = null, _serviceId = null, _conversationId = null,
93653         _folderId = null, _type = type, _timestamp = null,
93654         _from = null, _hasAttachment = false, _messageStatus = null,
93655         msg = {};
93656
93657     if (messageInit !== undefined && messageInit !== null) {
93658         if (msg_utils.setMsg(messageInit, msg) === false) {
93659             throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
93660         }
93661         if (messageInit.priv !== undefined) {
93662             /* secret constructor for PrivateMessage */
93663             _id = messageInit.priv.id;
93664             _serviceId = messageInit.priv.serviceId;
93665             _conversationId = messageInit.priv.conversationId;
93666             _folderId = messageInit.priv.folderId;
93667             _type = messageInit.priv.type;
93668             _timestamp = new Date(messageInit.priv.timestamp);
93669             _from = messageInit.priv.from;
93670             _hasAttachment = messageInit.priv.hasAttachment;
93671             _messageStatus = messageInit.priv.messageStatus;
93672         }
93673         msg.body = new MessageBody(_id, msg.body.loaded, msg.body.plainBody, msg.body.htmlBody, []);
93674     }
93675
93676     msg.__defineGetter__("id", function () {
93677         return _id;
93678     });
93679     msg.__defineGetter__("conversationId", function () {
93680         return _conversationId;
93681     });
93682     msg.__defineGetter__("folderId", function () {
93683         return _folderId;
93684     });
93685     msg.__defineGetter__("type", function () {
93686         return _type;
93687     });
93688     msg.__defineGetter__("timestamp", function () {
93689         return _timestamp;
93690     });
93691     msg.__defineGetter__("from", function () {
93692         return _from;
93693     });
93694     msg.__defineGetter__("hasAttachment", function () {
93695         return _hasAttachment;
93696     });
93697     msg.__defineGetter__("messageStatus", function () {
93698         return _messageStatus;
93699     });
93700     return msg;
93701 };
93702
93703 });
93704 define('ripple/platform/tizen/2.0/NDEFRecordMedia', function (require, exports, module) {
93705 /*
93706  *  Copyright 2013 Intel Corporation
93707  *
93708  * Licensed under the Apache License, Version 2.0 (the "License");
93709  * you may not use this file except in compliance with the License.
93710  * You may obtain a copy of the License at
93711  *
93712  * http://www.apache.org/licenses/LICENSE-2.0
93713  *
93714  * Unless required by applicable law or agreed to in writing, software
93715  * distributed under the License is distributed on an "AS IS" BASIS,
93716  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93717  * See the License for the specific language governing permissions and
93718  * limitations under the License.
93719  */
93720
93721 var t = require('ripple/platform/tizen/2.0/typecast'),
93722     NDEFRecordInternal = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
93723     NDEFRecordMedia;
93724
93725 NDEFRecordMedia = function (mimeType, data) {
93726     var i, type = [], payload;
93727
93728     t.NDEFRecordMedia(arguments, this);
93729
93730     for (i = 0; i < mimeType.length; i++) {
93731         type[i] = mimeType.charCodeAt(i);
93732     }
93733     payload = t.byte(data, "[]");
93734
93735     // Normally, we can use prototype to inherit a class, for example:
93736     //     NDEFRecordMedia.prototype = new NDEFRecord(2, [...], [...], [...]);
93737     // But the test case thinks that all the inherited property should be
93738     // the object's own property. So, we can only change the "this" point
93739     // of NDEFRecord constructor here.
93740     NDEFRecordInternal.call(this, tizen.nfc.NFC_RECORD_TNF_MIME_MEDIA, type,
93741             payload, []);
93742
93743     this.__defineGetter__("mimeType", function () {
93744         return mimeType;
93745     });
93746 };
93747
93748 module.exports = NDEFRecordMedia;
93749
93750 });
93751 define('ripple/platform/tizen/2.0/WebAPIException', function (require, exports, module) {
93752 /*
93753  *  Copyright 2012 Intel Corporation.
93754  *
93755  * Licensed under the Apache License, Version 2.0 (the "License");
93756  * you may not use this file except in compliance with the License.
93757  * You may obtain a copy of the License at
93758  *
93759  * http://www.apache.org/licenses/LICENSE-2.0
93760  *
93761  * Unless required by applicable law or agreed to in writing, software
93762  * distributed under the License is distributed on an "AS IS" BASIS,
93763  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93764  * See the License for the specific language governing permissions and
93765  * limitations under the License.
93766  */
93767
93768 var errorcode = require('ripple/platform/tizen/2.0/errorcode');
93769
93770 var msg = {
93771     0: "Generic Error",
93772     1: "Index or size is negative, or greater than the allowed value.",
93773     2: "Specified range of text does not fit into a DOMString.",
93774     3: "Node is inserted somewhere it doesn't belong.",
93775     4: "Node is used in a different document than the one that created it (that doesn't support it).",
93776     5: "An invalid or illegal character is specified.",
93777     6: "Data is specified for a Node which does not support data.",
93778     7: "An attempt is made to modify an object where modifications are not allowed.",
93779     8: "An attempt is made to reference a Node in a context where it does not exist.",
93780     9: "The implementation does not support the requested type of object or operation.",
93781     10: "An attempt is made to add an attribute that is already in use elsewhere.",
93782     11: "An attempt is made to use an object that is not, or is no longer, usable.",
93783     12: "An invalid or illegal string is specified.",
93784     13: "An attempt is made to modify the type of the underlying object.",
93785     14: "An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.",
93786     15: "A parameter or an operation is not supported by the underlying object.",
93787     16: "A call to a method such as insertBefore or removeChild would make the Node invalid with respect to \"partial validity\", this exception would be raised and the operation would not be done.",
93788     17: "The type of an object is incompatible with the expected type of the parameter associated to the object.",
93789     18: "An attempt is made to perform an operation or access some data in a way that would be a security risk or a violation of the user agent's security policy.",
93790     19: "A network error occurs in synchronous requests.",
93791     20: "The abort error occurs in asynchronous requests by user prompt.",
93792     21: "The operation could not be completed because the URL does not match.",
93793     22: "The quota has been exceeded.",
93794     23: "The operation timed out.",
93795     24: "The supplied node is incorrect or has an incorrect ancestor for this operation.",
93796     25: "The object can not be cloned.",
93797     99: "The content of an object does not include valid values.",
93798     100: "Error occurred in communication with the underlying implementation that meant the requested method could not complete.",
93799     111: "Requested service is not available."
93800 },
93801     errType = {
93802     0: "UnknownError",
93803     1: "IndexSizeError",
93804     2: "DOMStringSizeError",
93805     3: "HierarchyRequestError",
93806     4: "WrongDocumentError",
93807     5: "InvalidCharacterError",
93808     6: "NoDataAllowedError",
93809     7: "NoModificationAllowedError",
93810     8: "NotFoundError",
93811     9: "NotSupportedError",
93812     10: "InuseAttributeError",
93813     11: "InvalidStateError",
93814     12: "SyntaxError",
93815     13: "InvalidModificationError",
93816     14: "NamespaceError",
93817     15: "InvalidAccessError",
93818     16: "ValidationError",
93819     17: "TypeMismatchError",
93820     18: "SecurityError",
93821     19: "NetworkError",
93822     20: "AbortError",
93823     21: "URLMismatchError",
93824     22: "QuotaExceededError",
93825     23: "TimeoutError",
93826     24: "InvalidNodeTypeError",
93827     25: "DataCloneError",
93828     99: "InvalidValuesError",
93829     100: "IOError",
93830     111: "ServiceNotAvailableError"
93831 };
93832
93833 /*
93834   support 3 types of error:
93835   - WebAPIError()
93836       code = errorcode.UNKNOWN_ERR
93837       message = errorcode.message[UNKNOWN_ERR]
93838   - WebAPIError(errorcode."TYPE_MISMATCH_ERR")
93839       code = 17
93840       message = errorcode.message[17]
93841   - WebAPIError(my_own_error_code, "This is my error message.")
93842       code = my_own_error_code(number)
93843       message = "This is my error message."
93844 */
93845
93846 module.exports = function (code, message, name) {
93847     var g, c, _code, _message, _name;
93848
93849     for (c in errorcode) {
93850         g = errorcode.__lookupGetter__(c);
93851         if (g) {
93852             this.__defineGetter__(c, g);
93853         }
93854     }
93855
93856     if (typeof code !== 'number') {
93857         _code = errorcode.UNKNOWN_ERR;
93858         _message = msg[_code];
93859         _name = errType[_code];
93860     } else {
93861         _code = code;
93862         if (typeof message === 'string') {
93863             _message = message;
93864         } else {
93865             _message = msg[_code];
93866         }
93867         if (typeof name === 'string') {
93868             _name = name;
93869         } else {
93870             _name = errType[_code];
93871         }
93872     }
93873
93874     this.__defineGetter__("code", function () {
93875         return _code;
93876     });
93877     this.__defineGetter__("message", function () {
93878         return _message;
93879     });
93880     this.__defineGetter__("name", function () {
93881         return _name;
93882     });
93883 };
93884
93885 });
93886 define('ripple/platform/tizen/2.0/ApplicationControlData', function (require, exports, module) {
93887 /*
93888  *  Copyright 2013 Intel Corporation.
93889  *
93890  * Licensed under the Apache License, Version 2.0 (the "License");
93891  * you may not use this file except in compliance with the License.
93892  * You may obtain a copy of the License at
93893  *
93894  * http://www.apache.org/licenses/LICENSE-2.0
93895  *
93896  * Unless required by applicable law or agreed to in writing, software
93897  * distributed under the License is distributed on an "AS IS" BASIS,
93898  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93899  * See the License for the specific language governing permissions and
93900  * limitations under the License.
93901  */
93902
93903 var t = require('ripple/platform/tizen/2.0/typecast'),
93904     ApplicationControlData;
93905
93906 ApplicationControlData = function (key, value) {
93907     var applicationControlData = {};
93908
93909     t.ApplicationControlData(arguments, this);
93910
93911     applicationControlData.key   = key;
93912     applicationControlData.value = value;
93913
93914     this.__defineGetter__("key", function () {
93915         return applicationControlData.key;
93916     });
93917     this.__defineSetter__("key", function (val) {
93918         try {
93919             applicationControlData.key = t.DOMString(val);
93920         } catch (e) {
93921         }
93922     });
93923
93924     this.__defineGetter__("value", function () {
93925         return applicationControlData.value;
93926     });
93927     this.__defineSetter__("value", function (val) {
93928         try {
93929             applicationControlData.value = t.DOMString(val, '[]');
93930         } catch (e) {
93931         }
93932     });
93933 };
93934
93935 module.exports = ApplicationControlData;
93936
93937 });
93938 define('ripple/platform/tizen/2.0/MessagingService', function (require, exports, module) {
93939 /*
93940  *  Copyright 2012 Intel Corporation.
93941  *
93942  * Licensed under the Apache License, Version 2.0 (the "License");
93943  * you may not use this file except in compliance with the License.
93944  * You may obtain a copy of the License at
93945  *
93946  * http://www.apache.org/licenses/LICENSE-2.0
93947  *
93948  * Unless required by applicable law or agreed to in writing, software
93949  * distributed under the License is distributed on an "AS IS" BASIS,
93950  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
93951  * See the License for the specific language governing permissions and
93952  * limitations under the License.
93953  */
93954
93955 var event = require('ripple/event'),
93956     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
93957     deviceSettings = require('ripple/deviceSettings'),
93958     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
93959     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
93960     PrivMessage = require('ripple/platform/tizen/2.0/PrivMessage'),
93961     MessageStorage = require('ripple/platform/tizen/2.0/MessageStorage'),
93962     msg_utils = require('ripple/platform/tizen/2.0/msg_utils'),
93963     t = require('ripple/platform/tizen/2.0/typedef'),
93964     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
93965     _self,
93966     TIZEN_DEFAULT_MSG_FROM = {"messaging.sms": "13572468",
93967                               "messaging.mms": "13572468",
93968                               "messaging.email": "tizen.simulator@tizen.org"},
93969     INCOMING_TYPE = {"messaging.sms": "sms",
93970                      "messaging.mms": "mms",
93971                      "messaging.email": "email"};
93972
93973 _self = function (id, type, security_check) {
93974     var msg_service = {},
93975         pendingOperations = {},
93976         _msgSending = {},
93977         _receivedEmails = [],
93978         _id = id,
93979         _type = type,
93980         _security_check = security_check,
93981         _from = TIZEN_DEFAULT_MSG_FROM[_type],
93982         _incomingType = INCOMING_TYPE[_type],
93983         _messages = msg_utils.loadMsg(_type, _id),
93984         _messageStorage = new MessageStorage(_messages, _security_check);
93985
93986     event.on("MessageSent", function (rst) {
93987         var i, rsp_ok = [], rsp_fail = [];
93988         // rst.msg is the real msg in module
93989         if (rst.msg.priv.type !== _type ||
93990             rst.msg.priv.serviceId !== _id) {
93991             // not my msg
93992             return;
93993         }
93994         if (_msgSending[rst.id] !== undefined) {
93995             for (i in rst) {
93996                 if ((i !== "id") && (i !== "msg")) {
93997                     if (rst[i] === true) {
93998                         rsp_ok.push(i);
93999                     } else {
94000                         rsp_fail.push(i);
94001                     }
94002                 }
94003             }
94004             rst.msg.priv.folderId = "SENTBOX";
94005             if (rsp_fail.length === 0) {
94006                 rst.msg.priv.messageStatus = "SENT";
94007                 _msgSending[rst.id].onsuccess(rsp_ok);
94008             } else {
94009                 rst.msg.priv.messageStatus = "FAILED";
94010                 _msgSending[rst.id].onerror(rsp_fail);
94011             }
94012             msg_utils.saveMsg(rst.msg);  // sync to remote
94013             event.trigger("MsgSentRst", [rst.msg]);
94014             delete _msgSending[rst.id];
94015         }
94016     });
94017
94018     event.on("MessageReceived", function (rst) {
94019         var m, opt = {}, msgInit = {}, msg = {};
94020
94021         if (rst.type !== _incomingType) {
94022             // not my msg
94023             return;
94024         }
94025         msgInit.plainBody = rst.body;
94026         msgInit.to = [_from];
94027         // TODO: handle attachment
94028         if (msg_utils.setMsg(msgInit, msg) === false) {
94029             throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR, "received message error"));
94030         }
94031         opt.id = Math.uuid(8, 16);
94032         opt.serviceId = _id;
94033         opt.conversationId = opt.id;
94034         opt.folderId = "INBOX";
94035         opt.type = _type;
94036         opt.timestamp = new Date();
94037         opt.from = rst.from;
94038         if (msg.attachments.length === 0) {
94039             opt.hasAttachment = false;
94040         } else {
94041             opt.hasAttachment = true;
94042         }
94043         opt.messageStatus = "RECEIVED";
94044         m = new PrivMessage(msg, opt);
94045         msg_utils.saveMsg(m);   // save in server
94046         if (_type !== "messaging.email") {
94047             _messages.msg[m.priv.id] = m;  // sync to local
94048             event.trigger("MsgRecv", [m]);
94049         } else {
94050             _receivedEmails.push(m);  // don't sync to local yet
94051         }
94052     });
94053
94054     msg_service = {
94055         sendMessage: function (_msg, onSuccess, onError) {
94056             var m, msg = {}, opt = {}, shortMsg = {}, rst = {};
94057             if (_security_check.write === false) {
94058                 throw (new WebAPIException(errorcode.SECURITY_ERR));
94059             }
94060             if (_msg === null || _msg === undefined || _msg.id === undefined) {
94061                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
94062             }
94063
94064             if (msg_utils.setMsg(_msg, msg) === false) {
94065                 throw (new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
94066             }
94067             if ((arguments.length > 1) && onSuccess !== null && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
94068                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94069             }
94070             if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
94071                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94072             }
94073             if (deviceSettings.retrieve("CELLULAR_NETWORK.status") === false &&
94074                 (_incomingType === 'sms' || _incomingType === 'mms')) {
94075                 if (onError) {
94076                     setTimeout(function () {
94077                         onError(new WebAPIError(errorcode.NETWORK_ERR));
94078                     }, 1);
94079                 }
94080                 return;
94081             }
94082             if (deviceSettings.retrieve("WIFI_NETWORK.status") === false &&
94083                 _incomingType === 'email') {
94084                 if (onError) {
94085                     setTimeout(function () {
94086                         onError(new WebAPIError(errorcode.NETWORK_ERR));
94087                     }, 1);
94088                 }
94089                 return;
94090             }
94091             if (typeof _msg.id === 'string') {
94092                 if (_messages.msg[_msg.id] === undefined) {
94093                     if (onError) {
94094                         setTimeout(function () {
94095                             onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
94096                         }, 1);
94097                     }
94098                     return;
94099                 }
94100                 if (_messages.msg[_msg.id].priv.messageStatus === "DRAFT") {
94101                     msg_utils.delMsg(_messages.msg[_msg.id]);
94102                     delete _messages.msg[_msg.id];
94103                 } else {
94104                     // if msg found in storage, it can only be a draft.
94105                     if (onError) {
94106                         setTimeout(function () {
94107                             onError(new WebAPIError(errorcode.UNKNOWN_ERR));
94108                         }, 1);
94109                     }
94110                     return;
94111                 }
94112             }
94113             opt.id = Math.uuid(8, 16);
94114             opt.serviceId = _id;
94115             if ((msg.inResponseTo !== null) &&
94116                 (_messages.msg[msg.inResponseTo] !== undefined) &&
94117                 (_messages.msg[msg.inResponseTo].priv.messageStatus !== "DRAFT")) {
94118                 opt.conversationId = _messages.msg[msg.inResponseTo].priv.conversationId;
94119             } else {
94120                 opt.conversationId = opt.id;
94121             }
94122             opt.folderId = "OUTBOX";
94123             opt.type = _type;
94124             opt.timestamp = new Date();
94125             opt.from = _from;
94126             if (msg.attachments.length === 0) {
94127                 opt.hasAttachment = false;
94128             } else {
94129                 opt.hasAttachment = true;
94130             }
94131             opt.messageStatus = "SENDING";
94132
94133             m = new PrivMessage(msg, opt);
94134             _messages.msg[m.priv.id] = m;
94135             msg_utils.saveMsg(m);  // sync to remote
94136             shortMsg.msg = m;   // pass by ref
94137             shortMsg.id = m.priv.id;
94138             shortMsg.body = m.body.plainBody;
94139             shortMsg.to = m.to.slice(0);
94140             shortMsg.cc = m.cc.slice(0);
94141             shortMsg.bcc = m.bcc.slice(0);
94142             event.trigger("OutsideMessageReceived", [shortMsg]);
94143             rst.onsuccess = onSuccess;
94144             rst.onerror = onError;
94145             _msgSending[m.priv.id] = rst;
94146         },
94147
94148         loadMessageBody: function (msg, onSuccess, onError) {
94149             var pendingID;
94150             if (_security_check.write === false) {
94151                 throw (new WebAPIException(errorcode.SECURITY_ERR));
94152             }
94153             if (_messages.msg[msg.id] === undefined) {
94154                 throw (new WebAPIException(errorcode.NOT_FOUND_ERR));
94155             }
94156             if (!(new TypeCoerce(t.MessageBodySuccessCallback)).match(onSuccess)) {
94157                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94158             }
94159             if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
94160                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94161             }
94162             pendingID = setTimeout(function () {
94163                 if (pendingOperations.hasOwnProperty(pendingID) === false) {
94164                     // has been cancelled/expired
94165                     return;
94166                 }
94167                 delete pendingOperations[pendingID];
94168                 onSuccess(_messages.msg[msg.id].body);
94169             }, 1);
94170             pendingOperations[pendingID] = onError;
94171             return pendingID;
94172         },
94173         loadMessageAttachment: function (msg, onSuccess, onError) {
94174             var pendingID;
94175
94176             if (_security_check.write === false) {
94177                 throw (new WebAPIException(errorcode.SECURITY_ERR));
94178             }
94179             if (_messages.msg[msg.id] === undefined) {
94180                 throw (new WebAPIException(errorcode.NOT_FOUND_ERR));
94181             }
94182             if (!(new TypeCoerce(t.MessageAttachmentSuccessCallback)).match(onSuccess)) {
94183                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94184             }
94185             if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
94186                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94187             }
94188             pendingID = setTimeout(function () {
94189                 if (pendingOperations.hasOwnProperty(pendingID) === false) {
94190                     // has been cancelled/expired
94191                     return;
94192                 }
94193                 delete pendingOperations[pendingID];
94194                 onSuccess(_messages.msg[msg.id].attachments);
94195             }, 1);
94196             pendingOperations[pendingID] = onError;
94197             return pendingID;
94198         },
94199         sync: function (successCallback, errorCallback, limit) {
94200             var i, m, pendingID;
94201
94202             if (_security_check.write === false) {
94203                 throw (new WebAPIException(errorcode.SECURITY_ERR));
94204             }
94205             if ((arguments.length > 0) && successCallback !== null && !(new TypeCoerce(t.SuccessCallback)).match(successCallback)) {
94206                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94207             }
94208             if ((arguments.length > 1) && errorCallback !== null && !(new TypeCoerce(t.ErrorCallback)).match(errorCallback)) {
94209                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94210             }
94211             if ((arguments.length > 2) && limit !== null && !(new TypeCoerce(t.long)).match(limit)) {
94212                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94213             }
94214             pendingID = setTimeout(function () {
94215                 if (pendingOperations.hasOwnProperty(pendingID) === false) {
94216                     // has been cancelled/expired
94217                     return;
94218                 }
94219                 delete pendingOperations[pendingID];
94220                 for (i = 0; i < _receivedEmails.length; i++) {
94221                     m = _receivedEmails[i];
94222                     _messages.msg[m.priv.id] = m;  // sync to local
94223                     event.trigger("MsgRecv", [m]);
94224                 }
94225                 _receivedEmails = [];
94226                 if (successCallback) {
94227                     successCallback();
94228                 }
94229             }, 1);
94230             pendingOperations[pendingID] = errorCallback;
94231             return pendingID;
94232         },
94233
94234         syncFolder: function (folder, onSuccess, onError, limit) {
94235             var i, m, pendingID;
94236
94237             if (_security_check.write === false) {
94238                 throw (new WebAPIException(errorcode.SECURITY_ERR));
94239             }
94240             if (!(new TypeCoerce(t.MessageFolder)).match(folder)) {
94241                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94242             }
94243             if ((arguments.length > 1) && onSuccess !== null && !(new TypeCoerce(t.SuccessCallback)).match(onSuccess)) {
94244                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94245             }
94246             if ((arguments.length > 2) && onError !== null && !(new TypeCoerce(t.ErrorCallback)).match(onError)) {
94247                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94248             }
94249             if ((arguments.length > 3) && limit !== null && !(new TypeCoerce(t.long)).match(limit)) {
94250                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94251             }
94252             pendingID = setTimeout(function () {
94253                 if (pendingOperations.hasOwnProperty(pendingID) === false) {
94254                     // has been cancelled/expired
94255                     return;
94256                 }
94257                 delete pendingOperations[pendingID];
94258                 if (folder.id === "INBOX") {
94259                     for (i = 0; i < _receivedEmails.length; i++) {
94260                         m = _receivedEmails[i];
94261                         _messages.msg[m.priv.id] = m;  // sync to local
94262                         event.trigger("MsgRecv", [m]);
94263                     }
94264                     _receivedEmails = [];
94265                 }
94266                 onSuccess();
94267             }, 1);
94268             pendingOperations[pendingID] = onError;
94269             return pendingID;
94270         },
94271
94272         stopSync: function (pendingID) {
94273             if (!(new TypeCoerce(t.long)).match(pendingID)) {
94274                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
94275             }
94276             if (pendingOperations[pendingID] !== undefined) {
94277                 clearTimeout(pendingID);
94278                 pendingOperations[pendingID](new WebAPIError(errorcode.ABORT_ERR));
94279             }
94280             delete pendingOperations[pendingID];
94281         }
94282     };
94283     msg_service.__defineGetter__("type", function () {
94284         return _type;
94285     });
94286     msg_service.__defineGetter__("messageStorage", function () {
94287         return _messageStorage;
94288     });
94289     return msg_service;
94290 };
94291
94292 module.exports = _self;
94293
94294 });
94295 define('ripple/platform/tizen/2.0/vibration', function (require, exports, module) {
94296 /*
94297  *  Copyright 2012 Intel Corporation.
94298  *
94299  * Licensed under the Apache License, Version 2.0 (the "License");
94300  * you may not use this file except in compliance with the License.
94301  * You may obtain a copy of the License at
94302  *
94303  * http://www.apache.org/licenses/LICENSE-2.0
94304  *
94305  * Unless required by applicable law or agreed to in writing, software
94306  * distributed under the License is distributed on an "AS IS" BASIS,
94307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94308  * See the License for the specific language governing permissions and
94309  * limitations under the License.
94310  */
94311
94312 var event = require('ripple/event'),
94313     deviceSettings = require('ripple/deviceSettings'),
94314     constants = require('ripple/constants'),
94315     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
94316     emulatorBridge = require('ripple/emulatorBridge'),
94317     curPost,
94318     _self;
94319
94320 function isVibratorOn() {
94321     return deviceSettings.retrieve("Config.vibratingMode");
94322 }
94323
94324 var vibrator = (function () {
94325     var vibratorPattern,
94326         isVibrating = false,
94327         runTime = 0,
94328         vibrateTimeout = null,
94329         MILLILSECONDS_OF_ONE_VIBRATION = 100,
94330         node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
94331         movementIndex = 0,
94332         movement = [{ left: -10 }, { left: 0 }, { left: 10 }, { left: 0 },
94333                     {top: -10 }, { top: 0 }, {top: 10 }, { top: 0 }];
94334
94335     function _clearTimeout() {
94336         if (vibrateTimeout) {
94337             clearInterval(vibrateTimeout);
94338             vibrateTimeout = null;
94339         }
94340     }
94341
94342     function stopVibrate() {
94343         isVibrating = false;
94344         _clearTimeout();
94345         node.css({left: 0, top: 0}, MILLILSECONDS_OF_ONE_VIBRATION);
94346     }
94347
94348     function vibrate() {
94349         node.css(movement[movementIndex]);
94350         movementIndex = (movementIndex + 1) % 8;
94351     }
94352
94353     function changePulse() {
94354         if (emulatorBridge.document().hidden) {
94355             return;
94356         }
94357
94358         //run time
94359         runTime = runTime + MILLILSECONDS_OF_ONE_VIBRATION;
94360         if (curPost >= vibratorPattern.length) {
94361             setTimeout(stopVibrate, 1);
94362         }
94363         if (runTime > vibratorPattern[curPost]) {
94364             curPost = curPost + 1;
94365             runTime = 0;
94366         } else {
94367             if ((curPost % 2) === 0) {
94368                 vibrate();
94369             }
94370         }
94371     }
94372
94373     function startVibrate(_pattern) {
94374         if (!isVibratorOn())
94375             return;
94376
94377         vibratorPattern = _pattern;
94378         _clearTimeout();
94379         movementIndex = 0;
94380         if (_pattern) {
94381             runTime = 0;
94382             vibrateTimeout = setInterval(changePulse, MILLILSECONDS_OF_ONE_VIBRATION);
94383         }
94384         isVibrating = true;
94385     }
94386
94387     return {
94388         isVibrating: isVibrating,
94389         startVibrate: startVibrate,
94390         stopVibrate: stopVibrate
94391     };
94392 }());
94393
94394 _self = {
94395     vibrate: function () {
94396         var pattern = arguments[0],
94397             i;
94398
94399         // If vibrator is off, stop the vibration
94400         event.on("VibratingModeChanged", function (value) {
94401             if (value === false) {
94402                 vibrator.stopVibrate();
94403             }
94404         });
94405
94406         //1. If the hidden attribute [PAGE-VISIBILITY] is set to true, abort these steps.
94407         if (emulatorBridge.document().hidden) {
94408             return;
94409         }
94410
94411         //2. Let pattern be the value of the first argument.
94412         if (!tizen1_utils.isValidArray(pattern)) {
94413             pattern |= 0;
94414         } else {
94415             for (i = 0; i < pattern.length; i++) {
94416                 pattern[i] |= 0;
94417             }
94418         }
94419
94420         //3. If pattern is 0, or an empty list, cancel the pre-existing instance of the processing vibration patterns algorithm, if any, and abort these steps.
94421         if (pattern === 0 || (tizen1_utils.isValidArray(pattern) && pattern.length === 0)) {
94422             vibrator.stopVibrate();
94423             return;
94424         }
94425
94426         //4. If pattern is a list, proceed to the next step. Otherwise run the following substeps:
94427         //a. Let list be an initially empty list, and add pattern to list.
94428         //b. Let pattern be list.
94429         if (!tizen1_utils.isValidArray(pattern)) {
94430             pattern = [pattern];
94431         }
94432
94433         //5. If any entry of pattern exceeds an implementation-dependent limit, then the user agent may throw a NotSupportedError exception and abort these steps.
94434
94435         //6. If the length of pattern is even, then remove the last entry in pattern.
94436         if (pattern.length % 2 === 0) {
94437             pattern.pop();
94438         }
94439
94440         //7. Cancel the pre-existing instance of the processing vibration patterns algorithm, if any.
94441         if (vibrator.isVibrating) {
94442             vibrator.stopVibrate();
94443         }
94444
94445         curPost = 0;
94446         vibrator.startVibrate(pattern);
94447     }
94448 };
94449
94450 module.exports = _self;
94451
94452 });
94453 define('ripple/platform/tizen/2.0/poiBackend_openmapquest', function (require, exports, module) {
94454 /*
94455  *  Copyright 2012 Intel Corporation.
94456  *
94457  * Licensed under the Apache License, Version 2.0 (the "License");
94458  * you may not use this file except in compliance with the License.
94459  * You may obtain a copy of the License at
94460  *
94461  * http://www.apache.org/licenses/LICENSE-2.0
94462  *
94463  * Unless required by applicable law or agreed to in writing, software
94464  * distributed under the License is distributed on an "AS IS" BASIS,
94465  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94466  * See the License for the specific language governing permissions and
94467  * limitations under the License.
94468  */
94469
94470 var lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
94471     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
94472     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
94473     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
94474     POIGeometry = require('ripple/platform/tizen/2.0/POIGeometry'),
94475     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
94476     _security;
94477
94478 function POIPublic(prop) {
94479     /* This is created for public use */
94480     var _self, i, copy, attr,  _id = null, _providerName = null;
94481     if (prop.id) {
94482         _id = prop.id;
94483     }
94484     if (prop.providerName) {
94485         _providerName = prop.providerName;
94486     }
94487     _self = {
94488         name : null,
94489         categories : [],
94490         address : null,
94491         phoneNumbers : [],
94492         geometry : null,
94493         urls : [],
94494         rating : null,
94495         tags : null,
94496         toGeoJSON : function () {
94497             throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
94498         }
94499     };
94500
94501     _self.__defineGetter__("id", function () {
94502         return _id;
94503     });
94504
94505     _self.__defineGetter__("providerName", function () {
94506         return _providerName;
94507     });
94508
94509     if (prop) {
94510         if (prop.name) {
94511             _self.name = String(prop.name);
94512         }
94513         if (tizen1_utils.isValidArray(prop.categories)) {
94514             _self.categories = [];
94515             for (i in prop.categories) {
94516                 _self.categories.push(String(prop.categories[i]));
94517             }
94518         }
94519         if (prop.address) {
94520             if (typeof prop.address === "string") {
94521                 _self.address = String(prop.address);
94522             } else if (Object.prototype.toString.call(prop.address) === "[object Object]") {
94523                 copy = prop.address.constructor();
94524                 for (attr in prop.address) {
94525                     if (prop.address.hasOwnProperty(attr)) {
94526                         copy[attr] = prop.address[attr];
94527                     }
94528                 }
94529                 _self.address = copy;
94530             }
94531         }
94532         if (tizen1_utils.isValidArray(prop.phoneNumbers)) {
94533             _self.phoneNumbers = [];
94534             for (i in prop.phoneNumbers) {
94535                 _self.phoneNumbers.push(String(prop.phoneNumbers[i]));
94536             }
94537         }
94538         if (prop.geometry) {
94539             _self.geometry = new POIGeometry(prop.geometry.position, prop.geometry.viewport, prop.geometry.wkt);
94540         }
94541         if (tizen1_utils.isValidArray(prop.urls)) {
94542             _self.urls = [];
94543             for (i in prop.urls) {
94544                 _self.urls.push(String(prop.urls[i]));
94545             }
94546         }
94547         if (typeof prop.rating === "number") {
94548             _self.rating = prop.rating;
94549         }
94550         if (Object.prototype.toString.call(prop.tags) === "[object Object]") {
94551             copy = prop.tags.constructor();
94552             for (attr in prop.tags) {
94553                 if (prop.tags.hasOwnProperty(attr)) {
94554                     copy[attr] = prop.tags[attr];
94555                 }
94556             }
94557             _self.tags = copy;
94558         }
94559     }
94560
94561     return _self;
94562 }
94563
94564 module.exports = function (prop) {
94565
94566     var _self = new lbs.LocationServiceProvider(prop);
94567
94568     if (prop.metaData) {
94569         _security = prop.metaData;
94570     }
94571
94572     _self.__defineGetter__("supportedFilterTypes", function () {
94573         return [];
94574     });
94575
94576     _self.__defineGetter__("supportedPOIFilterAttributes", function () {
94577         return [];
94578     });
94579
94580     _self.__defineGetter__("supportedCategories", function () {
94581         /* reference: http://wiki.openstreetmap.org/wiki/Map_Features#Amenity */
94582         return ["bar", "bbq", "biergarten", "cafe", "drinking_water", "fast_food", "food_court", "ice_cream",
94583                 "pub", "restaurant", "college", "kindergarten", "library", "school", "university",
94584                 "bicycle_parking", "bicycle_rental", "bus_station", "car_rental", "car_sharing", "car_wash",
94585                 "ev_charging", "ferry_terminal", "fuel", "grit_bin", "parking", "parking_entrance",
94586                 "parking_space", "taxi", "atm", "bank", "bureau_de_change", "baby_hatch", "clinic",
94587                 "dentist", "doctors", "hospital", "nursing_home", "pharmacy", "social_facility", "veterinary",
94588                 "arts_centre", "cinema", "community_centre", "fountain", "nightclub", "social_centre",
94589                 "stripclub", "studio", "swingerclub", "theatre", "bench", "brothel", "clock", "courthouse",
94590                 "crematorium", "embassy", "fire_station", "grave_yard", "hunting_stand", "marketplace",
94591                 "place_of_worship", "police", "post_box", "post_office", "prison", "public_building",
94592                 "recycling", "sauna", "shelter", "shower", "telephone", "toilets", "townhall", "vending_machine",
94593                 "waste_basket", "waste_disposal", "watering_place"];
94594     });
94595
94596     _self.__defineGetter__("capabilities", function () {
94597         /* The set is empty, indicating that this provider supports only 'find' operations */
94598         return [];
94599     });
94600
94601     _self.find = function (point, successCallback, errorCallback, options) {
94602         /* This provider only supports searching by "GeoRectBounds" due to MapQuest XAPI limitation */
94603
94604         function _find() {
94605             var searchStr, pois = [], isTypeOK = false,
94606                 id, providerName, name, categories = [], geometry;
94607
94608             if (Object.prototype.toString.call(point) === "[object Object]") {
94609                 if (point.southWest && point.northEast) {
94610                     if (typeof point.southWest.latitude === "number" &&
94611                         typeof point.southWest.longitude === "number" &&
94612                         typeof point.northEast.latitude === "number" &&
94613                         typeof point.northEast.longitude === "number") {
94614                         isTypeOK = true;
94615                     }
94616                 }
94617             }
94618
94619             if (!isTypeOK) {
94620                 throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
94621             }
94622
94623             searchStr = "http://open.mapquestapi.com/xapi/api/0.6/node";
94624             if (options && tizen1_utils.isValidArray(options.categories) &&
94625                 options.categories.length > 0 && typeof options.categories[0] === "string") {
94626                 /* xapi support single amenity only */
94627                 searchStr += "[amenity=" + options.categories[0] + "]";
94628             }
94629             searchStr += "[bbox=" + point.southWest.longitude + "," + point.southWest.latitude + "," +
94630                 point.northEast.longitude + "," + point.northEast.latitude + "]";
94631
94632             /* use Open MapQuest online xapi service. (http://open.mapquestapi.com/xapi/) */
94633             $.ajax({
94634                 type: "GET",
94635                 url: searchStr,
94636                 dataType: "xml",
94637                 timeout: 15000, /* 15 secs timeout */
94638                 success: function (xml) {
94639                     providerName = $(xml).find("osm").attr("generator");
94640                     $(xml).find("node").each(function () {
94641                         var $item = $(this);
94642                         categories = [];
94643                         id = $item.attr("id");
94644                         geometry = new POIGeometry(new SimpleCoordinates($item.attr("lat"), $item.attr("lon")));
94645                         $item.find("tag").each(function () {
94646                             if ($(this).attr("k") === "name") {
94647                                 name = $(this).attr("v");
94648                             } else if ($(this).attr("k") === "amenity") {
94649                                 categories.push($(this).attr("v"));
94650                             }
94651                         });
94652                         pois.push(new POIPublic({id: id, providerName: providerName, name: name,
94653                                                 categories: categories, geometry: geometry}));
94654                     });
94655                     successCallback(pois);
94656                 },
94657                 error: function (obj, msg) {
94658                     if (errorCallback) {
94659                         if (msg === "timeout") {
94660                             setTimeout(function () {
94661                                 errorCallback(new WebAPIError(errorcode.TIMEOUT_ERR));
94662                             }, 1);
94663                         } else {
94664                             setTimeout(function () {
94665                                 errorCallback(new WebAPIError(errorcode.NETWORK_ERR));
94666                             }, 1);
94667                         }
94668                     }
94669                 }
94670             });
94671         }
94672
94673         if (!_security.all && !_security.find) {
94674             throw new WebAPIError(errorcode.SECURITY_ERR);
94675         }
94676
94677         tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
94678     };
94679
94680     _self.update = function (poi, successCallback, errorCallback) {
94681         if (!_security.all && !_security.update) {
94682             throw new WebAPIError(errorcode.SECURITY_ERR);
94683         }
94684
94685         throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
94686     };
94687
94688     _self.add = function (poi, successCallback, errorCallback) {
94689         if (!_security.all && !_security.add) {
94690             throw new WebAPIError(errorcode.SECURITY_ERR);
94691         }
94692
94693         throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
94694     };
94695
94696     _self.remove = function (poi, successCallback, errorCallback) {
94697         if (!_security.all && !_security.remove) {
94698             throw new WebAPIError(errorcode.SECURITY_ERR);
94699         }
94700
94701         throw new WebAPIError(errorcode.NOT_SUPPORTED_ERR);
94702     };
94703
94704     return _self;
94705 };
94706
94707 });
94708 define('ripple/platform/tizen/2.0/BluetoothClassDeviceService', function (require, exports, module) {
94709 /*
94710  *  Copyright 2013 Intel Corporation
94711  *
94712  * Licensed under the Apache License, Version 2.0 (the "License");
94713  * you may not use this file except in compliance with the License.
94714  * You may obtain a copy of the License at
94715  *
94716  * http://www.apache.org/licenses/LICENSE-2.0
94717  *
94718  * Unless required by applicable law or agreed to in writing, software
94719  * distributed under the License is distributed on an "AS IS" BASIS,
94720  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94721  * See the License for the specific language governing permissions and
94722  * limitations under the License.
94723  */
94724
94725 var BluetoothClassDeviceService = function () {
94726     this.__defineGetter__("LIMITED_DISCOVERABILITY", function () {
94727         return 0x0001;
94728     });
94729
94730     this.__defineGetter__("POSITIONING", function () {
94731         return 0x0008;
94732     });
94733
94734     this.__defineGetter__("NETWORKING", function () {
94735         return 0x0010;
94736     });
94737
94738     this.__defineGetter__("RENDERING", function () {
94739         return 0x0020;
94740     });
94741
94742     this.__defineGetter__("CAPTURING", function () {
94743         return 0x0040;
94744     });
94745
94746     this.__defineGetter__("OBJECT_TRANSFER", function () {
94747         return 0x0080;
94748     });
94749
94750     this.__defineGetter__("AUDIO", function () {
94751         return 0x0100;
94752     });
94753
94754     this.__defineGetter__("TELEPHONY", function () {
94755         return 0x0200;
94756     });
94757
94758     this.__defineGetter__("INFORMATION", function () {
94759         return 0x0400;
94760     });
94761 };
94762
94763 module.exports = BluetoothClassDeviceService;
94764
94765 });
94766 define('ripple/platform/tizen/2.0/download', function (require, exports, module) {
94767 /*
94768  *  Copyright 2012 Intel Corporation.
94769  *
94770  * Licensed under the Apache License, Version 2.0 (the "License");
94771  * you may not use this file except in compliance with the License.
94772  * You may obtain a copy of the License at
94773  *
94774  * http://www.apache.org/licenses/LICENSE-2.0
94775  *
94776  * Unless required by applicable law or agreed to in writing, software
94777  * distributed under the License is distributed on an "AS IS" BASIS,
94778  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
94779  * See the License for the specific language governing permissions and
94780  * limitations under the License.
94781  */
94782
94783 var db = require('ripple/db'),
94784     event = require('ripple/event'),
94785     t = require('ripple/platform/tizen/2.0/typecast'),
94786     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
94787     filesystem = require('ripple/platform/tizen/2.0/filesystem'),
94788     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
94789     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
94790     DownloadRequest = require('ripple/platform/tizen/2.0/DownloadRequest'),
94791     DownloadState = {
94792         QUEUED: "QUEUED",
94793         DOWNLOADING: "DOWNLOADING",
94794         PAUSED: "PAUSED",
94795         CANCELED: "CANCELED",
94796         COMPLETED: "COMPLETED",
94797         FAILED: "FAILED"
94798     },
94799     _security = {
94800         "http://tizen.org/privilege/download": ["start"]
94801     },
94802     DB_DOWNLOAD_KEY = "tizen1-db-download",
94803     DownloadItem, _isInitialized = false, INTERVAL = 1000,
94804     _downloads = [], _resources = [], _self;
94805
94806 function _initDownloadItem(download) {
94807     var url, index, isExist = false;
94808     url = download.url;
94809     if (download.destination === null) {
94810         download.destination = "downloads";
94811     }
94812     if (download.fileName === null) {
94813         index = url.lastIndexOf('\/') + 1;
94814         download.fileName = url.substring(index);
94815     }
94816     if (!_isInitialized) {
94817         initializeResource();
94818     }
94819     _resources.some(function (value) {
94820         if (value.url === url) {
94821             download.size           = Number(value.size);
94822             download.speed          = Number(value.speed);
94823             download.estimatedTime = Math.round(value.estimatedTime * 100) / 100;
94824             download.MIMEType       = value.MIMEType;
94825             isExist =  true;
94826             return;
94827         }
94828     });
94829     if (!isExist) {
94830         download.state = DownloadState.FAILED;
94831         _exec(download.callback, 'onfailed', download.id, new WebAPIError(errorcode.NOT_FOUND_ERR));
94832         return;
94833     }
94834     return download;
94835 }
94836
94837 function _exec(callback, name, downloadId, arg1, arg2) {
94838     if (callback === null) {
94839         return;
94840     }
94841
94842     window.setTimeout(function () {
94843         switch (name) {
94844         case "onprogress":
94845             callback[name](downloadId, arg1, arg2);
94846             break;
94847
94848         case "onpaused":
94849             callback[name](downloadId);
94850             break;
94851
94852         case "oncanceled":
94853             callback[name](downloadId);
94854             break;
94855
94856         case "oncompleted":
94857             callback[name](downloadId, arg1);
94858             break;
94859
94860         case "onfailed":
94861             callback[name](downloadId, arg1);
94862             break;
94863
94864         default:
94865             break;
94866         }
94867     }, 1);
94868 }
94869
94870 function _getDownloadObjById(id) {
94871     var isFound = false, backObj;
94872     id = Number(id);
94873     _downloads.some(function (obj) {
94874         if (obj.id === id) {
94875             backObj = obj;
94876             isFound = true;
94877             return;
94878         }
94879     });
94880     if (!isFound) {
94881         throw new WebAPIException(errorcode.NOT_FOUND_ERR);
94882     }
94883     return backObj;
94884 }
94885
94886 function initializeResource() {
94887     _resources = db.retrieveObject(DB_DOWNLOAD_KEY);
94888     _isInitialized = true;
94889 }
94890
94891 function _saveFile(downloadObj, callback) {
94892     var name, path, content;
94893
94894     name = downloadObj.fileName;
94895     path = downloadObj.destination;
94896     content = 'size|' + downloadObj.size + ',speed|' + downloadObj.speed + ',url|' + downloadObj.url + ',estimatedTime|' + downloadObj.estimatedTime;
94897     function onsuccess(fs) {
94898         fs.write(content);
94899         fs.close();
94900     }
94901     function onerror(e) {
94902         _exec(downloadObj.callback, 'onfailed', downloadObj.id, e);
94903     }
94904     function rename(name) { //index.html==>index_1.html
94905         var index, c;
94906         index = name.lastIndexOf('.');
94907         if (index < 0) {
94908             index = name.length;
94909         }
94910         c = name.substr(index - 2, 1);
94911         if (c === '_') {
94912             name = name.substr(0, index - 1) + (Number(name.substr(index - 1, 1)) + 1) + name.substring(index);
94913         } else {
94914             name = name.substr(0, index) + "_1" + name.substring(index);
94915         }
94916         return name;
94917     }
94918
94919     filesystem.resolve(path, function (dir) {
94920         var file, isExist = true;
94921         while (isExist) {
94922             try {
94923                 file = dir.resolve(name);
94924                 name = rename(name);
94925             } catch (e) {
94926                 isExist = false;
94927             }
94928         }
94929         file = dir.createFile(name);
94930         file.openStream('w', onsuccess, onerror, 'UTF-8');
94931         callback(name);
94932     }, onerror, "rw");
94933 }
94934
94935 DownloadItem = function (download, callback) {
94936     var _self;
94937     _self = {
94938         id           : Number(Math.uuid(8, 10)),
94939         url          : download.url,
94940         state        : DownloadState.QUEUED,
94941         fileName     : download.fileName || null,
94942         destination  : download.destination || null,
94943         callback     : callback || null
94944     };
94945     return _self;
94946 };
94947
94948 _self = function () {
94949     function start(downloadRequest, downloadCallback) {
94950         var downloadObj, fileSize, increment, receivedSize = 0, intervalId;
94951
94952         if (!_security.start) {
94953             throw new WebAPIException(errorcode.SECURITY_ERR);
94954         }
94955
94956         t.DownloadManager("start", arguments);
94957
94958         downloadObj = new DownloadItem(downloadRequest, downloadCallback);
94959         _downloads.push(downloadObj);
94960         downloadObj = _initDownloadItem(downloadObj);
94961         if (downloadObj === null || downloadObj === undefined) {
94962             return;
94963         }
94964         downloadObj.state = DownloadState.DOWNLOADING;
94965
94966         fileSize = downloadObj.size;
94967         increment = downloadObj.speed;
94968         intervalId = setInterval(function () {
94969             if (receivedSize >= fileSize) {//Finish downloading
94970                 receivedSize = fileSize;
94971                 downloadObj.state = DownloadState.COMPLETED;
94972                 _saveFile(downloadObj, function (fileName) {
94973                     _exec(downloadObj.callback, 'oncompleted', downloadObj.id, fileName);
94974                 });
94975                 clearInterval(intervalId);
94976             } else { // Continue downloading
94977                 receivedSize += increment;
94978                 downloadObj.receivedSize = receivedSize;
94979                 _exec(downloadObj.callback, 'onprogress', downloadObj.id, receivedSize, fileSize);
94980             }
94981         }, INTERVAL);
94982         downloadObj.intervalId = intervalId;
94983         return downloadObj.id;
94984     }
94985
94986     function cancel(downloadId) {
94987         var downloadObj;
94988
94989         t.DownloadManager("cancel", arguments);
94990
94991         downloadObj = _getDownloadObjById(downloadId);
94992         clearInterval(downloadObj.intervalId);
94993         if (downloadObj.state !== DownloadState.DOWNLOADING &&
94994             downloadObj.state !== DownloadState.PAUSED) {
94995             _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR));
94996             return;
94997         }
94998         downloadObj.state = DownloadState.CANCELED;
94999         _exec(downloadObj.callback, 'oncanceled', downloadObj.id);
95000     }
95001
95002     function pause(downloadId) {
95003         var downloadObj;
95004
95005         t.DownloadManager("pause", arguments);
95006
95007         downloadObj = _getDownloadObjById(downloadId);
95008         clearInterval(downloadObj.intervalId);
95009         if (downloadObj.state !== DownloadState.DOWNLOADING) {
95010             _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR));
95011             return;
95012         }
95013         downloadObj.state = DownloadState.PAUSED;
95014         _exec(downloadObj.callback, 'onpaused', downloadObj.id);
95015     }
95016
95017     function resume(downloadId) {
95018         var downloadObj, fileSize, receivedSize, increment, intervalId;
95019
95020         t.DownloadManager("resume", arguments);
95021
95022         downloadObj  = _getDownloadObjById(downloadId);
95023         fileSize     = downloadObj.size;
95024         receivedSize = downloadObj.receivedSize;
95025         increment    = downloadObj.speed;
95026
95027         if (downloadObj.state !== DownloadState.PAUSED) {
95028             _exec(downloadObj.callback, 'onfailed', downloadObj.id, new WebAPIError(errorcode.INVALID_VALUES_ERR));
95029             return;
95030         }
95031         downloadObj.state = DownloadState.DOWNLOADING;
95032         intervalId = setInterval(function () {
95033             if (receivedSize >= fileSize) {//Finish downloading
95034                 receivedSize = fileSize;
95035                 downloadObj.state = DownloadState.COMPLETED;
95036                 _saveFile(downloadObj, function (fileName) {
95037                     _exec(downloadObj.callback, 'oncompleted', downloadObj.id, fileName);
95038                 });
95039                 clearInterval(intervalId);
95040             } else {// Continue downloading
95041                 receivedSize += increment;
95042                 downloadObj.receivedSize = receivedSize;
95043                 _exec(downloadObj.callback, 'onprogress', downloadObj.id, receivedSize, fileSize);
95044             }
95045         }, INTERVAL);
95046         downloadObj.intervalId = intervalId;
95047     }
95048
95049     function getState(downloadId) {
95050         var downloadObj;
95051
95052         t.DownloadManager("getState", arguments);
95053
95054         downloadObj = _getDownloadObjById(downloadId);
95055         return downloadObj.state;
95056     }
95057
95058     function getDownloadRequest(downloadId) {
95059         var req, downloadObj;
95060
95061         t.DownloadManager("getDownloadRequest", arguments);
95062
95063         downloadObj = _getDownloadObjById(downloadId);
95064         req = new DownloadRequest(downloadObj.url, downloadObj.destination, downloadObj.fileName);
95065         return req;
95066     }
95067
95068     function getMIMEType(downloadId) {
95069         var downloadObj;
95070
95071         t.DownloadManager("getMIMEType", arguments);
95072
95073         downloadObj = _getDownloadObjById(downloadId);
95074         return downloadObj.MIMEType;
95075     }
95076
95077     function setListener(downloadId, downloadCallback) {
95078         var downloadObj;
95079
95080         t.DownloadManager("setListener", arguments);
95081
95082         downloadObj = _getDownloadObjById(downloadId);
95083         if (downloadObj) {
95084             downloadObj.callback = downloadCallback;
95085         }
95086     }
95087
95088     function handleSubFeatures(subFeatures) {
95089         var i, subFeature;
95090
95091         for (subFeature in subFeatures) {
95092             for (i in _security[subFeature]) {
95093                 _security[_security[subFeature][i]] = true;
95094             }
95095         }
95096     }
95097
95098     var download = {
95099         start: start,
95100         cancel: cancel,
95101         pause: pause,
95102         resume: resume,
95103         getState: getState,
95104         getDownloadRequest: getDownloadRequest,
95105         getMIMEType: getMIMEType,
95106         setListener: setListener,
95107         handleSubFeatures: handleSubFeatures
95108     };
95109
95110     return download;
95111 };
95112
95113 event.on('downloadResourceChanged', function () {
95114     _isInitialized = false;
95115 });
95116
95117 module.exports = _self;
95118
95119 });
95120 define('ripple/platform/tizen/2.0/websetting', function (require, exports, module) {
95121 /*
95122  *  Copyright 2014 Intel Corporation.
95123  *
95124  * Licensed under the Apache License, Version 2.0 (the "License");
95125  * you may not use this file except in compliance with the License.
95126  * You may obtain a copy of the License at
95127  *
95128  * http://www.apache.org/licenses/LICENSE-2.0
95129  *
95130  * Unless required by applicable law or agreed to in writing, software
95131  * distributed under the License is distributed on an "AS IS" BASIS,
95132  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95133  * See the License for the specific language governing permissions and
95134  * limitations under the License.
95135  */
95136
95137 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
95138     t = require('ripple/platform/tizen/2.0/typecast'),
95139     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
95140     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
95141     _data = {
95142         userAgent: null
95143     },
95144     _security = {
95145         "http://tizen.org/privilege/websetting": ["removeAllCookies"]
95146     },
95147     _self;
95148
95149 function _isInvalidString(str) {
95150     str = str.trim();
95151
95152     return (/\t|\n|\r|\v/.test(str)) || (str.length === 0);
95153 }
95154
95155 function _clearAllCookies() {
95156     var cookies = document.cookie.split(";"),
95157         i, equalPos, name;
95158
95159     for (i = 0; i < cookies.length; i++) {
95160         equalPos = cookies[i].indexOf("=");
95161         name = (equalPos > -1) ? cookies[i].substr(0, equalPos) : cookies[i];
95162
95163         document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
95164     }
95165 }
95166
95167 _self = function () {
95168     var websetting;
95169
95170     function setUserAgentString(userAgent, successCallback, errorCallback) {
95171         t.WebSettingManager("setUserAgentString", arguments, true);
95172
95173         window.setTimeout(function () {
95174             if (_isInvalidString(userAgent)) {
95175                 if (errorCallback) {
95176                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
95177                 }
95178                 return;
95179             }
95180
95181             if (_data.userAgent === null) {
95182                 navigator.__defineGetter__("userAgent", function() {
95183                     return _data.userAgent;
95184                 });
95185             }
95186
95187             _data.userAgent = userAgent;
95188
95189             successCallback();
95190         }, 1);
95191     }
95192
95193     function removeAllCookies(successCallback, errorCallback) {
95194         if (!_security.removeAllCookies) {
95195             throw new WebAPIException(errorcode.SECURITY_ERR);
95196         }
95197
95198         t.WebSettingManager("removeAllCookies", arguments);
95199
95200         window.setTimeout(function () {
95201             _clearAllCookies();
95202             successCallback();
95203         }, 1);
95204     }
95205
95206     function handleSubFeatures(subFeatures) {
95207         var i, subFeature;
95208
95209         for (subFeature in subFeatures) {
95210             for (i in _security[subFeature]) {
95211                 _security[_security[subFeature][i]] = true;
95212             }
95213         }
95214     }
95215
95216     websetting = {
95217         setUserAgentString: setUserAgentString,
95218         removeAllCookies: removeAllCookies,
95219         handleSubFeatures: handleSubFeatures
95220     };
95221
95222     return websetting;
95223 };
95224
95225 module.exports = _self;
95226
95227 });
95228 define('ripple/platform/tizen/2.0/CalendarAttendee', function (require, exports, module) {
95229 /*
95230  *  Copyright 2013 Intel Corporation.
95231  *
95232  * Licensed under the Apache License, Version 2.0 (the "License");
95233  * you may not use this file except in compliance with the License.
95234  * You may obtain a copy of the License at
95235  *
95236  * http://www.apache.org/licenses/LICENSE-2.0
95237  *
95238  * Unless required by applicable law or agreed to in writing, software
95239  * distributed under the License is distributed on an "AS IS" BASIS,
95240  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95241  * See the License for the specific language governing permissions and
95242  * limitations under the License.
95243  */
95244
95245 var t = require('ripple/platform/tizen/2.0/typecast'),
95246     CalendarAttendee;
95247
95248 CalendarAttendee = function (uri, attendeeInitDict) {
95249     var calendarAttendee = {}, attr;
95250
95251     t.CalendarAttendee(arguments, this);
95252
95253     calendarAttendee.uri          = uri;
95254     calendarAttendee.name         = undefined;
95255     calendarAttendee.role         = "REQ_PARTICIPANT";
95256     calendarAttendee.status       = "PENDING";
95257     calendarAttendee.RSVP         = false;
95258     calendarAttendee.type         = "INDIVIDUAL";
95259     calendarAttendee.group        = undefined;
95260     calendarAttendee.delegatorURI = undefined;
95261     calendarAttendee.delegateURI  = undefined;
95262     calendarAttendee.contactRef   = null;
95263
95264     if (attendeeInitDict) {
95265         for (attr in attendeeInitDict) {
95266             calendarAttendee[attr] = attendeeInitDict[attr];
95267         }
95268     }
95269
95270     this.__defineGetter__("uri", function () {
95271         return calendarAttendee.uri;
95272     });
95273     this.__defineSetter__("uri", function (val) {
95274         try {
95275             calendarAttendee.uri = t.DOMString(val);
95276         } catch (e) {
95277         }
95278     });
95279
95280     this.__defineGetter__("name", function () {
95281         return calendarAttendee.name;
95282     });
95283     this.__defineSetter__("name", function (val) {
95284         try {
95285             calendarAttendee.name = t.DOMString(val, "?");
95286         } catch (e) {
95287         }
95288     });
95289
95290     this.__defineGetter__("role", function () {
95291         return calendarAttendee.role;
95292     });
95293     this.__defineSetter__("role", function (val) {
95294         try {
95295             calendarAttendee.role = t.AttendeeRole(val);
95296         } catch (e) {
95297         }
95298     });
95299
95300     this.__defineGetter__("status", function () {
95301         return calendarAttendee.status;
95302     });
95303     this.__defineSetter__("status", function (val) {
95304         try {
95305             calendarAttendee.status = t.AttendeeStatus(val);
95306         } catch (e) {
95307         }
95308     });
95309
95310     this.__defineGetter__("RSVP", function () {
95311         return calendarAttendee.RSVP;
95312     });
95313     this.__defineSetter__("RSVP", function (val) {
95314         try {
95315             calendarAttendee.RSVP = t.boolean(val);
95316         } catch (e) {
95317         }
95318     });
95319
95320     this.__defineGetter__("type", function () {
95321         return calendarAttendee.type;
95322     });
95323     this.__defineSetter__("type", function (val) {
95324         try {
95325             calendarAttendee.type = t.AttendeeType(val);
95326         } catch (e) {
95327         }
95328     });
95329
95330     this.__defineGetter__("group", function () {
95331         return calendarAttendee.group;
95332     });
95333     this.__defineSetter__("group", function (val) {
95334         try {
95335             calendarAttendee.group = t.DOMString(val, "?");
95336         } catch (e) {
95337         }
95338     });
95339
95340     this.__defineGetter__("delegatorURI", function () {
95341         return calendarAttendee.delegatorURI;
95342     });
95343     this.__defineSetter__("delegatorURI", function (val) {
95344         try {
95345             calendarAttendee.delegatorURI = t.DOMString(val, "?");
95346         } catch (e) {
95347         }
95348     });
95349
95350     this.__defineGetter__("delegateURI", function () {
95351         return calendarAttendee.delegateURI;
95352     });
95353     this.__defineSetter__("delegateURI", function (val) {
95354         try {
95355             calendarAttendee.delegateURI = t.DOMString(val, "?");
95356         } catch (e) {
95357         }
95358     });
95359
95360     this.__defineGetter__("contactRef", function () {
95361         return calendarAttendee.contactRef;
95362     });
95363     this.__defineSetter__("contactRef", function (val) {
95364         try {
95365             calendarAttendee.contactRef = t.ContactRef(val, "?");
95366         } catch (e) {
95367         }
95368     });
95369 };
95370
95371 module.exports = CalendarAttendee;
95372
95373 });
95374 define('ripple/platform/tizen/2.0/decorator', function (require, exports, module) {
95375 /*
95376  *  Copyright 2013 Intel Corporation.
95377  *
95378  * Licensed under the Apache License, Version 2.0 (the "License");
95379  * you may not use this file except in compliance with the License.
95380  * You may obtain a copy of the License at
95381  *
95382  * http://www.apache.org/licenses/LICENSE-2.0
95383  *
95384  * Unless required by applicable law or agreed to in writing, software
95385  * distributed under the License is distributed on an "AS IS" BASIS,
95386  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95387  * See the License for the specific language governing permissions and
95388  * limitations under the License.
95389  */
95390
95391 var t = require('ripple/platform/tizen/2.0/typecast'),
95392     ContactDecorator,
95393     _self;
95394
95395 ContactDecorator = function (contact, overlap) {
95396     var raw = {};
95397
95398     // private
95399     function clone(obj) {
95400         return function () {
95401             var Contact = require('ripple/platform/tizen/2.0/ContactBase'),
95402                 duplicate;
95403
95404             duplicate = new Contact(obj);
95405
95406             duplicate.__defineGetter__("id", function () {
95407                 return null;
95408             });
95409
95410             duplicate.__defineGetter__("addressBookId", function () {
95411                 return null;
95412             });
95413
95414             return duplicate;
95415         };
95416     }
95417
95418     // public
95419     function convertToString(format) {
95420         t.Contact("convertToString", arguments);
95421
95422         // TODO: Convert contact according to VCard protocal
95423         return "";
95424     }
95425
95426     raw.id            = overlap ? overlap.id : null;
95427     raw.personId      = overlap ? overlap.personId : null;
95428     raw.addressBookId = overlap ? overlap.addressBookId : null;
95429     raw.lastUpdated   = overlap ? overlap.lastUpdated : null;
95430     raw.isFavorite    = overlap ? overlap.isFavorite : false;
95431     raw.name          = contact.name;
95432     raw.addresses     = contact.addresses;
95433     raw.photoURI      = contact.photoURI;
95434     raw.phoneNumbers  = contact.phoneNumbers;
95435     raw.emails        = contact.emails;
95436     raw.birthday      = contact.birthday;
95437     raw.anniversaries = contact.anniversaries;
95438     raw.organizations = contact.organizations;
95439     raw.notes         = contact.notes;
95440     raw.urls          = contact.urls;
95441     raw.ringtoneURI   = contact.ringtoneURI;
95442     raw.groupIds      = contact.groupIds;
95443
95444     contact.__defineGetter__("id", function () {
95445         return raw.id;
95446     });
95447
95448     contact.__defineGetter__("personId", function () {
95449         return raw.personId;
95450     });
95451
95452     contact.__defineGetter__("addressBookId", function () {
95453         return raw.addressBookId;
95454     });
95455
95456     contact.__defineGetter__("lastUpdated", function () {
95457         return raw.lastUpdated;
95458     });
95459
95460     contact.__defineGetter__("isFavorite", function () {
95461         return raw.isFavorite;
95462     });
95463
95464     contact.__defineGetter__("name", function () {
95465         return raw.name;
95466     });
95467     contact.__defineSetter__("name", function (val) {
95468         try {
95469             raw.name = t.ContactName(val, "?");
95470         } catch (e) {
95471         }
95472     });
95473
95474     contact.__defineGetter__("addresses", function () {
95475         return raw.addresses;
95476     });
95477     contact.__defineSetter__("addresses", function (val) {
95478         try {
95479             raw.addresses = t.ContactAddress(val, "[]");
95480         } catch (e) {
95481         }
95482     });
95483
95484     contact.__defineGetter__("photoURI", function () {
95485         return raw.photoURI;
95486     });
95487     contact.__defineSetter__("photoURI", function (val) {
95488         try {
95489             raw.photoURI = t.DOMString(val, "?");
95490         } catch (e) {
95491         }
95492     });
95493
95494     contact.__defineGetter__("phoneNumbers", function () {
95495         return raw.phoneNumbers;
95496     });
95497     contact.__defineSetter__("phoneNumbers", function (val) {
95498         try {
95499             raw.phoneNumbers = t.ContactPhoneNumber(val, "[]");
95500         } catch (e) {
95501         }
95502     });
95503
95504     contact.__defineGetter__("emails", function () {
95505         return raw.emails;
95506     });
95507     contact.__defineSetter__("emails", function (val) {
95508         try {
95509             raw.emails = t.ContactEmailAddress(val, "[]");
95510         } catch (e) {
95511         }
95512     });
95513
95514     contact.__defineGetter__("birthday", function () {
95515         return raw.birthday;
95516     });
95517     contact.__defineSetter__("birthday", function (val) {
95518         try {
95519             raw.birthday = t.Date(val, "?");
95520         } catch (e) {
95521         }
95522     });
95523
95524     contact.__defineGetter__("anniversaries", function () {
95525         return raw.anniversaries;
95526     });
95527     contact.__defineSetter__("anniversaries", function (val) {
95528         try {
95529             raw.anniversaries = t.ContactAnniversary(val, "[]");
95530         } catch (e) {
95531         }
95532     });
95533
95534     contact.__defineGetter__("organizations", function () {
95535         return raw.organizations;
95536     });
95537     contact.__defineSetter__("organizations", function (val) {
95538         try {
95539             raw.organizations = t.ContactOrganization(val, "[]");
95540         } catch (e) {
95541         }
95542     });
95543
95544     contact.__defineGetter__("notes", function () {
95545         return raw.notes;
95546     });
95547     contact.__defineSetter__("notes", function (val) {
95548         try {
95549             raw.notes = t.DOMString(val, "[]");
95550         } catch (e) {
95551         }
95552     });
95553
95554     contact.__defineGetter__("urls", function () {
95555         return raw.urls;
95556     });
95557     contact.__defineSetter__("urls", function (val) {
95558         try {
95559             raw.urls = t.ContactWebSite(val, "[]");
95560         } catch (e) {
95561         }
95562     });
95563
95564     contact.__defineGetter__("ringtoneURI", function () {
95565         return raw.ringtoneURI;
95566     });
95567     contact.__defineSetter__("ringtoneURI", function (val) {
95568         try {
95569             raw.ringtoneURI = t.DOMString(val, "?");
95570         } catch (e) {
95571         }
95572     });
95573
95574     contact.__defineGetter__("groupIds", function () {
95575         return raw.groupIds;
95576     });
95577     contact.__defineSetter__("groupIds", function (val) {
95578         try {
95579             raw.groupIds = t.ContactGroupId(val, "[]");
95580         } catch (e) {
95581         }
95582     });
95583
95584     if (contact.name) {
95585         contact.name.__defineGetter__("displayName", function () {
95586             return ((overlap && overlap.name) ? overlap.name.displayName :
95587                     null);
95588         });
95589     }
95590
95591     contact.convertToString = convertToString;
95592     contact.clone           = clone(contact);
95593 };
95594
95595 _self = {
95596     Contact: ContactDecorator
95597 };
95598
95599 module.exports = _self;
95600
95601 });
95602 define('ripple/platform/tizen/2.0/BookmarkItem', function (require, exports, module) {
95603 /*
95604  *  Copyright 2013 Intel Corporation.
95605  *
95606  * Licensed under the Apache License, Version 2.0 (the "License");
95607  * you may not use this file except in compliance with the License.
95608  * You may obtain a copy of the License at
95609  *
95610  * http://www.apache.org/licenses/LICENSE-2.0
95611  *
95612  * Unless required by applicable law or agreed to in writing, software
95613  * distributed under the License is distributed on an "AS IS" BASIS,
95614  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95615  * See the License for the specific language governing permissions and
95616  * limitations under the License.
95617  */
95618
95619 var t = require('ripple/platform/tizen/2.0/typecast'),
95620     BookmarkItem;
95621
95622 BookmarkItem = function (title, url) {
95623     t.BookmarkItem(arguments, this);
95624
95625     this.__defineGetter__("parent", function () {
95626         return undefined;
95627     });
95628     this.__defineGetter__("title", function () {
95629         return title;
95630     });
95631     this.__defineGetter__("url", function () {
95632         return url;
95633     });
95634 };
95635
95636 module.exports = BookmarkItem;
95637
95638 });
95639 define('ripple/platform/tizen/2.0/ContactAddress', function (require, exports, module) {
95640 /*
95641  *  Copyright 2013 Intel Corporation.
95642  *
95643  * Licensed under the Apache License, Version 2.0 (the "License");
95644  * you may not use this file except in compliance with the License.
95645  * You may obtain a copy of the License at
95646  *
95647  * http://www.apache.org/licenses/LICENSE-2.0
95648  *
95649  * Unless required by applicable law or agreed to in writing, software
95650  * distributed under the License is distributed on an "AS IS" BASIS,
95651  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95652  * See the License for the specific language governing permissions and
95653  * limitations under the License.
95654  */
95655
95656 var t = require('ripple/platform/tizen/2.0/typecast'),
95657     ContactAddress;
95658
95659 ContactAddress = function (addressInitDict) {
95660     var contactAddress = {}, attr, arr, i;
95661
95662     t.ContactAddress(arguments, this);
95663
95664     contactAddress.country               = null;
95665     contactAddress.region                = null;
95666     contactAddress.city                  = null;
95667     contactAddress.streetAddress         = null;
95668     contactAddress.additionalInformation = null;
95669     contactAddress.postalCode            = null;
95670     contactAddress.isDefault             = false;
95671     contactAddress.types                 = ["HOME"];
95672
95673     this.__defineGetter__("country", function () {
95674         return contactAddress.country;
95675     });
95676     this.__defineSetter__("country", function (val) {
95677         try {
95678             contactAddress.country = t.DOMString(val, "?");
95679         } catch (e) {
95680         }
95681     });
95682
95683     this.__defineGetter__("region", function () {
95684         return contactAddress.region;
95685     });
95686     this.__defineSetter__("region", function (val) {
95687         try {
95688             contactAddress.region = t.DOMString(val, "?");
95689         } catch (e) {
95690         }
95691     });
95692
95693     this.__defineGetter__("city", function () {
95694         return contactAddress.city;
95695     });
95696     this.__defineSetter__("city", function (val) {
95697         try {
95698             contactAddress.city = t.DOMString(val, "?");
95699         } catch (e) {
95700         }
95701     });
95702
95703     this.__defineGetter__("streetAddress", function () {
95704         return contactAddress.streetAddress;
95705     });
95706     this.__defineSetter__("streetAddress", function (val) {
95707         try {
95708             contactAddress.streetAddress = t.DOMString(val, "?");
95709         } catch (e) {
95710         }
95711     });
95712
95713     this.__defineGetter__("additionalInformation", function () {
95714         return contactAddress.additionalInformation;
95715     });
95716     this.__defineSetter__("additionalInformation", function (val) {
95717         try {
95718             contactAddress.additionalInformation = t.DOMString(val, "?");
95719         } catch (e) {
95720         }
95721     });
95722
95723     this.__defineGetter__("postalCode", function () {
95724         return contactAddress.postalCode;
95725     });
95726     this.__defineSetter__("postalCode", function (val) {
95727         try {
95728             contactAddress.postalCode = t.DOMString(val, "?");
95729         } catch (e) {
95730         }
95731     });
95732
95733     this.__defineGetter__("isDefault", function () {
95734         return contactAddress.isDefault;
95735     });
95736     this.__defineSetter__("isDefault", function (val) {
95737         try {
95738             contactAddress.isDefault = t.boolean(val);
95739         } catch (e) {
95740         }
95741     });
95742
95743     this.__defineGetter__("types", function () {
95744         return contactAddress.types;
95745     });
95746     this.__defineSetter__("types", function (val) {
95747         try {
95748             contactAddress.types = t.DOMString(val, "[]");
95749         } catch (e) {
95750         }
95751     });
95752
95753     if (addressInitDict) {
95754         for (attr in addressInitDict) {
95755             switch (attr) {
95756             case "types":
95757                 arr = addressInitDict[attr];
95758                 if (arr) {
95759                     for (i in arr) {
95760                         contactAddress[attr][i] = arr[i];
95761                     }
95762                 }
95763                 break;
95764
95765             default:
95766                 contactAddress[attr] = addressInitDict[attr];
95767                 break;
95768             }
95769         }
95770     }
95771 };
95772
95773 module.exports = ContactAddress;
95774
95775 });
95776 define('ripple/platform/tizen/2.0/ContactEmailAddress', function (require, exports, module) {
95777 /*
95778  *  Copyright 2013 Intel Corporation.
95779  *
95780  * Licensed under the Apache License, Version 2.0 (the "License");
95781  * you may not use this file except in compliance with the License.
95782  * You may obtain a copy of the License at
95783  *
95784  * http://www.apache.org/licenses/LICENSE-2.0
95785  *
95786  * Unless required by applicable law or agreed to in writing, software
95787  * distributed under the License is distributed on an "AS IS" BASIS,
95788  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95789  * See the License for the specific language governing permissions and
95790  * limitations under the License.
95791  */
95792
95793 var t = require('ripple/platform/tizen/2.0/typecast'),
95794     ContactEmailAddress;
95795
95796 ContactEmailAddress = function (email, types, isDefault) {
95797     var contactEmailAddress = {};
95798
95799     t.ContactEmailAddress(arguments, this);
95800
95801     contactEmailAddress.email     = email;
95802     contactEmailAddress.isDefault = isDefault || false;
95803     contactEmailAddress.types     = (types && types[0]) ? types : ["WORK"];
95804
95805     this.__defineGetter__("email", function () {
95806         return contactEmailAddress.email;
95807     });
95808     this.__defineSetter__("email", function (val) {
95809         try {
95810             contactEmailAddress.email = t.DOMString(val);
95811         } catch (e) {
95812         }
95813     });
95814
95815     this.__defineGetter__("isDefault", function () {
95816         return contactEmailAddress.isDefault;
95817     });
95818     this.__defineSetter__("isDefault", function (val) {
95819         try {
95820             contactEmailAddress.isDefault = t.boolean(val);
95821         } catch (e) {
95822         }
95823     });
95824
95825     this.__defineGetter__("types", function () {
95826         return contactEmailAddress.types;
95827     });
95828     this.__defineSetter__("types", function (val) {
95829         try {
95830             contactEmailAddress.types = t.DOMString(val, "[]");
95831         } catch (e) {
95832         }
95833     });
95834 };
95835
95836 module.exports = ContactEmailAddress;
95837
95838 });
95839 define('ripple/platform/tizen/2.0/account', function (require, exports, module) {
95840 /*
95841  *  Copyright 2012 Intel Corporation.
95842  *
95843  * Licensed under the Apache License, Version 2.0 (the "License");
95844  * you may not use this file except in compliance with the License.
95845  * You may obtain a copy of the License at
95846  *
95847  * http://www.apache.org/licenses/LICENSE-2.0
95848  *
95849  * Unless required by applicable law or agreed to in writing, software
95850  * distributed under the License is distributed on an "AS IS" BASIS,
95851  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
95852  * See the License for the specific language governing permissions and
95853  * limitations under the License.
95854  */
95855
95856 var db = require('ripple/db'),
95857     utils = require('ripple/utils'),
95858     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
95859     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
95860     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
95861     _data = {
95862         DB_ACCOUNT_KEY : "tizen1-db-accounts",
95863         accounts : {}
95864     },
95865     _self;
95866
95867 function _checkAccount(account) {
95868     if (typeof account !== "object" ||
95869         typeof account.id !== "string" ||
95870         typeof account.appid !== "string" ||
95871         typeof account.userName !== "string" ||
95872         typeof account.displayName !== "string" ||
95873         typeof account.service !== "object") {
95874         return false;
95875     }
95876
95877     return true;
95878 }
95879
95880 function _checkCallback(successCallback, errorCallback) {
95881     tizen1_utils.validateArgumentType(successCallback, "function",
95882                                         new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
95883     if (errorCallback) {
95884         tizen1_utils.validateArgumentType(errorCallback, "function",
95885                                             new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
95886     }
95887 }
95888
95889 _self = {
95890     getAccounts : function () {
95891         var results = [];
95892         utils.forEach(_data.accounts, function (account) {
95893             results.push(utils.copy(account));
95894         });
95895
95896         return results;
95897     },
95898
95899     getAccountById : function (id) {
95900         var acccount = null;
95901
95902         if (typeof id !== "string") {
95903             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
95904         }
95905
95906         if (_data.accounts[id]) {
95907             account = utils.copy(_data.accounts[id]);
95908         }
95909
95910         return account;
95911     },
95912
95913     getAccountByUserName : function (userName) {
95914         var result = null;
95915
95916         if (typeof userName !== "string") {
95917             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
95918         }
95919
95920         utils.forEach(_data.accounts, function (account) {
95921             if (userName === account.userName) {
95922                 result = utils.copy(account);
95923             }
95924         });
95925
95926         return result;
95927     },
95928
95929     getAccountByappId : function (appId) {
95930         var result = null;
95931
95932         if (typeof appId !== "string") {
95933             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
95934         }
95935
95936         utils.forEach(_data.accounts, function (account) {
95937             if (appId === account.appId) {
95938                 result = utils.copy(account);
95939             }
95940         });
95941
95942         return result;
95943     },
95944
95945     getAccountByServiceId : function (serviceId) {
95946         var result = null;
95947
95948         if (typeof serviceId !== "string") {
95949             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
95950         }
95951
95952         utils.forEach(_data.accounts, function (account) {
95953             if (serviceId === account.service.id) {
95954                 result = utils.copy(account);
95955             }
95956         });
95957
95958         return result;
95959     },
95960
95961     getAccountByTag : function (tag) {
95962         var results = [], i;
95963
95964         if (typeof tag !== "string") {
95965             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
95966         }
95967
95968         utils.forEach(_data.accounts, function (account) {
95969             for (i in account.service.tag) {
95970                 if (tag === account.service.tag[i]) {
95971                     results.push(utils.copy(account));
95972                     break;
95973                 }
95974             }
95975         });
95976
95977         return results;
95978     },
95979
95980     add : function (account, successCallback, errorCallback) {
95981         if (!_checkAccount(account)) {
95982             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
95983         }
95984
95985         _checkCallback(successCallback, errorCallback);
95986
95987         if (!_data.accounts[account.id]) {
95988             _data.accounts[account.id] = utils.copy(account);
95989         }
95990
95991         successCallback();
95992     },
95993
95994     update : function (account, successCallback, errorCallback) {
95995         if (!_checkAccount(account)) {
95996             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
95997         }
95998
95999         _checkCallback(successCallback, errorCallback);
96000
96001         if (!_data.accounts[account.id]) {
96002             errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
96003             return;
96004         }
96005
96006         _data.accounts[account.id] = utils.copy(account);
96007         successCallback();
96008     },
96009
96010     remove : function (id, successCallback, errorCallback) {
96011         if (typeof id !== "string") {
96012             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
96013         }
96014
96015         _checkCallback(successCallback, errorCallback);
96016
96017         if (!_data.accounts[id]) {
96018             errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
96019             return;
96020         }
96021
96022         delete _data.accounts[id];
96023         successCallback();
96024     },
96025
96026     getAccountApplications : function () {
96027         var results = [];
96028         /* FIXME: wait for API update */
96029         return results;
96030     }
96031 };
96032
96033 function _initialize() {
96034     _data.accounts = db.retrieveObject(_data.DB_ACCOUNT_KEY) || {};
96035 }
96036
96037 _initialize();
96038
96039 module.exports = _self;
96040
96041 });
96042 define('ripple/platform/tizen/2.0/syncml-js-lib/agent', function (require, exports, module) {
96043 // -*- coding: utf-8 -*-
96044 //-----------------------------------------------------------------------------
96045 // file: $Id$
96046 // lib:  syncml-js.agent
96047 // auth: griffin <griffin@uberdev.org>
96048 // date: 2012/10/22
96049 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
96050 //-----------------------------------------------------------------------------
96051
96052 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common');
96053
96054 var _self = (function () {
96055
96056     var exports = {};
96057
96058     //---------------------------------------------------------------------------
96059     exports.Agent = common.Base.extend({
96060
96061         //-------------------------------------------------------------------------
96062         constructor: function(options) {
96063             options = _.defaults(options, {
96064                 hierarchicalSync: false
96065             });
96066             this.hierarchicalSync = options.hierarchicalSync;
96067         },
96068
96069         //-------------------------------------------------------------------------
96070         dumpItem: function(item, stream, contentType, version, cb) {
96071             return this.dumpsItem(
96072                 item, contentType, version,
96073                 function(err, data, new_contentType, new_version) {
96074                     if ( err ) {
96075                         return cb(err);
96076                     }
96077                     stream.write(data, function(err) {
96078                         if ( err ) {
96079                             return cb(err);
96080                         }
96081                         cb(null, new_contentType, new_version);
96082                     });
96083                 });
96084         },
96085
96086         //-------------------------------------------------------------------------
96087         loadItem: function(stream, contentType, version, cb) {
96088             var self = this;
96089             stream.read(function(err, data) {
96090                 if ( err ) {
96091                     cb(err);
96092                 }
96093                 self.loadsItem(data, contentType, version, cb);
96094             });
96095         },
96096
96097         //-------------------------------------------------------------------------
96098         deleteAllItems: function(cb) {
96099             var self = this;
96100             self.getAllItems(function(err, items) {
96101                 if ( err ) {
96102                     return cb(err);
96103                 }
96104                 common.cascade(items, function(e, cb) {
96105                     self.deleteItem(e, cb);
96106                 }, cb);
96107             });
96108         },
96109
96110         // TODO: add documentation about all expected methods...
96111
96112         getAllItems: function(cb) {
96113             // cb(null, LIST)
96114             return cb(new common.NotImplementedError());
96115         },
96116
96117         dumpsItem: function(item, contentType, version, cb) {
96118             // cb(null, DATA [, NEW-CONTENTTYPE [, NEW-VERSION]])
96119             return cb(new common.NotImplementedError());
96120         },
96121
96122         loadsItem: function(data, contentType, version, cb) {
96123             // cb(null, ITEM)
96124             return cb(new common.NotImplementedError());
96125         },
96126
96127         addItem: function(item, cb) {
96128             // cb(null, ITEM)
96129             return cb(new common.NotImplementedError());
96130         },
96131
96132         getItem: function(itemID, cb) {
96133             // cb(null, ITEM)
96134             return cb(new common.NotImplementedError());
96135         },
96136
96137         replaceItem: function(item, reportChanges, cb) {
96138             // cb(null [, CSPEC])
96139             return cb(new common.NotImplementedError());
96140         },
96141
96142         deleteItem: function(itemID, cb) {
96143             // cb(null)
96144             return cb(new common.NotImplementedError());
96145         },
96146
96147         getContentTypes: function() {
96148             throw new common.NotImplementedError();
96149         },
96150
96151         matchItem: function(item, cb) {
96152             this.getAllItems(function(err, list) {
96153                 if ( err ) {
96154                     return cb(err);
96155                 }
96156                 var match = _.find(list, function(cur) {
96157                     return cur.compare && cur.compare(item) == 0;
96158                 });
96159                 return cb(null, match);
96160             });
96161         }
96162
96163     // TODO: mergeItems()
96164
96165     });
96166
96167     return exports;
96168
96169 })();
96170
96171 module.exports = _self;
96172
96173 });
96174 define('ripple/platform/tizen/2.0/syncml-js-lib/item', function (require, exports, module) {
96175 // -*- coding: utf-8 -*-
96176 //-----------------------------------------------------------------------------
96177 // file: $Id$
96178 // lib:  syncml-js.item
96179 // auth: griffin <griffin@uberdev.org>
96180 // date: 2012/11/30
96181 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
96182 //-----------------------------------------------------------------------------
96183
96184 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common');
96185
96186 var _self = (function () {
96187     var exports = {};
96188
96189     //---------------------------------------------------------------------------
96190     exports.Item = common.Base.extend({
96191
96192         //: the unique identifier (within the context of a SyncML datastore)
96193         //: of the current SyncML item.
96194         id: null,
96195
96196         compare: function(other) {
96197             return ( other === this ? 0 : 1 );
96198         }
96199
96200     });
96201
96202     return exports;
96203
96204 })();
96205
96206 module.exports = _self;
96207
96208 });
96209 define('ripple/platform/tizen/2.0/syncml-js-lib/storage', function (require, exports, module) {
96210 // -*- coding: utf-8 -*-
96211 //-----------------------------------------------------------------------------
96212 // file: $Id$
96213 // lib:  syncml-js.storage
96214 // auth: griffin <griffin@uberdev.org>
96215 // date: 2012/10/31
96216 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
96217 //-----------------------------------------------------------------------------
96218
96219 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
96220     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant');
96221
96222 var _self = (function () {
96223
96224     var exports = {};
96225
96226     //---------------------------------------------------------------------------
96227     _.extend(exports, {
96228
96229         //-------------------------------------------------------------------------
96230         errstr: function(target) {
96231             if ( target.error && typeof(target.error.toString) == 'function' )
96232         return target.error.toString();
96233     var ret = '';
96234     var count = 0;
96235     for ( var key in target.error )
96236         count += 1;
96237     if ( count == 1 && target.error.name )
96238         ret = '' + target.error.name;
96239     else
96240     {
96241         ret = '{';
96242         for ( var key in target.error )
96243     {
96244         ret += key + ': ' + target.error[key];
96245         count -= 1;
96246         if ( count > 0 )
96247         ret += ', ';
96248     }
96249     }
96250     if ( target.errorCode )
96251     {
96252         if ( ret.length <= 0 || ret == '{}' )
96253             ret = '' + target.errorCode;
96254         else
96255             ret = '[' + target.errorCode + '] ' + ret;
96256     }
96257     if ( ret.length <= 0 || ret == '{}' )
96258         // last ditch effort...
96259         ret = common.prettyJson(target);
96260     return ret;
96261         },
96262
96263             //-------------------------------------------------------------------------
96264             openDatabase: function(context, cb) {
96265                 var dbreq = context.storage.indexedDB.open(context.dbname, 1);
96266                 dbreq.onblocked = function(event) {
96267                     cb({code: 'syncml-js.storage.OD.10',
96268                         message: 'database blocked by other process/tab/window'});
96269                 };
96270                 dbreq.onerror = function(event) {
96271                     var errmsg = exports.errstr(event.target);
96272                     cb({code: 'syncml-js.storage.OD.20',
96273                         message: 'failed to open syncml-js database: ' + errmsg});
96274                 };
96275                 dbreq.onupgradeneeded = function(event) {
96276
96277
96278                     var db = event.target.result;
96279
96280                     var adapterTable = db.createObjectStore('adapter', {keyPath: 'id'});
96281                     adapterTable.createIndex('isLocal', 'isLocal', {unique: false});
96282                     adapterTable.createIndex('devID', 'devID', {unique: true});
96283
96284                     var mappingTable = db.createObjectStore(
96285                             'mapping',
96286                             {keyPath: ['store_id', 'guid']});
96287                     mappingTable.createIndex('store_id', 'store_id', {unique: false});
96288                     // mappingTable.createIndex('guid', 'guid', {unique: false});
96289                     // mappingTable.createIndex('luid', 'luid', {unique: false});
96290
96291                     var changeTable = db.createObjectStore(
96292                             'change',
96293                             {keyPath: ['store_id', 'item_id']});
96294                     changeTable.createIndex('store_id', 'store_id', {unique: false});
96295                     // changeTable.createIndex('item_id', 'item_id', {unique: false});
96296
96297                 };
96298                 dbreq.onsuccess = function(event) {
96299                     cb(null, event.target.result);
96300                 };
96301             },
96302
96303             //-------------------------------------------------------------------------
96304             getTransaction: function(db, tables, mode) {
96305                 // NOTE: the spec says passing in null should be valid... but
96306                 //       mozilla's indexedDB seems to barf with:
96307                 //         [Exception... "The operation failed because the
96308                 //         requested database object could not be found. For
96309                 //         example, an object store did not exist but was
96310                 //         being opened."  code: "8" nsresult: "0x80660003
96311                 //         (NotFoundError)"
96312                 if ( ! tables )
96313                     tables = ['adapter','mapping','change'];
96314                 if ( ! mode )
96315                     mode = 'readwrite';
96316                 return db.transaction(tables, mode);
96317             },
96318
96319             //-------------------------------------------------------------------------
96320             dumpDatabase: function(context, cb) {
96321
96322                 var ret = {};
96323                 var txn = context._txn();
96324
96325                 var steps = [
96326                     function(cb) {
96327                         exports.getAll(context, txn.objectStore('adapter'), {}, function(err, adapters) {
96328                             ret.adapter = adapters;
96329                             return cb(err);
96330                         });
96331                     },
96332                     function(cb) {
96333                         exports.getAll(context, txn.objectStore('mapping'), {}, function(err, mappings) {
96334                             ret.mapping = mappings;
96335                             return cb(err);
96336                         });
96337                     },
96338                     function(cb) {
96339                         exports.getAll(context, txn.objectStore('change'), {}, function(err, changes) {
96340                             ret.change = changes;
96341                             return cb(err);
96342                         });
96343                     }
96344                 ];
96345
96346                 common.cascade(steps, function(step, cb) {
96347                     return step(cb);
96348                 }, function(err) {
96349                     return cb(err, ret);
96350                 });
96351             },
96352
96353             //-------------------------------------------------------------------------
96354             clearDatabase: function(context, cb) {
96355                 var dbreq = context.storage.indexedDB.open(context.dbname, 1);
96356                 dbreq.onblocked = function(event) {
96357                     cb({code: 'syncml-js.storage.CD.10',
96358                         message: 'database blocked by other process/tab/window'});
96359                 };
96360                 dbreq.onerror = function(event) {
96361                     var errmsg = exports.errstr(event.target);
96362                     cb({code: 'syncml-js.storage.CD.20',
96363                         message: 'failed to open syncml-js database: ' + errmsg});
96364                 };
96365                 dbreq.onsuccess = function(event) {
96366                     var db = event.target.result;
96367                     db.onerror = dbreq.onerror;
96368                     async.map(['adapter', 'mapping', 'change'], function(name, cb) {
96369                         cb();
96370                     }, function(err) {
96371                         if ( err )
96372                         return cb(err);
96373                     db.close();
96374                     });
96375                 };
96376             },
96377
96378             //-------------------------------------------------------------------------
96379             getAll: function(context, source, options, cb) {
96380                 // supported options:
96381                 //   - range
96382                 //   - only
96383                 options = options || {};
96384                 var range = options.range;
96385                 if ( ! range && options.only )
96386                     range = context.storage.IDBKeyRange.only(options.only);
96387                 var req = source.openCursor(range);
96388                 var ret = [];
96389                 req.onsuccess = function(event) {
96390                     var cursor = event.target.result;
96391                     if ( cursor )
96392                     {
96393                         ret.push(cursor.value);
96394                         // ret.push({key: cursor.key, value: cursor.value});
96395                         return cursor.continue();
96396                     }
96397                     cb(null, ret);
96398                 };
96399                 req.onerror = function(event) {
96400                     cb(exports.errstr(event.target));
96401                 };
96402             },
96403
96404             //-------------------------------------------------------------------------
96405             put: function(store, object, cb) {
96406                 var req = store.put(object);
96407                 req.onsuccess = function(event) { cb(); };
96408                 req.onerror = function(event) {
96409                     cb(exports.errstr(event.target));
96410                 };
96411             },
96412
96413             //-------------------------------------------------------------------------
96414             delete: function(store, objectID, cb) {
96415                 var req = store.delete(objectID);
96416                 req.onsuccess = function(event) { cb(); };
96417                 req.onerror = function(event) {
96418                     cb(exports.errstr(event.target));
96419                 };
96420             },
96421
96422             //-------------------------------------------------------------------------
96423             deleteAll: function(source, matches, cb) {
96424                 var req = source.openCursor();
96425                 req.onsuccess = function(event) {
96426                     var cursor = event.target.result;
96427                     if ( cursor )
96428                     {
96429                         for (key in matches)
96430                             if ( matches[key] != cursor.value[key] )
96431                                 return cursor.continue();
96432                         exports.delete(source, cursor.key, function(err) {
96433                             if ( err )
96434                             return cb(err);
96435                         return cursor.continue();
96436                         });
96437                         return;
96438                     }
96439                     cb(null);
96440                 };
96441                 req.onerror = function(event) {
96442                     cb(exports.errstr(event.target));
96443                 };
96444             },
96445
96446             //-------------------------------------------------------------------------
96447             iterateCursor: function(openCursor, iterator, cb) {
96448                 openCursor.onsuccess = function(event) {
96449                     var cursor = event.target.result;
96450                     if ( ! cursor )
96451                         return cb();
96452                     iterator(cursor.value.value, cursor.value.id, function(err) {
96453                         if ( err )
96454                         return cb(err);
96455                     return cursor.continue();
96456                     });
96457                 };
96458                 openCursor.onerror = function(event) {
96459                     cb(exports.errstr(event.target));
96460                 };
96461             }
96462
96463     });
96464
96465     return exports;
96466
96467 })();
96468
96469 module.exports = _self;
96470
96471 });
96472 define('ripple/platform/tizen/2.0/syncml-js-lib/devinfo', function (require, exports, module) {
96473 // -*- coding: utf-8 -*-
96474 //-----------------------------------------------------------------------------
96475 // file: $Id$
96476 // lib:  syncml-js.devinfo
96477 // auth: griffin <griffin@uberdev.org>
96478 // date: 2012/11/06
96479 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
96480 //-----------------------------------------------------------------------------
96481
96482 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
96483     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
96484     storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'),
96485     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'),
96486     _self;
96487
96488 _self = (function () {
96489
96490     var exports = {};
96491
96492     var strAttributeMap = [
96493     ['manufacturerName',    'Man'],
96494       ['modelName',           'Mod'],
96495       ['oem',                 'OEM'],
96496       ['firmwareVersion',     'FwV'],
96497       ['softwareVersion',     'SwV'],
96498       ['hardwareVersion',     'HwV'],
96499       ['devID',               'DevID'],
96500       ['devType',             'DevTyp']
96501     ];
96502
96503 var boolAttributeMap = [
96504     ['utc',                 'UTC'],
96505       ['largeObjects',        'SupportLargeObjs'],
96506       ['hierarchicalSync',    'SupportHierarchicalSync'],
96507       ['numberOfChanges',     'SupportNumberOfChanges']
96508     ];
96509
96510 //---------------------------------------------------------------------------
96511 exports.DevInfo = common.Base.extend({
96512
96513     //-------------------------------------------------------------------------
96514     constructor: function(adapter, options) {
96515         var self = this;
96516         var options = _.defaults({}, options, {
96517             devType           : constant.DEVTYPE_WORKSTATION,
96518             manufacturerName  : '-',
96519             modelName         : '-',
96520             oem               : '-',
96521             hardwareVersion   : '-',
96522             firmwareVersion   : '-',
96523             softwareVersion   : '-',
96524             utc               : true,
96525             largeObjects      : true,
96526             hierarchicalSync  : true,
96527             numberOfChanges   : true,
96528             extensions        : {}
96529         });
96530
96531         // todo: is there anyway to mark attributes as read-only?...
96532
96533         //: [read-only] these are all read-only attributes
96534         this.devID            = options.devID || common.makeID();
96535         this.devType          = options.devType;
96536         this.manufacturerName = options.manufacturerName;
96537         this.modelName        = options.modelName;
96538         this.oem              = options.oem;
96539         this.hardwareVersion  = options.hardwareVersion;
96540         this.firmwareVersion  = options.firmwareVersion;
96541         this.softwareVersion  = options.softwareVersion;
96542         this.utc              = options.utc;
96543         this.largeObjects     = options.largeObjects;
96544         this.hierarchicalSync = options.hierarchicalSync;
96545         this.numberOfChanges  = options.numberOfChanges;
96546         this.extensions       = {};
96547
96548         _.each(options.extensions, function(values, name) {
96549             self.setExtension(name, values);
96550         });
96551
96552         // --- private attributes
96553         this._a       = adapter;
96554     },
96555
96556         //-------------------------------------------------------------------------
96557         setExtension: function(name, values) {
96558             this.extensions[name] = _.isArray(values) ? values : [values];
96559         },
96560
96561         //-------------------------------------------------------------------------
96562         getExtensionKeys: function() {
96563             return _.keys(this.extensions);
96564         },
96565
96566         //-------------------------------------------------------------------------
96567         getExtension: function(name) {
96568             return this.extensions[name];
96569         },
96570
96571         //-------------------------------------------------------------------------
96572         _load: function(cb) {
96573             cb();
96574         },
96575
96576         //-------------------------------------------------------------------------
96577         _updateModel: function(cb) {
96578             if ( ! this._a._model )
96579                 return cb('devinfo created on un-initialized adapter');
96580             this._a._model.devInfo = {
96581                 devID            : this.devID,
96582                 devType          : this.devType,
96583                 manufacturerName : this.manufacturerName,
96584                 modelName        : this.modelName,
96585                 oem              : this.oem,
96586                 hardwareVersion  : this.hardwareVersion,
96587                 firmwareVersion  : this.firmwareVersion,
96588                 softwareVersion  : this.softwareVersion,
96589                 utc              : this.utc,
96590                 largeObjects     : this.largeObjects,
96591                 hierarchicalSync : this.hierarchicalSync,
96592                 numberOfChanges  : this.numberOfChanges,
96593                 extensions       : this.extensions
96594             };
96595             cb();
96596         },
96597
96598         //-------------------------------------------------------------------------
96599         toSyncML: function(dtdVersion, stores) {
96600             dtdVersion = dtdVersion || constant.SYNCML_DTD_VERSION_1_2;
96601             if ( dtdVersion != constant.SYNCML_DTD_VERSION_1_2 )
96602                 throw new Error('unsupported DTD version "' + dtdVersion + '"')
96603                     var xret = ET.Element('DevInf', {'xmlns': constant.NAMESPACE_DEVINF})
96604                     ET.SubElement(xret, 'VerDTD').text = dtdVersion;
96605             for ( var idx=0 ; idx<strAttributeMap.length ; idx++ )
96606             {
96607                 var map = strAttributeMap[idx];
96608                 // todo: should i enforce the fact that these are all *required*?...
96609                 if ( this[map[0]] != undefined )
96610                     ET.SubElement(xret, map[1]).text = this[map[0]];
96611             }
96612             for ( var idx=0 ; idx<boolAttributeMap.length ; idx++ )
96613             {
96614                 var map = boolAttributeMap[idx];
96615                 if ( this[map[0]] )
96616                     ET.SubElement(xret, map[1])
96617             }
96618             if ( stores && stores.length > 0 )
96619                 for ( var idx=0 ; idx<stores.length ; idx++ )
96620                     xret.append(stores[idx].toSyncML());
96621             var xext = null;
96622             for ( var name in this.extensions )
96623             {
96624                 if ( ! xext )
96625                     xext = ET.SubElement(xret, 'Ext');
96626                 ET.SubElement(xext, 'XNam').text = name;
96627                 var values = this.extensions[name];
96628                 for ( var idx=0 ; idx<values.length ; idx++ )
96629                     ET.SubElement(xext, 'XVal').text = '' + values[idx];
96630             };
96631             return xret;
96632         },
96633
96634 }, {
96635
96636     //-------------------------------------------------------------------------
96637     fromSyncML: function(xnode) {
96638         var options = {};
96639         var stores  = []
96640             var dtdVersion = xnode.findtext('VerDTD')
96641             if ( dtdVersion != constant.SYNCML_DTD_VERSION_1_2 )
96642                 throw new common.ProtocolError('unsupported DTD version "' + dtdVersion + '"');
96643         for ( var idx=0 ; idx<strAttributeMap.length ; idx++ )
96644         {
96645             var map = strAttributeMap[idx];
96646             // todo: should i enforce the fact that these are all *required*?...
96647             options[map[0]] = xnode.findtext(map[1]);
96648         }
96649         for ( var idx=0 ; idx<boolAttributeMap.length ; idx++ )
96650         {
96651             var map = boolAttributeMap[idx];
96652             options[map[0]] = xnode.find(map[1]) != undefined;
96653         }
96654         _.each(xnode.getchildren(), function(child) {
96655             if ( child.tag == 'DataStore' )
96656             return stores.push(storemod.Store.fromSyncML(child));
96657         if ( child.tag == 'Ext' )
96658         {
96659             options.extensions = {};
96660             var elist = child.getchildren();
96661             var ecur  = null;
96662             for ( var idx=0 ; idx<elist.length ; idx++ )
96663         {
96664             var eitem = elist[idx];
96665             if ( eitem.tag == 'XNam' )
96666         {
96667             ecur = eitem.text;
96668             continue;
96669         }
96670         if ( ! ecur )
96671             // paranoia...
96672             continue;
96673         if ( ! options.extensions[ecur] )
96674             options.extensions[ecur] = [];
96675         options.extensions[ecur].push(eitem.text);
96676         }
96677         return;
96678         }
96679         });
96680         return [new exports.DevInfo(null, options), stores];
96681     }
96682
96683 });
96684
96685 return exports;
96686
96687 })();
96688
96689 module.exports = _self;
96690
96691 });
96692 define('ripple/platform/tizen/2.0/syncml-js-lib/ctype', function (require, exports, module) {
96693 // -*- coding: utf-8 -*-
96694 //-----------------------------------------------------------------------------
96695 // file: $Id$
96696 // auth: metagriffin <metagriffin@uberdev.org>
96697 // date: 2012/10/13
96698 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
96699 //-----------------------------------------------------------------------------
96700 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
96701     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'),
96702     _self;
96703
96704 _self = (function () {
96705
96706     var exports = {};
96707
96708     //---------------------------------------------------------------------------
96709     exports.ContentTypeInfo = common.Base.extend({
96710
96711         //-------------------------------------------------------------------------
96712         constructor: function(ctype, versions, options) {
96713             this.ctype    = ctype;
96714             this.versions = _.isArray(versions) ? versions : [versions];
96715             _.defaults(this, options || {}, {
96716                 preferred: false,
96717                 transmit:  true,
96718                 receive:   true,
96719             });
96720         },
96721
96722         //-------------------------------------------------------------------------
96723         merge: function(other) {
96724             if ( this.ctype != other.ctype
96725                 || ! _.isEqual(this.versions, other.versions)
96726                 || this.preferred != other.preferred )
96727                 return false;
96728             this.transmit = this.transmit || other.transmit;
96729             this.receive  = this.receive  || other.receive;
96730             return true
96731         },
96732
96733         //-------------------------------------------------------------------------
96734         toStruct: function() {
96735             return {
96736                 ctype: this.ctype,
96737                 versions: this.versions,
96738                 preferred: this.preferred,
96739                 transmit:  this.transmit,
96740                 receive:   this.receive
96741             };
96742         },
96743
96744         //-------------------------------------------------------------------------
96745         toSyncML: function(nodeName, uniqueVerCt) {
96746             if ( _.isFunction(nodeName) )
96747             {
96748                 cb = nodeName;
96749                 nodeName = null;
96750             }
96751             else if ( _.isFunction(uniqueVerCt) )
96752             {
96753                 cb = uniqueVerCt;
96754                 uniqueVerCt = null;
96755             }
96756             if ( ! nodeName )
96757             {
96758                 nodeName = this.transmit ? 'Tx' : 'Rx';
96759                 if ( this.preferred )
96760                     nodeName += '-Pref';
96761             }
96762             if ( this.preferred )
96763                 nodeName += '-Pref';
96764
96765             if ( uniqueVerCt )
96766             {
96767                 var ret = _.map(this.versions, function(v) {
96768                     var tmp = ET.Element(nodeName);
96769                     ET.SubElement(tmp, 'CTType').text = this.ctype;
96770                     ET.SubElement(tmp, 'VerCT').text = v;
96771                     return tmp;
96772                 }, this);
96773                 return ret;
96774             }
96775             var ret = ET.Element(nodeName);
96776             ET.SubElement(ret, 'CTType').text = this.ctype;
96777             _.each(this.versions, function(v) {
96778                 ET.SubElement(ret, 'VerCT').text = v;
96779             });
96780             return ret;
96781         },
96782
96783         describe: function(stream, cb) {
96784             stream.write(this.ctype);
96785             stream.write(this.versions.length == 1 ? ' version ' : ' versions ');
96786             stream.write(this.versions.join(', '));
96787             var flags = [];
96788             if ( this.preferred )
96789                 flags.push('preferred');
96790             if ( this.transmit )
96791                 flags.push('tx');
96792             if ( this.receive )
96793                 flags.push('rx');
96794             if ( flags.length > 0 )
96795             {
96796                 stream.write(' (');
96797                         stream.write(flags.join(', '));
96798                         stream.write(')');
96799                         }
96800                         stream.write('\n');
96801                         }
96802
96803                         }, {
96804
96805                             //-------------------------------------------------------------------------
96806                             fromStruct: function(struct) {
96807                                 return new exports.ContentTypeInfo(struct.ctype, struct.versions, struct);
96808                             },
96809
96810                     //-------------------------------------------------------------------------
96811                     fromSyncML: function(xnode) {
96812                         return new exports.ContentTypeInfo(
96813                             xnode.findtext('CTType'),
96814                             _.map(xnode.findall('VerCT'), function(e) { return e.text; }),
96815                             {
96816                                 preferred: xnode.tag.match('-Pref$') != undefined,
96817                         transmit:  xnode.tag.indexOf('Tx') >= 0,
96818                         receive:   xnode.tag.indexOf('Rx') >= 0
96819                             }
96820                             );
96821                     }
96822
96823                         });
96824
96825     return exports;
96826
96827 })();
96828
96829 module.exports = _self;
96830
96831 });
96832 define('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter', function (require, exports, module) {
96833 // -*- coding: utf-8 -*-
96834 //-----------------------------------------------------------------------------
96835 // file: $Id$
96836 // lib:  syncml-js.remoteadapter
96837 // auth: griffin <griffin@uberdev.org>
96838 // date: 2012/11/04
96839 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
96840 //-----------------------------------------------------------------------------
96841
96842 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
96843     devinfomod = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'),
96844     adapter = require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'),
96845     storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'),
96846     _self;
96847
96848 _self = (function () {
96849     var exports = {};
96850
96851     //---------------------------------------------------------------------------
96852     exports.RemoteAdapter = adapter.Adapter.extend({
96853
96854         //-------------------------------------------------------------------------
96855         constructor: function(adapter, options) {
96856
96857             //: [read-only] the URL of the remote syncml peer, acting as a server,
96858             //: to connect to.
96859             this.url = options.url || null;
96860
96861             //: [read-only] specifies whether this Adapter represents a local
96862             //: or remote peer.
96863             this.isLocal = false;
96864
96865             //: [read-only] the DevID of the remote syncml peer (which usually
96866             //: defaults to the URL).
96867             this.devID = options.devID || options.url || null;
96868
96869             //: [read-only] the authentication method to use to identify the local
96870             //: peer to the remote peer.
96871             ///TODO: this.auth = options.auth || null;
96872             this.auth = 'syncml:auth-basic';
96873
96874             //: [read-only] the human-friendly display name of the remote peer.
96875             this.displayName = options.displayName || null;
96876
96877             //: [read-only] the username to use during credential-based authentication.
96878             this.username = options.username || null;
96879
96880             //: [read-only] the password to use during credential-based authentication.
96881             this.password = options.password || null;
96882
96883             //: [read-only] the peer-wide default value of the maximum
96884             //: message size.
96885             this.maxMsgSize = options.maxMsgSize || null;
96886
96887             //: [read-only] the peer-wide default value of the maximum
96888             //: object size.
96889             this.maxObjSize = options.maxObjSize || null;
96890
96891             //: [read-only] the DevInfo object for this remote peer.
96892             this.devInfo = null;
96893
96894             this.lastSessionID = options.lastSessionID || null;
96895
96896             // --- private attributes
96897             this.id       = options.id || common.makeID();
96898             this._a       = adapter;
96899             this._c       = adapter._c;
96900             this._stores  = {};
96901             this._proxy   = null;
96902
96903             // TODO: filter these options for db-valid only properties...
96904             this._options = options;
96905         },
96906
96907             //-------------------------------------------------------------------------
96908             _load: function(cb) {
96909
96910                 var self  = this;
96911                 var model = this._getModel();
96912
96913                 // todo: should this be loading these?...
96914                 // self.displayName = model.displayName;
96915                 // self.devID       = model.devID;
96916
96917                 var loadDevInfo = function(cb) {
96918                     var di = new devinfomod.DevInfo(self, model.devInfo);
96919                     di._load(function(err) {
96920                         if ( err )
96921                         return cb(err);
96922                     self.devInfo = di;
96923                     cb();
96924                     });
96925                 };
96926
96927                 var loadStores = function(cb) {
96928                     common.cascade(model.stores, function(e, cb) {
96929                         var store = new storemod.Store(self, e);
96930                         store._load(function(err) {
96931                             if ( err )
96932                             return cb(err);
96933                         self._stores[store.uri] = store;
96934                         return cb();
96935                         });
96936                     }, cb);
96937                 };
96938
96939                 loadDevInfo(function(err) {
96940                     if ( err )
96941                     return cb(err);
96942                 loadStores(cb);
96943                 });
96944             },
96945
96946             //-------------------------------------------------------------------------
96947             _updateModel: function(cb) {
96948                 var self = this;
96949                 if ( ! this._a._model || ! this._a._model.peers )
96950                     return cb(new common.InternalError('peer created on un-initialized adapter'));
96951                 var model = self._getModel();
96952                 // todo: should this be in this._getModel()?...
96953                 if ( ! model )
96954                 {
96955                     model = {
96956                         id:       self.id,
96957                         devInfo:  null,
96958                         stores:   [],
96959                         routes:   []
96960                     };
96961                     self._a._model.peers.push(model);
96962                 }
96963
96964                 model.isLocal         = 0;
96965                 model.url             = self.url;
96966                 model.devID           = self.devID;
96967                 model.displayName     = self.displayName;
96968                 model.auth            = self.auth;
96969                 model.username        = self.username;
96970                 model.password        = self.password;
96971                 model.lastSessionID   = self.lastSessionID
96972                     model.maxMsgSize      = self.maxMsgSize;
96973                 model.maxObjSize      = self.maxObjSize;
96974
96975                 common.cascade([
96976
96977                         // update the devInfo model
96978                         function(cb) {
96979                             if ( ! self.devInfo )
96980                     return cb();
96981                 return self.devInfo._updateModel(cb);
96982                         },
96983
96984                         // update the stores model
96985                         function(cb) {
96986                             // TODO: this should really be the responsibility of the Store class...
96987                             // NOTE: since bindings are not stored in Store, they need to be saved
96988                             //       and re-applied.
96989                             // TODO: or, perhaps better, i should purge all unwanted stores
96990                             //       instead of doing this brute-force method...
96991                             var bindings = _.object(_.map(model.stores, function(store) {
96992                                 return [store.uri, store.binding];
96993                             }));
96994                             model.stores = [];
96995                             common.cascade(_.values(self._stores), function(store, cb) {
96996                                 store._updateModel(cb);
96997                             }, function(err) {
96998                                 if ( err )
96999                                 return cb(err);
97000                             _.each(bindings, function(binding, uri) {
97001                                 var store = _.find(model.stores, function(s) { return s.uri == uri; });
97002                                 if ( ! store )
97003                                 return;
97004                             store.binding = binding;
97005                             });
97006                             return cb();
97007                             });
97008                         },
97009
97010                         ], cb);
97011
97012             },
97013
97014             //-------------------------------------------------------------------------
97015             _getModel: function() {
97016                 return _.find(this._a._model.peers,
97017                         function(e) { return e.id == this.id; }, this);
97018             },
97019
97020             //-------------------------------------------------------------------------
97021             _setRemoteInfo: function(devInfo, stores, cb) {
97022                 var self      = this;
97023                 self._model   = self._getModel();
97024                 devInfo._a    = self;
97025                 self.devInfo  = devInfo;
97026                 self.devInfo._updateModel(function(err) {
97027                     if ( err )
97028                     return cb(err);
97029                 // merge the new datastore info with any pre-existing store bindings
97030                 // step 1: prepare the new stores (clean up the URIs)
97031                 var lut = _.object(_.map(stores, function(store) {
97032                     store.uri = self.normUri(store.uri);
97033                     return [store.uri, store];
97034                 }));
97035                 // step 2: remove all stores that are no longer mentioned
97036                 self._stores = _.object(
97037                     _.map(
97038                         _.filter(_.keys(self._stores), function(oldUri) {
97039                             return _.indexOf(_.keys(lut), oldUri) >= 0;
97040                         }), function(uri) {
97041                             return [uri, self._stores[uri]];
97042                         }
97043                         )
97044                     );
97045                 // step 3: merge the datastore info for existing stores
97046                 var merge_stores = function(cb) {
97047                     common.cascade(_.values(self._stores), function(store, cb) {
97048                         store.merge(lut[store.uri], function(err) {
97049                             if ( err )
97050                             return cb(err);
97051                         delete lut[store.uri];
97052                         return cb();
97053                         });
97054                     }, cb);
97055                 };
97056                 // step 4: add new datastores
97057                 var add_stores = function(cb) {
97058                     common.cascade(_.values(lut), function(store, cb) {
97059                         self.addStore(store, cb);
97060                     }, cb);
97061                 };
97062                 merge_stores(function(err) {
97063                     if ( err )
97064                     return cb(err);
97065                 add_stores(cb);
97066                 });
97067                 });
97068             },
97069
97070             //-------------------------------------------------------------------------
97071             setRoute: function(localUri, remoteUri, autoMapped, cb) {
97072                 if ( _.isFunction(autoMapped) )
97073                     // defaulting 'autoMapped' to false
97074                     return this.setRoute(localUri, remoteUri, false, autoMapped);
97075                 var pmodel = this._getModel();
97076                 if ( ! pmodel )
97077                     return cb(new common.InternalError('could not locate this peer in local adapter'));
97078                 pmodel.routes = _.filter(pmodel.routes, function(r) {
97079                     return r.localUri != localUri && r.remoteUri != remoteUri;
97080                 });
97081                 pmodel.routes.push({localUri   : localUri,
97082                     remoteUri  : remoteUri,
97083                     autoMapped : autoMapped
97084                 });
97085                 // now search through previous bindings, breaking incorrect ones...
97086                 // NOTE: this requires that a router.recalculate() is called at
97087                 //       some point later since other valid bindings may now be
97088                 //       possible...
97089                 _.each(pmodel.stores, function(store) {
97090                     if ( store.uri != remoteUri
97091                         && ( ! store.binding || store.binding.uri != localUri ) )
97092                     {
97093                         return;
97094                     }
97095                     if ( ! store.binding )
97096                 {
97097                     store.binding = {
97098                         uri          : localUri,
97099                     autoMapped   : autoMapped,
97100                     localAnchor  : null,
97101                     remoteAnchor : null
97102                     };
97103                     return;
97104                 }
97105                 if ( store.uri == remoteUri && store.binding.uri == localUri )
97106                 {
97107                     store.binding.autoMapped = store.binding.autoMapped && autoMapped;
97108                     return;
97109                 }
97110                 store.binding = null;
97111                 return;
97112                 });
97113                 // TODO: this additional route may impact "smart routing" - recalculate?...
97114                 // TODO: saving adapter from peer --- SHOULD IT BE DOING THIS?...
97115                 // TODO: get transaction from a session!...
97116                 this._a._save(this._c._txn(), cb);
97117             },
97118
97119             //-------------------------------------------------------------------------
97120             sendRequest: function(session, contentType, data, cb) {
97121                 var xmlhttp;
97122
97123                 // TODO: shouldn't proxies just overwrite .sendRequest() ?...
97124                 if ( this._proxy )
97125                     return this._proxy.sendRequest(session, contentType, data, cb);
97126
97127                 var req = {
97128                     url     : session.info.respUri || this.url,
97129                     method  : 'POST',
97130                     headers : {'Content-Type': contentType},
97131                     body    : data
97132                 };
97133
97134                 xmlhttp = new XMLHttpRequest();
97135                 xmlhttp.open(req.method, req.url, false);
97136
97137                 xmlhttp.setRequestHeader("Content-Type", contentType);
97138                 xmlhttp.send(req.body);
97139
97140                 var response = {
97141                     headers: {
97142                         "Content-Type": xmlhttp.getResponseHeader("content-type")
97143                     },
97144                     body: xmlhttp.responseXML
97145                 };
97146                 return cb(null, response);
97147             }
97148
97149     });
97150
97151     return exports;
97152
97153 })();
97154
97155 module.exports = _self;
97156
97157 });
97158 define('ripple/platform/tizen/2.0/syncml-js-lib/base64', function (require, exports, module) {
97159 // -*- coding: utf-8 -*-
97160 //-----------------------------------------------------------------------------
97161 // file: $Id$
97162 //-----------------------------------------------------------------------------
97163
97164 var _self = (function() {
97165
97166     // shamelessly scrubbed from:
97167     //   http://www.webtoolkit.info/javascript-base64.html
97168
97169     /**
97170      *
97171      *  Base64 encode / decode
97172      *  http://www.webtoolkit.info/
97173      *
97174      **/
97175
97176     var Base64 = {
97177
97178         // private property
97179         _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
97180
97181       // public method for encoding
97182       encode : function (input) {
97183           var output = "";
97184           var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
97185           var i = 0;
97186
97187           input = Base64._utf8_encode(input);
97188
97189           while (i < input.length) {
97190
97191               chr1 = input.charCodeAt(i++);
97192               chr2 = input.charCodeAt(i++);
97193               chr3 = input.charCodeAt(i++);
97194
97195               enc1 = chr1 >> 2;
97196               enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
97197               enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
97198               enc4 = chr3 & 63;
97199
97200               if (isNaN(chr2)) {
97201                   enc3 = enc4 = 64;
97202               } else if (isNaN(chr3)) {
97203                   enc4 = 64;
97204               }
97205
97206               output = output +
97207                   this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
97208                   this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
97209
97210           }
97211
97212           return output;
97213       },
97214
97215       // public method for decoding
97216       decode : function (input) {
97217           var output = "";
97218           var chr1, chr2, chr3;
97219           var enc1, enc2, enc3, enc4;
97220           var i = 0;
97221
97222           input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
97223
97224           while (i < input.length) {
97225
97226               enc1 = this._keyStr.indexOf(input.charAt(i++));
97227               enc2 = this._keyStr.indexOf(input.charAt(i++));
97228               enc3 = this._keyStr.indexOf(input.charAt(i++));
97229               enc4 = this._keyStr.indexOf(input.charAt(i++));
97230
97231               chr1 = (enc1 << 2) | (enc2 >> 4);
97232               chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
97233               chr3 = ((enc3 & 3) << 6) | enc4;
97234
97235               output = output + String.fromCharCode(chr1);
97236
97237               if (enc3 != 64) {
97238                   output = output + String.fromCharCode(chr2);
97239               }
97240               if (enc4 != 64) {
97241                   output = output + String.fromCharCode(chr3);
97242               }
97243
97244           }
97245
97246           output = Base64._utf8_decode(output);
97247
97248           return output;
97249
97250       },
97251
97252       // private method for UTF-8 encoding
97253       _utf8_encode : function (string) {
97254           string = string.replace(/\r\n/g,"\n");
97255           var utftext = "";
97256
97257           for (var n = 0; n < string.length; n++) {
97258
97259               var c = string.charCodeAt(n);
97260
97261               if (c < 128) {
97262                   utftext += String.fromCharCode(c);
97263               }
97264               else if((c > 127) && (c < 2048)) {
97265                   utftext += String.fromCharCode((c >> 6) | 192);
97266                   utftext += String.fromCharCode((c & 63) | 128);
97267               }
97268               else {
97269                   utftext += String.fromCharCode((c >> 12) | 224);
97270                   utftext += String.fromCharCode(((c >> 6) & 63) | 128);
97271                   utftext += String.fromCharCode((c & 63) | 128);
97272               }
97273
97274           }
97275
97276           return utftext;
97277       },
97278
97279       // private method for UTF-8 decoding
97280       _utf8_decode : function (utftext) {
97281           var string = "";
97282           var i = 0;
97283           var c = c1 = c2 = 0;
97284
97285           while ( i < utftext.length ) {
97286
97287               c = utftext.charCodeAt(i);
97288
97289               if (c < 128) {
97290                   string += String.fromCharCode(c);
97291                   i++;
97292               }
97293               else if((c > 191) && (c < 224)) {
97294                   c2 = utftext.charCodeAt(i+1);
97295                   string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
97296                   i += 2;
97297               }
97298               else {
97299                   c2 = utftext.charCodeAt(i+1);
97300                   c3 = utftext.charCodeAt(i+2);
97301                   string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
97302                   i += 3;
97303               }
97304
97305           }
97306
97307           return string;
97308       }
97309
97310     };
97311
97312     return Base64;
97313
97314 })();
97315
97316 module.exports = _self;
97317
97318 });
97319 define('ripple/platform/tizen/2.0/syncml-js-lib/constant', function (require, exports, module) {
97320 // -*- coding: utf-8 -*-
97321 //-----------------------------------------------------------------------------
97322 // file: $Id$
97323 // desc: SyncML constants
97324 // auth: metagriffin <metagriffin@uberdev.org>
97325 // date: 2012/10/13
97326 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
97327 //-----------------------------------------------------------------------------
97328
97329 var _self = {
97330     // SyncML versions
97331     SYNCML_VERSION_1_0                      : 'SyncML/1.0',
97332     SYNCML_VERSION_1_1                      : 'SyncML/1.1',
97333     SYNCML_VERSION_1_2                      : 'SyncML/1.2',
97334     SYNCML_DTD_VERSION_1_0                  : '1.0',
97335     SYNCML_DTD_VERSION_1_1                  : '1.1',
97336     SYNCML_DTD_VERSION_1_2                  : '1.2',
97337
97338     // SyncML alert/sync codes
97339     ALERT_DISPLAY                           : 100,
97340     ALERT_TWO_WAY                           : 200,
97341     ALERT_SLOW_SYNC                         : 201,
97342     ALERT_ONE_WAY_FROM_CLIENT               : 202,
97343     ALERT_REFRESH_FROM_CLIENT               : 203,
97344     ALERT_ONE_WAY_FROM_SERVER               : 204,
97345     ALERT_REFRESH_FROM_SERVER               : 205,
97346     ALERT_TWO_WAY_BY_SERVER                 : 206,
97347     ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER     : 207,
97348     ALERT_REFRESH_FROM_CLIENT_BY_SERVER     : 208,
97349     ALERT_ONE_WAY_FROM_SERVER_BY_SERVER     : 209,
97350     ALERT_REFRESH_FROM_SERVER_BY_SERVER     : 210,
97351     // alert codes 211-220 are reserved for future use
97352
97353     // SyncML SyncCap SyncTypes
97354     SYNCTYPE_AUTO                           : null,
97355     SYNCTYPE_TWO_WAY                        : 1,
97356     SYNCTYPE_SLOW_SYNC                      : 2,
97357     SYNCTYPE_ONE_WAY_FROM_CLIENT            : 3,
97358     SYNCTYPE_REFRESH_FROM_CLIENT            : 4,
97359     SYNCTYPE_ONE_WAY_FROM_SERVER            : 5,
97360     SYNCTYPE_REFRESH_FROM_SERVER            : 6,
97361     SYNCTYPE_SERVER_ALERTED                 : 7,
97362
97363     // Special syncml-js SyncTypes
97364     SYNCTYPE_DISCOVER                       : 'discover',
97365
97366     // SyncML synctype-to-alertcode mapping
97367     // taking advantage of the fact that 1..7 maps to 200..206
97368     // (more or less... "7" is a bit "nebulous"...)
97369     SyncTypeToAlert: _.object(_.map(_.range(7), function(i) {
97370         return [ i + 1, i + 200 ];
97371     })),
97372
97373     // Conflict handling policies
97374     POLICY_ERROR                            : 1,
97375     POLICY_CLIENT_WINS                      : 2,
97376     POLICY_SERVER_WINS                      : 3,
97377
97378     // SyncML XML namespaces
97379     NAMESPACE_SYNCML_1_0                    : 'syncml:syncml1.0',
97380     NAMESPACE_SYNCML_1_1                    : 'syncml:syncml1.1',
97381     NAMESPACE_SYNCML_1_2                    : 'syncml:syncml1.2',
97382     NAMESPACE_METINF                        : 'syncml:metinf',
97383     NAMESPACE_DEVINF                        : 'syncml:devinf',
97384     NAMESPACE_AUTH_BASIC                    : 'syncml:auth-basic',
97385     NAMESPACE_AUTH_MD5                      : 'syncml:auth-md5',
97386     NAMESPACE_FILTER_CGI                    : 'syncml:filtertype-cgi',
97387
97388     // Commonly used content-types
97389     TYPE_TEXT_PLAIN                         : 'text/plain',
97390     TYPE_VCARD_V21                          : 'text/x-vcard',
97391     TYPE_VCARD_V30                          : 'text/vcard',
97392     TYPE_VCALENDAR                          : 'text/x-vcalendar',
97393     TYPE_ICALENDAR                          : 'text/calendar',
97394     TYPE_MESSAGE                            : 'text/message',
97395     TYPE_SYNCML                             : 'application/vnd.syncml',
97396     TYPE_SYNCML_DEVICE_INFO                 : 'application/vnd.syncml-devinf',
97397     TYPE_SYNCML_ICALENDAR                   : 'application/vnd.syncml-xcal',
97398     TYPE_SYNCML_EMAIL                       : 'application/vnd.syncml-xmsg',
97399     TYPE_SYNCML_BOOKMARK                    : 'application/vnd.syncml-xbookmark',
97400     TYPE_SYNCML_RELATIONAL_OBJECT           : 'application/vnd.syncml-xrelational',
97401     TYPE_OMADS_FOLDER                       : 'application/vnd.omads-folder',
97402     TYPE_OMADS_FILE                         : 'application/vnd.omads-file',
97403     TYPE_OMADS_EMAIL                        : 'application/vnd.omads-email',
97404     TYPE_SQL                                : 'application/sql',
97405     TYPE_LDAP                               : 'text/directory',
97406     TYPE_EMAIL                              : 'message/rfc2822',
97407     TYPE_EMAIL_822                          : 'message/rfc822',
97408     TYPE_SIF_CONTACT                        : 'text/x-s4j-sifc',
97409     TYPE_SIF_NOTE                           : 'text/x-s4j-sifn',
97410     TYPE_SIF_TASK                           : 'text/x-s4j-sift',
97411     TYPE_SIF_EVENT                          : 'text/x-s4j-sife',
97412
97413     // non-agent URI paths
97414     URI_DEVINFO_1_0                         : 'devinf10',
97415     URI_DEVINFO_1_1                         : 'devinf11',
97416     URI_DEVINFO_1_2                         : 'devinf12',
97417
97418     // Response codes - Generic
97419     STATUS_INVALID_CODE                     : 0,
97420     // Response codes - Informational 1xx
97421     STATUS_IN_PROGRESS                      : 101,
97422     // Response codes - Successful 2xx
97423     STATUS_OK                               : 200,
97424     STATUS_ITEM_ADDED                       : 201,
97425     STATUS_ACCEPTED_FOR_PROCESSING          : 202,
97426     STATUS_NONAUTHORIATATIVE_RESPONSE       : 203,
97427     STATUS_NO_CONTENT                       : 204,
97428     STATUS_RESET_CONTENT                    : 205,
97429     STATUS_PARTIAL_CONTENT                  : 206,
97430     STATUS_CONFLICT_RESOLVED_MERGE          : 207,
97431     STATUS_CONFLICT_RESOLVED_CLIENT_DATA    : 208,
97432     STATUS_CONFLICT_RESOLVED_DUPLICATE      : 209,
97433     STATUS_DELETE_WITHOUT_ARCHIVE           : 210,
97434     STATUS_ITEM_NOT_DELETED                 : 211,
97435     STATUS_AUTHENTICATION_ACCEPTED          : 212,
97436     STATUS_CHUNKED_ITEM_ACCEPTED            : 213,
97437     STATUS_OPERATION_CANCELLED_OK           : 214,
97438     STATUS_NOT_EXECUTED                     : 215,
97439     STATUS_ATOMIC_ROLLBACK_OK               : 216,
97440     STATUS_RESULT_ALERT                     : 221,
97441     STATUS_NEXT_MESSAGE                     : 222,
97442     STATUS_NO_END_OF_DATA                   : 223,
97443     STATUS_SUSPEND                          : 224,
97444     STATUS_RESUME                           : 225,
97445     STATUS_DATA_MANAGEMENT                  : 226,
97446     // status codes 227-250 are reserved for future use,
97447     // Response codes - Redirection 3xx
97448     STATUS_MULTIPLE_CHOICES                 : 300,
97449     STATUS_MOVED_PERMANENTLY                : 301,
97450     STATUS_FOUND                            : 302,
97451     STATUS_SEE_ANOTHER_URI                  : 303,
97452     STATUS_NOT_MODIFIED                     : 304,
97453     STATUS_USE_PROXY                        : 305,
97454     // Response codes - Originator Exceptions 4xx
97455     STATUS_BAD_REQUEST                      : 400,
97456     STATUS_INVALID_CREDENTIALS              : 401,
97457     STATUS_PAYMENT_REQUIRED                 : 402,
97458     STATUS_FORBIDDEN                        : 403,
97459     STATUS_NOT_FOUND                        : 404,
97460     STATUS_COMMAND_NOT_ALLOWED              : 405,
97461     STATUS_OPTIONAL_FEATURE_NOT_SUPPORTED   : 406,
97462     STATUS_MISSING_CREDENTIALS              : 407,
97463     STATUS_REQUEST_TIMEOUT                  : 408,
97464     STATUS_UPDATE_CONFLICT                  : 409,
97465     STATUS_GONE                             : 410,
97466     STATUS_SIZE_REQUIRED                    : 411,
97467     STATUS_INCOMPLETE_COMMAND               : 412,
97468     STATUS_REQUESTED_ENTITY_TOO_LARGE       : 413,
97469     STATUS_URI_TOO_LONG                     : 414,
97470     STATUS_UNSUPPORTED_MEDIA_TYPE           : 415,
97471     STATUS_REQUESTED_SIZE_TOO_BIG           : 416,
97472     STATUS_RETRY_LATER                      : 417,
97473     STATUS_ALREADY_EXISTS                   : 418,
97474     STATUS_CONFLICT_RESOLVED_SERVER_DATA    : 419,
97475     STATUS_DEVICE_FULL                      : 420,
97476     STATUS_UNKNOWN_SEARCH_GRAMMAR           : 421,
97477     STATUS_BAD_CGI_SCRIPT                   : 422,
97478     STATUS_SOFT_DELETE_CONFLICT             : 423,
97479     STATUS_OBJECT_SIZE_MISMATCH             : 424,
97480     STATUS_PERMISSION_DENIED                : 425,
97481     // Response codes - Recipient Exceptions 5xx
97482     STATUS_COMMAND_FAILED                   : 500,
97483     STATUS_NOT_IMPLEMENTED                  : 501,
97484     STATUS_BAD_GATEWAY                      : 502,
97485     STATUS_SERVICE_UNAVAILABLE              : 503,
97486     STATUS_GATEWAY_TIMEOUT                  : 504,
97487     STATUS_VERSION_NOT_SUPPORTED            : 505,
97488     STATUS_PROCESSING_ERROR                 : 506,
97489     STATUS_ATOMIC_FAILED                    : 507,
97490     STATUS_REFRESH_REQUIRED                 : 508,
97491     STATUS_RECIPIENT_EXCEPTION_RESERVED1    : 509,
97492     STATUS_DATASTORE_FAILURE                : 510,
97493     STATUS_SERVER_FAILURE                   : 511,
97494     STATUS_SYNCHRONIZATION_FAILED           : 512,
97495     STATUS_PROTOCOL_VERSION_NOT_SUPPORTED   : 513,
97496     STATUS_OPERATION_CANCELLED              : 514,
97497     STATUS_ATOMIC_ROLLBACK_FAILED           : 516,
97498     STATUS_ATOMIC_RESPONSE_TOO_LARGE_TO_FIT : 517,
97499
97500     // SyncML codecs
97501     CODEC_XML                               : 'xml',
97502     CODEC_WBXML                             : 'wbxml',
97503     FORMAT_B64                              : 'b64',
97504     FORMAT_AUTO                             : 'auto',
97505
97506     // SyncML nodes
97507     NODE_SYNCML                             : 'SyncML',
97508     NODE_SYNCBODY                           : 'SyncBody',
97509
97510     // SyncML commands
97511     CMD_SYNCHDR                             : 'SyncHdr',
97512     CMD_SYNC                                : 'Sync',
97513     CMD_ALERT                               : 'Alert',
97514     CMD_STATUS                              : 'Status',
97515     CMD_GET                                 : 'Get',
97516     CMD_PUT                                 : 'Put',
97517     CMD_ADD                                 : 'Add',
97518     CMD_REPLACE                             : 'Replace',
97519     CMD_DELETE                              : 'Delete',
97520     CMD_RESULTS                             : 'Results',
97521     CMD_ATOMIC                              : 'Atomic',
97522     CMD_COPY                                : 'Copy',
97523     CMD_EXEC                                : 'Exec',
97524     CMD_MAP                                 : 'Map',
97525     CMD_MAPITEM                             : 'MapItem',
97526     CMD_SEARCH                              : 'Search',
97527     CMD_SEQUENCE                            : 'Sequence',
97528     CMD_FINAL                               : 'Final',
97529
97530     // SyncML standard device types
97531     DEVTYPE_HANDHELD                        : 'handheld',
97532     DEVTYPE_PAGER                           : 'pager',
97533     DEVTYPE_PDA                             : 'pda',
97534     DEVTYPE_PHONE                           : 'phone',
97535     DEVTYPE_SERVER                          : 'server',
97536     DEVTYPE_SMARTPHONE                      : 'smartphone',
97537     DEVTYPE_WORKSTATION                     : 'workstation',
97538
97539     // Item status codes
97540     ITEM_OK                                 : 0,
97541     ITEM_ADDED                              : 1,
97542     ITEM_MODIFIED                           : 2,
97543     ITEM_DELETED                            : 3,
97544     ITEM_SOFTDELETED                        : 4,
97545 };
97546
97547 module.exports = _self;
97548
97549 });
97550 define('ripple/platform/tizen/2.0/syncml-js-lib/context', function (require, exports, module) {
97551 // -*- coding: utf-8 -*-
97552 //-----------------------------------------------------------------------------
97553 // file: $Id$
97554 // lib:  syncml-js.context
97555 // auth: griffin <griffin@uberdev.org>
97556 // date: 2012/10/22
97557 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
97558 //-----------------------------------------------------------------------------
97559
97560 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
97561     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
97562     storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
97563     router = require('ripple/platform/tizen/2.0/syncml-js-lib/router'),
97564     synchronizer = require('ripple/platform/tizen/2.0/syncml-js-lib/synchronizer'),
97565     protocol = require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'),
97566     localadapter = require('ripple/platform/tizen/2.0/syncml-js-lib/localadapter'),
97567     idxdb = {},
97568     _self;
97569
97570 // todo: is this the right place to put this?...
97571 //       the reason that i did not put it in the `define` call is
97572 //       because it needs access to `this.indexedDB`...
97573 var idxdb = {};
97574 if ( typeof(window) != 'undefined' && window.indexedDB )
97575 {
97576     idxdb.indexedDB   = window.indexedDB;
97577     idxdb.IDBKeyRange = window.IDBKeyRange;
97578 }
97579 else
97580 {
97581     idxdb.indexedDB   = this.indexedDB;
97582     idxdb.IDBKeyRange = this.IDBKeyRange;
97583 }
97584
97585 _self = (function () {
97586     var exports = {};
97587
97588     //---------------------------------------------------------------------------
97589     exports.Context = common.Base.extend({
97590
97591         //-------------------------------------------------------------------------
97592         constructor: function(options) {
97593             // options.storage expects the following properties:
97594             //   - indexedDB
97595             //   - IDBKeyRange
97596             options = options || {};
97597             this.storage      = options.storage || idxdb;
97598             this.dbname       = ( options.prefix || '' ) + 'syncml-js';
97599             this.autoCommit   = options.autoCommit == undefined ? true : options.autoCommit;
97600             this.router       = options.router || new router.SmartRouter();
97601             this.synchronizer = options.synchronizer || new synchronizer.Synchronizer();
97602             this.protocol     = options.protocol || new protocol.Protocol();
97603             this.codec        = options.codec || constant.CODEC_XML;
97604             this.listener     = options.listener;
97605             this.ua           = options.ua;
97606             this.config       = _.defaults({}, options.config, {
97607                 trustDevInfo      : false,
97608                 exposeErrorTrace  : false
97609             });
97610             this._db          = null;
97611             this._dbtxn       = null;
97612         },
97613
97614             //-------------------------------------------------------------------------
97615             getAdapter: function(options, devInfo, cb) {
97616                 options = options || {};
97617                 var self = this;
97618                 if ( this._db == undefined )
97619                 {
97620                     storage.openDatabase(this, function(err, db) {
97621                         if ( err ) {
97622                             return cb(err);
97623                         }
97624                         self._db = db;
97625                         self._db.onerror = function(event) {
97626                             // todo: remove this?...
97627                         };
97628                         self._dbtxn = storage.getTransaction(self._db, null, 'readwrite');
97629                         self.getAdapter(options, devInfo, cb);
97630                     });
97631                 }
97632                 else
97633                 {
97634                     var ret = new localadapter.LocalAdapter(this, options, devInfo);
97635                     return ret._load(cb);
97636                 }
97637             },
97638
97639             //-------------------------------------------------------------------------
97640             _txn: function() {
97641                 try {
97642                     // this is a work-around for XPC-based syncml... try to open
97643                     // a store, if it fails, we need a new transaction.
97644                     var store = this._dbtxn.objectStore('mapping');
97645                     return this._dbtxn;
97646                 } catch ( exc ) {
97647                     this._dbtxn = storage.getTransaction(this._db, null, 'readwrite');
97648                     return this._dbtxn;
97649                 }
97650             },
97651
97652             //-------------------------------------------------------------------------
97653             getEasyClientAdapter: function(options, cb) {
97654                 try{
97655                     this._getEasyClientAdapter(options, cb);
97656                 }catch(e){
97657                     cb(e);
97658                 }
97659             },
97660
97661             //-------------------------------------------------------------------------
97662             _getEasyClientAdapter: function(options, cb) {
97663                 // options should be:= {
97664                 //   // devID,
97665                 //   // displayName,
97666                 //   devInfo: {},
97667                 //   stores: [],
97668                 //   peer: {},
97669                 //   routes: [
97670                 //     [ source, target ],
97671                 //   ]
97672                 // }
97673                 // response: cb(err, adapter, stores, peer);
97674
97675                 var self = this;
97676
97677                 var ret = {
97678                     adapter: null,
97679                     stores: [],
97680                     peer: null
97681                 };
97682
97683                 var setupAdapter = function(cb) {
97684                     var adapterOptions = _.omit(options, 'devInfo', 'stores', 'peers', 'routes');
97685                     self.getAdapter(adapterOptions, options.devInfo, function(err, adapter) {
97686                         if ( err ) {
97687                             return cb(err);
97688                         }
97689                         ret.adapter = adapter;
97690                         if ( adapter.devInfo ) {
97691                             return cb();
97692                         }
97693                         adapter.setDevInfo(options.devInfo, cb);
97694                     });
97695                 };
97696
97697                 var setupStores = function(cb) {
97698                     common.cascade(options.stores, function(storeInfo, cb) {
97699                         var store = ret.adapter.getStore(storeInfo.uri);
97700                         if ( store != undefined )
97701                         {
97702                             if ( storeInfo.agent ) {
97703                                 store.agent = storeInfo.agent;
97704                             }
97705                             ret.stores.push(store);
97706                             return cb();
97707                         }
97708                         ret.adapter.addStore(storeInfo, function(err, store) {
97709                             if ( err ) {
97710                                 return cb(err);
97711                             }
97712                             ret.stores.push(store);
97713                             return cb();
97714                         });
97715                     }, cb);
97716                 };
97717
97718                 var setupPeer = function(cb) {
97719                     var peer = _.find(ret.adapter.getPeers(), function(p) {
97720                         return p.url == options.peer.url;
97721                     });
97722                     if ( peer )
97723                     {
97724                         ret.peer = peer;
97725                         return cb();
97726                     }
97727                     ret.adapter.addPeer(options.peer, function(err, peer) {
97728                         if ( err ) {
97729                             return cb(err);
97730                         }
97731                         ret.peer = peer;
97732                         common.cascade(options.routes, function(route, cb) {
97733                             ret.peer.setRoute(route[0], route[1], cb);
97734                         }, cb);
97735                     });
97736                 };
97737                 setupAdapter(function(err) {
97738                     if ( err ) {
97739                         return cb(err);
97740                     }
97741                     setupStores(function(err) {
97742                         if ( err ) {
97743                             return cb(err);
97744                         }
97745                         setupPeer(function(err) {
97746                             if ( err ) {
97747                                 return cb(err);
97748                             }
97749                             cb(null, ret.adapter, ret.stores, ret.peer);
97750                         });
97751                     });
97752                 });
97753             },
97754
97755             //-------------------------------------------------------------------------
97756             close: function(cb) {
97757                 if ( this._db )
97758                     this._db.close();
97759                 this._db = null;
97760                 cb(null);
97761             }
97762
97763     });
97764
97765     return exports;
97766
97767 })();
97768
97769 module.exports = _self;
97770
97771 });
97772 define('ripple/platform/tizen/2.0/syncml-js-lib/state', function (require, exports, module) {
97773 // -*- coding: utf-8 -*-
97774 //-----------------------------------------------------------------------------
97775 // file: $Id$
97776 // auth: metagriffin <metagriffin@uberdev.org>
97777 // date: 2012/10/27
97778 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
97779 //-----------------------------------------------------------------------------
97780
97781 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
97782     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
97783     _self;
97784
97785 _self = (function () {
97786     var exports = {};
97787
97788     //---------------------------------------------------------------------------
97789     exports.makeCommand = function(options) {
97790         return _.defaults({}, options, {
97791             // ?
97792         });
97793     };
97794
97795     //---------------------------------------------------------------------------
97796     exports.makeStats = function(options) {
97797         return _.defaults({}, options, {
97798             mode      : null,
97799                hereAdd   : 0,
97800                hereMod   : 0,
97801                hereDel   : 0,
97802                hereErr   : 0,
97803                peerAdd   : 0,
97804                peerMod   : 0,
97805                peerDel   : 0,
97806                peerErr   : 0,
97807                conflicts : 0,
97808                merged    : 0,
97809         });
97810     };
97811
97812     //---------------------------------------------------------------------------
97813     exports.makeSessionInfo = function(options) {
97814         return _.defaults({}, options, {
97815             id           : null,
97816                msgID        : null,
97817                cmdID        : 0,
97818                dsstates     : {},
97819                lastCommands : [],
97820                stats        : exports.makeStats()
97821         });
97822     };
97823
97824     //---------------------------------------------------------------------------
97825     exports.makeStoreSyncState = function(options) {
97826         return _.defaults({}, options, {
97827             uri        : null,
97828                peerUri    : null,
97829                lastAnchor : null,
97830                nextAnchor : '' + common.ts(),
97831                mode       : constant.ALERT_TWO_WAY,
97832                action     : null,
97833                stats      : exports.makeStats()
97834         });
97835     };
97836
97837     //---------------------------------------------------------------------------
97838     exports.makeSession = function(options) {
97839         return new (function() {
97840             this.context   = options.context || null;
97841             this.ua        = options.ua      || null;
97842             this.txn       = options.txn     || options.context.txn;
97843             this.adapter   = options.adapter || null;
97844             this.peer      = options.peer    || null;
97845             this.info      = options.info    || null;
97846             this.discover  = options.discover ? true : false;
97847             this.isServer  = options.isServer ? true : false;
97848             this.nextCmdID = function() {
97849                 this.info.cmdID += 1;
97850                 return this.info.cmdID;
97851             };
97852         })();
97853
97854         // return _.defaults({}, options, {
97855         //   context : null,
97856         //   adapter : null,
97857         //   peer    : null,
97858         //   info    : null
97859         // });
97860     };
97861
97862     var smult = function(s, count) {
97863         var ret = '';
97864         for ( var idx=0 ; idx<count ; idx++ )
97865             ret += s;
97866         return ret;
97867     };
97868
97869     var num2str = function(num) {
97870         // TODO: i18n...
97871         // TODO: this is *UGLY*
97872         // TODO: OMG, i'm *so* embarrassed
97873         // TODO: but it works... sort of.
97874         if ( num == 0 )
97875             return '-';
97876         var ret = '';
97877         num = '' + num;
97878         for ( var idx=num.length ; idx>0 ; idx-=3 )
97879         {
97880             if ( ret.length > 0 )
97881                 ret = ',' + ret;
97882             ret = num.charAt(idx - 1) + ret;
97883             if ( idx - 1 > 0 )
97884                 ret = num.charAt(idx - 2) + ret;
97885             if ( idx - 2 > 0 )
97886                 ret = num.charAt(idx - 3) + ret;
97887         }
97888         return ret;
97889     };
97890
97891     var center = function(s, wid, pad) {
97892         // todo: is there no way to get sprintf to do this for me???...
97893         pad = pad || ' ';
97894         if ( wid <= s.length )
97895             return s;
97896         var diff = wid - s.length;
97897         return smult(pad, Math.floor(diff / 2)) + s + smult(pad, Math.ceil(diff / 2));
97898     };
97899
97900     var right = function(s, wid, pad) {
97901         // todo: is there no way to get sprintf to do this for me???...
97902         pad = pad || ' ';
97903         if ( wid <= s.length )
97904             return s;
97905         return smult(pad, wid - s.length) + s;
97906     };
97907
97908     //---------------------------------------------------------------------------
97909     // TODO: this should probably be put into another package...
97910     exports.describeStats = function(stats, stream, options) {
97911
97912         // ASCII OBJECTIVE:
97913         // +----------------------------------------------------------------------------------+
97914         // |                                      TITLE                                       |
97915         // +----------+------+-------------------------+--------------------------+-----------+
97916         // |          |      |          Local          |          Remote          | Conflicts |
97917         // |   Source | Mode |  Add  | Mod | Del | Err |   Add  | Mod | Del | Err | Col | Mrg |
97918         // +----------+------+-------+-----+-----+-----+--------+-----+-----+-----+-----+-----+
97919         // | contacts |  <=  |   -   |  -  |  -  |  -  | 10,387 |  -  |  -  |  -  |  -  |  -  |
97920         // |     note |  SS  | 1,308 |  -  |   2 |  -  |    -   |  -  |  -  |  -  |  -  |  -  |
97921         // +----------+------+-------+-----+-----+-----+--------+-----+-----+-----+-----+-----+
97922         // |                  1,310 local changes and 10,387 remote changes.                  |
97923         // +----------------------------------------------------------------------------------+
97924
97925         // UNICODE OBJECTIVE:
97926         // ┌──────────────────────────────────────────────────────────────────────────────────┐
97927         // │                                      TITLE                                       │
97928         // ├──────────┬──────┬─────────────────────────┬──────────────────────────┬───────────┤
97929         // │          │      │          Local          │          Remote          │ Conflicts │
97930         // │   Source │ Mode │  Add    Mod   Del   Err │   Add    Mod   Del   Err │ Col   Mrg │
97931         // ├──────────┼──────┼───────┼─────┼─────┼─────┼────────┼─────┼─────┼─────┼─────┼─────┤
97932         // │ contacts │  <=  │       │     │     │     │ 10,387 │     │     │     │     │     │
97933         // │     note │  SS  │ 1,308 │     │   2 │     │        │     │     │     │     │     │
97934         // ├──────────┴──────┴───────┴─────┴─────┴─────┴────────┴─────┴─────┴─────┴─────┴─────┤
97935         // │                  1,310 local changes and 10,387 remote changes.                  │
97936         // └──────────────────────────────────────────────────────────────────────────────────┘
97937
97938         // todo: perhaps the fancy version should have color-coding as well?...
97939
97940         options = _.defaults({}, options, {
97941             title      : null,
97942                 details    : true,
97943                 totals     : true,
97944                 ascii      : false,
97945                 gettext    : function(text) { return text; }
97946         });
97947
97948         var modeStringLut = _.object([
97949                 [constant.SYNCTYPE_TWO_WAY             , '<>'],
97950                 [constant.SYNCTYPE_SLOW_SYNC           , 'SS'],
97951                 [constant.SYNCTYPE_ONE_WAY_FROM_CLIENT , '->'],
97952                 [constant.SYNCTYPE_REFRESH_FROM_CLIENT , '=>'],
97953                 [constant.SYNCTYPE_ONE_WAY_FROM_SERVER , '<-'],
97954                 [constant.SYNCTYPE_REFRESH_FROM_SERVER , '<=']
97955                 ]);
97956
97957         if ( options.ascii )
97958         {
97959
97960             // unicode graphing characters: ('\xe2\x94\x80' - '\xe2\x94\xc0')
97961             // mapping table unicode ==> ascii
97962
97963             glyphs = {
97964                 '─': '-',
97965                 '━': '-',
97966                 '│': '|',
97967                 '┃': '|',
97968                 '┄': '-',
97969                 '┅': '-',
97970                 '┆': '|',
97971                 '┇': '|',
97972                 '┈': '-',
97973                 '┉': '-',
97974                 '┊': '|',
97975                 '┋': '|',
97976                 '┌': '+',
97977                 '┍': '+',
97978                 '┎': '+',
97979                 '┏': '+',
97980                 '┐': '+',
97981                 '┑': '+',
97982                 '┒': '+',
97983                 '┓': '+',
97984                 '└': '+',
97985                 '┕': '+',
97986                 '┖': '+',
97987                 '┗': '+',
97988                 '┘': '+',
97989                 '┙': '+',
97990                 '┚': '+',
97991                 '┛': '+',
97992                 '├': '+',
97993                 '┝': '+',
97994                 '┞': '+',
97995                 '┟': '+',
97996                 '┠': '+',
97997                 '┡': '+',
97998                 '┢': '+',
97999                 '┣': '+',
98000                 '┤': '+',
98001                 '┥': '+',
98002                 '┦': '+',
98003                 '┧': '+',
98004                 '┨': '+',
98005                 '┩': '+',
98006                 '┪': '+',
98007                 '┫': '+',
98008                 '┬': '+',
98009                 '┭': '+',
98010                 '┮': '+',
98011                 '┯': '+',
98012                 '┰': '+',
98013                 '┱': '+',
98014                 '┲': '+',
98015                 '┳': '+',
98016                 '┴': '+',
98017                 '┵': '+',
98018                 '┶': '+',
98019                 '┷': '+',
98020                 '┸': '+',
98021                 '┹': '+',
98022                 '┺': '+',
98023                 '┻': '+',
98024                 '┼': '+',
98025                 '┽': '+',
98026                 '┾': '+',
98027                 '┿': '+',
98028             };
98029
98030             var UnicodeToAsciiStream = common.Stream.extend({
98031                 constructor: function(stream) {
98032                     this.stream = stream;
98033                 },
98034                 write: function(data) {
98035                     if ( data == undefined )
98036                 return;
98037             var ascii = '';
98038             for ( var idx=0 ; idx<data.length ; idx++ )
98039             {
98040                 var el = data[idx];
98041                 if ( glyphs[el] != undefined )
98042                 ascii += glyphs[el];
98043                 else
98044                 ascii += el;
98045             }
98046             this.stream.write(ascii);
98047                 }
98048             });
98049
98050             stream = new UnicodeToAsciiStream(stream);
98051
98052         }
98053
98054         // todo: this does not handle the case where the title is wider than the table.
98055
98056         var wSrc  = options.gettext('Source').length;
98057         var wMode = options.gettext('Mode').length;
98058         var wCon  = options.gettext('Conflicts').length;
98059         var wCol  = options.gettext('Col').length;
98060         var wMrg  = options.gettext('Mrg').length;
98061         var wHereAdd = wPeerAdd = options.gettext('Add').length;
98062         var wHereMod = wPeerMod = options.gettext('Mod').length;
98063         var wHereDel = wPeerDel = options.gettext('Del').length;
98064         var wHereErr = wPeerErr = options.gettext('Err').length
98065
98066             var totLoc = 0;
98067         var totRem = 0;
98068         var totErr = 0;
98069         var totCol = 0;
98070         var totMrg = 0;
98071
98072         _.each(stats, function(value, key) {
98073             wSrc  = Math.max(wSrc, key.length);
98074             wMode = Math.max(wMode, modeStringLut[value.mode].length);
98075             wCol  = Math.max(wCol, num2str(value.conflicts).length);
98076             wMrg  = Math.max(wMrg, num2str(value.merged).length);
98077             wHereAdd = Math.max(wHereAdd, num2str(value.hereAdd).length);
98078             wPeerAdd = Math.max(wPeerAdd, num2str(value.peerAdd).length);
98079             wHereMod = Math.max(wHereMod, num2str(value.hereMod).length);
98080             wPeerMod = Math.max(wPeerMod, num2str(value.peerMod).length);
98081             wHereDel = Math.max(wHereDel, num2str(value.hereDel).length);
98082             wPeerDel = Math.max(wPeerDel, num2str(value.peerDel).length);
98083             wHereErr = Math.max(wHereErr, num2str(value.hereErr).length);
98084             wPeerErr = Math.max(wPeerErr, num2str(value.peerErr).length);
98085             totLoc += value.hereAdd + value.hereMod + value.hereDel;
98086             totRem += value.peerAdd + value.peerMod + value.peerDel;
98087             totErr += value.hereErr + value.peerErr;
98088             totCol += value.conflicts;
98089             totMrg += value.merged;
98090         });
98091
98092         // TODO: i'm 100% sure there is a python library that can do this for me...
98093
98094         if ( wCon > wCol + 3 + wMrg )
98095         {
98096             diff = wCon - ( wCol + 3 + wMrg );
98097             wCol += diff / 2;
98098             wMrg = wCon - 3 - wCol;
98099         }
98100         else
98101             wCon = wCol + 3 + wMrg;
98102
98103         if ( options.details )
98104             tWid = ( wSrc + 3 + wMode + 3
98105                     + wHereAdd + wHereMod + wHereDel + wHereErr + 9 + 3
98106                     + wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 + 3
98107                     + wCon );
98108         else
98109             tWid = options.title ? options.title.length : 0;
98110
98111         if ( options.totals )
98112         {
98113             // TODO: oh dear. from an i18n POV, this is *horrible*!...
98114             sumlist = [];
98115             // for val, singular, plural in [
98116             _.each([
98117                     [totLoc, options.gettext('local change'), options.gettext('local changes')],
98118                     [totRem, options.gettext('remote change'), options.gettext('remote changes')],
98119                     [totErr, options.gettext('error'), options.gettext('errors')]
98120                     ], function(set) {
98121                         if ( set[0] <= 0 )
98122                 return;
98123             sumlist.push(num2str(set[0]) + ' ' + ( set[0] == 1 ? set[1] : set[2] ));
98124                     });
98125             if ( sumlist.length <= 0 )
98126                 sumlist = options.gettext('No changes');
98127             else if ( sumlist.length == 1 )
98128                 sumlist = sumlist[0];
98129             else
98130                 sumlist = ( sumlist.slice(0, -1).join(', ') + ' '
98131                         + options.gettext('and') + ' ' + sumlist[sumlist.length - 1] );
98132             if ( totMrg > 0 || totCol > 0 )
98133             {
98134                 sumlist += ': ';
98135                 if ( totMrg == 1 )
98136                     sumlist += num2str(totMrg) + ' ' + options.gettext('merge');
98137                 else if ( totMrg > 1 )
98138                     sumlist += num2str(totMrg) + ' ' + options.gettext('merges');
98139                 if ( totMrg > 0 && totCol > 0 )
98140                     sumlist += ' ' + options.gettext('and') + ' ';
98141                 if ( totCol == 1 )
98142                     sumlist += num2str(totCol) + ' ' + options.gettext('conflict');
98143                 else if ( totCol > 1 )
98144                     sumlist += num2str(totCol) + ' ' + options.gettext('conflicts');
98145             }
98146             sumlist += '.';
98147             if ( sumlist.length > tWid )
98148             {
98149                 wSrc += sumlist.length - tWid;
98150                 tWid = sumlist.length;
98151             }
98152         }
98153
98154         if ( options.title )
98155         {
98156             stream.write('┏━' + smult('━', tWid) + '━┓\n');
98157             stream.write('┃ ' + center(options.title, tWid) + ' ┃\n');
98158         }
98159
98160         if ( options.details )
98161         {
98162             if ( options.title )
98163                 stream.write('┡━'
98164                         + smult('━', wSrc)
98165                         + '━┯━'
98166                         + smult('━', wMode)
98167                         + '━┯━'
98168                         + smult('━', ( wHereAdd + wHereMod + wHereDel + wHereErr + 9 ))
98169                         + '━┯━'
98170                         + smult('━', ( wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 ))
98171                         + '━┯━'
98172                         + smult('━', wCon)
98173                         + '━┩\n'
98174                         );
98175             else
98176                 stream.write('┌─'
98177                         + smult('─', wSrc)
98178                         + '─┬─'
98179                         + smult('─', wMode)
98180                         + '─┬─'
98181                         + smult('─', ( wHereAdd + wHereMod + wHereDel + wHereErr + 9 ))
98182                         + '─┬─'
98183                         + smult('─', ( wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 ))
98184                         + '─┬─'
98185                         + smult('─', wCon)
98186                         + '─┐\n'
98187                         );
98188
98189             stream.write('│ ' + smult(' ', wSrc));
98190             stream.write(' │ ' + smult(' ', wMode));
98191             stream.write(' │ ' + center(options.gettext('Local'), wHereAdd + wHereMod + wHereDel + wHereErr + 9 ));
98192             stream.write(' │ ' + center(options.gettext('Remote'), wPeerAdd + wPeerMod + wPeerDel + wPeerErr + 9 ));
98193             stream.write(' │ ' + center(options.gettext('Conflicts'), wCon));
98194             stream.write(' │\n');
98195
98196             stream.write('│ ' + right(options.gettext('Source'), wSrc));
98197             stream.write(' │ ' + center(options.gettext('Mode'), wMode));
98198             stream.write(' │ ' + center(options.gettext('Add'), wHereAdd));
98199             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Mod'), wHereMod));
98200             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Del'), wHereDel));
98201             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Err'), wHereErr));
98202             stream.write(' │ ' + center(options.gettext('Add'), wPeerAdd));
98203             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Mod'), wPeerMod));
98204             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Del'), wPeerDel));
98205             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Err'), wPeerErr));
98206             stream.write(' │ ' + center(options.gettext('Col'), wCol));
98207             stream.write(( options.ascii ? ' │ ' : '   ' ) + center(options.gettext('Mrg'), wMrg));
98208             stream.write(' │\n');
98209
98210             stream.write('├─' + smult('─', wSrc)
98211                     + '─┼─' + smult('─', wMode)
98212                     + '─┼─' + smult('─', wHereAdd)
98213                     + '─┼─' + smult('─', wHereMod)
98214                     + '─┼─' + smult('─', wHereDel)
98215                     + '─┼─' + smult('─', wHereErr)
98216                     + '─┼─' + smult('─', wPeerAdd)
98217                     + '─┼─' + smult('─', wPeerMod)
98218                     + '─┼─' + smult('─', wPeerDel)
98219                     + '─┼─' + smult('─', wPeerErr)
98220                     + '─┼─' + smult('─', wCol)
98221                     + '─┼─' + smult('─', wMrg)
98222                     + '─┤\n'
98223                     );
98224
98225             var numcol = function(val, wid) {
98226                 if ( val == 0 )
98227                     return ' │ ' + center(options.ascii ? '-' : ' ', wid);
98228                 return ' │ ' + right(num2str(val), wid);
98229             };
98230
98231             var keys = _.keys(stats);
98232             // todo: sort case insensitively...
98233             keys.sort();
98234             _.each(keys, function(key) {
98235                 var stat = stats[key];
98236                 stream.write('│ ' + right(key, wSrc));
98237                 stream.write(' │ ' + center(modeStringLut[stat.mode], wMode));
98238                 stream.write(numcol(stat.hereAdd, wHereAdd));
98239                 stream.write(numcol(stat.hereMod, wHereMod));
98240                 stream.write(numcol(stat.hereDel, wHereDel));
98241                 stream.write(numcol(stat.hereErr, wHereErr));
98242                 stream.write(numcol(stat.peerAdd, wPeerAdd));
98243                 stream.write(numcol(stat.peerMod, wPeerMod));
98244                 stream.write(numcol(stat.peerDel, wPeerDel));
98245                 stream.write(numcol(stat.peerErr, wPeerErr));
98246                 stream.write(numcol(stat.conflicts, wCol));
98247                 stream.write(numcol(stat.merged, wMrg));
98248                 stream.write(' │\n');
98249             });
98250
98251             if ( options.totals )
98252                 stream.write('├─');
98253             else
98254                 stream.write('└─');
98255
98256             stream.write(smult('─', wSrc)
98257                     + '─┴─' + smult('─', wMode)
98258                     + '─┴─' + smult('─', wHereAdd)
98259                     + '─┴─' + smult('─', wHereMod)
98260                     + '─┴─' + smult('─', wHereDel)
98261                     + '─┴─' + smult('─', wHereErr)
98262                     + '─┴─' + smult('─', wPeerAdd)
98263                     + '─┴─' + smult('─', wPeerMod)
98264                     + '─┴─' + smult('─', wPeerDel)
98265                     + '─┴─' + smult('─', wPeerErr)
98266                     + '─┴─' + smult('─', wCol)
98267                     + '─┴─' + smult('─', wMrg)
98268                     );
98269
98270             if ( options.totals )
98271                 stream.write('─┤\n');
98272             else
98273                 stream.write('─┘\n');
98274         }
98275
98276         // ─━│┃┄┅┆┇┈┉┊┋┼┽┾┿
98277         // ┌┍┎┏┐┑┒┓└┕┖┗┘┙┚┛
98278         // ├┝┞┟┠┡┢┣┤┥┦┧┨┩┪┫
98279         // ┬┭┮┯┰┱┲┳┴┵┶┷┸┹┺┻
98280
98281         if ( options.totals )
98282         {
98283             if ( !! options.title && ! options.details )
98284                 stream.write('┌─' + smult('─', tWid) + '─┐\n');
98285             stream.write('│ ' + center(sumlist, tWid));
98286             stream.write(' │\n');
98287             stream.write('└─' + smult('─', tWid) + '─┘\n');
98288         }
98289
98290         return;
98291
98292     };
98293
98294     return exports;
98295
98296 })();
98297
98298 module.exports = _self;
98299
98300 });
98301 define('ripple/platform/tizen/2.0/syncml-js-lib/elementtree', function (require, exports, module) {
98302 /*
98303  *  Copyright 2013 Intel Corporation
98304  *
98305  * Licensed under the Apache License, Version 2.0 (the "License");
98306  * you may not use this file except in compliance with the License.
98307  * You may obtain a copy of the License at
98308  *
98309  * http://www.apache.org/licenses/LICENSE-2.0
98310  *
98311  * Unless required by applicable law or agreed to in writing, software
98312  * distributed under the License is distributed on an "AS IS" BASIS,
98313  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
98314  * See the License for the specific language governing permissions and
98315  * limitations under the License.
98316  */
98317
98318 var utils = require('ripple/utils'),
98319     _parser,
98320     _serializer,
98321     _self;
98322
98323 function _find(query, element, type) {
98324     var querylist = query.split("/"),
98325         e = element._node,
98326         tag, i, ret;
98327
98328     if (querylist.length === 0) {
98329         return undefined;
98330     }
98331
98332     for(i = 0; i < querylist.length; i++) {
98333         tag = querylist[i];
98334         try {
98335             e = e.getElementsByTagName(tag)[0];
98336         } catch (error) {
98337             e = undefined;
98338             break;
98339         }
98340     }
98341
98342     if (e) {
98343         if (type === "TEXT") {
98344             return e.textContent;
98345         } else if (type === "NODE") {
98346             ret = {
98347                 _doc: element,
98348                 _node: e,
98349                 find: function (query) {
98350                     return _find(query, this, "NODE");
98351                 },
98352                 findtext: function (query) {
98353                     return _find(query, this, "TEXT");
98354                 },
98355                 findall: function (query) {
98356                     return _findall(query, this);
98357                 },
98358                 getchildren: function () {
98359                     return _getchildren(this);
98360                 },
98361                 append: function (node) {
98362                     this._node.appendChild(node._node);
98363                 },
98364                 getroot: function () {
98365                     return this;
98366                 }
98367             };
98368             ret.__defineSetter__("text", function (text) {
98369                 this._node.textContent = text;
98370             });
98371             ret.__defineGetter__("text", function () {
98372                 return this._node.textContent;
98373             });
98374             ret.__defineGetter__("tag", function () {
98375                 return _tag(this);
98376             });
98377             return ret;
98378         }
98379     } else {
98380         return undefined;
98381     }
98382 }
98383
98384 function _findall(query, element) {
98385     var querylist = query.split("/"),
98386         e = element._node,
98387         tag,
98388         array,
98389         tmp,
98390         ret = [],
98391         i;
98392
98393     for(i = 0; i < querylist.length - 1; i++) {
98394         tag = querylist[i];
98395         try {
98396             e = e.getElementsByTagName(tag)[0];
98397         } catch (error) {
98398             return ret;
98399         }
98400     }
98401
98402     tag = querylist[querylist.length - 1];
98403     array = e.getElementsByTagName(tag);
98404     ///return ret;
98405     for(i = 0; i < array.length; i++) {
98406         tmp = {
98407             _doc: element,
98408             _node: array[i],
98409             find: function (query) {
98410                 return _find(query, this, "NODE");
98411             },
98412             findtext: function (query) {
98413                 return _find(query, this, "TEXT");
98414             },
98415             findall: function (query) {
98416                 return _findall(query, this);
98417             },
98418             getchildren: function () {
98419                 return _getchildren(this);
98420             },
98421             append: function (node) {
98422                 this._node.appendChild(node._node);
98423             },
98424             getroot: function () {
98425                 return this;
98426             }
98427         };
98428         tmp.__defineSetter__("text", function (text) {
98429             this._node.textContent = text;
98430         });
98431         tmp.__defineGetter__("text", function () {
98432             return this._node.textContent;
98433         });
98434         tmp.__defineGetter__("tag", function () {
98435             return _tag(this);
98436         });
98437         ret.push(tmp);
98438     }
98439     return ret;
98440 }
98441
98442 function _tag(element) {
98443     var array;
98444     array = element._node.tagName.split(":");
98445     return array[array.length - 1];
98446 }
98447
98448 function _getchildren(element) {
98449     var ret = [], e, i;
98450     for (i = 0; i < element._node.childNodes.length; i++) {
98451         e = {
98452             _doc: element,
98453             _node: element._node.childNodes[i],
98454             find: function (query) {
98455                 return _find(query, this, "NODE");
98456             },
98457             findtext: function (query) {
98458                 return _find(query, this, "TEXT");
98459             },
98460             findall: function (query) {
98461                 return _findall(query, this);
98462             },
98463             getchildren: function () {
98464                 return _getchildren(this);
98465             },
98466             append: function (node) {
98467                 this._node.appendChild(node._node);
98468             },
98469             getroot: function () {
98470                 return this;
98471             }
98472         };
98473         e.__defineSetter__("text", function (text) {
98474             this._node.textContent = text;
98475         });
98476         e.__defineGetter__("text", function () {
98477             return this._node.textContent;
98478         });
98479         e.__defineGetter__("tag", function () {
98480             return _tag(this);
98481         });
98482         ret.push(e);
98483     }
98484
98485     return ret;
98486 }
98487
98488
98489 _self = (function () {
98490     ET = {};
98491
98492     ET.Element = function(name, attributes) {
98493         var element = {},
98494             doc,
98495             node;
98496
98497         doc = _parser.parseFromString("<" + name + "></" + name + ">", "text/xml");
98498         node = doc.childNodes[0];
98499         if (attributes) {
98500             utils.forEach(attributes, function (value, key) {
98501                 node.setAttribute(key, value);
98502             });
98503         }
98504
98505         element = {
98506             _doc: doc,
98507             _node: node,
98508             find: function (query) {
98509                 return _find(query, this, "NODE");
98510             },
98511             findtext: function (query) {
98512                 return _find(query, this, "TEXT");
98513             },
98514             findall: function (query) {
98515                 return _findall(query, this);
98516             },
98517             getchildren: function () {
98518                 return _getchildren(this);
98519             },
98520             append: function (node) {
98521                 this._node.appendChild(node._node);
98522             },
98523             getroot: function () {
98524                 return this;
98525             }
98526         };
98527
98528         element.__defineSetter__("text", function (text) {
98529             this._node.textContent = text;
98530         });
98531
98532         element.__defineGetter__("text", function () {
98533             return this._node.textContent;
98534         });
98535
98536         element.__defineGetter__("tag", function () {
98537             return _tag(this);
98538         });
98539
98540         return element;
98541     };
98542
98543     ET.SubElement = function(element, name, attributes) {
98544         var subElement = {},
98545             node;
98546         node = element._doc.createElement(name);
98547         if (attributes) {
98548             utils.forEach(attributes, function (value, key) {
98549                 node.setAttribute(key, value);
98550             });
98551         }
98552         element._node.appendChild(node);
98553         subElement = {
98554             _doc: element._doc,
98555             _node: node,
98556             find: function (query) {
98557                 return _find(query, this, "NODE");
98558             },
98559             findtext: function (query) {
98560                 return _find(query, this, "TEXT");
98561             },
98562             findall: function (query) {
98563                 return _findall(query, this);
98564             },
98565             getchildren: function () {
98566                 return _getchildren(this);
98567             },
98568             append: function (node) {
98569                 this._node.appendChild(node._node);
98570             },
98571             getroot: function () {
98572                 return this;
98573             }
98574         };
98575         subElement.__defineSetter__("text", function (text) {
98576             this._node.textContent = text;
98577         });
98578         subElement.__defineGetter__("text", function () {
98579             return this._node.textContent;
98580         });
98581         subElement.__defineGetter__("tag", function () {
98582             return _tag(this);
98583         });
98584
98585         return subElement;
98586     };
98587
98588     ET.tostring = function(element) {
98589         return _serializer.serializeToString(element._node);
98590     };
98591     ET.parse = function(doc) {
98592         var element = {};
98593
98594         element = {
98595             _doc: doc,
98596             _node: doc.childNodes[0],
98597             find: function (query) {
98598                 return _find(query, this, "NODE");
98599             },
98600             findtext: function (query) {
98601                 return _find(query, this, "TEXT");
98602             },
98603             findall: function (query) {
98604                 return _findall(query, this);
98605             },
98606             getchildren: function () {
98607                 return _getchildren(this);
98608             },
98609             append: function (node) {
98610                 this._node.appendChild(node._node);
98611             },
98612             getroot: function () {
98613                 return this;
98614             }
98615         };
98616         element.__defineSetter__("text", function (text) {
98617             this._node.textContent = text;
98618         });
98619         element.__defineGetter__("text", function () {
98620             return this._node.textContent;
98621         });
98622         element.__defineGetter__("tag", function () {
98623             return _tag(this);
98624         });
98625
98626         return element;
98627     };
98628
98629     ET.CdataElement = function(str) {
98630         var doc, cdata;
98631         doc = _parser.parseFromString("<data></data>", "text/xml");
98632         cdata = doc.createCDATASection(str);
98633         return cdata;
98634     };
98635
98636     return ET;
98637 })();
98638
98639 _parser = new DOMParser();
98640 _serializer = new XMLSerializer();
98641
98642 module.exports = _self;
98643
98644 });
98645 define('ripple/platform/tizen/2.0/syncml-js-lib/localadapter', function (require, exports, module) {
98646 // -*- coding: utf-8 -*-
98647 //-----------------------------------------------------------------------------
98648 // file: $Id$
98649 // lib:  syncml-js.localadapter
98650 // auth: griffin <griffin@uberdev.org>
98651 // date: 2012/10/22
98652 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
98653 //-----------------------------------------------------------------------------
98654
98655 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
98656     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
98657     codec = require('ripple/platform/tizen/2.0/syncml-js-lib/codec'),
98658     storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
98659     remote = require('ripple/platform/tizen/2.0/syncml-js-lib/remoteadapter'),
98660     storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store'),
98661     devinfomod = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'),
98662     adapter = require('ripple/platform/tizen/2.0/syncml-js-lib/adapter'),
98663     state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'),
98664     useragent = require('ripple/platform/tizen/2.0/syncml-js-lib/useragent'),
98665     _self;
98666
98667 _self = (function () {
98668     var exports = {};
98669
98670     //---------------------------------------------------------------------------
98671     exports.LocalAdapter = adapter.Adapter.extend({
98672
98673         //-------------------------------------------------------------------------
98674         constructor: function(context, options, devInfo) {
98675
98676             // todo: is there anyway to mark attributes as read-only?...
98677
98678             //: [read-only] devInfo describes this adapter's device info and
98679             //: capabilities.
98680             this.devInfo = null;
98681
98682             //: [read-only] the device ID of this adapter.
98683             this.devID = options.devID || null;
98684
98685             //: [read-only] specifies whether this Adapter represents a local
98686             //: or remote peer.
98687             this.isLocal = true;
98688
98689             //: [read-only] human-facing name of this adapter
98690             this.displayName = options.displayName || null;
98691
98692             //: [read-only] the adapter-wide default value of the maximum
98693             //: message size.
98694             this.maxMsgSize = options.maxMsgSize || null;
98695
98696             //: [read-only] the adapter-wide default value of the maximum
98697             //: object size.
98698             this.maxObjSize = options.maxObjSize || null;
98699
98700             //: [read-only] specifies default conflict resolution policy for
98701             //: this adapter. if undefined, defaults to constant.POLICY_ERROR.
98702             this.conflictPolicy = options.conflictPolicy || constant.POLICY_ERROR;
98703
98704             // --- private attributes
98705             this.id       = options.id || common.makeID();
98706             this._c       = context;
98707             // TODO: use _.pick() for these options...
98708             this._options = options;
98709             this._devInfo = devInfo;
98710             this._model   = null;
98711             this._stores  = {};
98712             this._peers   = [];
98713         },
98714
98715             //-------------------------------------------------------------------------
98716             _getModel: function() {
98717                 return this._model;
98718             },
98719
98720             //-------------------------------------------------------------------------
98721             setDevInfo: function(devInfo, cb) {
98722                 if ( this._model == undefined )
98723                     this._model = {
98724                         id              : this.id,
98725                         displayName     : this.displayName,
98726                         maxMsgSize      : this.maxMsgSize,
98727                         maxObjSize      : this.maxObjSize,
98728                         conflictPolicy  : this.conflictPolicy,
98729                         devInfo         : null,
98730                         stores          : [],
98731                         peers           : [],
98732                         isLocal         : 1
98733                     };
98734
98735                 var di = new devinfomod.DevInfo(this, devInfo);
98736                 di._updateModel(_.bind(function(err) {
98737                     if ( err )
98738                         return cb(err);
98739
98740                     this._model.devID = this._model.devInfo.devID;
98741                     this.devID        = this._model.devInfo.devID;
98742                     this.devInfo      = di;
98743
98744                 // since the local devinfo has changed, we need to ensure that
98745                 // we rebroadcast it (in case there are any affects...), thus
98746                 // resetting all anchors.
98747                 // TODO: this seems a little heavy-handed, since this will force
98748                 //       a slow-sync for each datastore. is that really the best
98749                 //       thing?...
98750                 this._resetAllAnchors();
98751
98752                 this._save(this._c._txn(), cb);
98753
98754                 }, this));
98755             },
98756
98757             //-------------------------------------------------------------------------
98758             _resetAllAnchors: function() {
98759                 _.each(this._model.peers, function(peer) {
98760                     _.each(peer.stores, function(store) {
98761                         if ( ! store.binding )
98762                         return;
98763                     store.binding.localAnchor  = null;
98764                     store.binding.remoteAnchor = null;
98765                     });
98766                 });
98767             },
98768
98769             //-------------------------------------------------------------------------
98770             getPeers: function() {
98771                 return this._peers;
98772             },
98773
98774             //-------------------------------------------------------------------------
98775             addPeer: function(peerInfo, cb) {
98776                 var self = this;
98777
98778                 // TODO: if there is already a peer for the specified URL, then
98779                 //       we may have a problem!...
98780
98781                 // todo: if we are adding a peer to an adapter that already has
98782                 //       non-client peers, then we may have a problem!...
98783                 //       (this is only true while syncml-js is not capable of truly
98784                 //       operating in peer-to-peer mode)
98785
98786                 var peer = new remote.RemoteAdapter(this, peerInfo);
98787                 peer._updateModel(function(err) {
98788                     if ( err )
98789                     return cb(err);
98790                 self._peers.push(peer);
98791                 cb(null, peer);
98792                 });
98793             },
98794
98795             //-------------------------------------------------------------------------
98796             save: function(cb) {
98797                 this._save(this._c._txn(), cb);
98798             },
98799
98800             //-------------------------------------------------------------------------
98801             _save: function(dbtxn, cb) {
98802                 var self = this;
98803                 self._updateModel(function(err) {
98804                     if ( err )
98805                     return cb(err);
98806                 storage.put(dbtxn.objectStore('adapter'), self._model, cb);
98807                 });
98808             },
98809
98810             //-------------------------------------------------------------------------
98811             _updateModel: function(cb) {
98812                 var self = this;
98813                 var model = self._model;
98814                 model.displayName    = self.displayName;
98815                 model.devID          = self.devID;
98816                 model.maxMsgSize     = self.maxMsgSize;
98817                 model.maxObjSize     = self.maxObjSize;
98818                 model.conflictPolicy = self.conflictPolicy;
98819                 model.isLocal        = 1;
98820                 common.cascade([
98821                         // update the devInfo model
98822                         function(cb) {
98823                             if ( ! self.devInfo )
98824                     return cb();
98825                 return self.devInfo._updateModel(cb);
98826                         },
98827                         // update the stores model
98828                         function(cb) {
98829                             model.stores = [];
98830                             common.cascade(_.values(self._stores), function(store, cb) {
98831                                 store._updateModel(cb);
98832                             }, cb);
98833                         },
98834
98835                         // update the peers model
98836                         function(cb) {
98837                             // NOTE: unlike stores, which can completely regenerate the
98838                             //       model based on the class, the peers store binding
98839                             //       and routing info is only in the model, so cannot be
98840                             //       completely deleted...
98841                             common.cascade(self._peers, function(peer, cb) {
98842                                 peer._updateModel(cb);
98843                             }, cb);
98844                         }
98845
98846                 ], cb);
98847             },
98848
98849             //-------------------------------------------------------------------------
98850             _load: function(cb) {
98851                 var self = this;
98852
98853                 // TODO: if options specifies a devID/name/etc, use that...
98854
98855                 storage.getAll(
98856                     this._c,
98857                     this._c._txn().objectStore('adapter').index('isLocal'),
98858                     {only: 1},
98859                     function(err, adapters) {
98860                         if ( err ) {
98861                             return cb(err);
98862                         }
98863                         if ( adapters.length > 1 )
98864                             return cb('multiple local adapters defined - specify which devID to load');
98865                         if ( adapters.length <= 0 )
98866                             return cb(null, self);
98867                         self._loadModel(adapters[0], function(err) {
98868                             if ( err )
98869                                 return cb(err);
98870                             return cb(null, self);
98871                         });
98872                     }
98873                 );
98874             },
98875
98876             //-------------------------------------------------------------------------
98877             _loadModel: function(model, cb) {
98878                 var self = this;
98879                 self._model         = model;
98880                 self.displayName    = model.displayName;
98881                 self.devID          = model.devID;
98882                 self.maxMsgSize     = model.maxMsgSize;
98883                 self.maxObjSize     = model.maxObjSize;
98884                 self.conflictPolicy = model.conflictPolicy;
98885                 common.cascade([
98886                         // load device info
98887                         function(cb) {
98888                             var di = new devinfomod.DevInfo(self, self._model.devInfo);
98889                             di._load(function(err) {
98890                                 if ( err )
98891                                 return cb(err);
98892                             self.devInfo = di;
98893                             cb();
98894                             });
98895                         },
98896                         // load stores
98897                         function(cb) {
98898                             common.cascade(model.stores, function(e, cb) {
98899                                 var store = new storemod.Store(self, e);
98900                                 store._load(function(err) {
98901                                     if ( err )
98902                                     return cb(err);
98903                                 self._stores[store.uri] = store;
98904                                 return cb();
98905                                 });
98906                             }, cb);
98907                         },
98908                         // load peers
98909                         function(cb) {
98910                             var remotes = _.filter(model.peers, function(e) {
98911                                 return ! e.isLocal;
98912                             });
98913                             self._peers = [];
98914                             common.cascade(remotes, function(e, cb) {
98915                                 var peer = new remote.RemoteAdapter(self, e);
98916                                 peer._load(function(err) {
98917                                     if ( err )
98918                                     return cb(err);
98919                                 self._peers.push(peer);
98920                                 return cb();
98921                                 });
98922                             }, cb);
98923                         }
98924                 ], cb);
98925             },
98926
98927             //-------------------------------------------------------------------------
98928             sync: function(peer, mode, options, cb) {
98929                 // `options` is optional and can have the following properties:
98930                 //   * `ua`
98931
98932                 // TODO: initialize a new context transaction?...
98933                 // todo: or perhaps add a new session.txn?...
98934
98935                 if ( cb == undefined && _.isFunction(options) )
98936                 {
98937                     cb = options;
98938                     options = {};
98939                 }
98940                 options = options || {};
98941
98942                 var self = this;
98943                 var discover = ( mode == constant.SYNCTYPE_DISCOVER );
98944                 if ( discover )
98945                     mode = constant.SYNCTYPE_SLOW_SYNC;
98946
98947                 if ( ! _.find(self._peers, function(p) { return p === peer; }) )
98948                     return cb(new common.InvalidAdapter('invalid peer for adapter'));
98949                 if ( mode != constant.SYNCTYPE_AUTO )
98950                 {
98951                     mode = common.synctype2alert(mode);
98952                     if ( ! mode )
98953                         return cb(new common.TypeError('invalid synctype'));
98954                 }
98955                 if ( ! self.devInfo )
98956                     return cb(new common.InvalidAdapter('cannot synchronize adapter as client: invalid devInfo'));
98957
98958                 var session = state.makeSession({
98959                     context  : self._c,
98960                     ua       : new useragent.UserAgentMultiplexer([options.ua, self._c.ua]),
98961                     txn      : _.bind(self._c._txn, self._c),
98962                     adapter  : self,
98963                     peer     : peer,
98964                     isServer : false,
98965                     discover : discover,
98966                     info     : state.makeSessionInfo({
98967                         id       : ( peer.lastSessionID || 0 ) + 1,
98968                     msgID    : 1,
98969                     codec    : self._c.codec,
98970                     mode     : mode
98971                     })
98972                 });
98973
98974                 session.send = function(contentType, data, cb) {
98975                     session.peer.sendRequest(session, contentType, data, function(err, response) {
98976                         if ( err )
98977                         return cb(err);
98978                     // todo: allow the client to force the server to authorize itself as well...
98979                     self._receive(session, response, null, cb);
98980                     });
98981                 };
98982
98983                 // TODO: should i do a router.calculate() at this point?
98984                 //       the reason is that if there was a sync, then a
98985                 //       .setRoute(), then things may have changed...
98986                 //       corner-case, yes... but still valid.
98987
98988                 var failed = 0;
98989
98990                 var startSession = function() {
98991                     session.context.protocol.initialize(session, null, function(err, commands) {
98992                         if ( err )
98993                         return cb(err);
98994                     self._transmit(session, commands, function(err) {
98995                         if ( err )
98996                     {
98997                         if ( ! ( err instanceof common.InvalidCredentials )
98998                             && ! ( err instanceof common.CredentialsRequired ) )
98999                             return cb(err);
99000                         if ( err instanceof common.InvalidCredentials )
99001                         failed += 1;
99002                     if ( failed > 100 )
99003                     {
99004                         return cb(err);
99005                     }
99006                     var credErr = err;
99007                     var uaEvent = {
99008                         session : session,
99009                         auth    : err.auth,
99010                         count   : failed
99011                     };
99012                     return session.ua.fetchCredentials(uaEvent, function(err, auth) {
99013                         if ( err )
99014                         return cb(err);
99015                     if ( ! auth )
99016                         return cb(credErr);
99017                     if ( auth.persist )
99018                     {
99019                         session.peer.auth = auth.type;
99020                         session.peer.username = auth.username;
99021                         session.peer.password = auth.password;
99022                     }
99023                     else
99024                         session.auth = auth;
99025                     // todo: should i just create a new session?...
99026                     session.info.id += 1;
99027                     session.info.msgID = 1;
99028                     return startSession();
99029                     });
99030                     }
99031                     self._save(session.txn(), function(err) {
99032                         if ( err )
99033                         return cb(err);
99034                     return cb(null, self._session2stats(session));
99035                     });
99036                     });
99037                     });
99038                 };
99039
99040                 session.context.synchronizer.initStoreSync(session, function(err) {
99041                     if ( err )
99042                     return cb(err);
99043                 startSession();
99044                 });
99045
99046             },
99047
99048             //-------------------------------------------------------------------------
99049             _session2stats: function(session) {
99050                 var ret = {};
99051                 _.each(_.values(session.info.dsstates), function(ds) {
99052                     var stats = _.clone(ds.stats);
99053                     stats.mode = common.alert2synctype(ds.mode);
99054                     if ( ds.action == 'error' && ds.error )
99055                     stats.error = ds.error;
99056                 ret[ds.uri] = stats;
99057                 });
99058                 return ret;
99059             },
99060
99061             //-------------------------------------------------------------------------
99062             _transmit: function(session, commands, cb) {
99063                 var self = this;
99064                 if ( session.info.msgID > 20 )
99065                     return cb('too many client/server messages');
99066                 session.context.protocol.negotiate(session, commands, function(err, commands) {
99067                     if ( err )
99068                     return cb(err);
99069                 if ( session.context.protocol.isComplete(session, commands) )
99070                 {
99071                     // we're done! store all the anchors and session IDs and exit...
99072                     var pmodel = session.peer._getModel();
99073                     if ( ! pmodel )
99074                     return cb('unexpected error: could not locate this peer in local adapter');
99075                 _.each(session.info.dsstates, function(ds, uri) {
99076                     var pstore = _.find(pmodel.stores, function(s) { return s.uri == ds.peerUri; });
99077                     if ( ! pstore )
99078                     return cb('unexpected error: could not locate bound peer store in local adapter');
99079                 pstore.binding.localAnchor  = ds.nextAnchor;
99080                 pstore.binding.remoteAnchor = ds.peerNextAnchor;
99081                 });
99082                 session.peer.lastSessionID = session.info.id;
99083                 pmodel.lastSessionID       = session.info.id;
99084                 return cb();
99085                 }
99086                 session.context.protocol.produce(session, commands, function(err, tree) {
99087                     if ( err )
99088                     return cb(err);
99089                 codec.Codec.autoEncode(tree, session.info.codec, function(err, contentType, data) {
99090                     if ( err )
99091                     return cb(err);
99092                 // update the session with the last request commands so
99093                 // that when we receive the response package, it can be
99094                 // compared against that.
99095                 // TODO: should that only be done on successful transmit?...
99096                 session.info.lastCommands = commands;
99097                 session.send(contentType, data, function(err) {
99098                     if ( err )
99099                     return cb(err);
99100                 cb();
99101                 });
99102                 })
99103                 });
99104                 });
99105             },
99106
99107             //-------------------------------------------------------------------------
99108             authorize: function(request, sessionInfo, authorize, cb) {
99109                 var self = this;
99110                 var ct   = request.headers['Content-Type'];
99111                 codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) {
99112                     if ( err )
99113                     return cb(err);
99114                 self._c.protocol.authorize(xtree, null, authorize, cb);
99115                 });
99116             },
99117
99118             //-------------------------------------------------------------------------
99119             getTargetID: function(request, sessionInfo, cb) {
99120                 var self = this;
99121                 var ct   = request.headers['Content-Type'];
99122                 codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) {
99123                     if ( err )
99124                     return cb(err);
99125                 return cb(null, self._c.protocol.getTargetID(xtree));
99126                 });
99127             },
99128
99129             //-------------------------------------------------------------------------
99130             handleRequest: function(request, sessionInfo, authorize, response, options, cb) {
99131
99132                 // TODO: initialize a new context transaction?...
99133                 // todo: or perhaps add a new session.txn?...
99134
99135                 if ( cb == undefined && _.isFunction(options) )
99136                 {
99137                     cb = options;
99138                     options = {};
99139                 }
99140                 options = options || {};
99141
99142                 var self = this;
99143                 var session = state.makeSession({
99144                     context  : self._c,
99145                     ua       : new useragent.UserAgentMultiplexer([options.ua, self._c.ua]),
99146                     txn      : _.bind(self._c._txn, self._c),
99147                     adapter  : self,
99148                     peer     : null,
99149                     isServer : true,
99150                     info     : sessionInfo
99151                 });
99152                 session.send = response;
99153                 this._receive(session, request, authorize, function(err, stats) {
99154                     if ( err )
99155                     return cb(err);
99156                 self._save(session.txn(), function(err) {
99157                     if ( err )
99158                     return cb(err);
99159                 return cb(null, self._session2stats(session));
99160                 });
99161                 });
99162             },
99163
99164             //-------------------------------------------------------------------------
99165             _receive: function(session, request, authorize, cb) {
99166                 var self = this;
99167                 if ( ! session.isServer )
99168                 {
99169                     session.info.lastMsgID = session.info.msgID;
99170                     session.info.msgID += 1;
99171                 }
99172                 var ct = request.headers['Content-Type'];
99173                 codec.Codec.autoDecode(ct, request.body, function(err, xtree, codecName) {
99174                     if ( err )
99175                     return cb(err);
99176                 session.info.codec = codecName;
99177                 var do_authorize = ( ! authorize ) ? common.noop : function(cb) {
99178                     session.context.protocol.authorize(xtree, null, authorize, function(err) {
99179                         return cb(err);
99180                     });
99181                 };
99182                 do_authorize(function(err) {
99183                     if ( err )
99184                     return cb(err);
99185                 session.context.protocol.consume(
99186                     session, session.info.lastCommands, xtree,
99187                     function(err, commands) {
99188                         if ( err ) {
99189                             return cb(err);
99190                         }
99191                         if ( session.discover && session.peer.devInfo )
99192                     return cb(null, self._session2stats(session));
99193                 self._transmit(session, commands, function(err) {
99194                     if ( err )
99195                     return cb(err);
99196                 if ( ! session.isServer )
99197                     return cb();
99198                 self._save(session.txn(), function(err) {
99199                     if ( err )
99200                     return cb(err);
99201                 return cb(null, self._session2stats(session));
99202                 });
99203                 });
99204                     }
99205                 );
99206                 });
99207                 })
99208             },
99209
99210     });
99211
99212     return exports;
99213
99214 })();
99215
99216 module.exports = _self;
99217
99218 });
99219 define('ripple/platform/tizen/2.0/syncml-js-lib/protocol', function (require, exports, module) {
99220 // -*- coding: utf-8 -*-
99221 //-----------------------------------------------------------------------------
99222 // file: $Id$
99223 // lib:  syncml-js.protocol
99224 // auth: griffin <griffin@uberdev.org>
99225 // date: 2012/11/04
99226 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
99227 //-----------------------------------------------------------------------------
99228
99229 var db = require('ripple/db'),
99230     common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
99231     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
99232     devinfo = require('ripple/platform/tizen/2.0/syncml-js-lib/devinfo'),
99233     state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'),
99234     base64 = require('ripple/platform/tizen/2.0/syncml-js-lib/base64'),
99235     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree'),
99236     _firstflag = false,
99237     changednum, _counts;
99238
99239 var _self = (function () {
99240
99241     var exports = {};
99242
99243     //---------------------------------------------------------------------------
99244     var getError = function(xnode) {
99245         var ret = {
99246             message: xnode.findtext('Item/Data')
99247         };
99248         try{
99249             var xerr  = xnode.find('Error');
99250         }catch(e){
99251             var xerr = null;
99252         }
99253         if ( ! xerr )
99254 {
99255     try{
99256         var xerr  = xnode.find('Item/Error');
99257     }catch(e){
99258         var xerr = null;
99259     }
99260 }
99261 if ( ! xerr )
99262 {
99263     if ( ! ret.message )
99264         return null;
99265     return ret;
99266 }
99267 ret.code    = xerr.findtext('Code');
99268 ret.message = xerr.findtext('Message');
99269 ret.trace   = xerr.findtext('Trace');
99270 return ret;
99271 }
99272
99273 //---------------------------------------------------------------------------
99274 var badStatus = function(xnode, kls, attrs) {
99275     if ( ! kls )
99276         kls = common.ProtocolError;
99277     var code  = xnode.findtext('Data');
99278     var cname = xnode.findtext('Cmd');
99279     var msg   = null;
99280     if ( kls == common.ProtocolError )
99281         msg = 'unexpected status code ' + code + ' for command "' + cname + '"';
99282     else
99283         msg = 'received status code ' + code + ' for command "' + cname + '"';
99284     var error = getError(xnode);
99285     if ( error )
99286     {
99287         if ( error.code )
99288             msg += ': [' + error.code + '] ' + error.message;
99289         else
99290             msg += ': ' + error.message;
99291     }
99292     return new kls(msg, undefined, attrs)
99293 };
99294
99295 //---------------------------------------------------------------------------
99296 exports.getError  = getError;
99297 exports.badStatus = badStatus;
99298
99299 //---------------------------------------------------------------------------
99300 exports.Protocol = common.Base.extend({
99301
99302     //-------------------------------------------------------------------------
99303     constructor: function(options) {
99304     },
99305
99306     //-------------------------------------------------------------------------
99307     authorize: function(xtree, uri, authorize, cb) {
99308
99309         // TODO: if this session has been authorized before, don't call authorize
99310         //       ie.:
99311         //         if ( session.info.authAccepted )
99312         //           return cb();
99313         //       BUT this requires the session object... oops.
99314
99315         if ( ! authorize )
99316     authorize = function(uri, data, cb) { return cb(null, data); };
99317 if ( xtree.tag != 'SyncML' )
99318     throw new common.ProtocolError('root element was not "SyncML"');
99319 var xcred = xtree.find('SyncHdr/Cred');
99320 if ( ! xcred )
99321     return authorize(uri, null, cb);
99322 var data = xcred.findtext('Data');
99323 var authtype = xcred.findtext('Meta/Type');
99324 var format = xcred.findtext('Meta/Format');
99325 if ( format == constant.FORMAT_B64 )
99326     data = base64.decode(data);
99327 else if ( format )
99328     throw new common.UnknownFormatType(format);
99329 switch ( authtype )
99330 {
99331     case constant.NAMESPACE_AUTH_BASIC:
99332         {
99333             data = common.splitn(data, ':', 1);
99334             return authorize(uri, {
99335                 auth:     constant.NAMESPACE_AUTH_BASIC,
99336                    username: data[0],
99337                    password: data[1]
99338             }, cb);
99339         }
99340     case constant.NAMESPACE_AUTH_MD5:
99341         {
99342             return authorize(uri, {
99343                 auth:   constant.NAMESPACE_AUTH_BASIC,
99344                    digest: data
99345             }, cb);
99346         }
99347     default:
99348         {
99349             return cb(new common.UnknownAuthType(
99350                         'unknown/unimplemented auth type "' + authtype + '"'));
99351         }
99352 }
99353 },
99354
99355     //-------------------------------------------------------------------------
99356     getTargetID: function(xtree) {
99357         if ( xtree.tag != 'SyncML' )
99358             throw new common.ProtocolError('root element was not "SyncML"');
99359         // todo: do more validity checks?...
99360         return xtree.findtext('SyncHdr/Target/LocURI');
99361     },
99362
99363     //-------------------------------------------------------------------------
99364     isComplete: function(session, commands) {
99365         return (! session.isServer
99366                 && commands.length == 3
99367                 && commands[0].name == constant.CMD_SYNCHDR
99368                 && commands[1].name == constant.CMD_STATUS
99369                 && commands[1].statusOf == constant.CMD_SYNCHDR
99370                 && commands[1].statusCode == constant.STATUS_OK
99371                 && commands[2].name == constant.CMD_FINAL
99372                );
99373     },
99374
99375     //----------------------<---------------------------------------------------
99376     initialize: function(session, xtree, cb) {
99377         var cmd = state.makeCommand({
99378             name        : constant.CMD_SYNCHDR,
99379         cmdID       : 0,
99380         version     : constant.SYNCML_VERSION_1_2,
99381         source      : session.info.effectiveID || session.adapter.devID,
99382         sourceName  : session.adapter.displayName,
99383         respUri     : session.isServer ? session.info.returnUrl : null
99384         });
99385
99386         var checkPeer = ( ! session.isServer ) ? function(cb) {
99387             if ( ! xtree )
99388                 return cb();
99389             var xhdr = xtree.find('SyncHdr');
99390             // todo: check peer id...
99391             if ( session.info.id != common.int(xhdr.findtext('SessionID')) )
99392             {
99393                 return cb(new common.ProtocolError('session ID mismatch "'
99394                             + xhdr.findtext('SessionID')
99395                             + '" (expected: ' + session.info.id + ')'));
99396                         }
99397                         // todo: check message id...
99398                         cb();
99399                         } : function(cb) {
99400                             var xhdr = xtree.find('SyncHdr');
99401                             var peerID = xhdr.findtext('Source/LocURI');
99402                             if ( session.info.peerID && session.info.peerID != peerID )
99403                 {
99404                     return cb(new common.ProtocolError('unexpected peer ID "' + peerID + '"'));
99405                 }
99406                 if ( session.peer && session.peer.devID != peerID )
99407                 {
99408                     return cb(new common.ProtocolError('unacceptable peer ID "' + peerID + '"'));
99409                 }
99410                 session.info.peerID = peerID;
99411                 // check that no session swapping occurred
99412                 if ( session.info.id != undefined
99413                     && session.info.id != common.int(xhdr.findtext('SessionID')) )
99414                 {
99415                     return cb(new common.ProtocolError('session ID mismatch "'
99416                                 + xhdr.findtext('SessionID')
99417                                 + '" (expected: ' + session.info.id + ')'));
99418                             }
99419                             session.info.id     = common.int(xhdr.findtext('SessionID'));
99420                             session.info.msgID  = common.int(xhdr.findtext('MsgID'));
99421                             if ( session.peer && session.peer.devID == peerID )
99422                             return cb();
99423                             // TODO: i should delete unused peers here... ie. anything that
99424                             //       hasn't been used in some configurable number of seconds,
99425                             //       which should probably default to something like a month...
99426                             session.peer = _.find(session.adapter.getPeers(), function(peer) {
99427                                 return ( peer.devID == peerID );
99428                             });
99429                             if ( session.peer )
99430                             {
99431                                 return cb();
99432                             }
99433                             var peerInfo = {
99434                                 devID:        peerID,
99435                            displayName:  xhdr.findtext('Source/LocName'),
99436                            maxMsgSize:   common.int(xhdr.findtext('Meta/MaxMsgSize')),
99437                            maxObjSize:   common.int(xhdr.findtext('Meta/MaxObjSize'))
99438                             };
99439                             session.adapter.addPeer(peerInfo, function(err, peer) {
99440                                 if ( err )
99441                                 return cb(err);
99442                             session.peer = peer;
99443                             return cb();
99444                             });
99445                         };
99446
99447         checkPeer(function(err) {
99448
99449             session.info.cmdID        = 0;
99450             session.info.pendingMsgID = ( session.isServer
99451                 ? session.info.msgID
99452                 : session.info.lastMsgID );
99453             cmd.sessionID   = session.info.id;
99454             cmd.msgID       = session.info.msgID;
99455             cmd.target      = session.peer ? session.peer.devID || null : null;
99456             cmd.targetName  = session.peer ? session.peer.displayName || null : null;
99457             cmd.auth        = session.auth
99458             ? session.auth.type
99459             : session.peer
99460             ? session.peer.auth
99461             : null;
99462
99463         if ( err )
99464             return cb(err, [cmd]);
99465
99466         if ( cmd.msgID == 1 )
99467         {
99468             // NOTE: normally, the "server" would not send this info. however, in
99469             //       the syncml-js world where it is much more peer-oriented
99470             //       instead of client/server, i send this as well... the
99471             //       idea being, if two "client" peers are communicating in
99472             //       the event of server unavailability, then they may need
99473             //       to know each-others limitations...
99474             cmd.maxMsgSize = common.getMaxMemorySize(session.context);
99475             cmd.maxObjSize = common.getMaxMemorySize(session.context);
99476             ///cmd.maxMsgSize = 150000;
99477             ///cmd.maxObjSize = 4000000;
99478         }
99479         cb(null, [cmd]);
99480         });
99481     },
99482
99483     //-------------------------------------------------------------------------
99484     negotiate: function(session, commands, cb) {
99485         // // todo: determine why i decided to clone the commands...
99486         // commands = _.clone(commands);
99487
99488         if ( commands.length > 0 && _.last(commands).name == constant.CMD_FINAL )
99489             return cb(null, commands);
99490
99491         if ( commands.length > 0
99492                 && _.last(commands).name == constant.CMD_ALERT
99493                 && _.last(commands).data == constant.STATUS_NEXT_MESSAGE )
99494             // todo: should i add a "final" here?...
99495             // commands.push(state.makeCommand({name: constant.CMD_FINAL}));
99496             return cb(null, commands);
99497
99498         var createDevInfoCommands = function(commands, cb) {
99499             // todo: this flag is crap. instead, the local devInfo should have
99500             //       a record of which sessionID lead to the recording, and
99501             //       base it on that. maybe timestamp too... (but it must be
99502             //       in the minutes, just in case...)
99503             session.info.gotinfo = true;
99504             if ( ! session.discover )
99505             {
99506                 commands.push(state.makeCommand({
99507                     name       : constant.CMD_PUT,
99508                     cmdID      : session.nextCmdID(),
99509                     type       : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec,
99510                     source     : './' + constant.URI_DEVINFO_1_2,
99511                     data       : session.adapter.devInfo.toSyncML(constant.SYNCML_DTD_VERSION_1_2,
99512                         _.values(session.adapter._stores))
99513                 }));
99514             }
99515             commands.push(state.makeCommand({
99516                 name     : constant.CMD_GET,
99517                 cmdID    : session.nextCmdID(),
99518                 type     : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec,
99519                 target   : './' + constant.URI_DEVINFO_1_2
99520             }));
99521             return cb(null, commands);
99522         };
99523
99524         var createCommands = function(commands, cb) {
99525             // request the remote device info if not currently available or
99526             // in discover mode or explicitly re-exchanging it (paranoid mode)
99527             var putget = false;
99528             if ( !! session.discover )
99529             {
99530                 return createDevInfoCommands(commands, cb);
99531             }
99532             if ( ! session.peer.devInfo )
99533             {
99534                 var uaEvent = {session: session};
99535                 return session.ua.acceptDevInfoSwap(uaEvent, function(err) {
99536                     if ( err )
99537                 {
99538                     return cb(err);
99539                 }
99540                 return createDevInfoCommands(commands, cb);
99541                 });
99542             }
99543             if ( ! session.context.config.trustDevInfo && ! session.info.gotinfo )
99544             {
99545                 return createDevInfoCommands(commands, cb);
99546             }
99547             // NOTE: in the current handling of "trustDevInfo", i am doing a
99548             //       potentially unnecessary extra request/response phase to
99549             //       confirm that the devInfo has not changed... i *could*
99550             //       issue the put/get as well as the alert, *assuming* that
99551             //       no devInfo is going to change...
99552             return session.context.synchronizer.actions(session, commands, cb);
99553         };
99554
99555         return createCommands(commands, function(err, commands) {
99556             if ( err )
99557             return cb(err);
99558         //Hack: Memotoo service need to send alert command at the beging
99559         var args, tmp;
99560         args = db.retrieveObject("syncml-alert-args");
99561         tmp = {
99562             name       : constant.CMD_ALERT,
99563                cmdID      : session.nextCmdID(),
99564                data       : args.data,
99565                source     : args.source,
99566                target     : args.target,
99567                maxObjSize : "4000000"
99568         };
99569         if (args.lastAnchor) {
99570             tmp.lastAnchor = args.lastAnchor;
99571         }
99572
99573         if (args.nextAnchor) {
99574             tmp.nextAnchor = args.nextAnchor;
99575         }
99576         _firstflag = db.retrieveObject("syncml-first-flag");
99577         if( !_firstflag) {
99578             commands.push(state.makeCommand(tmp));
99579             db.saveObject("syncml-first-flag", true);
99580         }
99581         commands.push(state.makeCommand({name: constant.CMD_FINAL}));
99582         cb(null, commands);
99583         });
99584     },
99585
99586     //-------------------------------------------------------------------------
99587     // NOTE: `produce` is equivalent to the `pysyncml.protocol.commands2tree`...
99588     // Consumes state.Command commands and converts them to an ET protocol tree
99589     produce: function(session, commands, cb) {
99590
99591         if ( commands.length <= 0 )
99592             return cb('protocol.produce received empty commands');
99593
99594         var hdrcmd = commands[0];
99595         commands = _.rest(commands, 1);
99596
99597         if ( hdrcmd.name != constant.CMD_SYNCHDR )
99598             return cb('unexpected first command "' + hdrcmd.name + '"');
99599
99600         if ( hdrcmd.version != constant.SYNCML_VERSION_1_2 )
99601             return cb('unsupported SyncML version "' + hdrcmd.version + '"');
99602
99603         var xsync = ET.Element(constant.NODE_SYNCML);
99604         var xhdr  = ET.SubElement(xsync, hdrcmd.name);
99605         if ( hdrcmd.version == constant.SYNCML_VERSION_1_2 )
99606         {
99607             ET.SubElement(xhdr, 'VerDTD').text = constant.SYNCML_DTD_VERSION_1_2;
99608             ET.SubElement(xhdr, 'VerProto').text = hdrcmd.version;
99609         }
99610
99611         ET.SubElement(xhdr, 'SessionID').text = hdrcmd.sessionID;
99612         ET.SubElement(xhdr, 'MsgID').text = hdrcmd.msgID;
99613         var xsrc = ET.SubElement(xhdr, 'Source');
99614         ET.SubElement(xsrc, 'LocURI').text = hdrcmd.source;
99615         if ( hdrcmd.sourceName )
99616             ET.SubElement(xsrc, 'LocName').text = hdrcmd.sourceName;
99617         var xtgt = ET.SubElement(xhdr, 'Target');
99618         ET.SubElement(xtgt, 'LocURI').text = hdrcmd.target;
99619         if ( hdrcmd.targetName )
99620             ET.SubElement(xtgt, 'LocName').text = hdrcmd.targetName;
99621         if ( hdrcmd.respUri )
99622             ET.SubElement(xhdr, 'RespURI').text = hdrcmd.respUri;
99623
99624         if ( hdrcmd.auth && ! session.info.authAccepted )
99625         {
99626             // TODO: implement other auth schemes...
99627             if ( hdrcmd.auth != constant.NAMESPACE_AUTH_BASIC )
99628                 return cb('auth method "' + hdrcmd.auth + '" not implemented');
99629
99630             if ( hdrcmd.auth == constant.NAMESPACE_AUTH_BASIC )
99631             {
99632                 var xcred = ET.SubElement(xhdr, 'Cred');
99633                 var xmeta = ET.SubElement(xcred, 'Meta');
99634                 ET.SubElement(xmeta, 'Format', {'xmlns': constant.NAMESPACE_METINF}).text = 'b64';
99635                 ET.SubElement(xmeta, 'Type', {'xmlns': constant.NAMESPACE_METINF}).text   = hdrcmd.auth;
99636                 ET.SubElement(xcred, 'Data').text = base64.encode(
99637                         ( session.auth ? session.auth.username : session.peer.username )
99638                         + ':' + ( session.auth ? session.auth.password : session.peer.password ) );
99639             }
99640
99641         }
99642         if ( hdrcmd.maxMsgSize || hdrcmd.maxObjSize )
99643         {
99644             var xmeta = ET.SubElement(xhdr, 'Meta');
99645             if ( hdrcmd.maxMsgSize )
99646                 ET.SubElement(xmeta, 'MaxMsgSize',
99647                         {'xmlns': constant.NAMESPACE_METINF}).text = hdrcmd.maxMsgSize;
99648             if ( hdrcmd.maxObjSize )
99649                 ET.SubElement(xmeta, 'MaxObjSize',
99650                         {'xmlns': constant.NAMESPACE_METINF}).text = hdrcmd.maxObjSize;
99651         }
99652
99653         var xbody = ET.SubElement(xsync, constant.NODE_SYNCBODY);
99654
99655         for ( var idx=0 ; idx<commands.length ; idx++ )
99656         {
99657             var cmd  = commands[idx];
99658             var xcmd = ET.SubElement(xbody, cmd.name);
99659             if ( cmd.cmdID != undefined )
99660                 ET.SubElement(xcmd, 'CmdID').text = cmd.cmdID;
99661             var func = this['_produce_cmd_' + cmd.name.toLowerCase()];
99662             if ( ! func )
99663                 return cb(new common.InternalError('unexpected command "' + cmd.name + '"'));
99664             try{
99665                 func.call(this, session, cmd, xcmd);
99666             }catch(e){
99667                 return cb(new common.InternalError(
99668                             'failed invoking protocol sub-production of "' + cmd.name + '": ' + e, e));
99669             }
99670             if ( cmd.name == constant.CMD_FINAL && idx + 1 != commands.length )
99671                 return cb('command "' + cmd.name + '" not at end of commands');
99672         }
99673
99674         cb(null, xsync);
99675     },
99676
99677     //-------------------------------------------------------------------------
99678     _produce_cmd_alert: function(session, cmd, xcmd) {
99679         ET.SubElement(xcmd, 'Data').text = cmd.data;
99680         var xitem = ET.SubElement(xcmd, 'Item');
99681         ET.SubElement(ET.SubElement(xitem, 'Source'), 'LocURI').text = cmd.source;
99682         ET.SubElement(ET.SubElement(xitem, 'Target'), 'LocURI').text = cmd.target;
99683         if ( cmd.lastAnchor || cmd.nextAnchor || cmd.maxObjSize )
99684         {
99685             var xmeta = ET.SubElement(xitem, 'Meta');
99686             var xanch = ET.SubElement(xmeta, 'Anchor', {'xmlns': constant.NAMESPACE_METINF});
99687             if ( cmd.lastAnchor )
99688                 ET.SubElement(xanch, 'Last').text = cmd.lastAnchor;
99689             if ( cmd.nextAnchor )
99690                 ET.SubElement(xanch, 'Next').text = cmd.nextAnchor;
99691             if ( cmd.maxObjSize )
99692                 ET.SubElement(xmeta, 'MaxObjSize',
99693                         {'xmlns': constant.NAMESPACE_METINF}).text = cmd.maxObjSize;
99694         }
99695     },
99696
99697     //-------------------------------------------------------------------------
99698     _produce_cmd_status: function(session, cmd, xcmd) {
99699         ET.SubElement(xcmd, 'MsgRef').text    = '' + cmd.msgRef;
99700         ET.SubElement(xcmd, 'CmdRef').text    = '' + cmd.cmdRef;
99701         ET.SubElement(xcmd, 'Cmd').text       = cmd.statusOf;
99702         if ( cmd.sourceRef )
99703             ET.SubElement(xcmd, 'SourceRef').text = cmd.sourceRef;
99704         if ( cmd.targetRef )
99705             ET.SubElement(xcmd, 'TargetRef').text = cmd.targetRef;
99706         ET.SubElement(xcmd, 'Data').text      = cmd.statusCode;
99707         var xitem = null;
99708         var xdata = null;
99709         if ( cmd.nextAnchor || cmd.lastAnchor )
99710         {
99711             xitem = ET.SubElement(xcmd, 'Item');
99712             xdata = ET.SubElement(xitem, 'Data');
99713             var xanch = ET.SubElement(xdata, 'Anchor', {'xmlns': constant.NAMESPACE_METINF});
99714             if ( cmd.lastAnchor )
99715                 ET.SubElement(xanch, 'Last').text = cmd.lastAnchor;
99716             if ( cmd.nextAnchor )
99717                 ET.SubElement(xanch, 'Next').text = cmd.nextAnchor;
99718         }
99719         // NOTE: this is NOT standard SyncML...
99720         if ( cmd.errorCode || cmd.errorMsg )
99721         {
99722             xitem = xitem || ET.SubElement(xcmd, 'Item');
99723             xdata = xdata || ET.SubElement(xitem, 'Data');
99724             var xerr = ET.SubElement(xitem, 'Error');
99725             xdata.text = cmd.errorMsg;
99726             if ( cmd.errorCode )
99727                 ET.SubElement(xerr, 'Code').text = cmd.errorCode;
99728             if ( cmd.errorMsg )
99729                 ET.SubElement(xerr, 'Message').text = cmd.errorMsg;
99730             if ( session.context.config.exposeErrorTrace && cmd.errorTrace )
99731                 ET.SubElement(xerr, 'Trace').text = cmd.errorTrace;
99732         }
99733     },
99734
99735     //-------------------------------------------------------------------------
99736     _produce_cmd_get: function(session, cmd, xcmd) {
99737         ET.SubElement(ET.SubElement(xcmd, 'Meta'), 'Type',
99738                 {'xmlns': constant.NAMESPACE_METINF}).text = cmd.type;
99739         if ( cmd.source || cmd.target || cmd.data )
99740         {
99741             var xitem = ET.SubElement(xcmd, 'Item');
99742             if ( cmd.source )
99743             {
99744                 var xsrc = ET.SubElement(xitem, 'Source');
99745                 ET.SubElement(xsrc, 'LocURI').text  = cmd.source;
99746                 ET.SubElement(xsrc, 'LocName').text = cmd.source;
99747             }
99748             if ( cmd.target )
99749             {
99750                 var xtgt = ET.SubElement(xitem, 'Target');
99751                 ET.SubElement(xtgt, 'LocURI').text  = cmd.target;
99752                 ET.SubElement(xtgt, 'LocName').text = cmd.target;
99753             }
99754             if ( cmd.data )
99755             {
99756                 if ( _.isString(cmd.data) )
99757                     ET.SubElement(xitem, 'Data').text = cmd.data;
99758                 else
99759                     // assuming here that it is an ElementTree object...
99760                     ET.SubElement(xitem, 'Data').append(cmd.data);
99761             }
99762         }
99763     },
99764
99765     //-------------------------------------------------------------------------
99766     _produce_cmd_put: function(session, cmd, xcmd) {
99767         return this._produce_cmd_get(session, cmd, xcmd);
99768     },
99769
99770     //-------------------------------------------------------------------------
99771     _produce_cmd_results: function(session, cmd, xcmd) {
99772         ET.SubElement(xcmd, 'MsgRef').text    = cmd.msgRef;
99773         ET.SubElement(xcmd, 'CmdRef').text    = cmd.cmdRef;
99774         ET.SubElement(ET.SubElement(xcmd, 'Meta'), 'Type',
99775                 {'xmlns': constant.NAMESPACE_METINF}).text = cmd.type;
99776         var xitem = ET.SubElement(xcmd, 'Item');
99777         var xsrc  = ET.SubElement(xitem, 'Source');
99778         ET.SubElement(xsrc, 'LocURI').text  = cmd.source;
99779         ET.SubElement(xsrc, 'LocName').text = cmd.source;
99780         if ( cmd.data )
99781         {
99782             if ( _.isString(cmd.data) )
99783                 ET.SubElement(xitem, 'Data').text = cmd.data;
99784             else
99785                 // assuming here that it is an ElementTree object...
99786                 ET.SubElement(xitem, 'Data').append(cmd.data);
99787         }
99788     },
99789
99790     //-------------------------------------------------------------------------
99791     _produce_cmd_sync: function(session, cmd, xcmd) {
99792         ET.SubElement(ET.SubElement(xcmd, 'Source'), 'LocURI').text = cmd.source;
99793         ET.SubElement(ET.SubElement(xcmd, 'Target'), 'LocURI').text = cmd.target;
99794         if ( cmd.noc != undefined )
99795             ET.SubElement(xcmd, 'NumberOfChanges').text = '' + cmd.noc;
99796         if ( ! cmd.data )
99797             return;
99798         for ( var idx=0 ; idx<cmd.data.length ; idx++ )
99799         {
99800             var scmd = cmd.data[idx];
99801             var xscmd = ET.SubElement(xcmd, scmd.name);
99802             if ( scmd.cmdID )
99803                 ET.SubElement(xscmd, 'CmdID').text = scmd.cmdID;
99804             if ( scmd.type
99805                     || ( scmd.format && scmd.format != constant.FORMAT_AUTO ) )
99806             {
99807                 var xsmeta = ET.SubElement(xscmd, 'Meta')
99808                     // todo: implement auto encoding determination...
99809                     //       (the current implementation just lets XML encoding
99810                     //       do it, which is for most things good enough, but
99811                     //       not so good for sequences that need a large amount
99812                     //       of escaping such as binary data...)
99813                     if ( scmd.format && scmd.format != constant.FORMAT_AUTO )
99814                         ET.SubElement(xsmeta, 'Format',
99815                                 {'xmlns': constant.NAMESPACE_METINF}).text = scmd.format;
99816                 if ( scmd.type )
99817                     ET.SubElement(xsmeta, 'Type',
99818                             {'xmlns': constant.NAMESPACE_METINF}).text = scmd.type;
99819             }
99820             var xsitem = ET.SubElement(xscmd, 'Item');
99821             if ( scmd.source )
99822                 ET.SubElement(ET.SubElement(xsitem, 'Source'),
99823                         'LocURI').text = scmd.source;
99824             if ( scmd.sourceParent )
99825                 ET.SubElement(ET.SubElement(xsitem, 'SourceParent'),
99826                         'LocURI').text = scmd.sourceParent;
99827             if ( scmd.target )
99828                 ET.SubElement(ET.SubElement(xsitem, 'Target'),
99829                         'LocURI').text = scmd.target;
99830             if ( scmd.targetParent )
99831                 ET.SubElement(ET.SubElement(xsitem, 'TargetParent'),
99832                         'LocURI').text = scmd.targetParent;
99833             if ( scmd.data )
99834             {
99835                 if ( _.isString(scmd.data) )
99836                     ET.SubElement(xsitem, 'Data').text = scmd.data;
99837                 else
99838                     // assuming here that it is an ElementTree object...
99839                     ET.SubElement(xsitem, 'Data')._node.appendChild(scmd.data);
99840             }
99841         }
99842     },
99843
99844     //-------------------------------------------------------------------------
99845     _produce_cmd_map: function(session, cmd, xcmd) {
99846         ET.SubElement(ET.SubElement(xcmd, 'Source'), 'LocURI').text = cmd.source;
99847         ET.SubElement(ET.SubElement(xcmd, 'Target'), 'LocURI').text = cmd.target;
99848         if ( cmd.sourceItem || cmd.targetItem )
99849         {
99850             var xitem = ET.SubElement(xcmd, constant.CMD_MAPITEM);
99851             if ( cmd.sourceItem )
99852                 ET.SubElement(ET.SubElement(xitem, 'Source'), 'LocURI').text = cmd.sourceItem;
99853             if ( cmd.targetItem )
99854                 ET.SubElement(ET.SubElement(xitem, 'Target'), 'LocURI').text = cmd.targetItem;
99855         }
99856     },
99857
99858     //-------------------------------------------------------------------------
99859     _produce_cmd_final: function(session, cmd, xcmd) {
99860         return;
99861     },
99862
99863     //-------------------------------------------------------------------------
99864     // NOTE: `consume` is equivalent to the `pysyncml.protocol.tree2commands`...
99865     // consume: function...
99866     consume: function(session, lastcmds, xsync, cb) {
99867
99868         // do some preliminary sanity checks...
99869         // todo: do i really want to be returning an error instead of
99870         // generating an error response?...
99871
99872         if ( xsync.tag != constant.NODE_SYNCML
99873                 || xsync.getchildren().length != 2
99874                 || xsync.getchildren()[0].tag != constant.CMD_SYNCHDR
99875                 || xsync.getchildren()[1].tag != constant.NODE_SYNCBODY
99876            )
99877         {
99878             return cb('unexpected SyncML document structure');
99879         }
99880
99881         var version = xsync.getchildren()[0].findtext('VerProto');
99882         if ( version != constant.SYNCML_VERSION_1_2 )
99883             return cb('unsupported SyncML version "' + version + '"');
99884
99885         var verdtd = xsync.getchildren()[0].findtext('VerDTD');
99886         if ( verdtd != constant.SYNCML_DTD_VERSION_1_2 )
99887             return cb('unsupported SyncML DTD version "' + verdtd + '"');
99888
99889         var self = this;
99890
99891         self.initialize(session, xsync, function(err, cmds) {
99892             var hdrcmd = ( cmds && cmds.length > 0 ) ? cmds[0] : null;
99893             var makeErrorCommands = function(err, cb) {
99894
99895                 if ( err.exception )
99896
99897             if ( ! session.isServer )
99898             return cb(err);
99899
99900         var errcmd = state.makeCommand({
99901             name       : constant.CMD_STATUS,
99902             cmdID      : '1',
99903             msgRef     : session.info.pendingMsgID,
99904             cmdRef     : 0,
99905             sourceRef  : xsync.getchildren()[0].findtext('Source/LocURI'),
99906             targetRef  : xsync.getchildren()[0].findtext('Target/LocURI'),
99907             statusOf   : constant.CMD_SYNCHDR,
99908             statusCode : constant.STATUS_COMMAND_FAILED,
99909             errorMsg   : 'an error occurred during processing'
99910         });
99911
99912         // TODO: make this configurable as to whether or not any error
99913         //       is sent back to the peer as a SyncML "standardized" error
99914         //       status...
99915
99916         // TODO: make sure this is doing what is expected/intended...
99917         if ( err.code || err.name )
99918             errcmd.errorCode  = 'syncml-js.' + ( err.code || err.name );
99919         errcmd.errorMsg   = err.message || common.j(err) || '' + err;
99920
99921         return cb(null, [hdrcmd, errcmd,
99922                 state.makeCommand({name: constant.CMD_FINAL})]);
99923             };
99924
99925             if ( err )
99926                 return makeErrorCommands(err, cb);
99927
99928             try {
99929                 self._consume(session, lastcmds, xsync, cmds, function(err, commands) {
99930                     if ( err )
99931                     return makeErrorCommands(err, cb);
99932                 return cb(null, commands);
99933                 });
99934             } catch ( exc ) {
99935                 return makeErrorCommands(exc, cb);
99936             }
99937
99938         });
99939     },
99940
99941     //-------------------------------------------------------------------------
99942     _consume: function(session, lastcmds, xsync, commands, cb) {
99943
99944         var self       = this;
99945         var hdrcmd     = commands[0];
99946         var statusCode = constant.STATUS_OK;
99947
99948         // analyze the SyncHdr
99949         var children = xsync.getchildren()[0].getchildren();
99950         for ( var idx=0 ; idx<children.length ; idx++ )
99951         {
99952             var child = children[idx];
99953
99954
99955             if ( child.tag == 'VerDTD' )
99956             {
99957                 if ( hdrcmd.version == constant.SYNCML_VERSION_1_2 )
99958                 {
99959                     if ( child.text != constant.SYNCML_DTD_VERSION_1_2 )
99960                         return cb(new common.ProtocolError('bad VerDTD "' + child.text + '"'));
99961                 }
99962                 else
99963                     return cb(new common.FeatureNotSupported(
99964                                 'unsupported internal SyncML version "' + hdrcmd.version + '"'));
99965                 continue;
99966             }
99967
99968             if ( child.tag == 'VerProto' )
99969                 // this was checked earlier...
99970                 continue;
99971
99972             if ( child.tag == 'SessionID' )
99973             {
99974                 if ( child.text != hdrcmd.sessionID )
99975                     return cb(new common.ProtocolError(
99976                                 'session ID mismatch: "' + child.text + '" != "' + hdrcmd.sessionID + '"'));
99977                 continue;
99978             }
99979
99980             if ( child.tag == 'MsgID' )
99981             {
99982                 var chkmsg = ( session.isServer ? hdrcmd.msgID : lastcmds[0].msgID );
99983                 if ( child.text != chkmsg )
99984                     return cb(new common.ProtocolError(
99985                                 'message ID mismatch: "' + child.text + '" != "' + chkmsg + '"'));
99986                 continue;
99987             }
99988
99989             if ( child.tag == 'Target' )
99990             {
99991                 var uri = child.findtext('LocURI');
99992
99993                 // TODO... server-side...
99994
99995                 if ( uri != hdrcmd.source )
99996                     return cb(new common.ProtocolError(
99997                                 'incoming target mismatch: "' + uri + '" != "' + hdrcmd.source + '"'));
99998                 continue;
99999             }
100000
100001             if ( child.tag == 'Source' )
100002             {
100003                 var uri = child.findtext('LocURI');
100004                 if ( uri != hdrcmd.target && uri != lastcmds[0].target )
100005                     return cb(new common.ProtocolError(
100006                                 'incoming source mismatch: "' + uri + '" != "' + hdrcmd.target + '"'));
100007                 continue;
100008             }
100009
100010             if ( child.tag == 'RespURI' )
100011             {
100012                 // hdrcmd.target = child.text
100013                 // session.info.respUri = child.text
100014                 if ( ! session.isServer )
100015                     session.info.respUri = child.text;
100016                 continue;
100017             }
100018
100019             if ( child.tag == 'Cred' )
100020             {
100021                 // the responsibility is on the calling framework to ensure this is
100022                 // checked long before we get here... ie. Adapter.authorize(...)
100023                 // or via the Adapter.handleRequest() `authorize` parameter...
100024                 statusCode = constant.STATUS_AUTHENTICATION_ACCEPTED;
100025                 continue;
100026             }
100027
100028             if ( child.tag == 'Meta' )
100029             {
100030                 // this should already have been consumed during the protocol.initialize() call
100031                 continue;
100032             }
100033
100034             return cb(new common.ProtocolError('unexpected header node "' + child.tag + '"'));
100035         };
100036
100037         commands.push(state.makeCommand({
100038             name       : constant.CMD_STATUS,
100039             cmdID      : session.nextCmdID(),
100040             msgRef     : session.info.pendingMsgID,
100041             cmdRef     : 0,
100042             sourceRef  : xsync.getchildren()[0].findtext('Source/LocURI'),
100043             targetRef  : xsync.getchildren()[0].findtext('Target/LocURI'),
100044             statusOf   : constant.CMD_SYNCHDR,
100045             statusCode : statusCode
100046         }));
100047
100048         // and now evaluate the SyncBody
100049
100050         var chkcmds = _.filter(lastcmds, function(e) {
100051             return e.name != constant.CMD_STATUS && e.name != constant.CMD_FINAL;
100052         });
100053
100054         // for each "sync" command, search for sub-commands
100055         // todo: should this be generalized to search for any sub-commands?...
100056         _.each(chkcmds, function(e) {
100057             if ( e.name != constant.CMD_SYNC || ! e.data || e.data.length <= 0 )
100058             return;
100059         _.each(e.data, function(sub) { chkcmds.push(sub); });
100060         });
100061
100062         var children = xsync.getchildren()[1].getchildren();
100063
100064         // first, check all the 'Status' commands
100065
100066         var consumeStatus = function(cb) {
100067
100068             common.cascade(children, function(child, cb) {
100069
100070                 if ( child.tag != constant.CMD_STATUS )
100071                 return cb();
100072
100073             cname = child.findtext('Cmd');
100074
100075             var blen   = chkcmds.length;
100076             var chkcmd = null;
100077             var chkerr = null;
100078
100079             chkcmds = _.filter(chkcmds, function(cmd) {
100080                 if ( chkerr )
100081                 return;
100082             if ( cmd.cmdID != child.findtext('CmdRef')
100083                 || cmd.name != cname
100084                 || lastcmds[0].msgID != child.findtext('MsgRef') )
100085                 return true;
100086             if ( chkcmd )
100087                 chkerr = new Error('unexpected error: multiple check commands match status command');
100088             chkcmd = cmd;
100089             return false;
100090             });
100091
100092             if ( chkerr )
100093                 return cb(chkerr);
100094
100095             if ( chkcmds.length >= blen )
100096                 return cb(new common.ProtocolError(
100097                             'unexpected status node "s' + session.info.id + '.m' + child.findtext('MsgRef')
100098                             + '.c' + child.findtext('CmdRef') + ' cmd=' + cname + '"'));
100099
100100             // TODO: check for unknown elements (and complain?)...
100101
100102             var code = common.int(child.findtext('Data'));
100103
100104             if ( code == constant.STATUS_MISSING_CREDENTIALS )
100105             {
100106                 var authtype = child.findtext('Chal/Meta/Type');
100107                 var attrs = {auth: {type: authtype}};
100108                 return cb(badStatus(child, common.CredentialsRequired, attrs));
100109             }
100110
100111             if ( code == constant.STATUS_INVALID_CREDENTIALS )
100112             {
100113                 // TODO: get the auth type... from where??...
100114                 var authtype = child.findtext('Chal/Meta/Type');
100115                 var attrs = {auth: {type: authtype}};
100116                 return cb(badStatus(child, common.InvalidCredentials, attrs));
100117             }
100118
100119             var targetRef = child.findtext('TargetRef');
100120             if ( targetRef )
100121             {
100122                 // note: doing a normUri on chkcmd.target because it could be "./devinf12"...
100123                 if ( session.peer.normUri(targetRef) != session.peer.normUri(chkcmd.target) )
100124                     return cb(new common.ProtocolError('unexpected target-ref "'
100125                                 + targetRef + '" != "' + chkcmd.target
100126                                 + '" for command "' + cname + '"'));
100127             }
100128
100129             var sourceRef = child.findtext('SourceRef');
100130             if ( sourceRef )
100131             {
100132                 // note: doing a normUri on chkcmd.source because it could be "./devinf12"...
100133                 if ( cname == constant.CMD_SYNCHDR )
100134                 {
100135                     // this is a little odd, but syncevolution strips the sessionid path
100136                     // parameter off for some reason, so compensating here...
100137                     if ( _.indexOf([session.adapter.normUri(chkcmd.source),
100138                                 session.info.effectiveID,
100139                                 session.info.returnUrl],
100140                                 session.adapter.normUri(sourceRef)) < 0
100141                             && session.adapter.normUri(chkcmd.source).indexOf(session.adapter.normUri(sourceRef)) != 0 )
100142                         return cb(new common.ProtocolError('unexpected source-ref "'
100143                                     + sourceRef + '" != "' + chkcmd.source
100144                                     + '" for command "' + cname + '"'));
100145                 }
100146                 else
100147                 {
100148                     if ( session.adapter.normUri(sourceRef) != session.adapter.normUri(chkcmd.source) )
100149                         return cb(new common.ProtocolError('unexpected source-ref "'
100150                                     + sourceRef + '" != "' + chkcmd.source
100151                                     + '" for command "' + cname + '"'));
100152                 }
100153             }
100154
100155             // todo: any other common elements?...
100156
100157             switch ( cname )
100158             {
100159
100160                 case constant.CMD_SYNCHDR:
100161                     {
100162                         if ( code != constant.STATUS_OK && code != constant.STATUS_AUTHENTICATION_ACCEPTED )
100163                             return cb(badStatus(child));
100164                         if ( code == constant.STATUS_AUTHENTICATION_ACCEPTED )
100165                         {
100166                             // TODO: there is currently nothing that can "reset" the
100167                             //       authAccepted flag...  there should be a trap such
100168                             //       that if an auth fails, then authAccepted gets set
100169                             //       to false.
100170                             session.info.authAccepted = true;
100171                         }
100172                         return cb();
100173                     }
100174
100175                 case constant.CMD_ALERT:
100176                     {
100177                         if ( code == constant.STATUS_OK )
100178                             // TODO: do something with the Item/Data/Anchor/Next?...
100179                             return cb();
100180                         if ( code == constant.STATUS_REFRESH_REQUIRED && ! session.isServer )
100181                         {
100182                             // TODO: support the ability for the UA to control which kind of
100183                             //       refresh to do (slow-sync, client-refresh, server-refresh)
100184                             return cb();
100185                         }
100186                         return cb(badStatus(child));
100187                     }
100188
100189                 case constant.CMD_GET:
100190                     {
100191                         if ( code != constant.STATUS_OK )
100192                             return cb(badStatus(child));
100193                         return cb();
100194                     }
100195
100196                 case constant.CMD_PUT:
100197                     {
100198                         if ( code != constant.STATUS_OK )
100199                             return cb(badStatus(child));
100200                         return cb();
100201                     }
100202
100203                 case constant.CMD_RESULTS:
100204                     {
100205                         if ( code != constant.STATUS_OK )
100206                             return cb(badStatus(child));
100207                         return cb();
100208                     }
100209
100210                 case constant.CMD_SYNC:
100211                     {
100212                         // todo: should this be moved into the synchronizer as a "settle" event?...
100213                         var ds = session.info.dsstates[session.adapter.normUri(chkcmd.source)]
100214                             if ( code != constant.STATUS_OK )
100215                             {
100216                                 // check for server-side errors...
100217                                 if ( code >= 500 && code < 600 && child.findtext('Item/Data') )
100218                                 {
100219                                     ds.action = 'error';
100220                                     ds.error  = getError(child);
100221                                     ds.stats.peerErr += 1;
100222                                     return cb();
100223                                 }
100224                                 return cb(badStatus(child));
100225                             }
100226                         if ( ds.action == 'send' )
100227                         {
100228                             if ( session.isServer )
100229                             {
100230                                 ds.action = 'save';
100231                                 return cb();
100232                             }
100233                             ds.action = common.oneWayOut(session, ds.mode) ? 'done' : 'recv';
100234                             return cb();
100235                         }
100236                         return cb(new common.ProtocolError('unexpected sync state for action=' + ds.action));
100237                     }
100238
100239                 case constant.CMD_ADD:
100240                 case constant.CMD_REPLACE:
100241                 case constant.CMD_DELETE:
100242                     {
100243                         var scmd = state.makeCommand({
100244                             name       : cname,
100245                             msgID      : hdrcmd.msgID,
100246                             cmdID      : child.findtext('CmdID'),
100247                             sourceRef  : sourceRef,
100248                             targetRef  : targetRef,
100249                             data       : code
100250                         });
100251
100252                         session.context.synchronizer.settle(
100253                                 session, scmd, chkcmd, child,
100254                                 function(err, cmds) {
100255                                     if ( err )
100256                             return cb(err);
100257                         _.each(cmds, function(cmd) { commands.push(cmd); });
100258                         return cb();
100259                                 });
100260                         return;
100261                     }
100262
100263                 case constant.CMD_MAP:
100264                     {
100265                         if ( session.isServer )
100266                             return cb(new common.ProtocolError(
100267                                         'unexpected server-side status for command "' + cname + '"'));
100268                         if ( code != constant.STATUS_OK )
100269                             return cb(badStatus(child));
100270                         return cb();
100271                     }
100272
100273                 default:
100274                     {
100275                         return cb(new common.ProtocolError('unexpected status for command "' + cname + '"'));
100276                     }
100277
100278             }
100279
100280             }, cb);
100281
100282         };
100283
100284         // second, check all the non-'Status' commands
100285
100286         var consumeCommands = function(cb) {
100287
100288             var gotFinal = false;
100289
100290             common.cascade(children, function(child, cb) {
100291
100292
100293                 if ( child.tag == constant.CMD_STATUS )
100294                 return cb();
100295
100296             if ( child.tag == constant.CMD_FINAL )
100297             {
100298                 gotFinal = true;
100299                 return cb();
100300             }
100301
100302
100303             // todo: restrict this to the following commands?...
100304             //         CMD_ALERT, CMD_GET, CMD_PUT,
100305             //         CMD_SYNC, CMD_RESULTS, CMD_MAP
100306
100307             var func = self['_consume_node_' + child.tag.toLowerCase()];
100308
100309             if ( ! func )
100310                 return cb(new common.ProtocolError('unexpected command node "' + child.tag + '"'));
100311
100312             try{
100313
100314                 func.call(self, session, lastcmds, xsync, child, function(err, cmds) {
100315                     if ( err )
100316                     return cb(err);
100317                 _.each(cmds, function(cmd) { commands.push(cmd); });
100318                 return cb();
100319                 });
100320
100321             }catch(e){
100322                 // log.error('failed invoking protocol sub-consumption of "%s": %s', child.tag, e);
100323                 // log.error('  ' + stacktrace({e: e}).join('\n  '));
100324                 return cb(new common.InternalError(
100325                             'failed invoking protocol sub-consumption of "' + child.tag + '": ' + e, e));
100326             }
100327
100328             }, function(err) {
100329
100330                 if ( err )
100331                     return cb(err);
100332
100333                 if ( ! gotFinal )
100334                 {
100335                     commands.push(state.makeCommand({
100336                         name       : constant.CMD_ALERT,
100337                         cmdID      : session.nextCmdID(),
100338                         data       : constant.STATUS_NEXT_MESSAGE,
100339                         source     : session.adapter.devID,
100340                         target     : session.peer.devID,
100341                     }));
100342                 }
100343
100344                 return cb();
100345
100346             });
100347
100348         };
100349
100350         // do it!
100351
100352         consumeStatus(function(err) {
100353
100354             if ( err )
100355             return cb(err);
100356
100357         // TODO: is this right?... or should i be getting pissed off and
100358         //       raising hell that all my commands were not addressed?...
100359
100360         _.each(chkcmds, function(chkcmd) {
100361             commands.push(chkcmd);
100362         });
100363
100364         return consumeCommands(function(err) {
100365             if ( err )
100366             return cb(err);
100367         return cb(null, commands);
100368         });
100369
100370         });
100371
100372     },
100373
100374     //-------------------------------------------------------------------------
100375     _consume_node_get: function(session, lastcmds, xsync, xnode, cb) {
100376         var cttype = xnode.findtext('Meta/Type');
100377         var target = xnode.findtext('Item/Target/LocURI');
100378         if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0
100379                 && session.adapter.normUri(target) == constant.URI_DEVINFO_1_2 )
100380             return this._consume_node_get_devinf12(session, lastcmds, xsync, xnode, cb);
100381         // todo: make error status node...
100382         cb(new common.ProtocolError(
100383                     'unexpected "' + constant.CMD_GET + '" command for local "' + target + '"'));
100384     },
100385
100386     //-------------------------------------------------------------------------
100387     _consume_node_get_devinf12: function(session, lastcmds, xsync, xnode, cb) {
100388         var ret = [];
100389         ret.push(state.makeCommand({
100390             name       : constant.CMD_STATUS,
100391             cmdID      : session.nextCmdID(),
100392             msgRef     : session.info.pendingMsgID,
100393             cmdRef     : xnode.findtext('CmdID'),
100394             statusOf   : xnode.tag,
100395             statusCode : constant.STATUS_OK,
100396             targetRef  : xnode.findtext('Item/Target/LocURI')
100397         }));
100398         ret.push(state.makeCommand({
100399             name       : constant.CMD_RESULTS,
100400             cmdID      : session.nextCmdID(),
100401             msgRef     : session.info.pendingMsgID,
100402             cmdRef     : xnode.findtext('CmdID'),
100403             type       : constant.TYPE_SYNCML_DEVICE_INFO + '+' + session.info.codec,
100404             source     : './' + constant.URI_DEVINFO_1_2,
100405             data       : session.adapter.devInfo.toSyncML(constant.SYNCML_DTD_VERSION_1_2,
100406                 _.values(session.adapter._stores))
100407
100408         }));
100409         cb(null, ret);
100410     },
100411
100412     //-------------------------------------------------------------------------
100413     _consume_node_put: function(session, lastcmds, xsync, xnode, cb) {
100414         var cttype = xnode.findtext('Meta/Type');
100415         var source = xnode.findtext('Item/Source/LocURI');
100416         if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0
100417                 && session.peer.normUri(source) == constant.URI_DEVINFO_1_2 )
100418             return this._consume_node_put_devinf12(session, lastcmds, xsync, xnode, cb);
100419         // todo: make error status node...
100420         cb(new common.ProtocolError(
100421                     'unexpected "' + constant.CMD_PUT + '" command for remote "' + source + '"'));
100422     },
100423
100424     //-------------------------------------------------------------------------
100425     _consume_node_put_devinf12: function(session, lastcmds, xsync, xnode, cb) {
100426         var xdev = xnode.find('Item/Data/DevInf');
100427         var res  = devinfo.DevInfo.fromSyncML(xdev);
100428         session.peer._setRemoteInfo(res[0], res[1], function(err) {
100429             if ( err )
100430             return cb(err);
100431
100432         var okcmd = state.makeCommand({
100433             name       : constant.CMD_STATUS,
100434             cmdID      : session.nextCmdID(),
100435             msgRef     : xsync.findtext('SyncHdr/MsgID'),
100436             cmdRef     : xnode.findtext('CmdID'),
100437             sourceRef  : xnode.findtext('Item/Source/LocURI'),
100438             statusOf   : xnode.tag,
100439             statusCode : constant.STATUS_OK
100440         });
100441
100442         if ( session.isServer )
100443             return cb(null, [okcmd]);
100444
100445         // TODO: this should only cause a `recalculate` if any
100446         //       meta-information actually changed...
100447
100448         session.context.router.recalculate(session.adapter, session.peer, function(err) {
100449             if ( err )
100450             return cb(err);
100451         session.context.synchronizer.initStoreSync(session, function(err) {
100452             if ( err )
100453             return cb(err);
100454
100455         // TODO: the call to _setRemoteInfo makes the peer
100456         //       "dirty" without saving changes to the model...
100457         //       make sure the `save` executed in Adapter.sync()
100458         //       or Adapter.handleRequest() appropriately causes
100459         //       objects to save themselves to the model...
100460
100461         // session.adapter._save(session.txn(), function(err) {
100462         //   if ( err )
100463         //     return cb(err);
100464
100465         return cb(null, [okcmd]);
100466
100467         // });
100468
100469         });
100470         });
100471         });
100472     },
100473
100474     //-------------------------------------------------------------------------
100475     _consume_node_results: function(session, lastcmds, xsync, xnode, cb) {
100476         var cttype = xnode.findtext('Meta/Type');
100477         var source = xnode.findtext('Item/Source/LocURI');
100478         if ( cttype.indexOf(constant.TYPE_SYNCML_DEVICE_INFO) == 0
100479                 && session.peer.normUri(source) == constant.URI_DEVINFO_1_2 )
100480             return this._consume_node_put_devinf12(session, lastcmds, xsync, xnode, cb);
100481         // todo: make error status node...
100482         return cb(new common.ProtocolError('unexpected "' + constant.CMD_RESULTS
100483                     + '" command for remote "' + source + '"'))
100484     },
100485
100486     //-------------------------------------------------------------------------
100487     _consume_node_alert: function(session, lastcmds, xsync, xnode, cb) {
100488         var code = common.int(xnode.findtext('Data'));
100489         var statusCode = constant.STATUS_OK
100490             switch ( code )
100491             {
100492                 case constant.ALERT_TWO_WAY:
100493                 case constant.ALERT_SLOW_SYNC:
100494                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
100495                 case constant.ALERT_REFRESH_FROM_CLIENT:
100496                 case constant.ALERT_ONE_WAY_FROM_SERVER:
100497                 case constant.ALERT_REFRESH_FROM_SERVER:
100498                     // todo: these should only be received out-of-band: right?...
100499                     // case constant.ALERT_TWO_WAY_BY_SERVER:
100500                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
100501                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
100502                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
100503                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
100504                     {
100505                         break;
100506                     }
100507                 default:
100508                     {
100509                         if ( session.isServer && code == constant.STATUS_RESUME )
100510                         {
100511                             code = constant.ALERT_SLOW_SYNC;
100512                         }
100513                         else
100514                         {
100515                             return cb(new common.FeatureNotSupported(
100516                                         'unimplemented sync mode '
100517                                         + code + ' ("' + common.mode2string(code) + '")'));
100518                         }
100519                     }
100520             }
100521
100522         if ( session.isServer )
100523         {
100524             // TODO: if this is the server, we need to validate that the requested
100525             //       sync mode is actually feasible... i.e. check:
100526             //         - do the anchors match?
100527             //         - have we bound the datastores together?
100528             //         - is there a pending sync?
100529         }
100530
100531         var uri  = session.adapter.normUri(xnode.findtext('Item/Target/LocURI'));
100532         var ruri = session.peer.normUri(xnode.findtext('Item/Source/LocURI'));
100533
100534         // TODO: this should really be done by the synchronizer... as it can
100535         //       then also do a lot of checks - potentially responding with
100536         //       an error...
100537
100538         var getDS = function(cb) {
100539             if ( session.isServer )
100540             {
100541                 var ds = session.info.dsstates[uri];
100542                 if ( ds )
100543                 {
100544                     ds.action = 'alert';
100545                     return cb(null, ds);
100546                 }
100547
100548                 var peerStore = session.peer.getStore(ruri);
100549                 if ( ! peerStore )
100550                     return cb(new common.ProtocolError(
100551                                 'request to synchronize unknown remote client URI "' + ruri
100552                                 + '" (to local server URI "' + uri + '")'));
100553
100554                 // todo: if already correctly bound, then we don't need to re-bind
100555                 // if ( peerStore._getBinding() )
100556                 // {
100557                 //   log.critical('(currently bound)');
100558                 // }
100559                 // else
100560                 //   log.critical('(currently unbound)');
100561
100562                 session.peer.setRoute(uri, ruri, true, function(err) {
100563                     if ( err )
100564                     return cb(err);
100565                 var peerStore = session.peer.getStore(ruri);
100566                 var ds = state.makeStoreSyncState({
100567                     uri        : uri,
100568                     peerUri    : ruri,
100569                     lastAnchor : peerStore._getBinding().localAnchor,
100570                     mode       : null,
100571                     action     : 'alert'
100572                 });
100573                 session.info.dsstates[uri] = ds;
100574                 return cb(null, ds);
100575                 });
100576                 return;
100577             }
100578             else
100579             {
100580                 var ds = session.info.dsstates[uri];
100581                 if ( ! ds )
100582                     return cb(new common.ProtocolError('request for unreflected local datastore "'
100583                                 + uri + '"'));
100584                 ds.action = 'send';
100585                 if ( code == ds.mode )
100586                     return cb(null, ds);
100587
100588                 var uaEvent = {
100589                     session   : session,
100590                     uri       : uri,
100591                     peerUri   : ruri,
100592                     modeReq   : ds.mode,
100593                     modeRes   : code
100594                 };
100595                 session.ua.acceptSyncModeSwitch(uaEvent, function(err) {
100596                     if ( err )
100597                 {
100598                     return cb(err);
100599                 }
100600                 if ( session.context.listener )
100601                     session.context.listener(uaEvent);
100602                 return cb(null, ds);
100603                 });
100604             }
100605         };
100606
100607
100608         getDS(function(err, ds) {
100609
100610             if ( err )
100611             return cb(err);
100612
100613         ds.mode = code;
100614         ds.peerLastAnchor = xnode.findtext('Item/Meta/Anchor/Last', null);
100615         ds.peerNextAnchor = xnode.findtext('Item/Meta/Anchor/Next', null);
100616
100617         if ( ds.peerLastAnchor != session.peer.getStore(ruri)._getBinding().remoteAnchor )
100618         {
100619             ds.peerLastAnchor = null;
100620             switch ( ds.mode )
100621         {
100622             case constant.ALERT_SLOW_SYNC:
100623             case constant.ALERT_REFRESH_FROM_CLIENT:
100624             case constant.ALERT_REFRESH_FROM_SERVER:
100625                 {
100626                     break;
100627                 }
100628             default:
100629                 {
100630                     if ( session.isServer )
100631                     {
100632                         ds.mode = constant.ALERT_SLOW_SYNC;
100633                         statusCode = constant.STATUS_REFRESH_REQUIRED;
100634                     }
100635                     else
100636                     {
100637                         // todo: should i assume that the server knows something
100638                         //       that i don't and just go along with it?...
100639                         return cb(new common.ProtocolError(
100640                                     'server-side requested inappropriate ' + common.mode2string(ds.mode)
100641                                     + ' sync mode on unbound datastore "' + uri + '"'));
100642                     }
100643                 }
100644         }
100645         }
100646
100647         return cb(null, [state.makeCommand({
100648             name       : constant.CMD_STATUS,
100649                cmdID      : session.nextCmdID(),
100650                msgRef     : xsync.findtext('SyncHdr/MsgID'),
100651                cmdRef     : xnode.findtext('CmdID'),
100652                targetRef  : xnode.findtext('Item/Target/LocURI'),
100653                sourceRef  : xnode.findtext('Item/Source/LocURI'),
100654                statusOf   : xnode.tag,
100655                statusCode : statusCode,
100656                // todo: syncevolution does not echo the remote last anchor... why not?
100657                lastAnchor : ds.peerLastAnchor,
100658                nextAnchor : ds.peerNextAnchor
100659         })]);
100660
100661         });
100662
100663     },
100664
100665     //-------------------------------------------------------------------------
100666     _consume_node_sync: function(session, lastcmds, xsync, xnode, cb) {
100667         var self   = this;
100668         var uri    = xnode.findtext('Target/LocURI');
100669         var store  = session.adapter.getStore(session.adapter.normUri(uri));
100670         var ds     = session.info.dsstates[session.adapter.normUri(uri)];
100671         var commands = [state.makeCommand({
100672             name        : constant.CMD_SYNC,
100673             msgID       : xsync.findtext('SyncHdr/MsgID'),
100674             cmdID       : xnode.findtext('CmdID'),
100675             source      : xnode.findtext('Source/LocURI'),
100676             target      : uri,
100677             data        : [],
100678         })];
100679         var noc = common.int(xnode.findtext('NumberOfChanges'));
100680         if (noc !== undefined) {
100681             changednum = noc;
100682             _counts = 0;
100683         }
100684         common.cascade(xnode.getchildren(), function(child, cb) {
100685             switch ( child.tag )
100686         {
100687             case 'CmdID':
100688             case 'Target':
100689             case 'Source':
100690             case 'NumberOfChanges':
100691                 {
100692                     return cb();
100693                 }
100694             case constant.CMD_ADD:
100695             case constant.CMD_REPLACE:
100696             case constant.CMD_DELETE:
100697                 {
100698                     var func = self['_consume_sync_' + child.tag.toLowerCase()];
100699                     func.call(self, session, lastcmds, store, xsync, child, function(err, cmds) {
100700                         if ( err )
100701                         return cb(err);
100702                     _.each(cmds, function(cmd) { commands[0].data.push(cmd); });
100703                     return cb();
100704                     });
100705                     return;
100706                 }
100707             default:
100708                 {
100709                     return cb(new common.ProtocolError('unexpected sync command "' + child.tag + '"'));
100710                 }
100711         }
100712         }, function(err) {
100713             if ( err )
100714                 return cb(err);
100715             // confirm that i received the right number of changes...
100716             /*
100717                if ( noc != undefined && noc != commands[0].data.length )
100718                return cb(new common.ProtocolError('number-of-changes mismatch (received '
100719                + commands[0].data.length + ', expected '
100720                + noc + ')'));
100721                */
100722             _counts =  _counts + commands[0].data.length;
100723             if ( ds.action != 'error' )
100724             {
100725                 if ( ! session.isServer )
100726                 {
100727                     if ( ds.action != 'recv' )
100728                         return cb(new common.ProtocolError('unexpected sync state for URI "'
100729                                     + uri + '": action=' + ds.action));
100730                     if (changednum != undefined && changednum <= _counts)  {
100731                         ds.action = 'done';
100732                         changednum = undefined;
100733                         _counts = 0;
100734                     }
100735                 }
100736                 else
100737                 {
100738                     if ( ds.action != 'alert' )
100739                         return cb(new common.ProtocolError(
100740                                     'unexpected sync state for URI "' + uri + '": action=' + ds.action));
100741                     ds.action = common.oneWayIn(session, ds.mode) ? 'save' : 'send';
100742                 }
100743             }
100744             return session.context.synchronizer.reactions(session, commands, cb);
100745         });
100746     },
100747
100748     //-------------------------------------------------------------------------
100749     _consume_xnode2item: function(session, lastcmds, store, xsync, xnode, cb) {
100750         var ctype  = xnode.findtext('Meta/Type');
100751         // todo: can the version be specified in the Meta tag?... maybe create an
100752         //       extension to SyncML to communicate this?...
100753         var ctver  = null;
100754         var format = xnode.findtext('Meta/Format');
100755         var xitem  = xnode.findall('Item/Data');
100756         if ( xitem.length > 1 )
100757             return cb(new common.ProtocolError(
100758                         '"' + xnode.tag + '" command with non-singular item data nodes'));
100759         if ( xitem.length < 1 )
100760             return cb(new common.ProtocolError(
100761                         '"' + xnode.tag + '" command with missing data node'));
100762         var xitem = xitem[0];
100763         // todo: confirm that getchildren only returns element nodes...
100764         if ( xitem.getchildren().length == 1 )
100765             data = xitem.getchildren()[0];
100766         else
100767         {
100768             data = xitem.text;
100769             if ( format == constant.FORMAT_B64 )
100770                 data = base64.decode(data);
100771         }
100772         return store.agent.loadsItem(data, ctype, ctver, cb);
100773     },
100774
100775     //-------------------------------------------------------------------------
100776     _consume_sync_add: function(session, lastcmds, store, xsync, xnode, cb) {
100777         this._consume_xnode2item(session, lastcmds, store, xsync, xnode, function(err, item) {
100778             if ( err )
100779             return cb(err);
100780         return cb(null, [state.makeCommand({
100781             name          : constant.CMD_ADD,
100782                msgID         : xsync.findtext('SyncHdr/MsgID'),
100783                cmdID         : xnode.findtext('CmdID'),
100784                source        : xnode.findtext('Item/Source/LocURI'),
100785                sourceParent  : xnode.findtext('Item/SourceParent/LocURI'),
100786                targetParent  : xnode.findtext('Item/TargetParent/LocURI'),
100787                data          : item
100788         })]);
100789         });
100790     },
100791
100792     //-------------------------------------------------------------------------
100793     _consume_sync_replace: function(session, lastcmds, store, xsync, xnode, cb) {
100794         this._consume_xnode2item(session, lastcmds, store, xsync, xnode, function(err, item) {
100795             if ( err )
100796             return cb(err);
100797         return cb(null, [state.makeCommand({
100798             name          : constant.CMD_REPLACE,
100799                msgID         : xsync.findtext('SyncHdr/MsgID'),
100800                cmdID         : xnode.findtext('CmdID'),
100801                source        : xnode.findtext('Item/Source/LocURI'),
100802                sourceParent  : xnode.findtext('Item/SourceParent/LocURI'),
100803                target        : xnode.findtext('Item/Target/LocURI'),
100804                targetParent  : xnode.findtext('Item/TargetParent/LocURI'),
100805                data          : item
100806         })]);
100807         });
100808     },
100809
100810     //-------------------------------------------------------------------------
100811     _consume_sync_delete: function(session, lastcmds, store, xsync, xnode, cb) {
100812         return cb(null, [state.makeCommand({
100813             name          : constant.CMD_DELETE,
100814         msgID         : xsync.findtext('SyncHdr/MsgID'),
100815         cmdID         : xnode.findtext('CmdID'),
100816         source        : xnode.findtext('Item/Source/LocURI'),
100817         sourceParent  : xnode.findtext('Item/SourceParent/LocURI'),
100818         target        : xnode.findtext('Item/Target/LocURI'),
100819         targetParent  : xnode.findtext('Item/TargetParent/LocURI')
100820         })]);
100821     },
100822
100823     // #----------------------------------------------------------------------------
100824     // def makeStatus(self, session, xsync, xnode, status=constant.STATUS_OK, **kw):
100825     //   return state.Command(
100826     //     name       = constant.CMD_STATUS,
100827     //     cmdID      = session.nextCmdID(),
100828     //     msgRef     = xsync.findtext('SyncHdr/MsgID'),
100829     //     cmdRef     = xnode.findtext('CmdID'),
100830     //     statusOf   = xnode.tag,
100831     //     statusCode = status,
100832     //     **kw
100833     //     )
100834
100835     //-------------------------------------------------------------------------
100836     _consume_node_map: function(session, lastcmds, xsync, xnode, cb) {
100837         if ( ! session.isServer )
100838             return cb(new common.ProtocolError(
100839                         'unexpected "Map" command received by client-side SyncML peer'));
100840         // TODO: convert the sender-side to support command.items like
100841         //       this as well...
100842         var cmd = state.makeCommand({
100843             name    : constant.CMD_MAP,
100844             msgID   : xsync.findtext('SyncHdr/MsgID'),
100845             cmdID   : xnode.findtext('CmdID'),
100846             source  : xnode.findtext('Source/LocURI'),
100847             target  : xnode.findtext('Target/LocURI'),
100848             items   : []
100849         });
100850         _.each(xnode.findall('MapItem'), function(xnode) {
100851             // todo: support hierarchical sync...
100852             cmd.items.push({
100853                 source        : xnode.findtext('Source/LocURI'),
100854                 // sourceParent  : xnode.findtext('SourceParent/LocURI'),
100855                 target        : xnode.findtext('Target/LocURI'),
100856                 // targetParent  : xnode.findtext('TargetParent/LocURI')
100857             });
100858         });
100859         return session.context.synchronizer.reactions(session, [cmd], cb);
100860     }
100861
100862
100863 });
100864
100865 return exports;
100866
100867 })();
100868
100869 module.exports = _self;
100870
100871 });
100872 define('ripple/platform/tizen/2.0/syncml-js-lib/router', function (require, exports, module) {
100873 // -*- coding: utf-8 -*-
100874 //-----------------------------------------------------------------------------
100875 // file: $Id$
100876 // lib:  syncml-js.router
100877 // auth: griffin <griffin@uberdev.org>
100878 // date: 2012/11/04
100879 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
100880 //-----------------------------------------------------------------------------
100881
100882 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
100883     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
100884     ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'),
100885     matcher = require('ripple/platform/tizen/2.0/syncml-js-lib/matcher'),
100886     stablematch = require('ripple/platform/tizen/2.0/syncml-js-lib/stablematch'),
100887     _self;
100888
100889 _self = (function () {
100890
100891     var exports = {};
100892
100893     //---------------------------------------------------------------------------
100894     exports.Router = common.Base.extend({
100895
100896         //-------------------------------------------------------------------------
100897         constructor: function(options) {
100898         },
100899
100900         //-------------------------------------------------------------------------
100901         getTargetUri: function(adapter, peer, sourceUri) {
100902             var pmodel = peer._getModel();
100903             for ( var idx=0 ; idx<pmodel.routes.length ; idx++ )
100904     {
100905         var route = pmodel.routes[idx];
100906         if ( route.localUri == sourceUri )
100907         return route.remoteUri;
100908     }
100909     for ( var idx=0 ; idx<pmodel.stores.length ; idx++ )
100910     {
100911         var store = pmodel.stores[idx];
100912         if ( store.binding && store.binding.uri == sourceUri )
100913         return store.uri;
100914     }
100915     return null;
100916         },
100917
100918         //-------------------------------------------------------------------------
100919         recalculate: function(adapter, peer, cb) {
100920             // the non-"SmartRouter" only connects manually-configured routes...
100921             var routes = _.filter(peer._getModel().routes,
100922                     function(r) { return ! r.autoMapped; });
100923             return this._setupRoutes(adapter, peer, routes, cb);
100924         },
100925
100926         //-------------------------------------------------------------------------
100927         _setupRoutes: function(adapter, peer, routes, cb) {
100928             // available local URIs
100929             var lset = _.map(adapter._getModel().stores,
100930                     function(s) { return adapter.normUri(s.uri); });
100931             // available remote URIs
100932             var rset = _.map(peer._getModel().stores,
100933                     function(s) { return peer.normUri(s.uri); });
100934
100935             // break all routes not listed
100936             var ruris = _.map(routes, function(r) { return r.remoteUri; });
100937             var xrset = _.filter(rset, function(uri) {
100938                 return _.indexOf(ruris, uri) < 0;
100939             });
100940             _.each(xrset, function(uri) {
100941                 var smodel = peer.getStore(uri)._getModel();
100942                 if ( ! smodel.binding )
100943                 return;
100944             smodel.binding = null;
100945             });
100946
100947             var err = null;
100948             _.each(routes, function(route) {
100949                 if ( err )
100950                 return;
100951
100952             route.localUri  = adapter.normUri(route.localUri);
100953             route.remoteUri = peer.normUri(route.remoteUri);
100954             if ( _.indexOf(rset, route.remoteUri) < 0
100955                 || _.indexOf(lset, route.localUri) < 0 )
100956             {
100957                 err = 'unable to route from "' + route.localUri
100958                 + '" (here) to "' + route.remoteUri
100959                 + '" (peer): no such stores or already routed elsewhere';
100960             return;
100961             }
100962
100963             lset = _.filter(lset, function(uri) { return uri != route.localUri; });
100964             rset = _.filter(rset, function(uri) { return uri != route.remoteUri; });
100965
100966
100967             var smodel = peer.getStore(route.remoteUri)._getModel();
100968             if ( smodel.binding && smodel.binding.uri == route.localUri )
100969                 return;
100970             smodel.binding = {
100971                 uri          : route.localUri,
100972                 autoMapped   : route.autoMapped,
100973                 localAnchor  : null,
100974                 remoteAnchor : null
100975             };
100976             });
100977
100978             if ( err )
100979                 return cb(err);
100980
100981             return cb();
100982         },
100983
100984         //-------------------------------------------------------------------------
100985         getBestTransmitContentType: function(adapter, peer, uri) {
100986             var lstore = adapter.getStore(uri);
100987             var rstore = peer.getStore(this.getTargetUri(adapter, peer, uri));
100988             return matcher.pickTransmitContentType(lstore, rstore);
100989         },
100990
100991     });
100992
100993     //---------------------------------------------------------------------------
100994     exports.SmartRouter = exports.Router.extend({
100995
100996         //-------------------------------------------------------------------------
100997         recalculate: function(adapter, peer, cb) {
100998
100999             // note: if you don't want smart routing, assign the non-SmartRouter
101000             //       router (i.e. syncml-js.Router) to the loaded context
101001
101002             // available local URIs
101003             var llut = _.object(
101004                 _.map(adapter._getModel().stores,
101005                     function(s) { return [adapter.normUri(s.uri), s]; }));
101006             var lset = _.keys(llut);
101007
101008             // available remote URIs
101009             var rlut = _.object(
101010                 _.map(peer._getModel().stores,
101011                     function(s) { return [adapter.normUri(s.uri), s]; }));
101012             var rset = _.keys(rlut);
101013
101014             // TODO: i am directly touching the model here.
101015             //       total i-rep violation.
101016             //       i'm embarrassed.
101017             //       fortunately, it's just between syncml-js classes...
101018             //       but now you know, doh! please don't blackmail me!... ;-)
101019
101020             // manual routes
101021             var pmodel = peer._getModel();
101022             pmodel.routes = _.filter(pmodel.routes,
101023                     function(r) { return ! r.autoMapped; });
101024
101025             // remove manual routes from available routes
101026             var uris = _.map(pmodel.routes, function(r) { return r.localUri; });
101027             lset = _.filter(lset, function(uri) {
101028                 return _.indexOf(uris, uri) < 0;
101029             });
101030             uris = _.map(pmodel.routes, function(r) { return r.remoteUri; });
101031             rset = _.filter(rset, function(uri) {
101032                 return _.indexOf(uris, uri) < 0;
101033             });
101034
101035             // match remaining stores
101036             var rankL = function(luri) {
101037                 var ret = _.rest(rset, 0);
101038                 ret.sort(function(a, b) {
101039                     return matcher.cmpStore(llut[luri], rlut[a], rlut[b]);
101040                 });
101041                 return ret;
101042             };
101043             var rankR = function(ruri) {
101044                 var ret = _.rest(lset, 0);
101045                 ret.sort(function(a, b) {
101046                     return matcher.cmpStore(rlut[ruri], llut[a], llut[b]);
101047                 });
101048                 return ret;
101049             };
101050             var matches = stablematch.match(lset, rset, rankL, rankR);
101051
101052             // add them to the routes (as auto-routed)
101053             for ( var idx=0 ; idx<matches.length ; idx++ )
101054             {
101055                 var pair = matches[idx];
101056                 pmodel.routes.push({
101057                     localUri   : pair[0],
101058                     remoteUri  : pair[1],
101059                     autoMapped : true
101060                 });
101061             }
101062
101063             return this._setupRoutes(adapter, peer, pmodel.routes, cb);
101064         },
101065
101066     });
101067
101068     return exports;
101069
101070 })();
101071
101072 module.exports = _self;
101073
101074 });
101075 define('ripple/platform/tizen/2.0/syncml-js-lib/codec', function (require, exports, module) {
101076 // -*- coding: utf-8 -*-
101077 //-----------------------------------------------------------------------------
101078 // file: $Id$
101079 // auth: metagriffin <metagriffin@uberdev.org>
101080 // date: 2012/10/13
101081 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
101082 //-----------------------------------------------------------------------------
101083
101084 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
101085     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
101086     _self;
101087
101088 _self = (function () {
101089
101090     var exports = {};
101091
101092     //---------------------------------------------------------------------------
101093     exports.Codec = common.Base.extend({
101094
101095         encode: function(xtree, cb) {
101096             throw new common.NotImplementedError();
101097         },
101098
101099         decode: function(contentType, data, cb) {
101100             throw new common.NotImplementedError();
101101         },
101102     }, {
101103
101104         factory: function(codec) {
101105             // todo: should this be converted to callback-based?...
101106             if ( codec == constant.CODEC_XML )
101107         return new exports.XmlCodec()
101108         // TODO
101109         // if ( codec == constant.CODEC_WBXML )
101110         //   return exports.WbxmlCodec()
101111         throw new common.UnknownCodec('unknown or unimplemented codec "' + codec + '"')
101112         },
101113
101114             autoEncode: function(xtree, codecName, cb) {
101115                 exports.Codec.factory(codecName).encode(xtree, cb);
101116             },
101117
101118             autoDecode: function(contentType, data, cb) {
101119                 if ( contentType.indexOf(constant.TYPE_SYNCML + '+') != 0 )
101120                     return cb('unknown or unimplemented content type "' + contentType + '"');
101121                 var ct = contentType.slice((constant.TYPE_SYNCML + '+').length).split(';')[0];
101122                 exports.Codec.factory(ct).decode(contentType, data, function(err, tree) {
101123                     if ( err )
101124                     return cb(err);
101125                 return cb(null, tree, ct);
101126                 });
101127             },
101128     });
101129
101130     //---------------------------------------------------------------------------
101131     exports.XmlCodec = exports.Codec.extend({
101132
101133         name: constant.CODEC_XML,
101134
101135         encode: function(xtree, cb) {
101136             // todo: really enforce this charset...
101137             var ctype = constant.TYPE_SYNCML + '+' + this.name + '; charset=UTF-8';
101138             var ret = ET.tostring(xtree);
101139             if ( ret.charAt(0) == '<' && ret.charAt(1) == '?' )
101140     {
101141         var idx = ret.indexOf('?>');
101142         if ( idx >= 0 )
101143         ret = ret.substr(0, idx + 2).replace(/'/g, '"') + ret.substr(idx + 2);
101144     }
101145     cb(null, ctype, ret);
101146         },
101147
101148         decode: function(contentType, data, cb) {
101149             var expCT = constant.TYPE_SYNCML + '+' + this.name;
101150             if ( contentType.indexOf(expCT) != 0 )
101151         cb(new common.ProtocolError(
101152                 'received unexpected content-type "' + contentType + '" (expected "'
101153                     + expCT + '")'));
101154             try
101155             {
101156                 return cb(null, ET.parse(data).getroot());
101157             }
101158             catch(e)
101159             {
101160                 return cb(new common.ProtocolError('could not parse XML: ' + e, e));
101161             }
101162         }
101163
101164     });
101165
101166     //---------------------------------------------------------------------------
101167     // TODO: implement wbxml...
101168     // exports.WbXmlCodec = exports.Codec.extend({
101169     //   encode: function(xtree, cb) {
101170     //   },
101171     //   decode: function(contentType, data, cb) {
101172     //   }
101173     // });
101174
101175     return exports;
101176
101177 })();
101178
101179 module.exports = _self;
101180
101181 });
101182 define('ripple/platform/tizen/2.0/syncml-js-lib/stablematch', function (require, exports, module) {
101183 // -*- coding: utf-8 -*-
101184 //-----------------------------------------------------------------------------
101185 // file: $Id$
101186 // desc: implements a solution to the stable matching problem using a
101187 //       left-optimized algorithm. shamelessly adapted from:
101188 //         https://github.com/paulgb/Python-Gale-Shapley/
101189 // auth: metagriffin <mg.npmjs@uberdev.org>
101190 // date: 2012/12/29
101191 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
101192 //-----------------------------------------------------------------------------
101193
101194 var _self = (function () {
101195
101196     var exports = {};
101197
101198     // TODO: figure out how to pull this dynamically from package.json...
101199     exports.version = '0.0.4';
101200
101201     //---------------------------------------------------------------------------
101202     exports.match = function(A, B, rankA, rankB) {
101203         if ( ! A || ! B || ! A.length || ! B.length ) {
101204             return [];
101205         }
101206         if ( A.length == B.length ) {
101207             return exports._match(A, B, rankA, rankB);
101208         }
101209
101210         // TODO: this is a brute-force implementation of getting both
101211         //       lists to be of symmetric length... make this "better".
101212         //       for example, build this directly into _match() or use
101213         //       deterministic exclusion of the longer data set.
101214
101215         var sA   = _.rest(A, 0);
101216         var sB   = _.rest(B, 0);
101217         var mlen = Math.max(sA, sB);
101218         while ( sA.length < mlen )
101219             sA.push(null);
101220         while ( sB.length < mlen )
101221             sB.push(null);
101222         var sRA  = function(a) {
101223             var ret = rankA(a);
101224             while ( ret.length < mlen )
101225                 ret.push(null);
101226             return ret;
101227         };
101228         var sRB  = function(b) {
101229             var ret = rankB(b);
101230             while ( ret.length < mlen )
101231                 ret.push(null);
101232             return ret;
101233         };
101234         var ret = exports._match(sA, sB, sRA, sRB);
101235         return _.filter(ret, function(pair) {
101236             return pair[0] != null && pair[1] != null;
101237         });
101238     };
101239
101240     //---------------------------------------------------------------------------
101241     exports._match = function(A, B, rankA, rankB) {
101242         // this translates sets A and B to indeces, since _imatch can only work
101243         // with sets of elements that can be used as the key in a hash (in this
101244         // implementation).
101245         var iA  = _.range(A.length);
101246         var iB  = _.range(B.length);
101247         var iRA = function(ia) {
101248             var ret = rankA(A[ia]);
101249             return _.map(ret, function(item) {
101250                 return _.indexOf(B, item);
101251             });
101252         };
101253         var iRB = function(ib) {
101254             var ret = rankB(B[ib]);
101255             return _.map(ret, function(item) {
101256                 return _.indexOf(A, item);
101257             });
101258         };
101259         var ret = exports._imatch(iA, iB, iRA, iRB);
101260         return _.map(ret, function(item) {
101261             return [A[item[0]], B[item[1]]];
101262         });
101263     };
101264
101265     //---------------------------------------------------------------------------
101266     exports._imatch = function(A, B, rankA, rankB) {
101267         // TODO: improve this... it was a brute-force porting of
101268         //         https://github.com/paulgb/Python-Gale-Shapley
101269         //       without any eye on optimal outcome or performance...
101270         //: `partners` is a paring hash of { a => [b, rank] }
101271         var partners = {};
101272         _.each(A, function(a) {
101273             partners[a] = [rankA(a)[0], 0];
101274         });
101275         //: `stable` indicates stability of the current pairing in `partners`
101276         var stable = false;
101277         while ( ! stable )
101278         {
101279             stable = true;
101280             _.each(B, function(b) {
101281                 var paired = false;
101282                 for ( var n=0 ; n<A.length ; n++ )
101283                 {
101284                     var a = rankB(b)[n];
101285                     var pair = partners[a];
101286                     if ( pair[0] == b )
101287                     {
101288                         if ( paired )
101289                         {
101290                             stable = false;
101291                             partners[a] = [rankA(a)[pair[1] + 1], pair[1] + 1];
101292                         }
101293                         else
101294                             paired = true;
101295                     }
101296                 }
101297             });
101298         }
101299         return _.map(_.keys(partners), function(a) {
101300             return [a, partners[a][0]];
101301         });
101302     };
101303
101304     return exports;
101305 })();
101306
101307 module.exports = _self;
101308
101309 });
101310 define('ripple/platform/tizen/2.0/syncml-js-lib/common', function (require, exports, module) {
101311 // -*- coding: utf-8 -*-
101312 //-----------------------------------------------------------------------------
101313 // file: $Id$
101314 // auth: metagriffin <metagriffin@uberdev.org>
101315 // date: 2012/10/13
101316 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
101317 //-----------------------------------------------------------------------------
101318
101319 var constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
101320     _self;
101321
101322 _self = (function () {
101323     var exports = {};
101324
101325     //---------------------------------------------------------------------------
101326     // object inheritance helper routines shamelessly scrubbed from backbone.js
101327
101328     // The self-propagating extend function that Backbone classes use.
101329     var extend = exports.extend = function (protoProps, classProps) {
101330         var child = inherits(this, protoProps, classProps);
101331         child.extend = this.extend;
101332         return child;
101333     };
101334
101335     // Shared empty constructor function to aid in prototype-chain creation.
101336     var ctor = function(){};
101337
101338     // Helper function to correctly set up the prototype chain, for subclasses.
101339     // Similar to `goog.inherits`, but uses a hash of prototype properties and
101340     // class properties to be extended.
101341     var inherits = function(parent, protoProps, staticProps) {
101342         var child;
101343
101344         // The constructor function for the new subclass is either defined by you
101345         // (the "constructor" property in your `extend` definition), or defaulted
101346         // by us to simply call the parent's constructor.
101347         if (protoProps && protoProps.hasOwnProperty('constructor')) {
101348             child = protoProps.constructor;
101349         } else {
101350             child = function(){ parent.apply(this, arguments); };
101351         }
101352
101353         // Inherit class (static) properties from parent.
101354         _.extend(child, parent);
101355
101356         // Set the prototype chain to inherit from `parent`, without calling
101357         // `parent`'s constructor function.
101358         ctor.prototype = parent.prototype;
101359         child.prototype = new ctor();
101360
101361         // Add prototype properties (instance properties) to the subclass,
101362         // if supplied.
101363         if (protoProps) _.extend(child.prototype, protoProps);
101364
101365         // Add static properties to the constructor function, if supplied.
101366         if (staticProps) _.extend(child, staticProps);
101367
101368         // Correctly set child's `prototype.constructor`.
101369         child.prototype.constructor = child;
101370
101371         // Set a convenience property in case the parent's prototype is needed later.
101372         child.__super__ = parent.prototype;
101373
101374         return child;
101375     };
101376
101377     //-----------------------------------------------------------------------------
101378     exports.Base = function() {};
101379     exports.Base.extend = extend;
101380
101381     //-----------------------------------------------------------------------------
101382     var SyncmlError = exports.Base.extend({
101383         constructor: function(msg, exception, attrs) {
101384             this.message = this.name;
101385             if ( msg != undefined )
101386         this.message += ': ' + msg;
101387     this.exception = exception;
101388     if ( attrs )
101389         _.extend(this, attrs);
101390         },
101391         toString: function() {
101392             return this.message;
101393         }
101394     });
101395
101396     //---------------------------------------------------------------------------
101397     exports.Stream = exports.Base.extend({
101398
101399         writeln: function(data) {
101400             if ( data == undefined )
101401         return;
101402     return this.write(data + '\n');
101403         },
101404
101405         indented: function(indent) {
101406             return new exports.IndentStream(this, indent || this._indent);
101407         }
101408
101409     });
101410
101411     _.extend(exports, {
101412
101413         //---------------------------------------------------------------------------
101414         // exceptions
101415         SyncmlError:           SyncmlError.extend({name: 'SyncmlError'}),
101416         TypeError:             SyncmlError.extend({name: 'TypeError'}),
101417         NotImplementedError:   SyncmlError.extend({name: 'NotImplementedError'}),
101418         ProtocolError:         SyncmlError.extend({name: 'ProtocolError'}),
101419         InternalError:         SyncmlError.extend({name: 'InternalError'}),
101420         ConflictError:         SyncmlError.extend({name: 'ConflictError'}),
101421         FeatureNotSupported:   SyncmlError.extend({name: 'FeatureNotSupported'}),
101422         LogicalError:          SyncmlError.extend({name: 'LogicalError'}),
101423         CredentialsRequired:   SyncmlError.extend({name: 'CredentialsRequired'}),
101424         InvalidCredentials:    SyncmlError.extend({name: 'InvalidCredentials'}),
101425         InvalidContext:        SyncmlError.extend({name: 'InvalidContext'}),
101426         InvalidAdapter:        SyncmlError.extend({name: 'InvalidAdapter'}),
101427         InvalidStore:          SyncmlError.extend({name: 'InvalidStore'}),
101428         InvalidContentType:    SyncmlError.extend({name: 'InvalidContentType'}),
101429         InvalidAgent:          SyncmlError.extend({name: 'InvalidAgent'}),
101430         InvalidContent:        SyncmlError.extend({name: 'InvalidContent'}),
101431         InvalidItem:           SyncmlError.extend({name: 'InvalidItem'}),
101432         UnknownCodec:          SyncmlError.extend({name: 'UnknownCodec'}),
101433         NoSuchRoute:           SyncmlError.extend({name: 'NoSuchRoute'}),
101434         UnknownAuthType:       SyncmlError.extend({name: 'UnknownAuthType'}),
101435         UnknownFormatType:     SyncmlError.extend({name: 'UnknownFormatType'}),
101436
101437         //---------------------------------------------------------------------------
101438         // UUID generation
101439         makeID: function() {
101440             // shamelessly scrubbed from:
101441             //   http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
101442             // (adjusted to remove the dashes)
101443             // todo: see some of those links on how to make this more "robust"...
101444             return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
101445                 var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
101446                 return v.toString(16);
101447             });
101448         },
101449
101450         //-------------------------------------------------------------------------
101451         synctype2alert: function(type) {
101452             return constant.SyncTypeToAlert[type];
101453         },
101454
101455         //-------------------------------------------------------------------------
101456         alert2synctype: function(alert) {
101457             for ( var key in constant.SyncTypeToAlert )
101458             {
101459                 if ( constant.SyncTypeToAlert[key] == alert )
101460                     return exports.int(key);
101461             }
101462             return null;
101463         },
101464
101465         //-------------------------------------------------------------------------
101466         mode2string: function(code) {
101467             switch ( code )
101468             {
101469                 case constant.ALERT_TWO_WAY:                       return 'two-way';
101470                 case constant.ALERT_SLOW_SYNC:                     return 'slow-sync';
101471                 case constant.ALERT_ONE_WAY_FROM_CLIENT:           return 'one-way-from-client';
101472                 case constant.ALERT_REFRESH_FROM_CLIENT:           return 'refresh-from-client';
101473                 case constant.ALERT_ONE_WAY_FROM_SERVER:           return 'one-way-from-server';
101474                 case constant.ALERT_REFRESH_FROM_SERVER:           return 'refresh-from-server';
101475                 case constant.ALERT_TWO_WAY_BY_SERVER:             return 'two-way-by-server';
101476                 case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER: return 'one-way-from-client-by-server';
101477                 case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER: return 'refresh-from-client-by-server';
101478                 case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER: return 'one-way-from-server-by-server';
101479                 case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER: return 'refresh-from-server-by-server';
101480                 default: return 'UNKNOWN';
101481             }
101482         },
101483
101484         //-------------------------------------------------------------------------
101485         state2string: function(state) {
101486             switch ( state )
101487             {
101488                 case constant.ITEM_OK:           return 'ok';
101489                 case constant.ITEM_ADDED:        return 'added';
101490                 case constant.ITEM_MODIFIED:     return 'modified';
101491                 case constant.ITEM_DELETED:      return 'deleted';
101492                 case constant.ITEM_SOFTDELETED:  return 'soft-deleted';
101493                 default: return 'UNKNOWN';
101494             }
101495         },
101496
101497         //-------------------------------------------------------------------------
101498         oneWay: function(mode) {
101499             switch ( mode )
101500             {
101501                 case constant.ALERT_TWO_WAY:
101502                 case constant.ALERT_SLOW_SYNC:
101503                     return false;
101504                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
101505                 case constant.ALERT_REFRESH_FROM_CLIENT:
101506                 case constant.ALERT_ONE_WAY_FROM_SERVER:
101507                 case constant.ALERT_REFRESH_FROM_SERVER:
101508                     return true;
101509                     // case constant.ALERT_TWO_WAY_BY_SERVER:
101510                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
101511                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
101512                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
101513                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
101514                 default:
101515                     throw new exports.InternalError('invalid mode "' + mode + '"');
101516             }
101517         },
101518
101519         //-------------------------------------------------------------------------
101520         oneWayIn: function(session, mode) {
101521             switch ( mode )
101522             {
101523                 case constant.ALERT_TWO_WAY:
101524                 case constant.ALERT_SLOW_SYNC:
101525                     return false;
101526                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
101527                 case constant.ALERT_REFRESH_FROM_CLIENT:
101528                     return !! session.isServer;
101529                 case constant.ALERT_ONE_WAY_FROM_SERVER:
101530                 case constant.ALERT_REFRESH_FROM_SERVER:
101531                     return ! session.isServer;
101532                     // case constant.ALERT_TWO_WAY_BY_SERVER:
101533                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
101534                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
101535                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
101536                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
101537                 default:
101538                     throw new exports.InternalError('invalid mode "' + mode + '"');
101539             }
101540         },
101541
101542         //-------------------------------------------------------------------------
101543         oneWayOut: function(session, mode) {
101544             switch ( mode )
101545             {
101546                 case constant.ALERT_TWO_WAY:
101547                 case constant.ALERT_SLOW_SYNC:
101548                     return false;
101549                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
101550                 case constant.ALERT_REFRESH_FROM_CLIENT:
101551                     return ! session.isServer;
101552                 case constant.ALERT_ONE_WAY_FROM_SERVER:
101553                 case constant.ALERT_REFRESH_FROM_SERVER:
101554                     return !! session.isServer;
101555                     // case constant.ALERT_TWO_WAY_BY_SERVER:
101556                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
101557                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
101558                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
101559                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
101560                 default:
101561                     throw new exports.InternalError('invalid mode "' + mode + '"');
101562             }
101563         },
101564
101565         //-------------------------------------------------------------------------
101566         cascade: function(list, iterator, cb) {
101567             if ( ! cb && iterator )
101568             {
101569                 cb = iterator;
101570                 iterator = null;
101571             }
101572             if ( ! list )
101573                 return cb();
101574             var cur = 0;
101575             var next = function() {
101576                 if ( cur >= list.length )
101577                     return cb();
101578                 var curcb = function(err) {
101579                     if ( err )
101580                         return cb(err);
101581                     cur += 1;
101582                     var args = [];
101583                     for ( var idx=1 ; idx<arguments.length ; idx++ )
101584                         args.push(arguments[idx]);
101585                     return next.apply(null, args);
101586                 };
101587                 var func = iterator || list[cur];
101588                 var args = [];
101589                 if ( iterator )
101590                     args.push(list[cur]);
101591                 for ( var idx=0 ; idx<arguments.length ; idx++ )
101592                     args.push(arguments[idx]);
101593                 args.push(curcb);
101594                 return func.apply(null, args);
101595             };
101596             return next();
101597         },
101598
101599         //-------------------------------------------------------------------------
101600         ts: function() {
101601             return Math.floor((new Date()).getTime() / 1000);
101602         },
101603
101604         //-------------------------------------------------------------------------
101605         j: function(obj) {
101606             return JSON.stringify(obj);
101607         },
101608
101609         //-------------------------------------------------------------------------
101610         noop: function(cb) {
101611             return cb();
101612         },
101613
101614         //-------------------------------------------------------------------------
101615         platformBits: function() {
101616
101617             // TODO: implement this!...
101618
101619             return 32;
101620         },
101621
101622         //-------------------------------------------------------------------------
101623         getMaxMemorySize: function(context) {
101624
101625             // Returns the maximum size of a memory object. By default this
101626             // is, set to ``sys.maxint``, however the `context` may override
101627             // this behavior.
101628
101629             // NOTE: currently, this is being hardcoded to a maximum of 2GB for
101630             //       compatibility with funambol servers, which croak above that
101631             //       value.
101632
101633             // TODO: allow the context to control this, or implement auto-detect to
101634             //       determine what the remote peer can support...
101635
101636             return Math.min(Math.pow(2, exports.platformBits() - 1) - 1,
101637                     Math.pow(2, 31) - 1);
101638         },
101639
101640         //-------------------------------------------------------------------------
101641         normpath: function(path) {
101642             if ( path == undefined )
101643                 return null;
101644             if ( path.length <= 0 )
101645                 return '';
101646             if ( path.indexOf('/') < 0 )
101647                 path = path.replace('\\', '/');
101648             var ret = [];
101649             var plist = path.split('/');
101650             for ( var idx=0 ; idx<plist.length ; idx++ )
101651             {
101652                 var item = plist[idx];
101653                 if ( item.length <= 0 || item == '.' )
101654                     continue;
101655                 if ( item != '..' || ret.length <= 0 || ret[ret.length - 1] == '..' )
101656                 {
101657                     ret.push(item);
101658                     continue;
101659                 }
101660                 ret.pop();
101661             }
101662             ret = ret.join('/');
101663             if ( path.charAt(0) != '/' )
101664                 return ret;
101665             return '/' + ret;
101666         },
101667
101668         //-------------------------------------------------------------------------
101669         int: function(str, defval) {
101670             if ( ! str )
101671                 return defval;
101672             return parseInt(str, 10);
101673         },
101674
101675         //-------------------------------------------------------------------------
101676         cmp: function(a, b) {
101677             if ( a < b )
101678                 return -1;
101679             if ( a > b )
101680                 return 1;
101681             return 0;
101682         },
101683
101684         //-------------------------------------------------------------------------
101685         // partially emulates python's string.split() method
101686         splitn: function(str, sep, limit) {
101687             var ret = str.split(sep);
101688             if ( ret.length <= ( limit + 1 ) )
101689                 return ret;
101690             var tmp = ret.slice(0, limit);
101691             tmp.push(ret.slice(limit).join(sep));
101692             return tmp;
101693         },
101694
101695         //-------------------------------------------------------------------------
101696         prettyJson: function(obj, indent) {
101697             indent = indent || '';
101698             var ret = '';
101699             if ( _.isArray(obj) )
101700             {
101701                 if ( obj.length <= 0 )
101702                     return '[]';
101703                 ret = '[\n' + indent;
101704                 _.each(obj, function(el, idx) {
101705                     ret += '  ' + exports.prettyJson(el, indent + '  ');
101706                     if ( idx + 1 < obj.length )
101707                     ret += ',';
101708                 ret += '\n' + indent;
101709                 });
101710                 return ret + ']';
101711             }
101712             if ( _.isObject(obj) )
101713             {
101714                 var keys = _.keys(obj);
101715                 if ( keys.length <= 0 )
101716                     return '{}';
101717                 keys.sort();
101718                 ret = '{\n' + indent;
101719                     _.each(keys, function(key, idx) {
101720                         ret += '  ' + exports.prettyJson(key)
101721                         + ': ' + exports.prettyJson(obj[key], indent + '  ');
101722                     if ( idx + 1 < keys.length )
101723                         ret += ',';
101724                     ret += '\n' + indent;
101725                     });
101726                     return ret + ( indent.length <= 0 ? '}\n' : '}' );
101727             }
101728             return JSON.stringify(obj);
101729         },
101730
101731         //-------------------------------------------------------------------------
101732         urlEncode: function(dat) {
101733             return ( dat == undefined ? dat : encodeURIComponent(dat) );
101734         },
101735
101736         //-------------------------------------------------------------------------
101737         /*
101738            rmfr: function(path, cb) {
101739            fs.stat(path, function(err, stats) {
101740            if ( err && err.code == 'ENOENT' )
101741            return cb();
101742            if ( err )
101743            return cb(err);
101744            if ( ! stats.isDirectory() )
101745            return fs.unlink(path, cb);
101746            fs.readdir(path, function(err, files) {
101747            exports.cascade(files, function(file, cb) {
101748            var curpath = pathmod.join(path, file);
101749            return exports.rmfr(curpath, cb);
101750            }, function(err) {
101751            if ( err )
101752            return cb(err);
101753            fs.rmdir(path, cb);
101754            });
101755            });
101756            });
101757            },
101758            */
101759         //-------------------------------------------------------------------------
101760         /*
101761            makedirs: function(path, cb) {
101762         // node sucks. i can't believe it doesn't provide a fs.makedirs(). wtf.
101763         // clean up the path
101764         path = pathmod.normalize(path.split(/[\\\/]/).join('/'));
101765         var paths = path.split('/');
101766         paths = _.map(paths, function(p, idx) {
101767         return paths.slice(0, idx + 1).join('/');
101768         });
101769         if ( path.charAt(0) == '/' )
101770         paths.shift();
101771         exports.cascade(paths, function(path, cb) {
101772         fs.stat(path, function(err, stats) {
101773         if ( err && err.code == 'ENOENT' )
101774         return fs.mkdir(path, cb);
101775         if ( err )
101776         return cb(err);
101777         if ( stats.isDirectory() )
101778         return cb();
101779         // this probably won't work, but let's get the error anyhow...
101780         return fs.mkdir(path, cb);
101781         });
101782         }, cb);
101783         },
101784         */
101785
101786         //-------------------------------------------------------------------------
101787         StringStream: exports.Stream.extend({
101788
101789             constructor: function(initData) {
101790                 this._data = initData || '';
101791             },
101792
101793         write: function(data) {
101794             if ( data == undefined )
101795             return;
101796         this._data += data;
101797         },
101798
101799         getData: function() {
101800             return this._data;
101801         }
101802
101803         }),
101804
101805         //-------------------------------------------------------------------------
101806         IndentStream: exports.Stream.extend({
101807
101808             //-----------------------------------------------------------------------
101809             constructor: function(stream, indent, options) {
101810                 options = options || {};
101811                 this._stream    = stream;
101812                 this._indent    = indent || '  ';
101813                 this._cleared   = true;
101814                 this._stayBlank = !! options.stayBlank;
101815             },
101816
101817         //-----------------------------------------------------------------------
101818         write: function(data) {
101819             var self = this;
101820             if ( data == undefined )
101821             return;
101822         // if ( ! data || ! data.length || data.length <= 0 )
101823         //   return;
101824         var lines = data.split('\n');
101825         if ( self._cleared )
101826             self._stream.write(self._indent);
101827         self._cleared = false;
101828         for ( var idx=0 ; idx<lines.length ; idx++ )
101829         {
101830             var line = lines[idx];
101831             if ( line == '' )
101832             {
101833                 if ( idx + 1 >= lines.length )
101834                     self._cleared = true;
101835                 else
101836                 {
101837                     if ( idx != 0 && ! self._stayBlank )
101838                         self._stream.write(self._indent);
101839                 }
101840             }
101841             else
101842             {
101843                 if ( idx != 0 || self._cleared )
101844                     self._stream.write(self._indent);
101845                 self._stream.write(line);
101846             }
101847             if ( idx + 1 < lines.length )
101848                 self._stream.write('\n');
101849         }
101850         }
101851
101852         })
101853
101854     });
101855
101856     return exports;
101857 })();
101858
101859 module.exports = _self;
101860
101861 });
101862 define('ripple/platform/tizen/2.0/syncml-js-lib/useragent', function (require, exports, module) {
101863 // -*- coding: utf-8 -*-
101864 //-----------------------------------------------------------------------------
101865 // file: $Id$
101866 // lib:  syncml-js.useragent
101867 // auth: griffin <griffin@uberdev.org>
101868 // date: 2013/06/07
101869 // copy: (C) CopyLoose 2013 UberDev <hardcore@uberdev.org>, No Rights Reserved.
101870 //-----------------------------------------------------------------------------
101871
101872 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
101873     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
101874     _self;
101875
101876 _self = (function () {
101877     var exports = {};
101878
101879     //---------------------------------------------------------------------------
101880     exports.UserAgent = common.Base.extend({
101881         // primary handlers:
101882         acceptSyncModeSwitch:  null, // function(EVENT, CALLBACK(ERR))
101883             acceptDevInfoSwap:     null, // function(EVENT, CALLBACK(ERR))
101884             chooseRefreshRequired: null, // function(EVENT, CALLBACK(ERR, TYPE))
101885             fetchCredentials:      null, // function(EVENT, CALLBACK(ERR, AUTH))
101886             // fallback handlers:
101887             accept:                null, // function(TYPE, EVENT, CALLBACK(ERR))
101888             choose:                null, // function(TYPE, EVENT, CALLBACK(ERR, CHOICE))
101889             fetch:                 null, // function(TYPE, EVENT, CALLBACK(ERR, STRUCT))
101890             // catchall handler:
101891             handle:                null  // function(ACTION, TYPE, EVENT, CALLBACK(ERR, RESULT...))
101892     });
101893
101894     //---------------------------------------------------------------------------
101895     exports.UserAgentMultiplexer = common.Base.extend({
101896
101897         //-------------------------------------------------------------------------
101898         constructor: function(uaList) {
101899             this.ualist = uaList;
101900         },
101901
101902         //-------------------------------------------------------------------------
101903         _getHandler: function(name) {
101904             for ( var idx=0 ; idx<this.ualist.length ; idx++ )
101905     {
101906         var ua = this.ualist[idx];
101907         if ( ua && _.isFunction(ua[name]) )
101908         return ua[name];
101909     }
101910     return null;
101911         },
101912
101913         //-------------------------------------------------------------------------
101914         hasHandler: function(name) {
101915             return !! this._getHandler(name);
101916         },
101917
101918         //-------------------------------------------------------------------------
101919         acceptSyncModeSwitch: function(event, cb) {
101920             return this._handle({
101921                 handler: 'acceptSyncModeSwitch',
101922             action:  'accept',
101923             type:    'sync.mode.switch'
101924             }, event, cb);
101925         },
101926
101927         //-------------------------------------------------------------------------
101928         acceptDevInfoSwap: function(event, cb) {
101929             return this._handle({
101930                 handler: 'acceptDevInfoSwap',
101931             action:  'accept',
101932             type:    'dev.info.swap'
101933             }, event, cb);
101934         },
101935
101936         //-------------------------------------------------------------------------
101937         chooseRefreshRequired: function(event, cb) {
101938             return this._handle({
101939                 handler: 'chooseRefreshRequired',
101940             action:  'choose',
101941             type:    'refresh.required',
101942             choices: [
101943             {value: constant.SYNCTYPE_SLOW_SYNC, default: true},
101944             {value: constant.SYNCTYPE_REFRESH_FROM_CLIENT},
101945             {value: constant.SYNCTYPE_REFRESH_FROM_SERVER}
101946             ]
101947             }, event, function(err, choice) {
101948                 if ( err )
101949                 return cb(err);
101950             // todo: catch the condition where `choice` is not a valid synctype
101951             return cb(err, common.synctype2alert(choice));
101952             });
101953         },
101954
101955         //-------------------------------------------------------------------------
101956         fetchCredentials: function(event, cb) {
101957             return this._handle({
101958                 handler: 'fetchCredentials',
101959             action:  'fetch',
101960             type:    'auth.challenge',
101961             choices: [
101962             {value: constant.SYNCTYPE_SLOW_SYNC, default: true},
101963             {value: constant.SYNCTYPE_REFRESH_FROM_CLIENT},
101964             {value: constant.SYNCTYPE_REFRESH_FROM_SERVER}
101965             ]
101966             }, event, cb);
101967         },
101968
101969         //-------------------------------------------------------------------------
101970         _handle: function(spec, event, cb) {
101971             event = _.extend({}, spec, event, {
101972                 type         : spec.type,
101973             context      : event.session.context,
101974             adapter      : event.session.adapter,
101975             peer         : event.session.peer,
101976             ua_handler   : spec.handler,
101977             ua_action    : spec.action
101978             });
101979             var handler = this._getHandler(spec.handler);
101980             if ( handler )
101981                 return handler(event, cb);
101982             handler = this._getHandler(spec.action);
101983             if ( handler )
101984                 return handler(spec.type, event, cb);
101985             handler = this._getHandler('handle');
101986             if ( handler )
101987                 return handler(spec.action, spec.type, event, cb);
101988             if ( spec.action == 'accept' )
101989             {
101990                 return cb();
101991             }
101992             if ( spec.action == 'choose'
101993                     && event.choices && event.choices.length > 0 )
101994             {
101995                 var choice = _.find(event.choices, function(c) { return c.default; });
101996                 if ( ! choice )
101997                     choice = event.choices[0];
101998                 if ( choice.value )
101999                     choice = choice.value;
102000                 return cb(null, choice);
102001             }
102002             if ( spec.type == 'auth.challenge' )
102003                 return cb();
102004             return cb(new common.NotImplementedError(
102005                         'user-agent handler for event type "' + spec.type + '" (action: "'
102006                             + spec.action + '") not found or defined'));
102007         }
102008
102009     });
102010
102011     return exports;
102012
102013 })();
102014
102015 module.exports = _self;
102016
102017 });
102018 define('ripple/platform/tizen/2.0/syncml-js-lib/adapter', function (require, exports, module) {
102019 // -*- coding: utf-8 -*-
102020 //-----------------------------------------------------------------------------
102021 // file: $Id$
102022 // lib:  syncml-js.adapter
102023 // auth: griffin <griffin@uberdev.org>
102024 // date: 2012/10/22
102025 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
102026 //-----------------------------------------------------------------------------
102027
102028 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
102029     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
102030     storemod = require('ripple/platform/tizen/2.0/syncml-js-lib/store');
102031
102032
102033 var _self = (function () {
102034
102035     var exports = {};
102036
102037     //---------------------------------------------------------------------------
102038     exports.Adapter = common.Base.extend({
102039
102040         // //-------------------------------------------------------------------------
102041         // constructor: function(context, options, devInfo) {
102042
102043         //-------------------------------------------------------------------------
102044         normUri: function(uri) {
102045             return common.normpath(uri);
102046         },
102047
102048         //-------------------------------------------------------------------------
102049         getStores: function() {
102050             return _.values(this._stores);
102051         },
102052
102053         //-------------------------------------------------------------------------
102054         getStore: function(uri) {
102055             return this._stores[this.normUri(uri)];
102056         },
102057
102058         //-------------------------------------------------------------------------
102059         addStore: function(store, cb) {
102060             var self = this;
102061             if ( store instanceof storemod.Store )
102062             {
102063                 store.uri = self.normUri(store.uri);
102064                 store._a  = self;
102065             }
102066             else
102067                 store = new storemod.Store(this, store);
102068             store._updateModel(function(err) {
102069                 if ( err )
102070                 return cb(err);
102071             self._stores[store.uri] = store;
102072
102073             // TODO: remove this sensitivity...
102074             if ( ! self.isLocal )
102075                 return cb();
102076
102077             self._save(self._c._txn(), function(err) {
102078                 if ( err )
102079                 return cb(err);
102080             cb(null, store);
102081             });
102082             });
102083         },
102084
102085         //-------------------------------------------------------------------------
102086         removeStore: function(uri, cb) {
102087             var self = this;
102088             if ( ! self.isLocal )
102089                 // todo: implement
102090                 return cb(new common.LogicalError(
102091                             'cannot remove remote store "' + uri + '": remote peer responsibility'));
102092             if ( ! self._stores[uri] )
102093                 return cb(new common.InternalError(
102094                             'cannot remove store "' + uri + '": no such store'));
102095             delete self._stores[uri];
102096             var model = self._getModel();
102097             model.stores = _.filter(model.stores, function(store) {
102098                 return store.uri != uri;
102099             });
102100             _.each(model.peers, function(peer) {
102101                 peer.routes = _.filter(peer.routes, function(route) {
102102                     return route.localUri != uri;
102103                 });
102104                 _.each(peer.stores, function(store) {
102105                     if ( store.binding && store.binding.uri == uri )
102106                     store.binding = null;
102107                 });
102108             });
102109             return cb();
102110         },
102111
102112         //-------------------------------------------------------------------------
102113         _isMapper: function() {
102114             // indicates whether or not this adapter is capable of mapping
102115             // items. in the standard SyncML peer model, only the server
102116             // ever does mapping, but in the dream-land of syncml-js, all
102117             // peers can be mappers, or even better, implements an extension
102118             // "is-uuid/adopted" that does not require mapping. so, since
102119             // that is just a dream-land for now, this will try to identify
102120             // if this adapter represents a server...
102121             // todo: enhance syncml-js so that it is not needed!...
102122             if ( ! this.isLocal )
102123                 return this.url && this.url.length > 0;
102124             return this.devInfo && this.devInfo.devType == constant.DEVTYPE_SERVER;
102125         },
102126
102127         //-------------------------------------------------------------------------
102128         describe: function(stream, cb) {
102129             var self = this;
102130             if ( self.url )
102131                 stream.writeln('URL: ' + self.url);
102132             stream.writeln('Device ID: ' + self.devID);
102133             var s1 = stream.indented();
102134             var s2 = s1.indented();
102135
102136             var describe_stores = function(cb) {
102137                 var stores = self.getStores();
102138                 if ( stores.length <= 0 )
102139                 {
102140                     stream.writeln('Data stores: (none)');
102141                     return cb();
102142                 }
102143                 stream.writeln('Data stores:');
102144                 common.cascade(stores, function(store, cb) {
102145                     s1.writeln(( store.displayName || store.uri ) + ':');
102146                     store.describe(s2, cb);
102147                 }, cb);
102148             };
102149
102150             var describe_peers = function(cb) {
102151                 if ( ! self.getPeers )
102152                     return cb();
102153                 var peers = self.getPeers();
102154                 if ( peers.length <= 0 )
102155                 {
102156                     stream.writeln('Known peers: (none)');
102157                     return cb();
102158                 }
102159                 stream.writeln('Known peers:');
102160                 common.cascade(peers, function(peer, cb) {
102161                     s1.writeln(( peer.displayName || peer.url ) + ':');
102162                     peer.describe(s2, cb);
102163                 }, cb);
102164             }
102165
102166             describe_stores(function(err) {
102167                 if ( err )
102168                 return cb(err);
102169             describe_peers(cb);
102170             });
102171         }
102172
102173     });
102174
102175     return exports;
102176
102177     })();
102178
102179     module.exports = _self;
102180
102181 });
102182 define('ripple/platform/tizen/2.0/syncml-js-lib/synchronizer', function (require, exports, module) {
102183 // -*- coding: utf-8 -*-
102184 //-----------------------------------------------------------------------------
102185 // file: $Id$
102186 // lib:  syncml-js.synchronizer
102187 // auth: griffin <griffin@uberdev.org>
102188 // date: 2012/11/05
102189 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
102190 //-----------------------------------------------------------------------------
102191
102192 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
102193     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
102194     ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'),
102195     state = require('ripple/platform/tizen/2.0/syncml-js-lib/state'),
102196     protocol = require('ripple/platform/tizen/2.0/syncml-js-lib/protocol'),
102197     storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
102198     _self;
102199
102200 _self = (function () {
102201
102202     var exports = {};
102203     var badStatus = protocol.badStatus;
102204
102205     //---------------------------------------------------------------------------
102206     exports.Synchronizer = common.Base.extend({
102207
102208         //-------------------------------------------------------------------------
102209         constructor: function(options) {
102210         },
102211
102212         //-------------------------------------------------------------------------
102213         initStoreSync: function(session, cb) {
102214             async.eachSeries(session.peer._getModel().stores, function(rstore, cb) {
102215                 // TODO: should the server-side be doing this? probably not
102216                 //       since store mapping is a client-side decision...
102217                 var ruri = session.peer.normUri(rstore.uri);
102218                 if ( session.info.dsstates[ruri] || ! rstore.binding )
102219                 return cb();
102220             var lstore = session.adapter.getStore(rstore.binding.uri);
102221             if ( ! lstore || ! lstore.agent )
102222                 return cb();
102223             var ds = state.makeStoreSyncState({
102224                 uri        : lstore.uri,
102225                 peerUri    : ruri,
102226                 lastAnchor : rstore.binding.localAnchor,
102227                 mode       : session.info.mode || constant.ALERT_TWO_WAY,
102228                 action     : 'alert'
102229             });
102230             if ( ! ds.lastAnchor )
102231             {
102232                 switch ( ds.mode )
102233             {
102234                 case constant.ALERT_SLOW_SYNC:
102235                 case constant.ALERT_REFRESH_FROM_CLIENT:
102236                 case constant.ALERT_REFRESH_FROM_SERVER:
102237                     {
102238                         break;
102239                     }
102240                 case constant.ALERT_TWO_WAY:
102241                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
102242                 case constant.ALERT_ONE_WAY_FROM_SERVER:
102243                     {
102244                         if ( session.info.mode == constant.SYNCTYPE_AUTO )
102245                         {
102246                             ds.mode = constant.ALERT_SLOW_SYNC;
102247                             break;
102248                         }
102249                         var uaEvent = {
102250                             session   : session,
102251                             store     : lstore,
102252                             peerStore : rstore,
102253                             modeReq   : ds.mode
102254                         };
102255                         return session.ua.chooseRefreshRequired(uaEvent, function(err, mode) {
102256                             if ( err )
102257                             return cb(err);
102258                         if ( ! _.contains([constant.ALERT_SLOW_SYNC,
102259                                 constant.ALERT_REFRESH_FROM_CLIENT,
102260                                 constant.ALERT_REFRESH_FROM_SERVER], mode) )
102261                             return cb(new common.TypeError(
102262                                     'invalid mode chosen for refresh: ' + common.j(mode)));
102263                         ds.mode = mode;
102264                         session.info.dsstates[ds.uri] = ds;
102265                         return cb();
102266                         });
102267                     }
102268                 default:
102269                     {
102270                         return cb(new common.InternalError(
102271                                     'unexpected sync mode "' + ds.mode + '" requested'));
102272                     }
102273             }
102274             }
102275             session.info.dsstates[ds.uri] = ds;
102276             return cb();
102277             }, cb);
102278         },
102279
102280         //-------------------------------------------------------------------------
102281         // SYNCHRONIZATION PHASE: ACTION
102282         //-------------------------------------------------------------------------
102283
102284         //-------------------------------------------------------------------------
102285         actions: function(session, commands, cb) {
102286             var self = this;
102287             common.cascade(_.keys(session.info.dsstates), function(uri, cb) {
102288                 var ds = session.info.dsstates[uri];
102289                 if ( ds.action == 'done' )
102290                 return cb();
102291             // TODO: is this the right handling of an "error" dsstate?...
102292             if ( ds.action == 'error' )
102293                 return cb();
102294             var func = self['_action_' + ds.action.toLowerCase()];
102295             if ( ! func )
102296                 return cb(new common.InternalError(
102297                         'unexpected store action "' + ds.action + '"'));
102298             try{
102299                 func.call(self, session, ds, function(err, cmds) {
102300                     if ( err )
102301                     return cb(err);
102302                 _.each(cmds, function(cmd) { commands.push(cmd); });
102303                 return cb();
102304                 });
102305             }catch(e){
102306                 return cb(new common.InternalError(
102307                         'failed invoking synchronizer action: ' + e, e));
102308             }
102309             }, function(err) {
102310                 if ( err )
102311                     return cb(err);
102312                 return cb(null, commands);
102313             });
102314         },
102315
102316         //-------------------------------------------------------------------------
102317         _action_alert: function(session, dsstate, cb) {
102318
102319             var src = session.adapter.getStore(dsstate.uri);
102320             var tgt = session.peer.getStore(dsstate.peerUri);
102321
102322             // TODO: ensure that mode is acceptable...
102323
102324             // todo: perhaps i should only specify maxObjSize if it differs from
102325             //       adapter.maxObjSize?...
102326
102327             return cb(null, [state.makeCommand({
102328                 name        : constant.CMD_ALERT,
102329                    cmdID       : session.nextCmdID(),
102330                    data        : dsstate.mode,
102331                    source      : src.uri,
102332                    target      : tgt.uri,
102333                    lastAnchor  : dsstate.lastAnchor,
102334                    nextAnchor  : dsstate.nextAnchor,
102335                    maxObjSize  : src.maxObjSize,
102336             })]);
102337
102338         },
102339
102340         //-------------------------------------------------------------------------
102341         _action_send: function(session, dsstate, cb) {
102342             var store = session.adapter.getStore(dsstate.uri);
102343             var agent = store.agent;
102344             var peerStore = session.peer.getStore(dsstate.peerUri);
102345
102346             var cmd = state.makeCommand({
102347                 name   : constant.CMD_SYNC,
102348                 cmdID  : session.nextCmdID(),
102349                 source : dsstate.uri,
102350                 // target : adapter.router.getTargetUri(uri),
102351                 target : dsstate.peerUri
102352             });
102353
102354             switch ( dsstate.mode )
102355             {
102356                 case constant.ALERT_TWO_WAY:
102357                 case constant.ALERT_SLOW_SYNC:
102358                 case constant.ALERT_ONE_WAY_FROM_CLIENT:
102359                 case constant.ALERT_REFRESH_FROM_CLIENT:
102360                 case constant.ALERT_ONE_WAY_FROM_SERVER:
102361                 case constant.ALERT_REFRESH_FROM_SERVER:
102362                     // todo: these should only be received out-of-band, right?...
102363                     // case constant.ALERT_TWO_WAY_BY_SERVER:
102364                     // case constant.ALERT_ONE_WAY_FROM_CLIENT_BY_SERVER:
102365                     // case constant.ALERT_REFRESH_FROM_CLIENT_BY_SERVER:
102366                     // case constant.ALERT_ONE_WAY_FROM_SERVER_BY_SERVER:
102367                     // case constant.ALERT_REFRESH_FROM_SERVER_BY_SERVER:
102368                     {
102369                         break;
102370                     }
102371                 default:
102372                     {
102373                         return cb(new common.InternalError(
102374                                     'unexpected sync mode "' + common.mode2string(dsstate.mode) + '"'));
102375                     }
102376             }
102377
102378             if ( session.isServer )
102379             {
102380                 if ( dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT
102381                         || dsstate.mode == constant.ALERT_ONE_WAY_FROM_CLIENT )
102382                 {
102383                     cmd.noc = 0;
102384                     return cb(null, [cmd]);
102385                 }
102386             }
102387
102388             if ( ! session.isServer )
102389             {
102390                 if ( dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER
102391                         || dsstate.mode == constant.ALERT_ONE_WAY_FROM_SERVER )
102392                 {
102393                     cmd.noc = 0;
102394                     return cb(null, [cmd]);
102395                 }
102396             }
102397
102398             switch ( dsstate.mode )
102399             {
102400
102401                 case constant.ALERT_TWO_WAY:
102402                 case constant.ALERT_ONE_WAY_FROM_CLIENT: // when ! session.isServer
102403                 case constant.ALERT_ONE_WAY_FROM_SERVER: // when session.isServer
102404                     {
102405                         // send local changes
102406
102407                         storage.getAll(
102408                                 session.context,
102409                                 session.txn().objectStore('change').index('store_id'),
102410                                 {only: peerStore.id},
102411                                 function(err, changes) {
102412                                     if ( err )
102413                             return cb(err);
102414                         var ctype = session.context.router.getBestTransmitContentType(
102415                             session.adapter, session.peer, dsstate.uri);
102416                         cmd.data = [];
102417
102418                         // TODO: add support for hierarchical operations...
102419                         //       including MOVE, COPY, etc.
102420
102421                         // TODO: this assumes that the entire object set can fit in memory...
102422                         //       perhaps, as a work-around, just keep a reference to the object
102423                         //       and then stream-based serialize it actually gets converted to
102424                         //       XML.
102425
102426                         common.cascade(changes, function(change, cb) {
102427
102428                             if ( dsstate.conflicts && _.indexOf(dsstate.conflicts, change.item_id) >= 0 )
102429                             return cb();
102430
102431                         var scmdtype = null;
102432                         switch ( change.state )
102433                         {
102434                             case constant.ITEM_ADDED:    scmdtype = constant.CMD_ADD;     break;
102435                             case constant.ITEM_MODIFIED: scmdtype = constant.CMD_REPLACE; break;
102436                             case constant.ITEM_DELETED:  scmdtype = constant.CMD_DELETE;  break;
102437                             default:
102438                                                          {
102439                                                              return cb();
102440                                                          }
102441                         }
102442
102443                         // todo: do something with the ctype version (ie. ctype[1])?...
102444                         var scmd = state.makeCommand({
102445                             name    : scmdtype,
102446                             cmdID   : session.nextCmdID(),
102447                             format  : constant.FORMAT_AUTO,
102448                             type    : change.state != constant.ITEM_DELETED ? ctype[0] : null,
102449                             uri     : dsstate.uri
102450                         });
102451
102452                         // TODO: need to add hierarchical addition support here...
102453
102454                         var set_data = scmdtype == constant.CMD_DELETE ? common.noop : function(cb) {
102455
102456                             agent.getItem(change.item_id, function(err, item) {
102457                                 if ( err )
102458                                 return cb(err);
102459                             agent.dumpsItem(item, ctype[0], ctype[1], function(err, data, nct, nv) {
102460                                 if ( err )
102461                                 return cb(err);
102462                             scmd.data = data;
102463                             scmd.type = nct || scmd.type;
102464                             // todo: what to do with the content-type version?... eg.
102465                             //         scmd.version = nv || scmd.version;
102466                             // TODO: support hierarchical sync
102467                             // if ( agent.hierarchicalSync && item.parent )
102468                             //   scmd.sourceParent = '' + item.parent
102469                             return cb();
102470                             });
102471                             });
102472                         };
102473
102474                         var set_target = scmdtype == constant.CMD_ADD ? function(cb) {
102475                             scmd.source = change.item_id;
102476                             cb();
102477                         } : function(cb) {
102478                             if ( ! session.isServer )
102479                             {
102480                                 scmd.source = change.item_id;
102481                                 return cb();
102482                             }
102483                             peerStore._getMapping(change.item_id, function(err, luid) {
102484                                 if ( err )
102485                                 return cb(err);
102486                             if ( luid )
102487                                 scmd.target = luid;
102488                             else
102489                                 scmd.source = change.item_id;
102490                             cb();
102491                             });
102492                         };
102493
102494                         set_data(function(err) {
102495                             if ( err )
102496                             return cb(err);
102497                         set_target(function(err) {
102498                             if ( err )
102499                             return cb(err);
102500                         cmd.data.push(scmd);
102501                         return cb();
102502                         });
102503                         });
102504                         }, function(err) {
102505                             if ( err )
102506                                 return cb(err);
102507                             cmd.noc = cmd.data.length;
102508                             return cb(null, [cmd]);
102509                         });
102510                                 }
102511                         );
102512                         return;
102513                     }
102514                 case constant.ALERT_SLOW_SYNC:
102515                 case constant.ALERT_REFRESH_FROM_SERVER: // when session.isServer
102516                 case constant.ALERT_REFRESH_FROM_CLIENT: // when ! session.isServer
102517                     {
102518                         // todo: this approach assumes that the entire object set can fit
102519                         //       in memory... perhaps move to an iterator-based approach?...
102520                         cmd.data = [];
102521
102522                         agent.getAllItems(function(err, items) {
102523
102524                             if ( err )
102525                             return cb(err);
102526
102527                         // TODO: support hierarchical sync...
102528
102529                         if ( agent.hierarchicalSync )
102530                         {
102531                             return cb(new common.NotImplementedError('hierarchical-sync'));
102532                             //       orditems = []            # the ordered items
102533                             //       dunitems = dict()        # lut of the ordered items
102534                             //       curitems = dict()        # lut of current items (for loop detection)
102535                             //       lutitems = dict([(item.id, item) for item in items])
102536                             //       def appenditem(item):
102537                             //         if item.id in dunitems:
102538                             //           return
102539                             //         if item.id in curitems:
102540                             //           raise common.LogicalError('recursive item hierarchy detected at item %r' % (item,))
102541                             //         curitems[item.id] = True
102542                             //         if item.parent is not None:
102543                             //           appenditem(lutitems[item.parent])
102544                             //         orditems.append(item)
102545                             //         dunitems[item.id] = item
102546                             //       for item in items:
102547                             //         curitems = dict()
102548                             //         appenditem(item)
102549                         }
102550
102551                         var ctype = session.context.router.getBestTransmitContentType(
102552                                 session.adapter, session.peer, dsstate.uri);
102553
102554                         common.cascade(items, function(item, cb) {
102555
102556                             // TODO: these should all be non-deleted items, right?...
102557
102558                             if ( _.indexOf(dsstate.conflicts, '' + item.id) >= 0 )
102559                             return cb();
102560
102561                         // note: need to check for mappings since on slow-sync, the
102562                         // server will already have received the client's "add" commands
102563                         // at this point (and therefore should not send them back...)
102564                         var check_sync = function(cb) {
102565                             if ( ! session.isServer )
102566                             return cb(null, true);
102567                         peerStore._getMapping(item.id, function(err, luid) {
102568                             return cb(err, luid ? false : true);
102569                         });
102570                         };
102571
102572                         check_sync(function(err, dosync) {
102573                             if ( err )
102574                             return cb(err);
102575
102576                         if ( ! dosync )
102577                             return cb();
102578
102579                         agent.dumpsItem(
102580                             item, ctype[0], ctype[1],
102581                             function(err, data, new_ct, new_v) {
102582
102583                                 if ( err )
102584                             return cb(err);
102585
102586                         // todo: do something with the content-type version...
102587                         var scmd = state.makeCommand({
102588                             name    : constant.CMD_ADD,
102589                             cmdID   : session.nextCmdID(),
102590                             format  : constant.FORMAT_AUTO,
102591                             type    : new_ct || ctype[0],
102592                             uri     : dsstate.uri,
102593                             source  : '' + item.id,
102594                             data    : data
102595                         });
102596
102597                         if ( agent.hierarchicalSync )
102598                         {
102599                             // TODO: support hierarchical sync...
102600                             // if agent.hierarchicalSync and item.parent is not None:
102601                             //   scmd.sourceParent = str(item.parent)
102602                             return cb(new common.NotImplementedError('hierarchical-sync'));
102603                         }
102604
102605                         cmd.data.push(scmd);
102606                         return cb();
102607                             });
102608
102609                         });
102610
102611                         }, function(err) {
102612                             if ( err )
102613                                 return cb(err);
102614                             cmd.noc = cmd.data.length;
102615                             return cb(null, [cmd]);
102616                         });
102617
102618                         });
102619                         return;
102620                     }
102621             }
102622
102623             return cb(new common.InternalError(
102624                         'unexpected sync situation (action=' + dsstate.action
102625                             + ', mode=' + common.mode2string(dsstate.mode)
102626                             + ', isServer=' + ( session.isServer ? '1' : '0' ) + ')'));
102627                     },
102628
102629                     //-------------------------------------------------------------------------
102630                     _action_save: function(session, dsstate, cb) {
102631                         if ( ! session.isServer )
102632                 // TODO: for now, only servers should take the "save" action - the client
102633                 //       will explicitly do this at the end of the .sync() method.
102634                 //       ... mostly because clients don't call synchronizer.actions()
102635                 //       one final time ...
102636                 //       *BUT* perhaps that should be changed?... for example, .sync()
102637                 //       could call synchronizer.actions() to cause action_save's to occur
102638                 //       *AND* verify that synchronizer.actions() does not return anything...
102639                 return cb(new common.InternalError(
102640                         'unexpected sync save situation (action=' + dsstate.action
102641                             + ', mode=' + common.mode2string(dsstate.mode)
102642                             + ', isServer=' + ( session.isServer ? '1' : '0' ) + ')'));
102643
102644                     var peerStore = session.peer.getStore(dsstate.peerUri);
102645                     var binding = peerStore._getBinding();
102646                     binding.localAnchor  = dsstate.nextAnchor;
102647                     binding.remoteAnchor = dsstate.peerNextAnchor;
102648                     return cb(null);
102649                     },
102650
102651                     //-------------------------------------------------------------------------
102652                     // SYNCHRONIZATION PHASE: REACTION
102653                     //-------------------------------------------------------------------------
102654
102655                     //-------------------------------------------------------------------------
102656                     reactions: function(session, commands, cb) {
102657                         var self = this;
102658                         var ret  = [];
102659                         session.hierlut = null;
102660                         common.cascade(commands, function(cmd, cb) {
102661                             var func = self['_reaction_' + cmd.name.toLowerCase()];
102662                             if ( ! func )
102663                             return cb(new common.InternalError(
102664                                     'unexpected store reaction "' + cmd.name + '"'));
102665                         try{
102666                             func.call(self, session, cmd, function(err, cmds) {
102667                                 if ( err ) {
102668                                     return cb(err);
102669                                 }
102670                                 _.each(cmds, function(cmd) { ret.push(cmd); });
102671                                 return cb();
102672                             });
102673                         }catch(e){
102674                             return cb(new common.InternalError(
102675                                     'failed invoking synchronizer reaction: ' + e, e));
102676                         }
102677                         }, function(err) {
102678                             session.hierlut = null;
102679                             if ( err )
102680                                 return cb(err);
102681                             return cb(null, ret);
102682                         });
102683                     },
102684
102685                     //-------------------------------------------------------------------------
102686                     _reaction_sync: function(session, command, cb) {
102687                         var self = this;
102688                         var ret  = [state.makeCommand({
102689                             name       : constant.CMD_STATUS,
102690                             cmdID      : session.nextCmdID(),
102691                             msgRef     : command.msgID,
102692                             cmdRef     : command.cmdID,
102693                             targetRef  : command.target,
102694                             sourceRef  : command.source,
102695                             statusOf   : command.name,
102696                             statusCode : constant.STATUS_OK
102697                         })];
102698                         var store = session.adapter.getStore(session.adapter.normUri(command.target));
102699                         var dsstate = session.info.dsstates[store.uri];
102700                         if ( ! store.agent )
102701                         {
102702                             // todo: this is a bit different handling than anywhere else...
102703                             //       should everywhere else be like here, or the other way
102704                             //       round?...
102705                             //       the "REAL BIG ISSUE" is that atomicity of the changes
102706                             //       is a little vague at this point...
102707                             dsstate.stats.hereErr += 1;
102708                             dsstate.action = 'error';
102709                             dsstate.error  = {
102710                                 message:  'Sync agent for store "' + store.uri + '" not available',
102711                                 code:     'syncml-js.TypeError'
102712                             };
102713                             ret[0].statusCode = constant.STATUS_SERVICE_UNAVAILABLE;
102714                             ret[0].errorMsg   = dsstate.error.message;
102715                             ret[0].errorCode  = dsstate.error.code;
102716                             return cb(null, ret);
102717                         }
102718
102719                         if ( store.agent.hierarchicalSync )
102720                             session.hierlut = {};
102721
102722                         var preprocess = common.noop;
102723
102724                         if ( ( ! session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER )
102725                                 || ( session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT ) )
102726                         {
102727                             // delete all local items
102728                             preprocess = function(cb) {
102729                                 store.agent.getAllItems(function(err, items) {
102730                                     if ( err )
102731                                     return cb(err);
102732                                 common.cascade(items, function(item, cb) {
102733                                     store.agent.deleteItem(item.id, function(err) {
102734                                         if ( err )
102735                                         return cb(err);
102736                                     dsstate.stats.hereDel += 1;
102737                                     if ( ! session.isServer )
102738                                         return cb();
102739                                     store.registerChange(item.id, constant.ITEM_DELETED,
102740                                         {excludePeerID: session.peer.id}, cb);
102741                                     });
102742                                 }, function(err) {
102743                                     if ( err )
102744                                     return cb(err);
102745                                 return store.getPeerStore(session.peer)._delChange({}, cb);
102746                                 });
102747                                 });
102748                             };
102749                         }
102750
102751                         if ( dsstate.mode == constant.ALERT_SLOW_SYNC
102752                                 || ( session.isServer && dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER ) )
102753                         {
102754                             // delete all mappings and pending changes
102755                             var peerStore = store.getPeerStore(session.peer);
102756                             var prepreprocess = preprocess;
102757                             preprocess = function(cb) {
102758                                 prepreprocess(function(err) {
102759                                     if ( err )
102760                                     return cb(err);
102761                                 peerStore._delChange({}, function(err) {
102762                                     if ( err )
102763                                     return cb(err);
102764                                 peerStore._clearAllMappings(cb);
102765                                 });
102766                                 });
102767                             };
102768                         }
102769
102770                         preprocess(function(err) {
102771                             if ( err )
102772                             return cb(err);
102773
102774                         if ( command.data.length <= 0 )
102775                             return cb(null, ret);
102776
102777                         // paranoia: verify that i should be receiving data...
102778                         if ( ! ( dsstate.mode == constant.ALERT_TWO_WAY
102779                                 || dsstate.mode == constant.ALERT_SLOW_SYNC
102780                                 || ( ! session.isServer
102781                                     && ( dsstate.mode == constant.ALERT_ONE_WAY_FROM_SERVER
102782                                         || dsstate.mode == constant.ALERT_REFRESH_FROM_SERVER ) )
102783                                 || ( session.isServer
102784                                     && ( dsstate.mode == constant.ALERT_ONE_WAY_FROM_CLIENT
102785                                         || dsstate.mode == constant.ALERT_REFRESH_FROM_CLIENT ) ) ) )
102786                             return cb(new common.ProtocolError(
102787                                     'unexpected sync data (role="'
102788                                         + ( session.isServer ? 'server' : 'client' )
102789                                         + '", mode="' + common.mode2string(dsstate.mode)
102790                                         + '")'));
102791
102792                         common.cascade(command.data, function(cmd, cb) {
102793
102794                             // NOTE: commented this paranoia setting out, since the server
102795                             //       *may* decide to update/delete a client item...
102796                             //       e.g. conflict-resolved-merge (207)
102797                             // TODO: perhaps i should only allow non-ADDs for those items
102798                             //       that i received a conflict-resolved-merge (207) for?...
102799
102800                             // // paranoia: non-'add' sync commands should only be received in non-refresh modes
102801                             // if ( cmd.name != constant.CMD_ADD
102802                             //      && _.indexOf([constant.ALERT_TWO_WAY,
102803                             //                    constant.ALERT_ONE_WAY_FROM_SERVER,
102804                             //                    constant.ALERT_ONE_WAY_FROM_CLIENT], dsstate.mode) < 0 )
102805                             //   return cb(new common.ProtocolError(
102806                             //     'unexpected non-add sync command (role="'
102807                             //       + ( session.isServer ? 'server' : 'client' )
102808                             //       + '", mode="' + common.mode2string(dsstate.mode)
102809                             //       + '", command="' + cmd.name
102810                             //       + '")'));
102811
102812                             self._reaction_syncdispatch(session, cmd, store, dsstate, function(err, cmds) {
102813                                 if ( err )
102814                                 return cb(err);
102815                             _.each(cmds, function(cmd) { ret.push(cmd); });
102816                             return cb();
102817                             });
102818
102819                         }, function(err) {
102820                             if ( err )
102821                                 return cb(err);
102822                             return cb(null, ret);
102823                         });
102824                         });
102825                     },
102826
102827                     //-------------------------------------------------------------------------
102828                     _reaction_syncdispatch: function(session, cmd, store, dsstate, cb) {
102829
102830                         var self = this;
102831                         var func = self['_reaction_sync_' + cmd.name.toLowerCase()];
102832                         if ( ! func )
102833                             return cb(new common.ProtocolError(
102834                                         'unexpected reaction requested for sync command "' + cmd.name + '"'));
102835
102836                         var check_for_conflicts = common.noop;
102837
102838                         if ( session.isServer
102839                                 && cmd.name != constant.CMD_ADD
102840                                 && dsstate.mode != constant.ALERT_REFRESH_FROM_CLIENT )
102841                         {
102842                             // server, non-add, non-slowsync, non-refresh commands: check for conflicts.
102843                             // note that certain types of content could be a conflict even if it is an
102844                             // "Add" command; for example, two files with the same name cannot be added
102845                             // from separate clients.
102846
102847                             check_for_conflicts = function(cb) {
102848
102849                                 // todo: allow agents to raise a ConflictError...
102850                                 //       ==> perhaps this is already covered by the .matchItem() API?...
102851
102852                                 var policy = store.conflictPolicy || session.adapter.conflictPolicy;
102853                                 var peerStore = session.peer.getStore(dsstate.peerUri);
102854                                 self.getSourceMapping(
102855                                         session, constant.CMD_SYNC, cmd, peerStore, cmd.source,
102856                                         function(err, itemID) {
102857
102858                                             if ( err )
102859                                     return cb(err);
102860                                 if ( ! itemID )
102861                                     // this shouldn't happen...
102862                                     return cb();
102863
102864                                 peerStore._getChange(itemID, function(err, change) {
102865                                     if ( err )
102866                                     return cb(err);
102867                                 if ( ! change )
102868                                     return cb();
102869
102870                                 var retcmd = state.makeCommand({
102871                                     name       : constant.CMD_STATUS,
102872                                     cmdID      : session.nextCmdID(),
102873                                     msgRef     : cmd.msgID,
102874                                     cmdRef     : cmd.cmdID,
102875                                     sourceRef  : cmd.source,
102876                                     targetRef  : cmd.target,
102877                                     statusOf   : cmd.name,
102878                                     // todo: make this error message a bit more descriptive...
102879                                     errorMsg   : 'command "' + cmd.name + '" conflict for item ID "'
102880                                     + itemID + '" (state: ' + common.state2string(change.state) + ')'
102881                                 });
102882
102883
102884                                     // four possible states: mod-mod, mod-del, del-mod, del-del
102885                                     if ( ! dsstate.conflicts )
102886                                     dsstate.conflicts = [];
102887
102888                                     // handle mod-mod (but only if change-tracking is enabled)
102889                                     if ( change.state == constant.ITEM_MODIFIED
102890                                         && cmd.name == constant.CMD_REPLACE )
102891                                     {
102892                                         cmd._conflict = retcmd;
102893                                         cmd._change   = change;
102894                                         return cb();
102895                                     }
102896
102897                                     // handle del-del
102898                                     if ( change.state == constant.ITEM_DELETED
102899                                             && cmd.name == constant.CMD_DELETE )
102900                                     {
102901                                         // both changes are deletes... that's not a conflict.
102902                                         // TODO: should i really be doing all this here?... it does not
102903                                         //       follow the pattern..
102904                                         peerStore._delChange({
102905                                             itemID: change.item_id,
102906                                             state:  change.state
102907                                         }, function(err) {
102908                                             if ( err )
102909                                             return cb(err);
102910                                         dsstate.stats.peerDel   += 1;
102911                                         dsstate.stats.hereDel   += 1;
102912                                         dsstate.stats.merged    += 1;
102913                                         retcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_MERGE;
102914                                         retcmd.errorCode  = null;
102915                                         retcmd.errorMsg   = null;
102916                                         return cb(null, [retcmd]);
102917                                         });
102918                                         return;
102919                                     }
102920
102921                                     // handle del-mod or mod-del
102922                                     if ( ( change.state == constant.ITEM_DELETED
102923                                                 || cmd.name == constant.CMD_DELETE )
102924                                             && policy != constant.POLICY_ERROR )
102925                                     {
102926                                         // one of them is a delete and a conflict that can be solved
102927                                         // by the framework
102928                                         cmd._conflict = retcmd;
102929                                         cmd._change   = change;
102930                                         return cb();
102931                                     }
102932
102933                                     dsstate.conflicts.push(itemID);
102934                                     dsstate.stats.peerErr   += 1;
102935                                     dsstate.stats.conflicts += 1;
102936                                     retcmd.statusCode = constant.STATUS_UPDATE_CONFLICT;
102937                                     retcmd.errorCode  = 'syncml-js.synchronizer.RSd.10';
102938                                     return cb(null, [retcmd]);
102939                                 });
102940                                         }
102941                                 );
102942                             };
102943                         }
102944
102945                         check_for_conflicts(function(err, cmds) {
102946                             if ( err || cmds )
102947                             return cb(err, cmds);
102948                         try{
102949                             func.call(self, session, cmd, store, dsstate, cb);
102950                         }catch(e){
102951                             return cb(new common.InternalError(
102952                                     'failed invoking synchronizer sync reaction: ' + e, e));
102953                         }
102954                         });
102955
102956                     },
102957
102958                     //-------------------------------------------------------------------------
102959                     _reaction_sync_add: function(session, cmd, store, dsstate, cb) {
102960                         var curitem = null;
102961                         var item    = null;
102962                         if ( store.agent.hierarchicalSync )
102963                         {
102964                             if ( cmd.targetParent )
102965                                 cmd.data.parent = cmd.targetParent;
102966                             else if ( cmd.sourceParent )
102967                                 cmd.data.parent = session.hierlut[cmd.sourceParent];
102968                         }
102969
102970                         var matcher = common.noop;
102971                         if ( session.isServer && dsstate.mode == constant.ALERT_SLOW_SYNC )
102972                         {
102973                             // TODO: if the matched item is already mapped to another client-side
102974                             //       object, then this should cancel the matching...
102975                             matcher = function(cb) {
102976                                 store.agent.matchItem(cmd.data, function(err, match) {
102977                                     if ( err )
102978                                     return cb(err);
102979                                 if ( ! match || ! match.compare )
102980                                     return cb();
102981                                 curitem = match;
102982                                 if ( match.compare(cmd.data) == 0 )
102983                                     return cb();
102984                                 store.agent.mergeItems(curitem, cmd.data, null, function(err) {
102985                                     // TODO: if there is a common.ConflictError, set
102986                                     //       curitem to null and continue without error...
102987                                     if ( err )
102988                                     return cb(err);
102989                                 store.registerChange(curitem.id, constant.ITEM_MODIFIED,
102990                                     {changeSpec: cspec, excludePeerID: session.peer.id},
102991                                     cb);
102992                                 });
102993                                 });
102994                             };
102995                         }
102996
102997                         matcher(function(err) {
102998                             if ( err )
102999                             return cb(err);
103000                         var adder = common.noop;
103001                         if ( ! curitem )
103002                             adder = function(cb) {
103003                                 store.agent.addItem(cmd.data, function(err, newitem) {
103004                                     if ( err )
103005                                     return cb(err);
103006                                 item = newitem;
103007                                 dsstate.stats.hereAdd += 1;
103008                                 store.registerChange(item.id, constant.ITEM_ADDED,
103009                                     {excludePeerID: session.peer.id}, cb);
103010                                 });
103011                             };
103012                         else
103013                             item = curitem;
103014                         return adder(function(err) {
103015                             if ( err )
103016                             return cb(err);
103017
103018                         if ( store.agent.hierarchicalSync )
103019                             session.hierlut[cmd.source] = item.id;
103020
103021                         var ret = [state.makeCommand({
103022                             name       : constant.CMD_STATUS,
103023                             cmdID      : session.nextCmdID(),
103024                             msgRef     : cmd.msgID,
103025                             cmdRef     : cmd.cmdID,
103026                             sourceRef  : cmd.source,
103027                             statusOf   : cmd.name,
103028                             statusCode : ( curitem
103029                                 ? constant.STATUS_ALREADY_EXISTS
103030                                 : constant.STATUS_ITEM_ADDED )
103031                         })];
103032
103033                         if ( ! session.isServer )
103034                         {
103035                             ret.push(state.makeCommand({
103036                                 name       : constant.CMD_MAP,
103037                                 cmdID      : session.nextCmdID(),
103038                                 source     : store.uri,
103039                                 target     : dsstate.peerUri,
103040                                 sourceItem : item.id,
103041                                 targetItem : cmd.source
103042                             }));
103043                             return cb(null, ret);
103044                         }
103045
103046                         var peerStore = session.peer.getStore(dsstate.peerUri);
103047                         peerStore._setMapping(item.id, cmd.source, function(err) {
103048                             if ( err )
103049                             return cb(err);
103050                         return cb(null, ret);
103051                         });
103052
103053                         });
103054                         });
103055
103056                     },
103057
103058                     //-------------------------------------------------------------------------
103059                     getSourceMapping: function(session, cmdctxt, cmd, peerStore, luid, cb) {
103060                         peerStore._getReverseMapping(luid, function(err, guid) {
103061
103062                             if ( err )
103063                             return cb(err);
103064
103065                         if ( guid )
103066                             return cb(null, guid);
103067
103068                         return cb(new common.InvalidItem(
103069                                 'unexpected "' + cmdctxt + '/' + cmd.name
103070                                 + '" request for unmapped item ID "' + luid + '"'));
103071
103072                         // todo: pysyncml generates a nice cmd-specific error node:
103073                         //       (which is probably over-kill)
103074
103075                         //     curmap = adapter._context._model.Mapping.q(store_id=peerStore.id, luid=luid).one()
103076                         //     return str(curmap.guid)
103077                         //   except NoResultFound:
103078                         //     msg = 'unexpected "%s/%s" request for unmapped item ID: %r' % (cmdctxt, cmd.name, luid)
103079                         //     # todo: this is a bit of a hack when cmdctxt == 'Status'...
103080                         //     return state.Command(
103081                         //       name       = constant.CMD_STATUS,
103082                         //       cmdID      = session.nextCmdID(),
103083                         //       msgRef     = cmd.msgID,
103084                         //       cmdRef     = cmd.cmdID,
103085                         //       sourceRef  = cmd.source,
103086                         //       targetRef  = cmd.target,
103087                         //       statusOf   = cmd.name if cmdctxt != constant.CMD_STATUS else cmdctxt,
103088                         //       statusCode = constant.STATUS_COMMAND_FAILED,
103089                         //       errorCode  = __name__ + '.' + self.__class__.__name__ + '.GSM.10',
103090                         //       errorMsg   = msg,
103091                         //       )
103092
103093                         });
103094                     },
103095
103096                     //-------------------------------------------------------------------------
103097                     _reaction_sync_replace: function(session, cmd, store, dsstate, cb) {
103098
103099                         // TODO: handle hierarchical-sync...
103100                         var self = this;
103101                         var item = cmd.data;
103102                         var get_item_id = ( ! session.isServer ) ? function(cb) {
103103                             item.id = cmd.target;
103104                             return cb();
103105                         } : function(cb) {
103106                             var peerStore = session.peer.getStore(dsstate.peerUri);
103107                             self.getSourceMapping(
103108                                     session, constant.CMD_SYNC, cmd, peerStore, cmd.source,
103109                                     function(err, guid) {
103110
103111                                         if ( err )
103112                                 return cb(err);
103113
103114                             // todo: what if guid is null?...
103115
103116                             item.id = guid;
103117                             return cb();
103118                                     }
103119                                     );
103120                         };
103121
103122                         var okcmd = state.makeCommand({
103123                             name       : constant.CMD_STATUS,
103124                             cmdID      : session.nextCmdID(),
103125                             msgRef     : cmd.msgID,
103126                             cmdRef     : cmd.cmdID,
103127                             targetRef  : cmd.target,
103128                             sourceRef  : cmd.source,
103129                             statusOf   : cmd.name,
103130                             statusCode : constant.STATUS_OK
103131                         });
103132
103133                         var handle_conflict = ( ! cmd._conflict ) ? common.noop : function(cb) {
103134
103135                             //   if cmd._conflict is not None:
103136                             //     try:
103137                             //       if cmd._change.state == constant.ITEM_DELETED:
103138                             //         raise common.ConflictError('item deleted')
103139                             //       if cmd._change.changeSpec is None:
103140                             //         raise common.ConflictError('no change tracking enabled - falling back to policy')
103141                             //       cspec = store.agent.mergeItems(store.agent.getItem(item.id), item, cmd._change.changeSpec)
103142                             //       dsstate.stats.hereMod += 1
103143                             //       store.registerChange(item.id, constant.ITEM_MODIFIED,
103144                             //                            changeSpec=cspec, excludePeerID=adapter.peer.id)
103145                             //       okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_MERGE
103146                             //       # NOTE: *not* suppressing the change that is registered from server
103147                             //       #       to client, since the merge may have resulted in an item that
103148                             //       #       is not identical to the one on the client.
103149                             //       return [okcmd]
103150                             //     except common.ConflictError, e:
103151                             //       # conflict types: client=mod/server=mod or client=mod/server=del
103152                             //       if store.conflictPolicy == constant.POLICY_CLIENT_WINS:
103153                             //         adapter._context._model.session.delete(cmd._change)
103154                             //         dsstate.stats.merged += 1
103155                             //         okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA
103156                             //         if cmd._change.state == constant.ITEM_DELETED:
103157                             //           # todo: this "re-creation" of a new item is detrimental to
103158                             //           #       clients that are tracking changes to an item (for
103159                             //           #       example, a SyncML svn client bridge...). but then, to
103160                             //           #       them, this item may already have been deleted. ugh.
103161                             //           dsstate.stats.hereMod += 1
103162                             //           item = store.agent.addItem(item)
103163                             //           peerStore = store.peer
103164                             //           adapter._context._model.Mapping.q(store_id=peerStore.id, guid=item.id).delete()
103165                             //           newmap = adapter._context._model.Mapping(store_id=peerStore.id,
103166                             //                                                    guid=item.id,
103167                             //                                                    luid=cmd.source)
103168                             //           adapter._context._model.session.add(newmap)
103169                             //           store.registerChange(item.id, constant.ITEM_ADDED,
103170                             //                                excludePeerID=adapter.peer.id)
103171                             //           return [okcmd]
103172                             //         # falling back to standard handling...
103173                             //       elif store.conflictPolicy == constant.POLICY_SERVER_WINS:
103174                             //         dsstate.stats.merged += 1
103175                             //         okcmd.statusCode = constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA
103176                             //         return [okcmd]
103177                             //       else:
103178                             //         # store.conflictPolicy == constant.POLICY_ERROR or other...
103179                             //         dsstate.stats.peerErr    += 1
103180                             //         dsstate.stats.conflicts  += 1
103181                             //         cmd._conflict.errorMsg   += ', agent failed merge: ' + str(e)
103182                             //         cmd._conflict.statusCode = constant.STATUS_UPDATE_CONFLICT
103183                             //         cmd._conflict.errorCode  = common.fullClassname(self) + '.RSR.10'
103184                             //         dsstate.conflicts.append(str(item.id))
103185                             //         return [cmd._conflict]
103186
103187                             cb();
103188
103189                         };
103190
103191                         // TODO: support hierarchical-sync...
103192                         // if ( store.agent.hierarchicalSync )
103193                         //   session.hierlut[cmd.source] = item.id;
103194
103195                         get_item_id(function(err) {
103196                             if ( err )
103197                             return cb(err);
103198                         handle_conflict(function(err) {
103199                             if ( err )
103200                             return cb(err);
103201                         store.agent.replaceItem(item, session.isServer, function(err, cspec) {
103202                             if ( err )
103203                             return cb(err);
103204                         dsstate.stats.hereMod += 1;
103205                         store.registerChange(
103206                             item.id, constant.ITEM_MODIFIED,
103207                             {changeSpec: cspec, excludePeerID: session.peer.id},
103208                             function(err) {
103209                                 if ( err )
103210                             return cb(err);
103211                         return cb(null, [okcmd]);
103212                             }
103213                             );
103214                         });
103215                         });
103216                         });
103217
103218                     },
103219
103220                     //-------------------------------------------------------------------------
103221                     _reaction_sync_delete: function(session, cmd, store, dsstate, cb) {
103222
103223                         var self   = this;
103224                         var status = constant.STATUS_OK;
103225                         var itemID = null;
103226
103227                         var get_item_id = ( ! session.isServer ) ? function(cb) {
103228                             itemID = cmd.target;
103229                             return cb();
103230                         } : function(cb) {
103231                             var peerStore = session.peer.getStore(dsstate.peerUri);
103232                             self.getSourceMapping(
103233                                     session, constant.CMD_SYNC, cmd, peerStore, cmd.source,
103234                                     function(err, guid) {
103235
103236                                         // if not isinstance(itemID, basestring):
103237                                         //   return [itemID]
103238
103239                                         if ( err )
103240                                 return cb(err);
103241
103242                             // todo: what if guid is null?...
103243
103244                             itemID = guid;
103245                             if ( ! cmd._conflict )
103246                                 return cb();
103247                             var policy = store.conflictPolicy || session.adapter.conflictPolicy;
103248                             switch ( policy )
103249                             {
103250
103251                                 case constant.POLICY_CLIENT_WINS:
103252                                     {
103253
103254
103255                                         // TODO ::: implement these...
103256
103257                                         //   //     adapter._context._model.session.delete(cmd._change)
103258                                         //   //     status = constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA
103259                                         //   //     session.dsstates[store.uri].stats.merged += 1
103260                                         //   //     # falling back to standard handling...
103261
103262                                         //   break;
103263
103264                                     }
103265                                 case constant.POLICY_SERVER_WINS:
103266                                     {
103267
103268
103269                                         //   //     adapter._context._model.session.delete(cmd._change)
103270                                         //   //     store.peer.registerChange(itemID, constant.ITEM_ADDED)
103271                                         //   //     session.dsstates[store.uri].stats.merged += 1
103272                                         //   //     cmd._conflict.statusCode = constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA
103273                                         //   //     cmd._conflict.errorCode  = None
103274                                         //   //     cmd._conflict.errorMsg   = None
103275                                         //   //     return [cmd._conflict]
103276
103277                                         //   break;
103278
103279                                     }
103280
103281                                 default:
103282                                     {
103283                                         // a constant.POLICY_ERROR policy should have been handled by the dispatch
103284                                         return cb(new common.InternalError(
103285                                                     'unexpected conflictPolicy: %s', '' + policy));
103286                                     }
103287                             }
103288                                     }
103289                             );
103290
103291                         };
103292
103293                         get_item_id(function(err) {
103294                             if ( err )
103295                             return cb(err);
103296                         store.agent.deleteItem(itemID, function(err) {
103297                             if ( err )
103298                             return cb(err);
103299                         dsstate.stats.hereDel += 1;
103300                         store.registerChange(
103301                             itemID, constant.ITEM_DELETED, {excludePeerID: session.peer.id},
103302                             function(err) {
103303                                 if ( err )
103304                             return cb(err);
103305                         return cb(null, [state.makeCommand({
103306                             name       : constant.CMD_STATUS,
103307                                cmdID      : session.nextCmdID(),
103308                                msgRef     : cmd.msgID,
103309                                cmdRef     : cmd.cmdID,
103310                                targetRef  : cmd.target,
103311                                sourceRef  : cmd.source,
103312                                statusOf   : cmd.name,
103313                                // todo: should this return DELETE_WITHOUT_ARCHIVE instead of OK?...
103314                                // statusCode = constant.STATUS_DELETE_WITHOUT_ARCHIVE,
103315                                statusCode : status
103316                         })]);
103317                             }
103318                             );
103319                         });
103320                         });
103321
103322                     },
103323
103324                     //-------------------------------------------------------------------------
103325                     _reaction_map: function(session, command, cb) {
103326                         var peerStore = session.peer.getStore(command.source);
103327                         if ( command.target != peerStore._getBinding().uri )
103328                             return cb(new common.NoSuchRoute(
103329                                         'unexpected "Map" event for unbound stores (local: "'
103330                                             + command.target + ', remote: "' + command.source + '")'));
103331                         common.cascade(command.items, function(item, cb) {
103332                             // todo: support hierarchical sync...
103333                             peerStore._setMapping(item.target, item.source, cb);
103334                         }, function(err) {
103335                             if ( err )
103336                             return cb(err);
103337                         return cb(null, [state.makeCommand({
103338                             name       : constant.CMD_STATUS,
103339                                cmdID      : session.nextCmdID(),
103340                                msgRef     : command.msgID,
103341                                cmdRef     : command.cmdID,
103342                                targetRef  : command.target,
103343                                sourceRef  : command.source,
103344                                statusOf   : command.name,
103345                                statusCode : constant.STATUS_OK
103346                         })]);
103347                         });
103348                     },
103349
103350                     //-------------------------------------------------------------------------
103351                     // SYNCHRONIZATION PHASE: SETTLE
103352                     //-------------------------------------------------------------------------
103353
103354                     //-------------------------------------------------------------------------
103355                     settle: function(session, cmd, chkcmd, xnode, cb) {
103356
103357                         // TODO: remove the "xnode" parameter... it is a hack so that i can
103358                         //       call badStatus() the same way as in protocol.js
103359                         // todo: there is a bit of a disconnect between how action and reaction
103360                         //       phases are called (for a list of commands), whereas the settle
103361                         //       phase is called on a per-item basis... not ideal, but the protocol
103362                         //       is really set up that way :(
103363                         // TODO: check all valid values of ``data``...
103364                         // todo: anything else in common?...
103365                         // todo: trap errors...
103366
103367                         var func = this['_settle_' + cmd.name.toLowerCase()];
103368                         if ( ! func )
103369                             return cb(new common.ProtocolError('unexpected settle command "' + cmd.name + '"'));
103370                         return func.call(this, session, cmd, chkcmd, xnode, cb);
103371                     },
103372
103373                     //-------------------------------------------------------------------------
103374                     _settle_add: function(session, cmd, chkcmd, xnode, cb) {
103375                         switch ( cmd.data )
103376                         {
103377                             default:
103378                                 {
103379                                     return cb(badStatus(xnode));
103380                                 }
103381                             case constant.STATUS_OK:
103382                             case constant.STATUS_ITEM_ADDED:
103383                             case constant.STATUS_CONFLICT_RESOLVED_DUPLICATE:
103384                                 {
103385                                     session.info.dsstates[chkcmd.uri].stats.peerAdd += 1;
103386                                     break;
103387                                 }
103388                             case constant.STATUS_ALREADY_EXISTS:
103389                             case constant.STATUS_CONFLICT_RESOLVED_MERGE:
103390                                 // todo: should this conflict-resolved-merge status be stored so
103391                                 //       that only this item can have a non-"ADD" during initial
103392                                 //       sync?...
103393                             case constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA:
103394                                 {
103395                                     session.info.dsstates[chkcmd.uri].stats.merged += 1;
103396                                     break;
103397                                 }
103398                         }
103399
103400                         var peerStore = session.peer.getStore(
103401                                 session.context.router.getTargetUri(
103402                                     session.adapter, session.peer, chkcmd.uri));
103403
103404                         peerStore._delChange({
103405                             itemID: chkcmd.source,
103406                             state: constant.ITEM_ADDED
103407                         }, cb);
103408                     },
103409
103410                     //-------------------------------------------------------------------------
103411                     _settle_replace: function(session, cmd, chkcmd, xnode, cb) {
103412
103413                         var self = this;
103414                         var dsstate = session.info.dsstates[chkcmd.uri];
103415
103416                         if ( ! session.isServer && cmd.data == constant.STATUS_UPDATE_CONFLICT )
103417                         {
103418                             dsstate.stats.hereErr   += 1;
103419                             dsstate.stats.conflicts += 1;
103420                             return cb();
103421                         }
103422                         if ( cmd.data != constant.STATUS_OK
103423                                 && cmd.data != constant.STATUS_CONFLICT_RESOLVED_MERGE
103424                                 && cmd.data != constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA
103425                                 && cmd.data != constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA )
103426                             return cb(badStatus(xnode));
103427                         if ( cmd.data == constant.STATUS_CONFLICT_RESOLVED_MERGE
103428                                 || cmd.data == constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA
103429                                 || cmd.data == constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA )
103430                             dsstate.stats.merged += 1;
103431                         if ( cmd.data != constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA )
103432                             dsstate.stats.peerMod += 1;
103433
103434                         var peerStore = session.peer.getStore(
103435                                 session.context.router.getTargetUri(
103436                                     session.adapter, session.peer, chkcmd.uri));
103437
103438                         var get_item_id = ( ! session.isServer ) ? function(cb) {
103439                             return cb(null, chkcmd.source);
103440                         } : function(cb) {
103441                             // if not isinstance(locItemID, basestring):
103442                             //   return locItemID
103443
103444                             self.getSourceMapping(
103445                                     session, constant.CMD_STATUS, cmd, peerStore, chkcmd.target,
103446                                     function(err, guid) { return cb(err, guid); }
103447                                     );
103448                         };
103449
103450                         get_item_id(function(err, locItemID) {
103451
103452                             if ( err )
103453                             return cb(err);
103454
103455                         // todo: this is *technically* subject to a race condition... but the
103456                         //       same peer should really not be synchronizing at the same time...
103457                         // todo: also potentially check Change.registered...
103458                         // TODO: this could be solved by:
103459                         //         a) never updating a Change record (only deleting and replacing)
103460                         //         b) deleting Change records by ID instead of by store/item/state...
103461
103462                         peerStore._delChange({
103463                             itemID    : locItemID,
103464                             state     : constant.ITEM_MODIFIED,
103465                         }, cb);
103466
103467                         });
103468
103469                     },
103470
103471                     //-------------------------------------------------------------------------
103472                     _settle_delete: function(session, cmd, chkcmd, xnode, cb) {
103473                         var self    = this;
103474                         var dsstate = session.info.dsstates[chkcmd.uri];
103475                         if ( ! session.isServer && cmd.data == constant.STATUS_UPDATE_CONFLICT )
103476                         {
103477                             dsstate.stats.hereErr   += 1;
103478                             dsstate.stats.conflicts += 1;
103479                             return cb();
103480                         }
103481                         if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_MERGE )
103482                         {
103483                             dsstate.stats.hereDel   += 1;
103484                             dsstate.stats.peerDel   += 1;
103485                             dsstate.stats.merged    += 1;
103486                         }
103487                         else if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_CLIENT_DATA )
103488                         {
103489                             dsstate.stats.peerDel   += 1;
103490                             dsstate.stats.merged    += 1;
103491                         }
103492                         else if ( ! session.isServer && cmd.data == constant.STATUS_CONFLICT_RESOLVED_SERVER_DATA )
103493                             dsstate.stats.merged    += 1;
103494                         else if ( cmd.data == constant.STATUS_ITEM_NOT_DELETED )
103495                         {
103496                             // note: the reason that this *may* be ok is that some servers (funambol)
103497                             //       will report ITEM_NOT_DELETED when the item did not exist, thus this
103498                             //       is "alright"...
103499                             // todo: perhaps this should be raised as an error if the
103500                             //       remote peer != funambol?...
103501                         }
103502                         else if ( cmd.data == constant.STATUS_OK )
103503                             dsstate.stats.peerDel += 1;
103504                         else
103505                             return cb(badStatus(xnode));
103506
103507                         var peerStore = session.peer.getStore(
103508                                 session.context.router.getTargetUri(
103509                                     session.adapter, session.peer, chkcmd.uri));
103510
103511                         // todo: handle hierarchical sync...
103512                         var get_locItemID = ( ! chkcmd.target ) ? function(cb) {
103513                             cb(null, chkcmd.source);
103514                         } : function(cb) {
103515                             self.getSourceMapping(
103516                                     session, constant.CMD_STATUS, cmd, peerStore, chkcmd.target,
103517                                     function(err, guid) { return cb(err, guid); }
103518                                     );
103519                         };
103520
103521                         // todo: this is *technically* subject to a race condition... but the
103522                         //       same peer should really not be synchronizing at the same time...
103523                         // todo: also potentially check Change.registered...
103524                         // TODO: this could be solved by:
103525                         //         a) never updating a Change record (only deleting and replacing)
103526                         //         b) deleting Change records by ID instead of by store/item/state...
103527
103528                         get_locItemID(function(err, locItemID) {
103529                             if ( err )
103530                             return cb(err);
103531                         peerStore._delChange({
103532                             itemID    : locItemID,
103533                             state     : constant.ITEM_DELETED,
103534                         }, cb);
103535                         });
103536
103537                     }
103538
103539     });
103540
103541     return exports;
103542
103543 })();
103544
103545 module.exports = _self;
103546
103547 });
103548 define('ripple/platform/tizen/2.0/syncml-js-lib/store', function (require, exports, module) {
103549 // -*- coding: utf-8 -*-
103550 //-----------------------------------------------------------------------------
103551 // file: $Id$
103552 // lib:  syncml-js.store
103553 // auth: griffin <griffin@uberdev.org>
103554 // date: 2012/11/04
103555 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
103556 //-----------------------------------------------------------------------------
103557
103558
103559 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
103560     constant = require('ripple/platform/tizen/2.0/syncml-js-lib/constant'),
103561     ctype = require('ripple/platform/tizen/2.0/syncml-js-lib/ctype'),
103562     storage = require('ripple/platform/tizen/2.0/syncml-js-lib/storage'),
103563     ET = require('ripple/platform/tizen/2.0/syncml-js-lib/elementtree');
103564
103565
103566 var _self = (function () {
103567     var exports = {};
103568
103569     //---------------------------------------------------------------------------
103570     exports.Store = common.Base.extend({
103571
103572         //-------------------------------------------------------------------------
103573         constructor: function(adapter, options) {
103574
103575             // todo: some of these attributes should be modifiable...
103576
103577             //: for local stores, specifies the agent that will implement
103578             //: the actual item operations -- it must implement the
103579             //: syncml-js.Agent API.
103580             this.agent = options.agent || null;
103581
103582             //: [read-only] specifies the SyncML URI that this store is bound to.
103583             this.uri = ( adapter ? adapter.normUri(options.uri) : options.uri ) || null;
103584
103585             //: [read-only] specifies the human-readable name for this store.
103586             //: if undefined, defaults to URI.
103587             this.displayName = options.displayName || this.uri || null;
103588
103589             //: [read-only] specifies the maximum GUID size for items in this store.
103590             //: if undefined, defaults to adapter setting.
103591             this.maxGuidSize = options.maxGuidSize || null;
103592
103593             //: [read-only] specifies the maximum object size for items in this store.
103594             //: if undefined, defaults to adapter setting.
103595             this.maxObjSize = options.maxObjSize || null;
103596
103597             //: [read-only] specifies conflict resolution policy for this store.
103598             //: if undefined, defaults to adapter setting.
103599             this.conflictPolicy = options.conflictPolicy || null;
103600
103601             //: [read-only] specifies which syncTypes this store supports.
103602             //: (defaults to all.)
103603             this.syncTypes = options.syncTypes;
103604             if ( this.syncTypes == undefined || this.syncTypes.length <= 0 )
103605             {
103606                 this.syncTypes = [
103607                     constant.SYNCTYPE_TWO_WAY,
103608                     constant.SYNCTYPE_SLOW_SYNC,
103609                     constant.SYNCTYPE_ONE_WAY_FROM_CLIENT,
103610                     constant.SYNCTYPE_REFRESH_FROM_CLIENT,
103611                     constant.SYNCTYPE_ONE_WAY_FROM_SERVER,
103612                     constant.SYNCTYPE_REFRESH_FROM_SERVER,
103613                     constant.SYNCTYPE_SERVER_ALERTED
103614                 ];
103615             }
103616
103617             ctypes = options.contentTypes;
103618             if ( ! ctypes && options.agent )
103619                 ctypes = options.agent.getContentTypes();
103620
103621             this.contentTypes = _.map(ctypes, function(e) {
103622                 if ( e instanceof ctype.ContentTypeInfo ) {
103623                     return e;
103624                 }
103625                 return ctype.ContentTypeInfo.fromStruct(e);
103626             });
103627
103628             // --- private attributes
103629             this.id       = options.id || common.makeID();
103630             this._a       = adapter;
103631         },
103632
103633         //-------------------------------------------------------------------------
103634         _load: function(cb) {
103635             cb();
103636         },
103637
103638         //-------------------------------------------------------------------------
103639         _getModel: function() {
103640             var self = this;
103641             var uri  = self._a.normUri(self.uri);
103642             return _.find(this._a._getModel().stores,
103643                     function(s) { return self._a.normUri(s.uri) == uri; });
103644         },
103645
103646         //-------------------------------------------------------------------------
103647         _updateModel: function(cb) {
103648             if ( ! this._a._model || ! this._a._model.stores )
103649                 return cb('store created on un-initialized adapter');
103650             // TODO: this squashes any data that may already be there, such
103651             //       as *BINDING* info!...
103652             this._a._model.stores = _.filter(this._a._model.stores, function(e) {
103653                 return e.uri != this.uri;
103654             }, this);
103655             this._a._model.stores.push({
103656                 id              : this.id,
103657                 uri             : this.uri,
103658                 displayName     : this.displayName,
103659                 syncTypes       : this.syncTypes,
103660                 maxGuidSize     : this.maxGuidSize,
103661                 maxObjSize      : this.maxObjSize,
103662                 conflictPolicy  : this.conflictPolicy,
103663                 contentTypes    : _.map(this.contentTypes, function(e) { return e.toStruct(); })
103664             });
103665             cb();
103666         },
103667
103668         //-------------------------------------------------------------------------
103669         _getBinding: function() {
103670             return this._getModel().binding;
103671         },
103672
103673         //-------------------------------------------------------------------------
103674         _setBinding: function(binding) {
103675             this._getModel().binding = binding;
103676         },
103677
103678         //-------------------------------------------------------------------------
103679         getContentTypes: function() {
103680             if ( this.agent != undefined ) {
103681                 return this.agent.getContentTypes();
103682             }
103683             return this.contentTypes;
103684         },
103685
103686         //-------------------------------------------------------------------------
103687         getPeerStore: function(peer) {
103688             var peerUri = null;
103689             if ( this._a.isLocal ) {
103690                 peerUri = this._a._c.router.getTargetUri(this._a, peer, this.uri);
103691             }
103692             else {
103693                 var binding = this.getBinding();
103694                 peerUri = binding ? binding.uri : null;
103695             }
103696             if ( ! peerUri ) {
103697                 return null;
103698             }
103699             return peer.getStore(peerUri);
103700         },
103701
103702         //-------------------------------------------------------------------------
103703         merge: function(store, cb) {
103704             if ( this.uri != store.uri )
103705                 return cb(new common.InternalError(
103706                                 'unexpected merging of stores with different URIs ("' + this.uri
103707                                     + '" != "' + store.uri + '")'));
103708             if ( ! _.isEqual(this.contentTypes, store.contentTypes) )
103709             {
103710                 // todo: this is a bit drastic... perhaps have an operational setting
103711                 //       which controls how paranoid to be?...
103712                 this._setBinding(null);
103713             }
103714             this.displayName    = store.displayName;
103715             this.contentTypes   = _.rest(store.contentTypes, 0);
103716             this.syncTypes      = _.rest(store.syncTypes, 0);
103717             this.maxGuidSize    = store.maxGuidSize;
103718             this.maxObjSize     = store.maxObjSize;
103719             this.agent          = store.agent;
103720             this.conflictPolicy = store.conflictPolicy;
103721             return cb();
103722         },
103723
103724         //-------------------------------------------------------------------------
103725         _clearAllMappings: function(cb) {
103726             if ( this._a.isLocal )
103727                 return cb(new common.InternalError(
103728                             'unexpected mapping request for local store'));
103729             var mapping = this._a._c._txn().objectStore('mapping');
103730             storage.deleteAll(mapping, {store_id: this.id}, cb);
103731         },
103732
103733         //-------------------------------------------------------------------------
103734         _setMapping: function(guid, luid, cb) {
103735             var self = this;
103736             if ( this._a.isLocal )
103737                 return cb(new common.InternalError(
103738                             'unexpected mapping request for local store'));
103739             // delete all previous mappings for this guid/store (there should
103740             // be at most one)... but paranoia rules.
103741             var mapping = this._a._c._txn().objectStore('mapping');
103742             storage.deleteAll(mapping, {store_id: this.id, guid: guid}, function(err) {
103743                 if ( err ) {
103744                     return cb(err);
103745                 }
103746                 storage.put(mapping, {store_id: self.id, guid: guid, luid: luid}, function(err) {
103747                     if ( err ) {
103748                         return cb(err);
103749                     }
103750                     cb();
103751                 });
103752             });
103753         },
103754
103755         //-------------------------------------------------------------------------
103756         _getMapping: function(guid, cb) {
103757             if ( this._a.isLocal )
103758                 return cb(new common.InternalError(
103759                             'unexpected mapping request for local store'));
103760             // todo: there must be a way to use IndexedDB since i have everything
103761             //       needed to generate the keyPath!... eg:
103762             //         objectStore.get({store_id:X,guid:Y})?...
103763             var mapdb = this._a._c._txn().objectStore('mapping').index('store_id');
103764             storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) {
103765                 if ( err ) {
103766                     return cb(err);
103767                 }
103768                 var item = _.find(list, function(item) {
103769                     return item.guid == guid;
103770                 });
103771                 return cb(null, item ? item.luid : null);
103772             });
103773         },
103774
103775         //-------------------------------------------------------------------------
103776         _getMappings: function(cb) {
103777             if ( this._a.isLocal )
103778                 return cb(new common.InternalError(
103779                             'unexpected mapping request for local store'));
103780             var mapdb = this._a._c._txn().objectStore('mapping').index('store_id');
103781             storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) {
103782                 if ( err )
103783                     return cb(err);
103784                 return cb(null, _.map(list, function(item) {
103785                     return [item.guid, item.luid];
103786                 }));
103787             });
103788         },
103789
103790         //-------------------------------------------------------------------------
103791         _getReverseMapping: function(luid, cb) {
103792             if ( this._a.isLocal )
103793                 return cb(new common.InternalError(
103794                             'unexpected mapping request for local store'));
103795             // todo: there must be a way to use IndexedDB since i have everything
103796             //       needed to generate the keyPath!... eg:
103797             //         objectStore.get({store_id:X,guid:Y})?...
103798             var mapdb = this._a._c._txn().objectStore('mapping').index('store_id');
103799             storage.getAll(this._a._c, mapdb, {only: this.id}, function(err, list) {
103800                 if ( err )
103801                     return cb(err);
103802                 var item = _.find(list, function(item) {
103803                     return item.luid == luid;
103804                 });
103805                 return cb(null, item ? item.guid : null);
103806             });
103807         },
103808
103809         //-------------------------------------------------------------------------
103810         registerChange: function(itemID, state, options, cb) {
103811             // options can include:
103812             //   - changeSpec (string)
103813             //   - excludePeerID (string)
103814
103815             if ( ! _.contains([constant.ITEM_ADDED, constant.ITEM_MODIFIED,
103816                         constant.ITEM_DELETED], state) )
103817                 return cb(new common.TypeError(
103818                             'registerChange: invalid state "' + state + '"'));
103819
103820             options = options || {};
103821             var self = this;
103822             if ( self._a.isLocal )
103823             {
103824                 // TODO: THIS NEEDS TO BE SIGNIFICANTLY OPTIMIZED!... either:
103825                 //         a) optimize this reverse lookup, or
103826                 //         b) use a query that targets exactly the set of stores needed
103827                 //       note that a pre-emptive model.session.flush() may be necessary.
103828                 common.cascade(self._a.getPeers(), function(peer, cb) {
103829                     if ( options.excludePeerID && options.excludePeerID == peer.id )
103830                         return cb();
103831                     common.cascade(peer.getStores(), function(store, cb) {
103832                         var binding = store._getBinding()
103833                         if ( ! binding || binding.uri != self.uri )
103834                             return cb();
103835                         store.registerChange(itemID, state, options, cb);
103836                     }, cb);
103837                 }, cb);
103838                 return;
103839             }
103840
103841             // todo: a non-ADD change event for an ID that has never been
103842             // seen does not create an error... should it??? that would mean
103843             // that syncml-js needs to track that. not a good idea.
103844
103845             itemID = '' + itemID;
103846             var handled = false;
103847
103848             // paranoia
103849             if ( options.changeSpec && state != constant.ITEM_MODIFIED )
103850             {
103851                 options.changeSpec = null;
103852             }
103853
103854             var check_update = function(cb) {
103855                 self._getChange(itemID, function(err, change) {
103856                     if ( err )
103857                         return cb(err);
103858                     if ( ! change)
103859                         return cb();
103860                     var badstate = function(action) {
103861                     };
103862                 // note: many of the following change.state / state combinations
103863                 // should never occur. the following tries to recover gracefully.
103864                 // todo: should i raise an error for "illogical" conditions?
103865                     switch ( change.state )
103866                     {
103867                     case constant.ITEM_ADDED:
103868                     {
103869                         if ( state != constant.ITEM_DELETED )
103870                         {
103871                             // ADD + anything except DELETE stays ADD
103872                             handled = true;
103873                             return cb();
103874                         }
103875                         // ADD + DELETE cancels out
103876                         handled = true;
103877                         var changeTab = self._a._c._txn().objectStore('change');
103878                         storage.deleteAll(changeTab, change, function(err) {
103879                             if ( err )
103880                                 return cb(err);
103881                             return cb();
103882                         });
103883                         return;
103884                     }
103885                     case constant.ITEM_MODIFIED:
103886                     {
103887                         if ( state == constant.ITEM_ADDED )
103888                         {
103889                             badstate('squelching changeSpec');
103890                             delete change.changeSpec;
103891                             break;
103892                         }
103893                         if ( state == constant.ITEM_DELETED )
103894                         {
103895                             change.state = state;
103896                             delete change.changeSpec;
103897                             break;
103898                         }
103899                         if ( change.changeSpec )
103900                         {
103901                             if ( options.changeSpec )
103902                                 change.changeSpec += ';' + options.changeSpec;
103903                             else
103904                                 delete change.changeSpec;
103905                         }
103906                         break;
103907                     }
103908                     case constant.ITEM_DELETED:
103909                     {
103910                         if ( state == constant.ITEM_DELETED )
103911                         {
103912                             badstate('ignoring');
103913                             handled = true;
103914                             return cb();
103915                         }
103916                         badstate('reverting to modified');
103917                         change.state = constant.ITEM_MODIFIED;
103918                         delete change.changeSpec;
103919                         break;
103920                     }
103921                     default:
103922                     {
103923                         return cb(new common.InternalError(
103924                                     'unexpected recorded change state "' + change.state
103925                                     + '" for item ID "' + itemID + '"'));
103926                     }
103927                     }
103928                     // update the change
103929                     // todo: do i need to delete it first?
103930                     handled = true;
103931                     return storage.put(
103932                         self._a._c._txn().objectStore('change'),
103933                         change,
103934                         cb);
103935                 });
103936             };
103937
103938             var check_mapping = ( self._a._isMapper() || state == constant.ITEM_ADDED )
103939                 ? common.noop
103940                 : function(cb) {
103941                     // doing a `_getMapping` for non-add events to make sure that
103942                     // the remote peer actually has this object before we tell it
103943                     // to modify or delete an item...
103944                     self._getMapping(itemID, function(err, luid) {
103945                         if ( err )
103946                         return cb(err);
103947                     if ( luid )
103948                         return cb();
103949                     // this item does not exist as (or has not been mapped to) an
103950                     // item on the remote peer and is not an `ADD` event, so can
103951                     // therefore be ignored - mark it as "handled".
103952                     handled = true;
103953                     return cb();
103954                     });
103955                 };
103956
103957             // todo: there is a weirdness here wrt `handled` in the case
103958             //       of check_mapping and deletes... ie. there is a bit of
103959             //       a responsibility violation (handled does not actually
103960             //       mean handled...)
103961
103962             check_update(function(err) {
103963                 if ( err )
103964                     return cb(err);
103965                 if ( handled )
103966                     return cb();
103967                 check_mapping(function(err) {
103968                     if ( err )
103969                         return cb(err);
103970                     if ( handled && state != constant.ITEM_DELETED )
103971                         return cb();
103972                     // note: if it is a delete event, and it has not been mapped
103973                     // yet, so does not yet exist on the peer, therefore
103974                     // propagate nothing -- continuing just to execute the
103975                     // deleteAll().
103976                     var changeTab = self._a._c._txn().objectStore('change');
103977                     change = {store_id: self.id, item_id: itemID};
103978                     // todo: is this deleteAll really necessary?... paranoia rules!
103979                     storage.deleteAll(changeTab, change, function(err) {
103980                         if ( err )
103981                             return cb(err);
103982                         if ( handled )
103983                             return cb();
103984                         change.state = state;
103985                         change.changeSpec = options.changeSpec;
103986                         storage.put(changeTab, change, cb);
103987                     });
103988                 });
103989             });
103990         },
103991
103992         //-------------------------------------------------------------------------
103993         _getChange: function(itemID, cb) {
103994             // returns cb(null, CHANGE)
103995             // change ::= { store_id: ID, item_id: GUID, state: STATE, changeSpec: SPEC }
103996             itemID = '' + itemID;
103997             var self = this;
103998             // todo: there must be a way to use IndexedDB since i have everything
103999             //       needed to generate the keyPath!... eg:
104000             //         objectStore.get({store_id:X,guid:Y})?...
104001             var changedb = self._a._c._txn().objectStore('change').index('store_id');
104002             storage.getAll(self._a._c, changedb, {only: self.id}, function(err, changes) {
104003                 if ( err )
104004                     return cb(err);
104005                 var change = _.find(changes, function(change) {
104006                     return change.item_id == itemID;
104007                 });
104008                 return cb(null, change);
104009             });
104010         },
104011
104012         //-------------------------------------------------------------------------
104013         _delChange: function(options, cb) {
104014             // - if options is null/empty, delete all changes recorded
104015             //   for this store
104016
104017             // // todo: this is *technically* subject to a race condition... but the
104018             // //       same peer should really not be synchronizing at the same time...
104019             // // todo: also potentially check Change.registered...
104020             // // TODO: this could be solved by:
104021             // //         a) never updating a Change record (only deleting and replacing)
104022             // //         b) deleting Change records by ID instead of by store/item/state...
104023
104024             // var objstore = session.context._txn().objectStore('change');
104025             // storage.iterateCursor(
104026             //   objstore.index('store_id').openCursor(peerStore.id),
104027             //   function(value, key, cb) {
104028             //     if ( value.itemID != chkcmd.source || value.state != constant.ITEM_ADDED )
104029             //       return;
104030             //     storage.delete(objstore, key, cb);
104031             //   }, cb);
104032
104033             var dbstore = this._a._c._txn().objectStore('change');
104034             var matches = {store_id: this.id};
104035             if ( options.itemID )
104036                 matches.item_id = options.itemID;
104037             if ( options.state )
104038                 matches.state = options.state;
104039             storage.deleteAll(dbstore, matches, cb);
104040         },
104041
104042         //-------------------------------------------------------------------------
104043         toSyncML: function() {
104044             var xstore = ET.Element('DataStore');
104045             if ( this.uri )
104046                 ET.SubElement(xstore, 'SourceRef').text = this.uri;
104047             if ( this.displayName )
104048                 ET.SubElement(xstore, 'DisplayName').text = this.displayName;
104049             if ( this.maxGuidSize )
104050             {
104051                 // todo: this should ONLY be sent by the client... (according to the
104052                 //       spec, but not according to funambol behavior...)
104053                 ET.SubElement(xstore, 'MaxGUIDSize').text = this.maxGuidSize;
104054             }
104055             if ( this.maxObjSize )
104056                 ET.SubElement(xstore, 'MaxObjSize').text = this.maxObjSize;
104057
104058             var ctypes = this.getContentTypes();
104059
104060             if ( ctypes && ctypes.length > 0 )
104061             {
104062                 var pref = _.filter(ctypes, function(ct) { return ct.receive && ct.preferred; });
104063
104064                 // todo: should i just take the first one?...
104065                 if ( pref.length > 1 )
104066                     throw new Error('agents can prefer at most one receive content-type');
104067
104068                 if ( pref.length == 1 )
104069                 {
104070                     pref = pref[0].toSyncML('Rx', true);
104071                     pref[0].tag = 'Rx-Pref';
104072                     _.each(pref, function(xnode) { xstore.append(xnode); });
104073                 }
104074
104075                 _.each(
104076                         _.filter(ctypes, function(ct) { return ct.receive && ! ct.preferred; }),
104077                         function(ct) {
104078                             _.each(ct.toSyncML('Rx', true), function(xnode) {
104079                                 xstore.append(xnode);
104080                             });
104081                         });
104082
104083                 var pref = _.filter(ctypes, function(ct) { return ct.transmit && ct.preferred; });
104084
104085                 // todo: should i just take the first one?...
104086                 if ( pref.length > 1 )
104087                     throw new Error('agents can prefer at most one transmit content-type');
104088
104089                 if ( pref.length == 1 )
104090                 {
104091                     pref = pref[0].toSyncML('Tx', true);
104092                     pref[0].tag = 'Tx-Pref';
104093                     _.each(pref, function(xnode) { xstore.append(xnode); });
104094                 }
104095
104096                 _.each(
104097                         _.filter(ctypes, function(ct) { return ct.transmit && ! ct.preferred; }),
104098                         function(ct) {
104099                             _.each(ct.toSyncML('Tx', true), function(xnode) {
104100                                 xstore.append(xnode);
104101                             });
104102                         });
104103
104104             }
104105
104106             if ( this.syncTypes && this.syncTypes.length > 0 )
104107             {
104108                 var xcap = ET.SubElement(xstore, 'SyncCap');
104109                 for ( var idx=0 ; idx<this.syncTypes.length ; idx++ )
104110                     ET.SubElement(xcap, 'SyncType').text = this.syncTypes[idx];
104111             }
104112             return xstore;
104113
104114         },
104115
104116         //-------------------------------------------------------------------------
104117         describe: function(stream, cb) {
104118             stream.writeln('URI: ' + this.uri);
104119             stream.writeln('Max ID size: ' + ( this.maxGuidSize || '(none)' ));
104120             stream.writeln('Max object size: ' + ( this.maxObjSize || '(none)' ));
104121             stream.writeln('Sync types: ' + this.syncTypes.join(', '));
104122             var cts = this.getContentTypes();
104123             if ( cts.length <= 0 )
104124             {
104125                 stream.writeln('Capabilities: (none)');
104126                 return cb();
104127             }
104128             stream.writeln('Capabilities:');
104129             var s1 = new common.IndentStream(stream);
104130             common.cascade(cts, function(ct, cb) {
104131                 s1.write('- ');
104132                 ct.describe(s1);
104133                 return cb();
104134             }, cb);
104135         }
104136     }, {
104137
104138         //-------------------------------------------------------------------------
104139         fromSyncML: function(xnode) {
104140             var options = {
104141                 uri          : xnode.findtext('SourceRef'),
104142                 displayName  : xnode.findtext('DisplayName'),
104143                 maxGuidSize  : common.int(xnode.findtext('MaxGUIDSize')),
104144                 maxObjSize   : common.int(xnode.findtext('MaxObjSize')),
104145                 contentTypes : [],
104146                 syncTypes    : _.map(xnode.findall('SyncCap/SyncType'), function(e) {
104147                     return common.int(e.text);
104148                 })
104149             };
104150             _.each(xnode.getchildren(), function(child) {
104151                 if ( _.indexOf(['Rx-Pref', 'Rx', 'Tx-Pref', 'Tx'], child.tag) < 0 )
104152                 return;
104153             var cti = ctype.ContentTypeInfo.fromSyncML(child);
104154             var merged = false;
104155             _.each(options.contentTypes, function(ct) {
104156                 if ( merged )
104157                 return;
104158             if ( ct.merge(cti) )
104159                 merged = true;
104160             });
104161             if ( ! merged )
104162                 options.contentTypes.push(cti);
104163             });
104164             return new exports.Store(null, options);
104165         },
104166     });
104167
104168     return exports;
104169
104170 })();
104171
104172 module.exports = _self;
104173
104174 });
104175 define('ripple/platform/tizen/2.0/syncml-js-lib/matcher', function (require, exports, module) {
104176 // -*- coding: utf-8 -*-
104177 //-----------------------------------------------------------------------------
104178 // file: $Id$
104179 // lib:  syncml-js.matcher
104180 // auth: griffin <griffin@uberdev.org>
104181 // date: 2012/12/05
104182 // copy: (C) CopyLoose 2012 UberDev <hardcore@uberdev.org>, No Rights Reserved.
104183 //-----------------------------------------------------------------------------
104184
104185 var common = require('ripple/platform/tizen/2.0/syncml-js-lib/common'),
104186     _self;
104187
104188 _self = (function () {
104189
104190     var exports = {};
104191
104192     //---------------------------------------------------------------------------
104193     exports._cntpref = function(source, target) {
104194         return ( source.preferred ? 1 : 0 ) + ( target.preferred ? 1 : 0 );
104195     };
104196
104197     //---------------------------------------------------------------------------
104198     exports._pickTransmitContentType = function(source, target, prefcnt, checkVersion) {
104199         for ( var sidx=0 ; sidx<source.length ; sidx++ )
104200 {
104201     var sct = source[sidx];
104202     for ( var tidx=0 ; tidx<target.length ; tidx++ )
104203 {
104204     var tct = target[tidx];
104205     if ( sct.ctype != tct.ctype )
104206     continue;
104207 if ( ! checkVersion )
104208 {
104209     if ( exports._cntpref(sct, tct) >= prefcnt )
104210         return [sct.ctype, sct.versions[sct.versions.length - 1]];
104211     continue;
104212 }
104213 for ( var svidx=sct.versions.length ; svidx>0 ; svidx-- )
104214 {
104215     var sv = sct.versions[svidx - 1]
104216         for ( var tvidx=tct.versions.length ; tvidx>0 ; tvidx-- )
104217         {
104218             var tv = tct.versions[tvidx - 1]
104219                 if ( sv != tv )
104220                     continue;
104221             if ( exports._cntpref(sct, tct) >= prefcnt )
104222                 return [sct.ctype, sv];
104223         }
104224 }
104225 }
104226 }
104227 return null;
104228 };
104229
104230 //---------------------------------------------------------------------------
104231 exports.pickTransmitContentType = function(source, target) {
104232
104233     // TODO: this is probably not the most efficient algorithm!...
104234     //       (but it works... ;-)
104235
104236     // order of preference:
104237     //   - transmit => receive, BOTH preferred, VERSION match
104238     //   - transmit => receive, ONE preferred, VERSION match
104239     //   - transmit => receive, neither preferred, VERSION match
104240     //   - transmit => receive, BOTH preferred, no version match
104241     //   - transmit => receive, ONE preferred, no version match
104242     //   - transmit => receive, neither preferred, no version match
104243     //   - tx/rx => tx/rx, BOTH preferred, VERSION match
104244     //   - tx/rx => tx/rx, ONE preferred, VERSION match
104245     //   - tx/rx => tx/rx, neither preferred, VERSION match
104246     //   - tx/rx => tx/rx, BOTH preferred, no version match
104247     //   - tx/rx => tx/rx, ONE preferred, no version match
104248     //   - tx/rx => tx/rx, neither preferred, no version match
104249
104250     // todo: make it explicit (or overrideable) that i am depending on the ordering
104251     //       of the versions supported to give an indicator of preference...
104252
104253     var sct = source.getContentTypes();
104254     var tct = target.getContentTypes();
104255
104256     var fct = function(cts, transmit) {
104257         return _.filter(cts, function(ct) {
104258             return transmit ? ct.transmit : ct.receive;
104259         });
104260     };
104261
104262     return exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 2, true)
104263         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 1, true)
104264         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 0, true)
104265         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 2, false)
104266         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 1, false)
104267         || exports._pickTransmitContentType(fct(sct, true), fct(tct, false), 0, false)
104268         || exports._pickTransmitContentType(sct, tct, 2, true)
104269         || exports._pickTransmitContentType(sct, tct, 1, true)
104270         || exports._pickTransmitContentType(sct, tct, 0, true)
104271         || exports._pickTransmitContentType(sct, tct, 2, false)
104272         || exports._pickTransmitContentType(sct, tct, 1, false)
104273         || exports._pickTransmitContentType(sct, tct, 0, false)
104274         || null;
104275
104276 };
104277
104278 // TODO: OH MY GOD.
104279 //       this is insanely inefficient.
104280 //       i'm embarrassed.
104281 //       fortunately, it's hidden really low-level...
104282 //       but now you know, doh! please don't blackmail me!... ;-)
104283
104284 // TODO: this currently requires that both tx and rx match in both
104285 //       directions with the same velocity... it should prioritize
104286 //       that, but then fallback to giving simplex matches priority.
104287
104288 //---------------------------------------------------------------------------
104289 var has_ct = function(a, b, checkVersion, transmit, wildcard) {
104290     a = _.filter(a, function(e) { return transmit ? e.transmit : e.receive });
104291     b = _.filter(b, function(e) { return transmit ? e.transmit : e.receive });
104292     for ( var aidx=0 ; aidx<a.length ; aidx++ )
104293     {
104294         var ct_a = a[aidx];
104295         for ( var bidx=0 ; bidx<b.length ; bidx++ )
104296         {
104297             var ct_b = b[bidx];
104298             if ( ct_a.ctype != ct_b.ctype )
104299                 continue;
104300             if ( ! checkVersion )
104301                 return true;
104302             for ( var vaidx=0 ; vaidx<ct_a.versions.length ; vaidx++ )
104303             {
104304                 var va = ct_a.versions[vaidx];
104305                 for ( var vbidx=0 ; vbidx<ct_b.length ; vbidx++ )
104306                 {
104307                     var vb = ct_b.versions[vbidx];
104308                     if ( va == vb )
104309                         return true;
104310                 }
104311             }
104312         }
104313     } 
104314     return false;
104315 };
104316
104317 //---------------------------------------------------------------------------
104318 var has_ct_both = function(a, b, checkVersion, wildcard) {
104319     return has_ct(a, b, checkVersion, true, wildcard)
104320         && has_ct(a, b, checkVersion, false, wildcard);
104321 };
104322
104323 //---------------------------------------------------------------------------
104324 var cmpStore_ct_set_crit = function(base, ds1, ds2, checkVersion, wildcard) {
104325     var bds1 = has_ct_both(base, ds1, checkVersion, wildcard);
104326     var bds2 = has_ct_both(base, ds2, checkVersion, wildcard);
104327     if ( bds1 && bds2 )
104328         return 0;
104329     if ( bds1 )
104330         return -1;
104331     if ( bds2 )
104332         return 1;
104333     return 0;
104334 };
104335
104336 //---------------------------------------------------------------------------
104337 var cmpStore_ct_set = function(base, ds1, ds2) {
104338     var ret = cmpStore_ct_set_crit(base, ds1, ds2, true, false);
104339     if ( ret != 0 )
104340         return ret;
104341     ret = cmpStore_ct_set_crit(base, ds1, ds2, false, false);
104342     if ( ret != 0 )
104343         return ret;
104344     ret = cmpStore_ct_set_crit(base, ds1, ds2, true, true);
104345     if ( ret != 0 )
104346         return ret;
104347     ret = cmpStore_ct_set_crit(base, ds1, ds2, false, true);
104348     if ( ret != 0 )
104349         return ret;
104350     return 0;
104351 };
104352
104353 //---------------------------------------------------------------------------
104354 var getct = function(store) {
104355     return store.getContentTypes ? store.getContentTypes() : store.contentTypes;
104356 };
104357
104358 //---------------------------------------------------------------------------
104359 var cmpStore_ct_pref = function(base, ds1, ds2) {
104360     var basect = _.filter(getct(base), function(ct) { return ct.preferred; });
104361     var ds1ct  = _.filter(getct(ds1), function(ct) { return ct.preferred; });
104362     var ds2ct  = _.filter(getct(ds2), function(ct) { return ct.preferred; });
104363     return cmpStore_ct_set(basect, ds1ct, ds2ct);
104364 };
104365
104366 //---------------------------------------------------------------------------
104367 var cmpStore_ct_all = function(base, ds1, ds2) {
104368     return cmpStore_ct_set(getct(base), getct(ds1), getct(ds2));
104369 };
104370
104371 //---------------------------------------------------------------------------
104372 var cmpStore_ct = function(base, ds1, ds2) {
104373     var ret = cmpStore_ct_pref(base, ds1, ds2)
104374         if ( ret != 0 )
104375             return ret;
104376     return cmpStore_ct_all(base, ds1, ds2);
104377 };
104378
104379 //---------------------------------------------------------------------------
104380 var cmpStore_uri = function(base, ds1, ds2) {
104381     var ret = difflib.getCloseMatches(base.uri, [ds1.uri, ds2.uri], 1, 0.5);
104382     if ( ret.length <= 0 )
104383         return 0;
104384     if ( ret[0] == ds1.uri )
104385         return -1;
104386     return 1;
104387 };
104388
104389 //---------------------------------------------------------------------------
104390 exports.cmpStore = function(base, ds1, ds2) {
104391     var ret = cmpStore_ct(base, ds1, ds2);
104392     if ( ret != 0 )
104393         return ret;
104394     return cmpStore_uri(base, ds1, ds2);
104395 };
104396
104397 return exports;
104398
104399 })();
104400
104401 module.exports = _self;
104402
104403
104404 });
104405 define('ripple/platform/tizen/2.0/NDEFMessage', function (require, exports, module) {
104406 /*
104407  *  Copyright 2013 Intel Corporation
104408  *
104409  * Licensed under the Apache License, Version 2.0 (the "License");
104410  * you may not use this file except in compliance with the License.
104411  * You may obtain a copy of the License at
104412  *
104413  * http://www.apache.org/licenses/LICENSE-2.0
104414  *
104415  * Unless required by applicable law or agreed to in writing, software
104416  * distributed under the License is distributed on an "AS IS" BASIS,
104417  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
104418  * See the License for the specific language governing permissions and
104419  * limitations under the License.
104420  */
104421
104422 var t = require('ripple/platform/tizen/2.0/typecast'),
104423     NDEFRecord = require('ripple/platform/tizen/2.0/NDEFRecord'),
104424     NDEFRecordText = require('ripple/platform/tizen/2.0/NDEFRecordText'),
104425     NDEFRecordURI = require('ripple/platform/tizen/2.0/NDEFRecordURI'),
104426     NDEFRecordMedia = require('ripple/platform/tizen/2.0/NDEFRecordMedia'),
104427     NDEFRecordFactory,
104428     NDEFMessage;
104429
104430 NDEFRecordFactory = function (ndefRecord) {
104431     var record;
104432
104433     if (ndefRecord instanceof NDEFRecordText) {
104434         record = new NDEFRecordText(ndefRecord.text, ndefRecord.languageCode,
104435                 ndefRecord.encoding || null);
104436     } else if (ndefRecord instanceof NDEFRecordURI) {
104437         record = new NDEFRecordURI(ndefRecord.url);
104438     } else if (ndefRecord instanceof NDEFRecordMedia) {
104439         record = new NDEFRecordMedia(ndefRecord.mimeType, ndefRecord.payload);
104440     } else {
104441         record = new NDEFRecord(ndefRecord.tnf, ndefRecord.type,
104442                 ndefRecord.payload, ndefRecord.id || null);
104443     }
104444
104445     return record;
104446 };
104447
104448 NDEFMessage = function () {
104449     var voc, records = [];
104450
104451     // private
104452     function construct() {
104453         this.__defineGetter__("recordCount", function () {
104454             return this.records.length;
104455         });
104456
104457         this.__defineGetter__("records", function () {
104458             return records;
104459         });
104460
104461         this.__defineSetter__("records", function (val) {
104462             try {
104463                 t.NDEFRecord(val, "[]");
104464                 records = val;
104465             } catch (e) {
104466             }
104467         });
104468
104469         this.toByte = function () {
104470             var result = [], i, j, space = " ".charCodeAt(0);
104471
104472             for (i in this.records) {
104473                 for (j = 0; j < this.records[i].payload.length; j++) {
104474                     result.push(this.records[i].payload.charCodeAt(j));
104475                 }
104476                 if (i < this.records.length - 1) {
104477                     result.push(space);
104478                 }
104479             }
104480
104481             return result;
104482         };
104483     }
104484
104485     // constructor
104486     function NDEFMessage_NDEFRecords(ndefRecords) {
104487         var i;
104488
104489         construct.apply(this);
104490
104491         for (i = 0; i < ndefRecords.length; i++) {
104492             records[i] = new NDEFRecordFactory(ndefRecords[i]);
104493         }
104494     }
104495
104496     function NDEFMessage_bytes(rawData) {
104497         //TODO: NDEFMessage doesn't support rawData constructor
104498         construct.apply(this);
104499     }
104500
104501     function NDEFMessage_void() {
104502         construct.apply(this);
104503     }
104504
104505     voc = [NDEFMessage_NDEFRecords, NDEFMessage_bytes, NDEFMessage_void];
104506     t.NDEFMessage(arguments, this, voc);
104507 };
104508
104509 module.exports = NDEFMessage;
104510
104511 });
104512 define('ripple/platform/tizen/2.0/bluetooth', function (require, exports, module) {
104513 /*
104514  *  Copyright 2013 Intel Corporation.
104515  *
104516  * Licensed under the Apache License, Version 2.0 (the "License");
104517  * you may not use this file except in compliance with the License.
104518  * You may obtain a copy of the License at
104519  *
104520  * http://www.apache.org/licenses/LICENSE-2.0
104521  *
104522  * Unless required by applicable law or agreed to in writing, software
104523  * distributed under the License is distributed on an "AS IS" BASIS,
104524  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
104525  * See the License for the specific language governing permissions and
104526  * limitations under the License.
104527  */
104528
104529 var utils = require('ripple/utils'),
104530     db = require('ripple/db'),
104531     event = require('ripple/event'),
104532     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
104533     t = require('ripple/platform/tizen/2.0/typecast'),
104534     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
104535     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
104536     BluetoothDevice = require('ripple/platform/tizen/2.0/BluetoothDevice'),
104537     BluetoothClassDeviceMajor = require('ripple/platform/tizen/2.0/BluetoothClassDeviceMajor'),
104538     BluetoothClassDeviceMinor = require('ripple/platform/tizen/2.0/BluetoothClassDeviceMinor'),
104539     BluetoothClassDeviceService = require('ripple/platform/tizen/2.0/BluetoothClassDeviceService'),
104540     BluetoothServiceHandler = require('ripple/platform/tizen/2.0/BluetoothServiceHandler'),
104541     BluetoothAdapter,
104542     _data = {
104543         DB_BLUETOOTH_KEY: "tizen1-db-bluetooth_adapter-name",
104544         DEFAULT_ADAPTER_NAME: "Tizen BT Adapter",
104545         DEFAULT_ADAPTER_ADDRESS: "12:34:56:78:90:AB",
104546         availableDevsChanging: false,
104547         DEFAULT_VISIBLE_TIME: 180000,
104548         DISCOVER_TIME: 10000,
104549         DISCOVER_INTERVAL: 1000,
104550         bluetoothClassDeviceMajor: {},
104551         bluetoothClassDeviceMinor: {},
104552         bluetoothClassDeviceService: {},
104553         adapter: {},
104554         historyDevs: {},
104555         availableDevs: {},
104556         localServices: {}
104557     },
104558     _security = {
104559         "http://tizen.org/privilege/bluetoothmanager": ["setVisible"],
104560         "http://tizen.org/privilege/bluetooth.admin": ["setName", "setPowered"],
104561         "http://tizen.org/privilege/bluetooth.gap": ["getDefaultAdapter",
104562                 "discoverDevices", "stopDiscovery", "getKnownDevices",
104563                 "getDevice", "createBonding", "destroyBonding", "hasService"],
104564         "http://tizen.org/privilege/bluetooth.spp":
104565                 ["registerRFCOMMServiceByUUID", "connectToServiceByUUID",
104566                 "writeData", "readData", "close", "unregister"]
104567     },
104568     _self;
104569
104570 function _initialize() {
104571     var adapterName, devs;
104572
104573     _data.bluetoothClassDeviceMajor = new BluetoothClassDeviceMajor();
104574     _data.bluetoothClassDeviceMinor = new BluetoothClassDeviceMinor();
104575     _data.bluetoothClassDeviceService = new BluetoothClassDeviceService();
104576     adapterName = db.retrieveObject(_data.DB_BLUETOOTH_KEY) ||
104577             _data.DEFAULT_ADAPTER_NAME;
104578     _data.adapter = new BluetoothAdapter(adapterName,
104579             _data.DEFAULT_ADAPTER_ADDRESS);
104580
104581     // get defalt nearby devices
104582     devs = db.retrieveObject("bt-simulated-devices");
104583     utils.forEach(devs, function (item) {
104584         if (!_data.availableDevs[item.address]) {
104585             _data.availableDevs[item.address] = new BluetoothDevice({
104586                 name: item.name,
104587                 address: item.address,
104588                 deviceClass: item.deviceClass,
104589                 isBonded: false,
104590                 isTrusted: item.isTrusted,
104591                 isConnected: false,
104592                 services: item.services,
104593                 metaData: _security
104594             });
104595         }
104596     });
104597 }
104598
104599 BluetoothAdapter = function (devName, devAddress) {
104600     var adapter,
104601         timeoutVar,
104602         _devName = devName,
104603         _devAddress = devAddress,
104604         _devPowered = false,
104605         _devVisible = false,
104606         _isDiscovering = false,
104607         discoverInterval;
104608
104609     // private
104610     function updateVisibleStatus(status, time) {
104611         if (!_devPowered)
104612             return;
104613
104614         _devVisible = status;
104615         event.trigger("bt-adapter-visible-changed", [_devVisible]);
104616         if (_devVisible) {
104617             if (time > 0) {
104618                 timeoutVar = window.setTimeout(function () {
104619                     _devVisible = false;
104620                     event.trigger("bt-adapter-visible-changed", [_devVisible]);
104621                 }, time);
104622             }
104623         } else {
104624             window.clearTimeout(timeoutVar);
104625         }
104626     }
104627
104628     function updatePowerStatus(status) {
104629         if (_devPowered === status) {
104630             return;
104631         }
104632         if (!status) {
104633             updateVisibleStatus(false);
104634             utils.forEach(_data.historyDevs, function (dev) {
104635                 event.trigger("bt-service-state-update", [dev.address, false]);
104636                 event.trigger("bt-device-bonded-changed", [dev.address, false]);
104637                 jQuery("#service-transfer-textarea-" + dev.address.replace(/:/g, "")).val("");
104638                 jQuery("#service-receive-textarea-" + dev.address.replace(/:/g, "")).html("");
104639             });
104640         }
104641         _devPowered = status;
104642         event.trigger("bt-adapter-power-changed", [_devPowered]);
104643     }
104644
104645     // public
104646     function setName(name, successCallback, errorCallback) {
104647         if (!_security.setName) {
104648             throw new WebAPIException(errorcode.SECURITY_ERR);
104649         }
104650
104651         t.BluetoothAdapter("setName", arguments);
104652
104653         window.setTimeout(function () {
104654             if (!_devPowered) {
104655                 if (errorCallback) {
104656                     errorCallback(new WebAPIError(
104657                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104658                 }
104659                 return;
104660             }
104661
104662             _devName = name;
104663             db.saveObject(_data.DB_BLUETOOTH_KEY, _devName);
104664             event.trigger("bt-adapter-name-changed", [_devName]);
104665             if (successCallback) {
104666                 successCallback();
104667             }
104668         }, 1);
104669     }
104670
104671     function setPowered(state, successCallback, errorCallback) {
104672         if (!_security.setPowered) {
104673             throw new WebAPIException(errorcode.SECURITY_ERR);
104674         }
104675
104676         t.BluetoothAdapter("setPowered", arguments);
104677
104678         window.setTimeout(function () {
104679             updatePowerStatus(state);
104680             if (successCallback) {
104681                 successCallback();
104682             }
104683         }, 1);
104684     }
104685
104686     function setVisible(mode, successCallback, errorCallback, timeout) {
104687         if (!_security.setVisible) {
104688             throw new WebAPIException(errorcode.SECURITY_ERR);
104689         }
104690
104691         t.BluetoothAdapter("setVisible", arguments);
104692
104693         window.setTimeout(function () {
104694             var time;
104695
104696             if (!_devPowered) {
104697                 if (errorCallback) {
104698                     errorCallback(new WebAPIError(
104699                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104700                 }
104701                 return;
104702             }
104703
104704             if (typeof timeout === "number") {
104705                 if (timeout < 0) {
104706                     time = _data.DEFAULT_VISIBLE_TIME;
104707                 } else {
104708                     time = timeout * 1000;
104709                 }
104710             } else {
104711                 time = _data.DEFAULT_VISIBLE_TIME;
104712             }
104713             updateVisibleStatus(mode, time);
104714
104715             if (successCallback) {
104716                 successCallback();
104717             }
104718         }, 1);
104719     }
104720
104721     function discoverDevices(successCallback, errorCallback) {
104722         if (!_security.discoverDevices) {
104723             throw new WebAPIException(errorcode.SECURITY_ERR);
104724         }
104725
104726         t.BluetoothAdapter("discoverDevices", arguments);
104727
104728         window.setTimeout(function () {
104729             var interval;
104730
104731             if (!_devPowered) {
104732                 if (errorCallback) {
104733                     errorCallback(new WebAPIError(
104734                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104735                 }
104736                 return;
104737             }
104738
104739             // already discovering
104740             if (_isDiscovering) {
104741                 return;
104742             }
104743
104744             _isDiscovering = true;
104745             _data.historyDevs = {};
104746
104747             successCallback.onstarted();
104748
104749             _data.availableDevsChanging = false;
104750             utils.forEach(_data.availableDevs, function (item) {
104751                 _data.historyDevs[item.address] = item;
104752                 successCallback.ondevicefound(item);
104753             });
104754
104755             discoverInterval = window.setTimeout(function () {
104756                 var devs = [];
104757
104758                 window.clearInterval(interval);
104759                 utils.forEach(_data.historyDevs, function (item) {
104760                     devs.push(item);
104761                 });
104762                 successCallback.onfinished(devs);
104763                 _isDiscovering = false;
104764             }, _data.DISCOVER_TIME);
104765
104766             interval = window.setInterval(function () {
104767                 var removeList = [], i;
104768
104769                 if (!_isDiscovering) {
104770                     window.clearInterval(interval);
104771                     return;
104772                 }
104773
104774                 if (_data.availableDevsChanging) {
104775                     _data.availableDevsChanging = false;
104776                     utils.forEach(_data.historyDevs, function (item) {
104777                         if (!_data.availableDevs[item.address]) {
104778                             removeList.push(item.address);
104779                         }
104780                     });
104781                     for (i in removeList) {
104782                         successCallback.ondevicedisappeared(removeList[i]);
104783                         delete _data.historyDevs[removeList[i]];
104784                     }
104785                     utils.forEach(_data.availableDevs, function (item) {
104786                         if (!_data.historyDevs[item.address]) {
104787                             _data.historyDevs[item.address] = item;
104788                             successCallback.ondevicefound(item);
104789                         }
104790                     });
104791                 }
104792             }, _data.DISCOVER_INTERVAL);
104793         }, 1);
104794     }
104795
104796     function stopDiscovery(successCallback, errorCallback) {
104797         if (!_security.stopDiscovery) {
104798             throw new WebAPIException(errorcode.SECURITY_ERR);
104799         }
104800
104801         t.BluetoothAdapter("stopDiscovery", arguments);
104802
104803         window.setTimeout(function () {
104804             if (!_devPowered) {
104805                 if (errorCallback) {
104806                     errorCallback(new WebAPIError(
104807                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104808                 }
104809                 return;
104810             }
104811
104812             if (_isDiscovering) {
104813                 window.clearTimeout(discoverInterval);
104814             }
104815             _isDiscovering = false;
104816             if (successCallback) {
104817                 successCallback();
104818             }
104819         }, 1);
104820     }
104821
104822     function getKnownDevices(successCallback, errorCallback) {
104823         if (!_security.getKnownDevices) {
104824             throw new WebAPIException(errorcode.SECURITY_ERR);
104825         }
104826
104827         t.BluetoothAdapter("getKnownDevices", arguments);
104828
104829         window.setTimeout(function () {
104830             var devs = [];
104831
104832             if (!_devPowered) {
104833                 if (errorCallback) {
104834                     errorCallback(new WebAPIError(
104835                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104836                 }
104837                 return;
104838             }
104839             utils.forEach(_data.historyDevs, function (item) {
104840                 devs.push(new BluetoothDevice({
104841                     name: item.name,
104842                     address: item.address,
104843                     deviceClass: item.deviceClass,
104844                     isBonded: false,
104845                     isTrusted: item.isTrusted,
104846                     isConnected: false,
104847                     services: item.services,
104848                     metaData: _security
104849                 }));
104850             });
104851             successCallback(devs);
104852         }, 1);
104853     }
104854
104855     function getDevice(address, successCallback, errorCallback) {
104856         if (!_security.getDevice) {
104857             throw new WebAPIException(errorcode.SECURITY_ERR);
104858         }
104859
104860         t.BluetoothAdapter("getDevice", arguments);
104861
104862         window.setTimeout(function () {
104863             if (!_devPowered) {
104864                 if (errorCallback) {
104865                     errorCallback(new WebAPIError(
104866                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104867                 }
104868                 return;
104869             }
104870
104871             if (!_data.historyDevs[address]) {
104872                 if (!_data.availableDevs[address]) {
104873                     if (errorCallback) {
104874                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
104875                     }
104876                     return;
104877                 }
104878
104879                 _data.historyDevs[address] = _data.availableDevs[address];
104880             }
104881
104882             successCallback(_data.historyDevs[address]);
104883         }, 1);
104884     }
104885
104886     function createBonding(address, successCallback, errorCallback) {
104887         if (!_security.createBonding) {
104888             throw new WebAPIException(errorcode.SECURITY_ERR);
104889         }
104890
104891         t.BluetoothAdapter("createBonding", arguments);
104892
104893         window.setTimeout(function () {
104894             if (!_devPowered) {
104895                 if (errorCallback) {
104896                     errorCallback(new WebAPIError(
104897                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104898                 }
104899                 return;
104900             }
104901
104902             if (!_data.historyDevs[address]) {
104903                 if (!_data.availableDevs[address]) {
104904                     if (errorCallback) {
104905                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
104906                     }
104907                     return;
104908                 }
104909
104910                 _data.historyDevs[address] = _data.availableDevs[address];
104911             }
104912
104913             event.trigger("bt-device-bonded-changed", [address, true]);
104914             successCallback(_data.historyDevs[address]);
104915         }, 1);
104916     }
104917
104918     function destroyBonding(address, successCallback, errorCallback) {
104919         if (!_security.destroyBonding) {
104920             throw new WebAPIException(errorcode.SECURITY_ERR);
104921         }
104922
104923         t.BluetoothAdapter("destroyBonding", arguments);
104924
104925         window.setTimeout(function () {
104926             if (!_devPowered) {
104927                 if (errorCallback) {
104928                     errorCallback(new WebAPIError(
104929                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104930                 }
104931                 return;
104932             }
104933
104934             if (!_data.historyDevs[address]) {
104935                 if (!_data.availableDevs[address]) {
104936                     if (errorCallback) {
104937                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
104938                     }
104939                     return;
104940                 }
104941
104942                 _data.historyDevs[address] = _data.availableDevs[address];
104943             }
104944
104945             event.trigger("bt-service-state-update", [address, false]);
104946             event.trigger("bt-device-bonded-changed", [address, false]);
104947             if (successCallback) {
104948                 successCallback();
104949             }
104950         }, 1);
104951     }
104952
104953     function registerRFCOMMServiceByUUID(uuid, name, successCallback,
104954             errorCallback, securityLevel) {
104955         if (!_security.registerRFCOMMServiceByUUID) {
104956             throw new WebAPIException(errorcode.SECURITY_ERR);
104957         }
104958
104959         t.BluetoothAdapter("registerRFCOMMServiceByUUID", arguments);
104960
104961         window.setTimeout(function () {
104962             if (!_devPowered) {
104963                 if (errorCallback) {
104964                     errorCallback(new WebAPIError(
104965                             errorcode.SERVICE_NOT_AVAILABLE_ERR));
104966                 }
104967                 return;
104968             }
104969
104970             _data.localServices[uuid] = new BluetoothServiceHandler({
104971                 uuid: uuid,
104972                 name: name,
104973                 isConnected: false,
104974                 metaData: _security
104975             });
104976             successCallback(_data.localServices[uuid]);
104977         }, 1);
104978     }
104979
104980     event.on("bt-simulated-devices-changed", function () {
104981         var devs = db.retrieveObject("bt-simulated-devices");
104982         utils.forEach(_data.availableDevs, function (item) {
104983             if (!devs[item.address]) {
104984                 delete _data.availableDevs[item.address];
104985             }
104986         });
104987         utils.forEach(devs, function (item) {
104988             if (!_data.availableDevs[item.address]) {
104989                 _data.availableDevs[item.address] = new BluetoothDevice({
104990                     name: item.name,
104991                     address: item.address,
104992                     deviceClass: item.deviceClass,
104993                     isBonded: false,
104994                     isTrusted: item.isTrusted,
104995                     isConnected: false,
104996                     services: item.services,
104997                     metaData: _security
104998                 });
104999             }
105000         });
105001         _data.availableDevsChanging = true;
105002     });
105003
105004     event.on("bt-unregister-service", function (uuid, successCallback, errorCallback) {
105005         if (!_data.localServices[uuid]) {
105006             if (errorCallback) {
105007                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
105008             }
105009             return;
105010         }
105011         delete _data.localServices[uuid];
105012         if (successCallback) {
105013             successCallback();
105014         }
105015     });
105016
105017     event.on("bt-power-setting", function (status) {
105018         updatePowerStatus(status);
105019     });
105020
105021     adapter = {
105022         setName:                     setName,
105023         setPowered:                  setPowered,
105024         setVisible:                  setVisible,
105025         discoverDevices:             discoverDevices,
105026         stopDiscovery:               stopDiscovery,
105027         getKnownDevices:             getKnownDevices,
105028         getDevice:                   getDevice,
105029         createBonding:               createBonding,
105030         destroyBonding:              destroyBonding,
105031         registerRFCOMMServiceByUUID: registerRFCOMMServiceByUUID
105032     };
105033
105034     adapter.__defineGetter__("name", function () {
105035         return _devName;
105036     });
105037
105038     adapter.__defineGetter__("address", function () {
105039         return _devAddress;
105040     });
105041
105042     adapter.__defineGetter__("powered", function () {
105043         return _devPowered;
105044     });
105045
105046     adapter.__defineGetter__("visible", function () {
105047         return _devVisible;
105048     });
105049
105050     return adapter;
105051 };
105052
105053 _self = function () {
105054     var bluetooth;
105055
105056     function getDefaultAdapter() {
105057         if (!_security.getDefaultAdapter) {
105058             throw new WebAPIException(errorcode.SECURITY_ERR);
105059         }
105060
105061         if (!_data.adapter) {
105062             throw new WebAPIException(errorcode.UNKNOWN_ERR);
105063         }
105064
105065         return _data.adapter;
105066     }
105067
105068     function handleSubFeatures(subFeatures) {
105069         var i, subFeature;
105070
105071         for (subFeature in subFeatures) {
105072             for (i in _security[subFeature]) {
105073                 _security[_security[subFeature][i]] = true;
105074             }
105075         }
105076     }
105077
105078     bluetooth = {
105079         getDefaultAdapter: getDefaultAdapter,
105080         handleSubFeatures: handleSubFeatures
105081     };
105082
105083     bluetooth.__defineGetter__("deviceMajor", function () {
105084         return _data.bluetoothClassDeviceMajor;
105085     });
105086
105087     bluetooth.__defineGetter__("deviceMinor", function () {
105088         return _data.bluetoothClassDeviceMinor;
105089     });
105090
105091     bluetooth.__defineGetter__("deviceService", function () {
105092         return _data.bluetoothClassDeviceService;
105093     });
105094
105095     return bluetooth;
105096 };
105097
105098 _initialize();
105099
105100 module.exports = _self;
105101
105102 });
105103 define('ripple/platform/tizen/2.0/contact', function (require, exports, module) {
105104 /*
105105  *  Copyright 2013 Intel Corporation.
105106  *
105107  * Licensed under the Apache License, Version 2.0 (the "License");
105108  * you may not use this file except in compliance with the License.
105109  * You may obtain a copy of the License at
105110  *
105111  * http://www.apache.org/licenses/LICENSE-2.0
105112  *
105113  * Unless required by applicable law or agreed to in writing, software
105114  * distributed under the License is distributed on an "AS IS" BASIS,
105115  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
105116  * See the License for the specific language governing permissions and
105117  * limitations under the License.
105118  */
105119
105120 var db = require('ripple/db'),
105121     decorator = require('ripple/platform/tizen/2.0/decorator'),
105122     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
105123     t = require('ripple/platform/tizen/2.0/typecast'),
105124     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
105125     utils = require('ripple/utils'),
105126     ContactName = require('ripple/platform/tizen/2.0/ContactName'),
105127     ContactAddress = require('ripple/platform/tizen/2.0/ContactAddress'),
105128     ContactPhoneNumber = require('ripple/platform/tizen/2.0/ContactPhoneNumber'),
105129     ContactEmailAddress = require('ripple/platform/tizen/2.0/ContactEmailAddress'),
105130     ContactAnniversary = require('ripple/platform/tizen/2.0/ContactAnniversary'),
105131     ContactOrganization = require('ripple/platform/tizen/2.0/ContactOrganization'),
105132     ContactWebSite = require('ripple/platform/tizen/2.0/ContactWebSite'),
105133     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
105134     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
105135     AddressBook,
105136     AddressBookData,
105137     AddressBookStorage,
105138     Contact,
105139     ContactData,
105140     ContactInternal,
105141     ContactGroup,
105142     Person,
105143     PersonBuilder,
105144     _data = {
105145         DB_CONTACT_KEY: "tizen1-contact",
105146         addressBooks:   [],
105147         contacts:       {},
105148         persons:        {},
105149         contactData:    {},
105150         dbStorage:      {}
105151     },
105152     _security = {
105153         "http://tizen.org/privilege/contact.read": ["getAddressBooks",
105154                 "getUnifiedAddressBook", "getDefaultAddressBook",
105155                 "getAddressBook", "get", "find", "addChangeListener",
105156                 "removeChangeListener", "getGroup", "getGroups", "clone"],
105157         "http://tizen.org/privilege/contact.write": ["add", "addBatch",
105158                 "update", "updateBatch", "remove", "removeBatch", "addGroup",
105159                 "updateGroup", "removeGroup", "link", "unlink"]
105160     },
105161     _self;
105162
105163 function _get() {
105164     _data.dbStorage = db.retrieveObject(_data.DB_CONTACT_KEY) ||
105165             {addressBooks: [], persons: {}};
105166 }
105167
105168 function _save() {
105169     db.saveObject(_data.DB_CONTACT_KEY, _data.dbStorage);
105170 }
105171
105172 function _serialize(obj) {
105173     var i, dbObj = {};
105174
105175     for (i in obj) {
105176         if (typeof obj[i] !== "function")
105177             dbObj[i] = utils.copy(obj[i]);
105178     }
105179
105180     return dbObj;
105181 }
105182
105183 /* check filter type (it's a recursive function)
105184    0: It is not a filter
105185    1: CompositeFilter
105186    2: AttributeFilter
105187    3: AttributeRangeFilter
105188  */
105189 function _filterType(filter) {
105190     var i = 0, ret;
105191
105192     if (Object.prototype.toString.call(filter) !== "[object Object]") {
105193         return 0; // 0: it is not a filter
105194     }
105195
105196     /* check if it is CompositFilter or not */
105197     if (filter.type !== null && filter.type !== undefined) {
105198         /* attribute 'type' of CompositeFilter must be "UNION" or "INTERSECTION" */
105199         if (filter.type === "UNION" || filter.type === "INTERSECTION") {
105200             /*attribute 'filters' of CompositeFilter must be AbstractFilter array */
105201             if (tizen1_utils.isValidArray(filter.filters)) {
105202                 for (i = 0; i < filter.filters.length; i++) {
105203                     /* recursive call */
105204                     if (_filterType(filter.filters[i]) === 0) {
105205                         return 0; // 0: it is not a filter
105206                     }
105207                 }
105208             } else {
105209                 return 0; // 0: it is not a filter
105210             }
105211         } else {
105212             return 0; // 0: it is not a filter
105213         }
105214         return 1; // CompositeFilter
105215     }
105216
105217     /* AttributeFilter or AttributeRangeFilter must have attributeName */
105218     if (filter.attributeName === null || filter.attributeName === undefined) {
105219         return 0; // 0: it is not a filter
105220     } else {
105221         ret = 2; // assume it is an AttributeFilter
105222         if ((filter.initialValue !== null && filter.initialValue !== undefined) ||
105223             (filter.endValue !== null && filter.endValue !== undefined)) {
105224             ret = 3; // AttributeRangeFilter
105225         }
105226         return ret;
105227     }
105228 }
105229
105230 function _sort(objects, sortMode) {
105231     function getValue(obj, key) {
105232         var keys = key.split("."),
105233             value = obj[keys[0]],
105234             i;
105235
105236         for (i = 1; i < keys.length; i++) {
105237             if (value[keys[i]]) {
105238                 value = value[keys[i]];
105239             }
105240         }
105241
105242         return value;
105243     }
105244
105245     objects.sort(function (a, b) {
105246         return (sortMode.order === "ASC") ?
105247             (getValue(a, sortMode.attributeName) < getValue(b, sortMode.attributeName) ? -1 : 1):
105248             (getValue(a, sortMode.attributeName) > getValue(b, sortMode.attributeName) ? -1 : 1);
105249     });
105250
105251     return objects;
105252 }
105253
105254 function _replacePerson(oldId, newId) {
105255     var contact, dbAddressBook, idab, idc, i;
105256
105257     for (idab in _data.contacts) {
105258         for (idc in _data.contacts[idab]) {
105259             contact = _data.contacts[idab][idc];
105260             if (contact.personId === oldId) {
105261                 if (newId === null) {
105262                     delete _data.contacts[idab][idc];
105263                 } else {
105264                     contact.personId = newId;
105265                 }
105266             }
105267         }
105268     }
105269
105270     if (_data.persons[oldId]) {
105271         delete _data.persons[oldId];
105272     }
105273
105274     for (i in _data.dbStorage.addressBooks) {
105275         dbAddressBook = _data.dbStorage.addressBooks[i];
105276         for (idc in dbAddressBook.contacts) {
105277             contact = dbAddressBook.contacts[idc];
105278             if (contact.personId === oldId) {
105279                 if (newId === null) {
105280                     delete dbAddressBook.contacts[idc];
105281                 } else {
105282                     contact.personId = newId;
105283                 }
105284             }
105285         }
105286     }
105287
105288     if (_data.dbStorage.persons[oldId]) {
105289         delete _data.dbStorage.persons[oldId];
105290     }
105291 }
105292
105293 _self = function () {
105294     var contact;
105295
105296     // private
105297     function loadAddressBooks() {
105298         var i;
105299
105300         _get();
105301
105302         if (_data.dbStorage.addressBooks.length === 0) {
105303             // Initialize default address books if database is empty
105304             _data.dbStorage.addressBooks = [
105305                 new AddressBookStorage(Math.uuid(null, 16), "Phone address book", false, {}, []),
105306                 new AddressBookStorage(Math.uuid(null, 16), "SIM address book", false, {}, [])
105307             ];
105308         }
105309
105310         utils.forEach(_data.dbStorage.addressBooks, function (addressBook) {
105311             _data.addressBooks.push(new AddressBook(addressBook.id, addressBook.name,
105312                 addressBook.readOnly, addressBook.contacts, addressBook.groups));
105313         });
105314
105315         for (i in _data.dbStorage.persons) {
105316             _data.persons[i] = new Person(_data.dbStorage.persons[i]);
105317         }
105318     }
105319
105320     // public
105321     // Address Book Methods
105322     function getAddressBooks(successCallback, errorCallback) {
105323         if (!_security.getAddressBooks) {
105324             throw new WebAPIException(errorcode.SECURITY_ERR);
105325         }
105326
105327         t.ContactManager("getAddressBooks", arguments);
105328
105329         window.setTimeout(function () {
105330             if (_data.addressBooks.length === 0) {
105331                 loadAddressBooks();
105332             }
105333             successCallback(_data.addressBooks);
105334         }, 1);
105335     }
105336
105337     function getUnifiedAddressBook() {
105338         if (!_security.getUnifiedAddressBook) {
105339             throw new WebAPIException(errorcode.SECURITY_ERR);
105340         }
105341         if (_data.addressBooks.length === 0) {
105342             loadAddressBooks();
105343         }
105344         return _data.addressBooks[0];
105345     }
105346
105347     function getDefaultAddressBook() {
105348         if (!_security.getDefaultAddressBook) {
105349             throw new WebAPIException(errorcode.SECURITY_ERR);
105350         }
105351         if (_data.addressBooks.length === 0) {
105352             loadAddressBooks();
105353         }
105354         return _data.addressBooks[0];
105355     }
105356
105357     function getAddressBook(addressBookId) {
105358         var i;
105359
105360         if (!_security.getAddressBook) {
105361             throw new WebAPIException(errorcode.SECURITY_ERR);
105362         }
105363
105364         t.ContactManager("getAddressBook", arguments);
105365
105366         if (_data.addressBooks.length === 0) {
105367             loadAddressBooks();
105368         }
105369         for (i in _data.addressBooks) {
105370             if (_data.addressBooks[i].id === addressBookId) {
105371                 return _data.addressBooks[i];
105372             }
105373         }
105374
105375         /* Cannot found */
105376         throw new WebAPIException(errorcode.NOT_FOUND_ERR);
105377     }
105378
105379     // Person Methods
105380     function get(personId) {
105381         if (!_security.get) {
105382             throw new WebAPIException(errorcode.SECURITY_ERR);
105383         }
105384
105385         t.ContactManager("get", arguments);
105386
105387         if (_data.persons[personId] === undefined) {
105388             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
105389         }
105390
105391         return new Person(_data.persons[personId]);
105392     }
105393
105394     function update(person) {
105395         var updated;
105396
105397         if (!_security.update) {
105398             throw new WebAPIException(errorcode.SECURITY_ERR);
105399         }
105400
105401         t.ContactManager("update", arguments);
105402
105403         if (!person.id) {
105404             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
105405         }
105406         if (_data.persons[person.id] === undefined) {
105407             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
105408         }
105409
105410         updated = new Person(person);
105411
105412         _data.persons[updated.id] = updated;
105413         _data.dbStorage.persons[updated.id] = _serialize(updated);
105414         _save();
105415
105416         window.setTimeout(function () {
105417             utils.forEach(_data.contactData.listeners, function (listener) {
105418                 listener.onpersonsupdated([new Person(updated)]);
105419             });
105420         }, 1);
105421     }
105422
105423     function updateBatch(persons, successCallback, errorCallback) {
105424         if (!_security.updateBatch) {
105425             throw new WebAPIException(errorcode.SECURITY_ERR);
105426         }
105427
105428         t.ContactManager("updateBatch", arguments, true);
105429
105430         window.setTimeout(function () {
105431             var i, updated;
105432
105433             if (persons.length === 0) {
105434                 if (errorCallback) {
105435                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105436                 }
105437                 return;
105438             }
105439
105440             for (i in persons) {
105441                 if (!persons[i].id) {
105442                     if (errorCallback) {
105443                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105444                     }
105445                     return;
105446                 }
105447                 if (_data.persons[persons[i].id] === undefined) {
105448                     if (errorCallback) {
105449                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
105450                     }
105451                     return;
105452                 }
105453             }
105454             for (i in persons) {
105455                 updated = new Person(persons[i]);
105456
105457                 _data.persons[updated.id] = updated;
105458                 _data.dbStorage.persons[updated.id] = _serialize(updated);
105459             }
105460             _save();
105461             if (successCallback) {
105462                 successCallback();
105463             }
105464
105465             utils.forEach(_data.contactData.listeners, function (listener) {
105466                 var i, watched = [];
105467
105468                 for (i in persons) {
105469                     watched.push(new Person(_data.persons[persons[i].id]));
105470                 }
105471                 listener.onpersonsupdated(watched);
105472             });
105473         }, 1);
105474     }
105475
105476     function remove(personId) {
105477         if (!_security.remove) {
105478             throw new WebAPIException(errorcode.SECURITY_ERR);
105479         }
105480
105481         t.ContactManager("remove", arguments);
105482
105483         if (_data.persons[personId] === undefined) {
105484             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
105485         }
105486         _replacePerson(personId, null);
105487         _save();
105488
105489         window.setTimeout(function () {
105490             utils.forEach(_data.contactData.listeners, function (listener) {
105491                 listener.onpersonsremoved([personId]);
105492             });
105493         }, 1);
105494     }
105495
105496     function removeBatch(personIds, successCallback, errorCallback) {
105497         if (!_security.removeBatch) {
105498             throw new WebAPIException(errorcode.SECURITY_ERR);
105499         }
105500
105501         t.ContactManager("removeBatch", arguments, true);
105502
105503         window.setTimeout(function () {
105504             var i;
105505
105506             if (personIds.length === 0) {
105507                 if (errorCallback) {
105508                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105509                 }
105510                 return;
105511             }
105512
105513             for (i in personIds) {
105514                 if (!personIds[i]) {
105515                     if (errorCallback) {
105516                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105517                     }
105518                     return;
105519                 }
105520                 if (_data.persons[personIds[i]] === undefined) {
105521                     if (errorCallback) {
105522                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
105523                     }
105524                     return;
105525                 }
105526             }
105527             for (i in personIds) {
105528                 _replacePerson(personIds[i], null);
105529             }
105530             _save();
105531             if (successCallback) {
105532                 successCallback();
105533             }
105534
105535             utils.forEach(_data.contactData.listeners, function (listener) {
105536                 listener.onpersonsremoved(utils.copy(personIds));
105537             });
105538         }, 1);
105539     }
105540
105541     function find(successCallback, errorCallback, filter, sortMode) {
105542         if (!_security.find) {
105543             throw new WebAPIException(errorcode.SECURITY_ERR);
105544         }
105545
105546         t.ContactManager("find", arguments, true);
105547
105548         window.setTimeout(function () {
105549             var i, matched = [], result = [];
105550
105551             if (filter) {
105552                 switch (_filterType(filter)) {
105553                 case 0:
105554                     if (errorCallback) {
105555                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105556                     }
105557                     return;
105558
105559                 case 1:
105560                     //TODO:
105561                     //"compositeFilter doesn't support"
105562                     if (errorCallback) {
105563                         errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
105564                     }
105565                     return;
105566
105567                 case 2:
105568                 case 3:
105569                     break;
105570                 }
105571             }
105572
105573             if (filter === null || filter === undefined) {
105574                 utils.forEach(_data.persons, function (person) {
105575                     matched.push(person);
105576                 });
105577             } else {
105578                 switch (filter.attributeName) {
105579                 case "id":
105580                 case "displayName":
105581                 case "photoURI":
105582                 case "ringtoneURI":
105583                 case "displayContactId":
105584                     matched = tizen1_utils.matchAttributeFilter(_data.persons,
105585                             filter.attributeName, filter.matchFlag, filter.matchValue);
105586                     break;
105587
105588                 case "contactCount":
105589                     if ((filter.matchFlag !== "EXACTLY") ||
105590                             (typeof filter.matchValue !== "number")) {
105591                         if (errorCallback) {
105592                             errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105593                         }
105594                         return;
105595                     }
105596                     matched = tizen1_utils.matchAttributeFilter(_data.persons,
105597                             filter.attributeName, filter.matchFlag, filter.matchValue);
105598                     break;
105599
105600                 case "hasPhoneNumber":
105601                 case "hasEmail":
105602                 case "isFavorite":
105603                     if ((filter.matchFlag !== "EXACTLY") ||
105604                             (typeof filter.matchValue !== "boolean")) {
105605                         if (errorCallback) {
105606                             errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105607                         }
105608                         return;
105609                     }
105610                     matched = tizen1_utils.matchAttributeBooleanFilter(_data.persons,
105611                             filter.attributeName, filter.matchValue);
105612                     break;
105613
105614                 default:
105615                     if (errorCallback) {
105616                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105617                     }
105618                     return;
105619                 }
105620             }
105621
105622             if (sortMode) {
105623                 _sort(matched, sortMode);
105624             }
105625
105626             for (i in matched) {
105627                 result.push(new Person(matched[i]));
105628             }
105629
105630             successCallback(result);
105631         }, 1);
105632     }
105633
105634     function addChangeListener(successCallback) {
105635         var id;
105636
105637         if (!_security.addChangeListener) {
105638             throw new WebAPIException(errorcode.SECURITY_ERR);
105639         }
105640
105641         t.ContactManager("addChangeListener", arguments);
105642
105643         id = ++_data.contactData.nListener;
105644         _data.contactData.listeners[id] = successCallback;
105645
105646         return id;
105647     }
105648
105649     function removeChangeListener(watchId) {
105650         if (!_security.removeChangeListener) {
105651             throw new WebAPIException(errorcode.SECURITY_ERR);
105652         }
105653
105654         if (!_data.contactData.listeners[watchId])
105655             return;
105656
105657         delete _data.contactData.listeners[watchId];
105658     }
105659
105660     function handleSubFeatures(subFeatures) {
105661         var i, subFeature;
105662
105663         for (subFeature in subFeatures) {
105664             for (i in _security[subFeature]) {
105665                 _security[_security[subFeature][i]] = true;
105666             }
105667         }
105668     }
105669
105670     _data.contactData = new ContactData();
105671
105672     contact = {
105673         getAddressBooks:       getAddressBooks,
105674         getUnifiedAddressBook: getUnifiedAddressBook,
105675         getDefaultAddressBook: getDefaultAddressBook,
105676         getAddressBook:        getAddressBook,
105677
105678         get:                   get,
105679         update:                update,
105680         updateBatch:           updateBatch,
105681         remove:                remove,
105682         removeBatch:           removeBatch,
105683         find:                  find,
105684         addChangeListener:     addChangeListener,
105685         removeChangeListener:  removeChangeListener,
105686         handleSubFeatures:     handleSubFeatures
105687     };
105688
105689     return contact;
105690 };
105691
105692 AddressBook = function (id, name, readOnly, dbContacts, dbGroups) {
105693     var addressBook,
105694         privateData = new AddressBookData(dbContacts, dbGroups);
105695
105696     // private
105697     function addNewContact(contact, external) {
105698         var added, person;
105699
105700         added = new ContactInternal(contact);
105701         privateData.contacts[added.id] = added;
105702
105703         person = new PersonBuilder(added);
105704         _data.persons[person.id] = person;
105705
105706         added.personId = person.id;
105707         added.addressBookId = id;
105708
105709         dbContacts[added.id] = _serialize(added);
105710         _data.dbStorage.persons[person.id] = _serialize(_data.persons[person.id]);
105711
105712         decorator.Contact(external, added);
105713     }
105714
105715     // public
105716     function get(id) {
105717         if (!_security.get) {
105718             throw new WebAPIException(errorcode.SECURITY_ERR);
105719         }
105720
105721         t.AddressBook("get", arguments);
105722
105723         if (privateData.contacts[id] === undefined) {
105724             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
105725         }
105726         return new Contact(privateData.contacts[id]);
105727     }
105728
105729     function add(contact) {
105730         var external = contact;
105731
105732         if (!_security.add) {
105733             throw new WebAPIException(errorcode.SECURITY_ERR);
105734         }
105735         if (addressBook.readOnly) {
105736             throw new WebAPIException(errorcode.SECURITY_ERR);
105737         }
105738
105739         t.AddressBook("add", arguments, true);
105740
105741         addNewContact(contact, external);
105742         _save();
105743
105744         window.setTimeout(function () {
105745             utils.forEach(privateData.listeners, function (listener) {
105746                 listener.oncontactsadded([new Contact(external)]);
105747             });
105748             utils.forEach(_data.contactData.listeners, function (listener) {
105749                 listener.onpersonsadded([new Person(_data.persons[external.personId])]);
105750             });
105751         }, 1);
105752     }
105753
105754     function addBatch(contacts, successCallback, errorCallback) {
105755         var external = contacts;
105756         if (!_security.addBatch) {
105757             throw new WebAPIException(errorcode.SECURITY_ERR);
105758         }
105759         if (addressBook.readOnly) {
105760             throw new WebAPIException(errorcode.SECURITY_ERR);
105761         }
105762
105763         t.AddressBook("addBatch", arguments, true);
105764
105765         window.setTimeout(function () {
105766             var i, personIds = [];
105767
105768             if (contacts.length === 0) {
105769                 if (errorCallback) {
105770                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105771                 }
105772                 return;
105773             }
105774
105775             for (i in contacts) {
105776                 addNewContact(contacts[i], external[i]);
105777                 personIds.push(external[i].personId);
105778             }
105779             _save();
105780             if (successCallback) {
105781                 successCallback(external);
105782             }
105783
105784             utils.forEach(privateData.listeners, function (listener) {
105785                 var i, watched = [];
105786
105787                 for (i in contacts) {
105788                     watched.push(new Contact(external[i]));
105789                 }
105790                 listener.oncontactsadded(watched);
105791             });
105792             utils.forEach(_data.contactData.listeners, function (listener) {
105793                 var i, watched = [];
105794
105795                 for (i in personIds) {
105796                     watched.push(new Person(_data.persons[personIds[i]]));
105797                 }
105798                 listener.onpersonsadded(watched);
105799             });
105800         }, 1);
105801     }
105802
105803     function update(contact) {
105804         var updated;
105805
105806         if (!_security.update) {
105807             throw new WebAPIException(errorcode.SECURITY_ERR);
105808         }
105809         if (addressBook.readOnly) {
105810             throw new WebAPIException(errorcode.SECURITY_ERR);
105811         }
105812
105813         t.AddressBook("update", arguments);
105814
105815         if (!contact.id) {
105816             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
105817         }
105818         if (privateData.contacts[contact.id] === undefined) {
105819             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
105820         }
105821
105822         updated = new ContactInternal(contact);
105823
105824         privateData.contacts[updated.id] = updated;
105825         dbContacts[updated.id] = _serialize(updated);
105826         _save();
105827
105828         window.setTimeout(function () {
105829             utils.forEach(privateData.listeners, function (listener) {
105830                 listener.oncontactsupdated([new Contact(updated)]);
105831             });
105832         }, 1);
105833     }
105834
105835     function updateBatch(contacts, successCallback, errorCallback) {
105836         if (!_security.updateBatch) {
105837             throw new WebAPIException(errorcode.SECURITY_ERR);
105838         }
105839         if (addressBook.readOnly) {
105840             throw new WebAPIException(errorcode.SECURITY_ERR);
105841         }
105842
105843         t.AddressBook("updateBatch", arguments, true);
105844
105845         window.setTimeout(function () {
105846             var i, updated;
105847
105848             if (contacts.length === 0) {
105849                 if (errorCallback) {
105850                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105851                 }
105852                 return;
105853             }
105854
105855             for (i in contacts) {
105856                 if (!contacts[i].id) {
105857                     if (errorCallback) {
105858                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105859                     }
105860                     return;
105861                 }
105862                 if (privateData.contacts[contacts[i].id] === undefined) {
105863                     if (errorCallback) {
105864                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
105865                     }
105866                     return;
105867                 }
105868             }
105869             for (i in contacts) {
105870                 updated = new ContactInternal(contacts[i]);
105871
105872                 privateData.contacts[updated.id] = updated;
105873                 dbContacts[updated.id] = _serialize(updated);
105874             }
105875             _save();
105876             if (successCallback) {
105877                 successCallback();
105878             }
105879
105880             utils.forEach(privateData.listeners, function (listener) {
105881                 var i, watched = [];
105882
105883                 for (i in contacts) {
105884                     watched.push(new Contact(
105885                         privateData.contacts[contacts[i].id]));
105886                 }
105887                 listener.oncontactsupdated(watched);
105888             });
105889         }, 1);
105890     }
105891
105892     function remove(id) {
105893         if (!_security.remove) {
105894             throw new WebAPIException(errorcode.SECURITY_ERR);
105895         }
105896         if (addressBook.readOnly) {
105897             throw new WebAPIException(errorcode.SECURITY_ERR);
105898         }
105899
105900         t.AddressBook("remove", arguments);
105901
105902         if (privateData.contacts[id] === undefined) {
105903             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
105904         }
105905
105906         delete privateData.contacts[id];
105907         if (dbContacts[id]) {
105908             delete dbContacts[id];
105909         }
105910         _save();
105911
105912         window.setTimeout(function () {
105913             utils.forEach(privateData.listeners, function (listener) {
105914                 listener.oncontactsremoved([id]);
105915             });
105916         }, 1);
105917     }
105918
105919     function removeBatch(ids, successCallback, errorCallback) {
105920         if (!_security.removeBatch) {
105921             throw new WebAPIException(errorcode.SECURITY_ERR);
105922         }
105923         if (addressBook.readOnly) {
105924             throw new WebAPIException(errorcode.SECURITY_ERR);
105925         }
105926
105927         t.AddressBook("removeBatch", arguments, true);
105928
105929         window.setTimeout(function () {
105930             var i;
105931
105932             if (ids.length === 0) {
105933                 if (errorCallback) {
105934                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105935                 }
105936                 return;
105937             }
105938
105939             for (i in ids) {
105940                 if (!ids[i]) {
105941                     if (errorCallback) {
105942                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105943                     }
105944                     return;
105945                 }
105946                 if (privateData.contacts[ids[i]] === undefined) {
105947                     if (errorCallback) {
105948                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
105949                     }
105950                     return;
105951                 }
105952             }
105953             for (i in ids) {
105954                 delete privateData.contacts[ids[i]];
105955                 if (dbContacts[ids[i]]) {
105956                     delete dbContacts[ids[i]];
105957                 }
105958             }
105959             _save();
105960             if (successCallback) {
105961                 successCallback();
105962             }
105963
105964             utils.forEach(privateData.listeners, function (listener) {
105965                 listener.oncontactsremoved(utils.copy(ids));
105966             });
105967         }, 1);
105968     }
105969
105970     function find(successCallback, errorCallback, filter, sortMode) {
105971         if (!_security.find) {
105972             throw new WebAPIException(errorcode.SECURITY_ERR);
105973         }
105974
105975         t.AddressBook("find", arguments, true);
105976
105977         window.setTimeout(function () {
105978             var result = [], begin, end, i, atr, _re, errFlag = false,
105979                 _rangeMatch, low, high, matched, _existMatch, _arrayMatch;
105980
105981             if (filter) {
105982                 switch (_filterType(filter)) {
105983                 case 0:
105984                     if (errorCallback) {
105985                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
105986                     }
105987                     return;
105988
105989                 case 1:
105990                     //TODO:
105991                     //"compositeFilter doesn't support"
105992                     if (errorCallback) {
105993                         errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
105994                     }
105995                     return;
105996
105997                 case 2:
105998                 case 3:
105999                     break;
106000                 }
106001             }
106002
106003             /* return all contacts if no filter argument */
106004             if (filter === null || filter === undefined) {
106005                 utils.forEach(privateData.contacts, function (contact) {
106006                     result.push(new Contact(contact));
106007                 });
106008
106009                 successCallback(result);
106010                 return;
106011             }
106012
106013             /* check composition of filter.attributeName */
106014             switch (filter.attributeName) {
106015             case "id" :
106016             case "personId" :
106017             case "addressBookId" :
106018             case "name.prefix" :
106019             case "name.suffix" :
106020             case "name.firstName" :
106021             case "name.middleName" :
106022             case "name.lastName" :
106023             case "name.phoneticFirstName" :
106024             case "name.phoneticLastName" :
106025             case "name.displayName" :
106026             case "account.accountServiceId" :
106027             case "account.contactURI" :
106028             case "photoURI" :
106029             case "ringtoneURI" :
106030                 matched = tizen1_utils.matchAttributeFilter(privateData.contacts,
106031                         filter.attributeName, filter.matchFlag, filter.matchValue);
106032                 break;
106033
106034             case "name.nicknames" :
106035             case "notes" :
106036             case "groupIds" :
106037                 matched = tizen1_utils.matchAttributeArrayFilter(privateData.contacts,
106038                         filter.attributeName, filter.matchFlag, filter.matchValue);
106039                 break;
106040
106041             case "addresses.country" :
106042             case "addresses.region" :
106043             case "addresses.city" :
106044             case "addresses.streetAddress" :
106045             case "addresses.additionalInformation" :
106046             case "addresses.postalCode" :
106047             case "phoneNumbers.number" :
106048             case "emails.email" :
106049             case "anniversaries.label" :
106050             case "organizations.name" :
106051             case "organizations.department" :
106052             case "organizations.title" :
106053             case "organizations.role" :
106054             case "organizations.logoURI" :
106055             case "urls.url" :
106056             case "urls.type" :
106057                 atr = filter.attributeName.split(".");
106058                 _existMatch = function (obj) {
106059                     return (obj[atr[0]] !== undefined);
106060                 };
106061
106062                 if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") {
106063                     matched = utils.filter(privateData.contacts, _existMatch);
106064                     break;
106065                 }
106066
106067                 errFlag = false;
106068
106069                 switch (filter.matchFlag)
106070                 {
106071                 case "EXACTLY":
106072                     _re = new RegExp("^" + filter.matchValue + "$");
106073                     break;
106074                 case "FULLSTRING":
106075                     _re = new RegExp("^" + filter.matchValue + "$", "i");
106076                     break;
106077                 case "CONTAINS":
106078                     _re = new RegExp(filter.matchValue, "i");
106079                     break;
106080                 case "STARTSWITH":
106081                     _re = new RegExp("^" + filter.matchValue, "i");
106082                     break;
106083                 case "ENDSWITH":
106084                     _re = new RegExp(filter.matchValue + "$", "i");
106085                     break;
106086                 default:
106087                     errFlag = true;
106088                 }
106089
106090                 if (errFlag) {
106091                     matched = [];
106092                     break;
106093                 }
106094
106095                 _arrayMatch = function (obj) {
106096                     return (obj[atr[0]].some(function (o) {
106097                         if (typeof o[atr[1]] !== "string") {
106098                             return false;
106099                         } else {
106100                             return (o[atr[1]].search(_re) !== -1);
106101                         }
106102                     }));
106103                 };
106104
106105                 matched = utils.filter(privateData.contacts, _arrayMatch);
106106                 break;
106107
106108             case "addresses.types" :
106109             case "phoneNumbers.types" :
106110             case "emails.types" :
106111                 atr = filter.attributeName.split(".");
106112                 _existMatch = function (obj) {
106113                     return (obj[atr[0]].some(function (o) {
106114                         return (o[atr[1]] !== undefined);
106115                     }));
106116                 };
106117
106118                 if (filter.matchValue === undefined || filter.matchFlag === "EXISTS") {
106119                     matched = utils.filter(privateData.contacts, _existMatch);
106120                     break;
106121                 }
106122
106123                 errFlag = false;
106124
106125                 switch (filter.matchFlag) {
106126                 case "EXACTLY":
106127                     _re = new RegExp("^" + filter.matchValue + "$");
106128                     break;
106129                 case "FULLSTRING":
106130                     _re = new RegExp("^" + filter.matchValue + "$", "i");
106131                     break;
106132                 case "CONTAINS":
106133                     _re = new RegExp(filter.matchValue, "i");
106134                     break;
106135                 case "STARTSWITH":
106136                     _re = new RegExp("^" + filter.matchValue, "i");
106137                     break;
106138                 case "ENDSWITH":
106139                     _re = new RegExp(filter.matchValue + "$", "i");
106140                     break;
106141                 default:
106142                     errFlag = true;
106143                 }
106144
106145                 if (errFlag) {
106146                     matched = [];
106147                     break;
106148                 }
106149
106150                 _arrayMatch = function (obj) {
106151                     return (obj[atr[0]].some(function (o) {
106152                         if (!tizen1_utils.isValidArray(o[atr[1]])) {
106153                             return false;
106154                         } else {
106155                             return (o[atr[1]].some(function (t) {
106156                                 return (t.search(_re) !== -1);
106157                             }));
106158                         }
106159                     }));
106160                 };
106161
106162                 matched = utils.filter(privateData.contacts, _arrayMatch);
106163                 break;
106164
106165             case "anniversaries.date" :
106166                 low = filter.initialValue;
106167                 high = filter.endValue;
106168                 atr = filter.attributeName.split(".");
106169
106170                 _rangeMatch = function (obj) {
106171                     var isMatched = true;
106172                     if (low !== null && low !== undefined) {
106173                         if (!tizen1_utils.isValidArray(obj[atr[0]])) {
106174                             isMatched = false;
106175                         } else {
106176                             isMatched = (obj[atr[0]].some(function (o) {
106177                                 return (o[atr[1]] >= low);
106178                             }));
106179                         }
106180                     }
106181                     if (isMatched && (high !== null && high !== undefined)) {
106182                         if (!tizen1_utils.isValidArray(obj[atr[0]])) {
106183                             isMatched = false;
106184                         } else {
106185                             isMatched = (obj[atr[0]].some(function (o) {
106186                                 return (o[atr[1]] <= high);
106187                             }));
106188                         }
106189                     }
106190                     return isMatched;
106191                 };
106192
106193                 matched = utils.filter(privateData.contacts, _rangeMatch);
106194                 break;
106195
106196             case "addresses.isDefault" :
106197             case "phoneNumbers.isDefault" :
106198             case "emails.isDefault" :
106199                 break;
106200
106201             case "isFavorite" :
106202                 if (filter.matchFlag !== "EXACTLY" || typeof filter.matchValue !== "boolean") {
106203                     if (errorCallback) {
106204                         errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
106205                     }
106206                     return;
106207                 } else {
106208                     matched = tizen1_utils.matchAttributeBooleanFilter(privateData.contacts,
106209                             filter.attributeName, filter.matchValue);
106210                 }
106211                 break;
106212
106213             case "birthday" :
106214                 begin = filter.initialValue;
106215                 end = filter.endValue;
106216
106217                 matched = tizen1_utils.matchAttributeRangeFilter(privateData.contacts,
106218                         filter.attributeName, begin, end);
106219                 break;
106220
106221             default:
106222                 if (errorCallback) {
106223                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
106224                 }
106225                 return;
106226             }
106227
106228             if (sortMode) {
106229                 _sort(matched, sortMode);
106230             }
106231
106232             for (i in matched) {
106233                 result.push(new Contact(matched[i]));
106234             }
106235
106236             successCallback(result);
106237         }, 1);
106238     }
106239
106240     function addChangeListener(successCallback, errorCallback) {
106241         var id;
106242
106243         if (!_security.addChangeListener) {
106244             throw new WebAPIException(errorcode.SECURITY_ERR);
106245         }
106246
106247         t.AddressBook("addChangeListener", arguments);
106248
106249         id = ++privateData.nListener;
106250         privateData.listeners[id] = successCallback;
106251
106252         return id;
106253     }
106254
106255     function removeChangeListener(watchId) {
106256         if (!_security.removeChangeListener) {
106257             throw new WebAPIException(errorcode.SECURITY_ERR);
106258         }
106259
106260         if (!privateData.listeners[watchId])
106261             return;
106262
106263         delete privateData.listeners[watchId];
106264     }
106265
106266     function getGroup(groupId) {
106267         var i;
106268
106269         if (!_security.getGroup) {
106270             throw new WebAPIException(errorcode.SECURITY_ERR);
106271         }
106272
106273         t.AddressBook("getGroup", arguments);
106274
106275         for (i in privateData.groups) {
106276             if (privateData.groups[i].id === groupId)
106277                 break;
106278         }
106279         if (privateData.groups[i] === undefined) {
106280             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
106281         }
106282
106283         return new ContactGroup(privateData.groups[i]);
106284     }
106285
106286     function addGroup(group) {
106287         var external = group;
106288
106289         if (!_security.addGroup) {
106290             throw new WebAPIException(errorcode.SECURITY_ERR);
106291         }
106292
106293         t.AddressBook("addGroup", arguments, true);
106294
106295         group.id            = Math.uuid(null, 16);
106296         group.addressBookId = id;
106297
106298         external.__defineGetter__("id", function () {
106299             return group.id;
106300         });
106301
106302         external.__defineGetter__("addressBookId", function () {
106303             return group.addressBookId;
106304         });
106305
106306         privateData.groups.push(group);
106307         _save();
106308     }
106309
106310     function updateGroup(group) {
106311         var i;
106312
106313         if (!_security.updateGroup) {
106314             throw new WebAPIException(errorcode.SECURITY_ERR);
106315         }
106316
106317         t.AddressBook("updateGroup", arguments);
106318
106319         if (!group.id) {
106320             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
106321         }
106322         for (i in privateData.groups) {
106323             if (privateData.groups[i].id === group.id)
106324                 break;
106325         }
106326         if (privateData.groups[i].id === undefined) {
106327             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
106328         }
106329         if (privateData.groups[i].readOnly) {
106330             throw new WebAPIException(errorcode.SECURITY_ERR);
106331         }
106332         privateData.groups[i] = utils.copy(group);
106333         _save();
106334     }
106335
106336     function removeGroup(groupId) {
106337         var i;
106338
106339         if (!_security.removeGroup) {
106340             throw new WebAPIException(errorcode.SECURITY_ERR);
106341         }
106342
106343         t.AddressBook("removeGroup", arguments);
106344
106345         for (i in privateData.groups) {
106346             if (privateData.groups[i].id === groupId)
106347                 break;
106348         }
106349         if (privateData.groups[i].id === undefined) {
106350             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
106351         }
106352         if (privateData.groups[i].readOnly) {
106353             throw new WebAPIException(errorcode.SECURITY_ERR);
106354         }
106355
106356         privateData.groups.splice(i, 1);
106357         _save();
106358     }
106359
106360     function getGroups() {
106361         var groups = [], i;
106362
106363         if (!_security.getGroups) {
106364             throw new WebAPIException(errorcode.SECURITY_ERR);
106365         }
106366
106367         for (i in privateData.groups) {
106368             groups.push(new ContactGroup(privateData.groups[i]));
106369         }
106370         return groups;
106371     }
106372
106373     privateData.load();
106374     // Make private contacts accessible for Person methods
106375     _data.contacts[id] = privateData.contacts;
106376
106377     addressBook = {
106378         get:                  get,
106379         add:                  add,
106380         addBatch:             addBatch,
106381         update:               update,
106382         updateBatch:          updateBatch,
106383         remove:               remove,
106384         removeBatch:          removeBatch,
106385         find:                 find,
106386         addChangeListener:    addChangeListener,
106387         removeChangeListener: removeChangeListener,
106388
106389         getGroup:             getGroup,
106390         addGroup:             addGroup,
106391         updateGroup:          updateGroup,
106392         removeGroup:          removeGroup,
106393         getGroups:            getGroups
106394     };
106395
106396     addressBook.__defineGetter__("id", function () {
106397         return id;
106398     });
106399
106400     addressBook.__defineGetter__("name", function () {
106401         return name;
106402     });
106403
106404     addressBook.__defineGetter__("readOnly", function () {
106405         return readOnly;
106406     });
106407
106408     return addressBook;
106409 };
106410
106411 AddressBookData = function (contacts, groups) {
106412     var addressBookData;
106413
106414     // private
106415     function loadContacts() {
106416         for (var i in contacts) {
106417             addressBookData.contacts[i] = new ContactInternal(contacts[i]);
106418         }
106419     }
106420
106421     function loadGroups() {
106422         addressBookData.groups = groups;
106423     }
106424
106425     // public
106426     function load() {
106427         loadContacts();
106428         loadGroups();
106429     }
106430
106431     addressBookData = {
106432         contacts:  {},
106433         groups:    [],
106434         listeners: {},
106435         nListener: 0,
106436         load:      load
106437     };
106438
106439     return addressBookData;
106440 };
106441
106442 AddressBookStorage = function (id, name, readOnly, contacts, groups) {
106443     this.id       = id;
106444     this.name     = name;
106445     this.readOnly = readOnly;
106446     this.contacts = contacts;
106447     this.groups   = groups;
106448 };
106449
106450 Contact = function (contact) {
106451     var i, attr, arr;
106452
106453     this.name          = null;
106454     this.addresses     = [];
106455     this.photoURI      = null;
106456     this.phoneNumbers  = [];
106457     this.emails        = [];
106458     this.birthday      = null;
106459     this.anniversaries = [];
106460     this.organizations = [];
106461     this.notes         = [];
106462     this.urls          = [];
106463     this.ringtoneURI   = null;
106464     this.groupIds      = [];
106465
106466     for (attr in contact) {
106467         switch (attr) {
106468         case "name":
106469             this[attr] = new ContactName(contact[attr]);
106470             break;
106471
106472         case "addresses":
106473             arr = contact[attr];
106474             if (arr) {
106475                 for (i in arr) {
106476                     this[attr][i] = new ContactAddress(arr[i]);
106477                 }
106478             }
106479             break;
106480
106481         case "phoneNumbers":
106482             arr = contact[attr];
106483             if (arr) {
106484                 for (i in arr) {
106485                     this[attr][i] = new ContactPhoneNumber(arr[i].number,
106486                             arr[i].types || null, arr[i].isDefault || null);
106487                 }
106488             }
106489             break;
106490
106491         case "emails":
106492             arr = contact[attr];
106493             if (arr) {
106494                 for (i in arr) {
106495                     this[attr][i] = new ContactEmailAddress(arr[i].email,
106496                             arr[i].types || null, arr[i].isDefault || null);
106497                 }
106498             }
106499             break;
106500
106501         case "birthday":
106502             this[attr] = new Date(contact[attr]);
106503             break;
106504
106505         case "anniversaries":
106506             arr = contact[attr];
106507             if (arr) {
106508                 for (i in arr) {
106509                     if (!tizen1_utils.isValidDate(arr[i].date)) {
106510                         arr[i].date = new Date(arr[i].date);
106511                     }
106512                     this[attr][i] = new ContactAnniversary(arr[i].date,
106513                             arr[i].label || null);
106514                 }
106515             }
106516             break;
106517
106518         case "organizations":
106519             arr = contact[attr];
106520             if (arr) {
106521                 for (i in arr) {
106522                     this[attr][i] = new ContactOrganization(arr[i]);
106523                 }
106524             }
106525             break;
106526
106527         case "notes":
106528         case "groupIds":
106529             arr = contact[attr];
106530             if (arr) {
106531                 for (i in arr) {
106532                     this[attr][i] = arr[i];
106533                 }
106534             }
106535             break;
106536
106537         case "urls":
106538             arr = contact[attr];
106539             if (arr) {
106540                 for (i in arr) {
106541                     this[attr][i] = new ContactWebSite(arr[i].url,
106542                             arr[i].type || null);
106543                 }
106544             }
106545             break;
106546
106547         default:
106548             this[attr] = contact[attr];
106549             break;
106550         }
106551     }
106552
106553     decorator.Contact(this, contact);
106554     this.__proto__ = tizen.Contact.prototype;
106555 };
106556
106557 ContactInternal = function (contact) {
106558     var attr;
106559
106560     for (attr in contact) {
106561         this[attr] = contact[attr];
106562     }
106563
106564     if (!contact.id) {
106565         this.id = Math.uuid(null, 16);
106566         this.lastUpdated = new Date();
106567     } else {
106568         this.lastUpdated = new Date(contact.lastUpdated);
106569     }
106570
106571     if (this.name) {
106572         this.name.__defineGetter__("displayName", function () {
106573             var displayName = "";
106574
106575             if (!this)
106576                 return "";
106577
106578             if ((this.firstName !== null) &&
106579                 (this.lastName !== null)) {
106580                 displayName = [this.firstName, this.middleName, this.lastName];
106581                 displayName = displayName.join(" ").replace(/ +/g, " ").trim();
106582             } else if (this.nicknames.length !== 0) {
106583                 this.nicknames.some(function (nickname) {
106584                     displayName = nickname;
106585                     return displayName;
106586                 });
106587             }
106588
106589             return displayName;
106590         });
106591     }
106592 };
106593
106594 ContactData = function () {
106595     this.listeners = {};
106596     this.nListener = 0;
106597 };
106598
106599 ContactGroup = function (groupInitDict) {
106600     var id, addressBookId, readOnly;
106601
106602     this.__defineGetter__("id", function () {
106603         return id;
106604     });
106605
106606     this.__defineGetter__("addressBookId", function () {
106607         return addressBookId;
106608     });
106609
106610     this.__defineGetter__("readOnly", function () {
106611         return readOnly;
106612     });
106613
106614     id               = groupInitDict.id || null;
106615     addressBookId    = groupInitDict.addressBookId || null;
106616     readOnly         = groupInitDict.readOnly || false;
106617
106618     this.name        = groupInitDict.name || "";
106619     this.ringtoneURI = groupInitDict.ringtoneURI || null;
106620     this.photoURI    = groupInitDict.photoURI || null;
106621
106622     this.__proto__ = tizen.ContactGroup.prototype;
106623 };
106624
106625 Person = function (personInitDict) {
106626     var person = {};
106627
106628     function hasContactMethod(method) {
106629         var idab, idc, contact, count = 0;
106630
106631         for (idab in _data.contacts) {
106632             for (idc in _data.contacts[idab]) {
106633                 contact = _data.contacts[idab][idc];
106634                 if (contact.personId === person.id) {
106635                     count += contact[method].length;
106636                 }
106637             }
106638         }
106639
106640         return (count !== 0);
106641     }
106642
106643     person.id               = personInitDict.id || Math.uuid(null, 16);
106644     person.isFavorite       = personInitDict.isFavorite || false;
106645     person.photoURI         = personInitDict.photoURI || null;
106646     person.ringtoneURI      = personInitDict.ringtoneURI || null;
106647     person.displayContactId = personInitDict.displayContactId;
106648
106649     this.__defineGetter__("id", function () {
106650         return person.id;
106651     });
106652
106653     this.__defineGetter__("displayName", function () {
106654         var idab, contact, displayName = "";
106655
106656         for (idab in _data.contacts) {
106657             contact = _data.contacts[idab][this.displayContactId];
106658
106659             if (contact !== undefined) {
106660                 if (contact.name && contact.name.displayName) {
106661                     displayName = contact.name.displayName;
106662                 }
106663                 break;
106664             }
106665         }
106666
106667         return displayName;
106668     });
106669
106670     this.__defineGetter__("contactCount", function () {
106671         var idab, idc, contactCount = 0;
106672
106673         for (idab in _data.contacts) {
106674             for (idc in _data.contacts[idab]) {
106675                 if (_data.contacts[idab][idc].personId === person.id) {
106676                     ++contactCount;
106677                 }
106678             }
106679         }
106680
106681         return contactCount;
106682     });
106683
106684     this.__defineGetter__("hasPhoneNumber", function () {
106685         return hasContactMethod("phoneNumbers");
106686     });
106687
106688     this.__defineGetter__("hasEmail", function () {
106689         return hasContactMethod("emails");
106690     });
106691
106692     this.__defineGetter__("isFavorite", function () {
106693         return person.isFavorite;
106694     });
106695     this.__defineSetter__("isFavorite", function (val) {
106696         try {
106697             person.isFavorite = t.boolean(val);
106698         } catch (e) {
106699         }
106700     });
106701
106702     this.__defineGetter__("photoURI", function () {
106703         return person.photoURI;
106704     });
106705     this.__defineSetter__("photoURI", function (val) {
106706         try {
106707             person.photoURI = t.DOMString(val, "?");
106708         } catch (e) {
106709         }
106710     });
106711
106712     this.__defineGetter__("ringtoneURI", function () {
106713         return person.ringtoneURI;
106714     });
106715     this.__defineSetter__("ringtoneURI", function (val) {
106716         try {
106717             person.ringtoneURI = t.DOMString(val, "?");
106718         } catch (e) {
106719         }
106720     });
106721
106722     this.__defineGetter__("displayContactId", function () {
106723         return person.displayContactId;
106724     });
106725     this.__defineSetter__("displayContactId", function (val) {
106726         try {
106727             person.displayContactId = t.ContactId(val);
106728         } catch (e) {
106729         }
106730     });
106731
106732     this.link = function (personId) {
106733         if (!_security.link) {
106734             throw new WebAPIException(errorcode.SECURITY_ERR);
106735         }
106736
106737         t.Person("link", arguments);
106738
106739         if (_data.persons[personId] === undefined) {
106740             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
106741         }
106742
106743         _replacePerson(personId, person.id);
106744         _save();
106745     };
106746
106747     this.unlink = function (contactId) {
106748         var idab, contact, separated, i, dbAddressBook;
106749
106750         if (!_security.unlink) {
106751             throw new WebAPIException(errorcode.SECURITY_ERR);
106752         }
106753
106754         t.Person("unlink", arguments);
106755
106756         for (idab in _data.contacts) {
106757             if (_data.contacts[idab][contactId] !== undefined) {
106758                 contact = _data.contacts[idab][contactId];
106759                 break;
106760             }
106761         }
106762
106763         if (contact === undefined) {
106764             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
106765         }
106766         if (contact.personId !== person.id) {
106767             throw new WebAPIException(errorcode.UNKNOWN_ERR);
106768         }
106769
106770         separated = new PersonBuilder(contact);
106771         _data.persons[separated.id] = separated;
106772         contact.personId = separated.id;
106773
106774         _data.dbStorage.persons[separated.id] = _serialize(separated);
106775         for (i in _data.dbStorage.addressBooks) {
106776             dbAddressBook = _data.dbStorage.addressBooks[i];
106777             if (dbAddressBook.id === idab) {
106778                 dbAddressBook.contacts[contact.id].personId = separated.id;
106779                 break;
106780             }
106781         }
106782         _save();
106783
106784         return separated;
106785     };
106786 };
106787
106788 PersonBuilder = function (contact) {
106789     var person, personInitDict = {};
106790
106791     personInitDict.displayContactId = contact.id;
106792     person = new Person(personInitDict);
106793
106794     return person;
106795 };
106796
106797 module.exports = _self;
106798
106799 });
106800 define('ripple/platform/tizen/2.0/NDEFRecordText', function (require, exports, module) {
106801 /*
106802  *  Copyright 2013 Intel Corporation
106803  *
106804  * Licensed under the Apache License, Version 2.0 (the "License");
106805  * you may not use this file except in compliance with the License.
106806  * You may obtain a copy of the License at
106807  *
106808  * http://www.apache.org/licenses/LICENSE-2.0
106809  *
106810  * Unless required by applicable law or agreed to in writing, software
106811  * distributed under the License is distributed on an "AS IS" BASIS,
106812  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
106813  * See the License for the specific language governing permissions and
106814  * limitations under the License.
106815  */
106816
106817 var t = require('ripple/platform/tizen/2.0/typecast'),
106818     NDEFRecordInternal = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
106819     NDEFRecordText;
106820
106821 NDEFRecordText = function (text, languageCode, encoding) {
106822     var payload = [], i;
106823
106824     t.NDEFRecordText(arguments, this);
106825
106826     encoding = encoding || "UTF8";
106827
106828     // Store languageCode in payload
106829     payload.push(languageCode.length);
106830     for (i = 0; i < languageCode.length; i++) {
106831         payload.push(languageCode.charCodeAt(i));
106832     }
106833
106834     // Store text in payload
106835     for (i = 0; i < text.length; i++) {
106836         payload.push(text.charCodeAt(i));
106837     }
106838
106839     NDEFRecordInternal.call(this, tizen.nfc.NFC_RECORD_TNF_WELL_KNOWN,
106840             ["T".charCodeAt(0)], payload, []);
106841
106842     this.__defineGetter__("text", function () {
106843         return text;
106844     });
106845
106846     this.__defineGetter__("languageCode", function () {
106847         return languageCode;
106848     });
106849
106850     this.__defineGetter__("encoding", function () {
106851         return encoding;
106852     });
106853 };
106854
106855 module.exports = NDEFRecordText;
106856
106857 });
106858 define('ripple/platform/tizen/2.0/ContactOrganization', function (require, exports, module) {
106859 /*
106860  *  Copyright 2013 Intel Corporation.
106861  *
106862  * Licensed under the Apache License, Version 2.0 (the "License");
106863  * you may not use this file except in compliance with the License.
106864  * You may obtain a copy of the License at
106865  *
106866  * http://www.apache.org/licenses/LICENSE-2.0
106867  *
106868  * Unless required by applicable law or agreed to in writing, software
106869  * distributed under the License is distributed on an "AS IS" BASIS,
106870  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
106871  * See the License for the specific language governing permissions and
106872  * limitations under the License.
106873  */
106874
106875 var t = require('ripple/platform/tizen/2.0/typecast'),
106876     ContactOrganization;
106877
106878 ContactOrganization = function (orgInitDict) {
106879     var contactOrganization = {}, attr;
106880
106881     t.ContactOrganization(arguments, this);
106882
106883     contactOrganization.name       = null;
106884     contactOrganization.department = null;
106885     contactOrganization.title      = null;
106886     contactOrganization.role       = null;
106887     contactOrganization.logoURI    = null;
106888
106889     this.__defineGetter__("name", function () {
106890         return contactOrganization.name;
106891     });
106892     this.__defineSetter__("name", function (val) {
106893         try {
106894             contactOrganization.name = t.DOMString(val, "?");
106895         } catch (e) {
106896         }
106897     });
106898
106899     this.__defineGetter__("department", function () {
106900         return contactOrganization.department;
106901     });
106902     this.__defineSetter__("department", function (val) {
106903         try {
106904             contactOrganization.department = t.DOMString(val, "?");
106905         } catch (e) {
106906         }
106907     });
106908
106909     this.__defineGetter__("title", function () {
106910         return contactOrganization.title;
106911     });
106912     this.__defineSetter__("title", function (val) {
106913         try {
106914             contactOrganization.title = t.DOMString(val, "?");
106915         } catch (e) {
106916         }
106917     });
106918
106919     this.__defineGetter__("role", function () {
106920         return contactOrganization.role;
106921     });
106922     this.__defineSetter__("role", function (val) {
106923         try {
106924             contactOrganization.role = t.DOMString(val, "?");
106925         } catch (e) {
106926         }
106927     });
106928
106929     this.__defineGetter__("logoURI", function () {
106930         return contactOrganization.logoURI;
106931     });
106932     this.__defineSetter__("logoURI", function (val) {
106933         try {
106934             contactOrganization.logoURI = t.DOMString(val, "?");
106935         } catch (e) {
106936         }
106937     });
106938
106939     if (orgInitDict) {
106940         for (attr in orgInitDict) {
106941             contactOrganization[attr] = orgInitDict[attr];
106942         }
106943     }
106944 };
106945
106946 module.exports = ContactOrganization;
106947
106948 });
106949 define('ripple/platform/tizen/2.0/MessageFolder', function (require, exports, module) {
106950 /*
106951  *  Copyright 2012 Intel Corporation.
106952  *
106953  * Licensed under the Apache License, Version 2.0 (the "License");
106954  * you may not use this file except in compliance with the License.
106955  * You may obtain a copy of the License at
106956  *
106957  * http://www.apache.org/licenses/LICENSE-2.0
106958  *
106959  * Unless required by applicable law or agreed to in writing, software
106960  * distributed under the License is distributed on an "AS IS" BASIS,
106961  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
106962  * See the License for the specific language governing permissions and
106963  * limitations under the License.
106964  */
106965
106966 module.exports = function (opt) {
106967     var folder = {}, _id = opt.id, _parentId = null, _serviceId = opt.serviceId,
106968         _contentType = opt.contentType, _name = opt.id, _path = opt.path,
106969         _type = opt.type, _synchronizable = opt.synchronizable;
106970
106971     folder.name = _name;
106972     folder.synchronizable = _synchronizable;
106973     
106974     folder.__defineGetter__("id", function () {
106975         return _id;
106976     });
106977     folder.__defineGetter__("parentId", function () {
106978         return _parentId;
106979     });
106980     folder.__defineGetter__("serviceId", function () {
106981         return _serviceId;
106982     });
106983     folder.__defineGetter__("contentType", function () {
106984         return _contentType;
106985     });
106986     folder.__defineGetter__("path", function () {
106987         return _path;
106988     });
106989     folder.__defineGetter__("type", function () {
106990         return _type;
106991     });
106992     return folder;
106993 };
106994
106995 });
106996 define('ripple/platform/tizen/2.0/touchEvent', function (require, exports, module) {
106997 /*
106998  *  Copyright 2012 Intel Corporation
106999  *
107000  * Licensed under the Apache License, Version 2.0 (the "License");
107001  * you may not use this file except in compliance with the License.
107002  * You may obtain a copy of the License at
107003  *
107004  * http://www.apache.org/licenses/LICENSE-2.0
107005  *
107006  * Unless required by applicable law or agreed to in writing, software
107007  * distributed under the License is distributed on an "AS IS" BASIS,
107008  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
107009  * See the License for the specific language governing permissions and
107010  * limitations under the License.
107011  */
107012
107013 var emulatorBridge = require('ripple/emulatorBridge'),
107014     event = require('ripple/event'),
107015     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
107016     Touch,
107017     TouchList,
107018     TouchEvent,
107019     _touchCanvasElements = [],
107020     _dataEnlargeRatio = 4,
107021     _self;
107022
107023 function _isValidTouch(touches) {
107024     var touche, _touches = [], i;
107025     if (!touches) {
107026         return false;
107027     }
107028     if (!tizen1_utils.isValidArray(touches)) {
107029         _touches = [touches];
107030     }
107031
107032     for (i = 0; i < _touches.length; i++) {
107033         touche = _touches[i];
107034         if ((touche !== undefined) &&
107035             ((typeof touche !== "object") ||
107036             (typeof touche.target !== "object") ||
107037             (touche.identifier !== undefined) && (typeof touche.identifier !== "number") ||
107038             (touche.screenX !== undefined) && (typeof touche.screenX !== "number") ||
107039             (touche.screenY !== undefined) && (typeof touche.screenY !== "number") ||
107040             (touche.clientX !== undefined) && (typeof touche.clientX !== "number") ||
107041             (touche.clientY !== undefined) && (typeof touche.clientY !== "number") ||
107042             (touche.pageX !== undefined) && (typeof touche.pageX !== "number") ||
107043             (touche.pageY !== undefined) && (typeof touche.pageY !== "number")))
107044             return false;
107045     }
107046     return true;
107047 }
107048
107049 function _dispatchAllEvents(event) {
107050     _touchCanvasElements.forEach(function (value) {
107051         if (value !== undefined) {
107052             value.dispatchEvent(event);
107053         }
107054     });
107055 }
107056
107057 function _touchMove(event) {
107058     var data = event.data,
107059         touches = [],
107060         removedTouches = [],
107061         touchList,
107062         simulatedEvent,
107063         dataId,
107064         ids = [],
107065         intervalId,
107066         currentIndex,
107067         item = {};
107068
107069     if (_touchCanvasElements.length === 0)
107070         return;
107071
107072     for (dataId in data) {
107073         if (!data[dataId].length || data[dataId].length === 0)
107074             return;
107075
107076         ids.push(dataId);
107077         item = data[dataId][0];
107078         touches.push(new Touch(item.target, dataId, item.pageX * _dataEnlargeRatio, item.pageY * _dataEnlargeRatio, item.screenX * _dataEnlargeRatio,
107079                                item.screenY * _dataEnlargeRatio, item.offsetX * _dataEnlargeRatio, item.offsetY * _dataEnlargeRatio));
107080     }
107081
107082     // touch start
107083     touchList = new TouchList(touches);
107084     simulatedEvent = new TouchEvent("touchstart", true, true, touchList, touchList, touchList, event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
107085     _dispatchAllEvents(simulatedEvent);
107086     currentIndex = 0;
107087
107088     // touch move and touch end
107089     intervalId = setInterval(function () {
107090         touches = [];
107091         removedTouches = [];
107092
107093         ids.forEach(function (id) {
107094             var points = data[id],
107095                 touchItem, removedItem;
107096
107097             if (currentIndex < points.length) {
107098                 touchItem = points[currentIndex];
107099             } else {
107100                 removedItem = points[points.length - 1];
107101             }
107102
107103             if (touchItem)
107104                 touches.push(new Touch(touchItem.target, id, touchItem.pageX * _dataEnlargeRatio, touchItem.pageY * _dataEnlargeRatio, touchItem.screenX * _dataEnlargeRatio,
107105                                        touchItem.screenY * _dataEnlargeRatio, touchItem.offsetX * _dataEnlargeRatio, touchItem.offsetY * _dataEnlargeRatio));
107106             if (removedItem)
107107                 removedTouches.push(new Touch(removedItem.target, id, removedItem.pageX * _dataEnlargeRatio, removedItem.pageY * _dataEnlargeRatio, removedItem.screenX * _dataEnlargeRatio,
107108                                     removedItem.screenY * _dataEnlargeRatio, removedItem.offsetX * _dataEnlargeRatio, removedItem.offsetY * _dataEnlargeRatio));
107109         });
107110
107111         if (touches.length > 0) {
107112             simulatedEvent = new TouchEvent("touchmove", true, true, new TouchList(touches), new TouchList(touches), new TouchList(touches),
107113                 event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
107114             _dispatchAllEvents(simulatedEvent);
107115         } else {
107116             clearInterval(intervalId);
107117         }
107118
107119         if (removedTouches.length > 0) {
107120             simulatedEvent = new TouchEvent("touchend", true, true, new TouchList(removedTouches), new TouchList(removedTouches), new TouchList(removedTouches),
107121                 event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
107122             _dispatchAllEvents(simulatedEvent);
107123         }
107124         currentIndex++;
107125     }, 50);
107126 }
107127
107128 function _touchCancel(event) {
107129     var mousedownEvent = event.touchEvent,
107130         simulatedEvent;
107131
107132     simulatedEvent = new TouchEvent("touchcancel", true, true, new TouchList([]), new TouchList([]), new TouchList([]),
107133         event.altKey, event.metaKey, event.ctrlKey, event.shiftKey);
107134     _dispatchAllEvents(simulatedEvent);
107135 }
107136
107137 function _initialize() {
107138     event.on("touchCancel", _touchCancel);
107139     event.on("touchEvent", _touchMove);
107140 }
107141
107142 Touch = function (target, identifier, pageX, pageY, screenX, screenY, clientX, clientY) {
107143     var _identifier = Number(identifier) || 0,
107144         _screenX = Number(screenX) || 0,
107145         _screenY = Number(screenY) || 0,
107146         _clientX = Number(clientX) || 0,
107147         _clientY = Number(clientY) || 0,
107148         _pageX = Number(pageX) || 0,
107149         _pageY = Number(pageY) || 0;
107150
107151     this.__defineGetter__("identifier", function () {
107152         return _identifier;
107153     });
107154     this.__defineGetter__("target", function () {
107155         return target;
107156     });
107157     this.__defineGetter__("screenX", function () {
107158         return _screenX;
107159     });
107160     this.__defineGetter__("screenY", function () {
107161         return _screenY;
107162     });
107163     this.__defineGetter__("clientX", function () {
107164         return _clientX;
107165     });
107166     this.__defineGetter__("clientY", function () {
107167         return _clientY;
107168     });
107169     this.__defineGetter__("pageX", function () {
107170         return _pageX;
107171     });
107172     this.__defineGetter__("pageY", function () {
107173         return _pageY;
107174     });
107175 };
107176
107177 TouchList = function (touches) {
107178     var _touches = _isValidTouch(touches) ? tizen1_utils.copy(touches) : [],
107179         i, _self;
107180
107181     _self = {
107182         item : function (index) {
107183             if (typeof index !== "number") {
107184                 return null;
107185             }
107186             if (index.toString().indexOf(".") !== -1) {
107187                 return null;
107188             }
107189             if (/^\\d+$/.test(index) || index >= _touches.length) {
107190                 return null;
107191             }
107192             if (!_touches) {
107193                 return null;
107194             }
107195             return _touches[index];
107196         },
107197
107198         identifiedTouch : function (identifier) {
107199             if (typeof identifier !== "number") {
107200                 return null;
107201             }
107202             if (!_touches) {
107203                 return null;
107204             }
107205             for (var i in _touches) {
107206                 if (_touches[i].identifier === identifier) {
107207                     return _touches[i];
107208                 }
107209             }
107210             return null;
107211         }
107212     };
107213
107214     for (i = 0; i < _touches.length; i++) {
107215         _self.__defineGetter__(i, (function (index) {
107216             return function () {
107217                 return _touches[index];
107218             };
107219         }(i)));
107220     }
107221
107222     _self.__defineGetter__("length", function () {
107223         return _touches.length;
107224     });
107225
107226     return _self;
107227 };
107228
107229 TouchEvent = function (type, canBubble, cancelable, touches, targetTouches, changedTouches, altKey, metaKey, ctrlKey, shiftKey) {
107230     var touchEvent = emulatorBridge.document().createEvent("UIEvents");
107231     touchEvent.initUIEvent(type, canBubble, cancelable, emulatorBridge.window(), 1);
107232
107233     touchEvent.__defineGetter__("touches", function () {
107234         return touches;
107235     });
107236     touchEvent.__defineGetter__("targetTouches", function () {
107237         return targetTouches;
107238     });
107239     touchEvent.__defineGetter__("changedTouches", function () {
107240         return changedTouches;
107241     });
107242     touchEvent.__defineGetter__("altKey", function () {
107243         return altKey;
107244     });
107245     touchEvent.__defineGetter__("metaKey", function () {
107246         return metaKey;
107247     });
107248     touchEvent.__defineGetter__("ctrlKey", function () {
107249         return ctrlKey;
107250     });
107251     touchEvent.__defineGetter__("shiftKey", function () {
107252         return shiftKey;
107253     });
107254     return touchEvent;
107255 };
107256
107257 _self = {
107258     mask: function (frame) {
107259         frame.addEventListener("DOMContentLoaded", function () {
107260             /*
107261             var widgetDocument = frame.contentDocument,
107262                 getElementByIdOri = widgetDocument.getElementById;
107263
107264             widgetDocument.getElementById = function () {
107265                 var element, addEventListenerOri;
107266
107267                 element = getElementByIdOri.apply(widgetDocument, Array.prototype.slice.call(arguments));
107268
107269                 if (element) {
107270                     addEventListenerOri = element.addEventListener;
107271                     element.addEventListener = function (event, callback, useCapture) {
107272                         if (event === "touchstart") {
107273                             _touchCanvasElements.push(element);
107274                         }
107275                         addEventListenerOri.apply(element, arguments);
107276                     };
107277                 }
107278                 return element;
107279             };
107280
107281             widgetDocument.createTouch = function (view, target, identifier, pageX, pageY, screenX, screenY) {
107282                 return new Touch(view, target, identifier, pageX, pageY, screenX, screenY);
107283             };
107284
107285             widgetDocument.createTouchList = function (pattern) {
107286                 if (arguments.length !== 1) {
107287                     return null;
107288                 }
107289                 return new TouchList(pattern);
107290             };
107291             */
107292         });
107293     }
107294 };
107295
107296 _initialize();
107297
107298 module.exports = _self;
107299
107300 });
107301 define('ripple/platform/tizen/2.0/AttributeFilter', function (require, exports, module) {
107302 /*
107303  *  Copyright 2013 Intel Corporation.
107304  *
107305  * Licensed under the Apache License, Version 2.0 (the "License");
107306  * you may not use this file except in compliance with the License.
107307  * You may obtain a copy of the License at
107308  *
107309  * http://www.apache.org/licenses/LICENSE-2.0
107310  *
107311  * Unless required by applicable law or agreed to in writing, software
107312  * distributed under the License is distributed on an "AS IS" BASIS,
107313  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
107314  * See the License for the specific language governing permissions and
107315  * limitations under the License.
107316  */
107317
107318 var t = require('ripple/platform/tizen/2.0/typecast'),
107319     AttributeFilter;
107320
107321 AttributeFilter = function (attributeName, matchFlag, matchValue) {
107322     var attributeFilter = {};
107323
107324     t.AttributeFilter(arguments, this);
107325
107326     attributeFilter.attributeName = attributeName;
107327     attributeFilter.matchFlag     = matchFlag || "EXACTLY";
107328     attributeFilter.matchValue    = (matchFlag === "EXISTS") ? null :
107329             matchValue || null;
107330
107331     this.__defineGetter__("attributeName", function () {
107332         return attributeFilter.attributeName;
107333     });
107334     this.__defineSetter__("attributeName", function (val) {
107335         try {
107336             attributeFilter.attributeName = t.DOMString(val);
107337         } catch (e) {
107338         }
107339     });
107340
107341     this.__defineGetter__("matchFlag", function () {
107342         return attributeFilter.matchFlag;
107343     });
107344     this.__defineSetter__("matchFlag", function (val) {
107345         try {
107346             attributeFilter.matchFlag = t.FilterMatchFlag(val);
107347         } catch (e) {
107348         }
107349     });
107350
107351     this.__defineGetter__("matchValue", function () {
107352         return attributeFilter.matchValue;
107353     });
107354     this.__defineSetter__("matchValue", function (val) {
107355         try {
107356             if (attributeFilter.matchFlag === "EXISTS") {
107357                 return;
107358             }
107359             attributeFilter.matchValue = t.any(val, "?");
107360         } catch (e) {
107361         }
107362     });
107363 };
107364
107365 module.exports = AttributeFilter;
107366
107367 });
107368 define('ripple/platform/tizen/2.0/AccountService', function (require, exports, module) {
107369 /*
107370  *  Copyright 2012 Intel Corporation.
107371  *
107372  * Licensed under the Apache License, Version 2.0 (the "License");
107373  * you may not use this file except in compliance with the License.
107374  * You may obtain a copy of the License at
107375  *
107376  * http://www.apache.org/licenses/LICENSE-2.0
107377  *
107378  * Unless required by applicable law or agreed to in writing, software
107379  * distributed under the License is distributed on an "AS IS" BASIS,
107380  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
107381  * See the License for the specific language governing permissions and
107382  * limitations under the License.
107383  */
107384
107385 module.exports = function (serviceName, serviceType, tag, displayName, icon, settings) {
107386     var _self,
107387         _id = Math.uuid(null, 16);
107388
107389     _self = {
107390         serviceName : serviceName || "",
107391         serviceType : serviceType || "",
107392         displayName : displayName || null,
107393         icon : icon || null,
107394         settings : settings || null,
107395         tag : tag || []
107396     };
107397
107398     _self.__defineGetter__("id", function () {
107399         return _id;
107400     });
107401
107402     return _self;
107403 };
107404
107405 });
107406 define('ripple/platform/tizen/2.0/nfc', function (require, exports, module) {
107407 /*
107408  *  Copyright 2013 Intel Corporation
107409  *
107410  * Licensed under the Apache License, Version 2.0 (the "License");
107411  * you may not use this file except in compliance with the License.
107412  * You may obtain a copy of the License at
107413  *
107414  * http://www.apache.org/licenses/LICENSE-2.0
107415  *
107416  * Unless required by applicable law or agreed to in writing, software
107417  * distributed under the License is distributed on an "AS IS" BASIS,
107418  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
107419  * See the License for the specific language governing permissions and
107420  * limitations under the License.
107421  */
107422
107423 var db = require('ripple/db'),
107424     event = require('ripple/event'),
107425     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
107426     t = require('ripple/platform/tizen/2.0/typecast'),
107427     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
107428     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
107429     NDEFRecord = require('ripple/platform/tizen/2.0/NDEFRecordInternal'),
107430     NDEFMessage = require('ripple/platform/tizen/2.0/NDEFMessage'),
107431     NFCAdapter,
107432     NFCAdapterPrototype,
107433     NFCTag,
107434     NFCPeer,
107435     _data = {
107436         DB_NFC_TAG: "tizen1.0-nfc-tag",
107437         DB_NFC_PEER: "tizen1.0-nfc-peer",
107438         DB_NFC_OUTPUT_MESSAGE: "tizen1.0-nfc-output-message",
107439         INTERVAL: 1000,
107440         listener: {
107441             onCardEmulationChanged: null,
107442             onTagDetected: null,
107443             onPeerDetected: null,
107444             onNDEFReceived: null
107445         },
107446         pairedNFC: null,
107447         nfcAdapter: {},
107448         nfcCardEmulation: {},
107449         nfcTags: [],
107450         nfcTag: {},
107451         nfcPeer: null,
107452         isNear: false,      // Identify the device is whether near
107453         isDetectTag: false, // Identify NFC tag is detected
107454         isPeerConnected: false,
107455         connectedState: false
107456     },
107457     _security = {
107458         "http://tizen.org/privilege/nfc.admin": ["setPowered"],
107459         "http://tizen.org/privilege/nfc.common": ["getDefaultAdapter",
107460                 "setExclusiveMode", "getCachedMessage"],
107461         "http://tizen.org/privilege/nfc.p2p": ["setPeerListener",
107462                 "unsetPeerListener", "setReceiveNDEFListener",
107463                 "unsetReceiveNDEFListener", "sendNDEF"],
107464         "http://tizen.org/privilege/nfc.tag": ["setTagListener",
107465                 "unsetTagListener", "readNDEF", "writeNDEF", "transceive"]
107466     },
107467     _self;
107468
107469 _self = function () {
107470     var nfc, _exclusiveMode = false;
107471
107472     function getDefaultAdapter() {
107473         if (!_security.getDefaultAdapter) {
107474             throw new WebAPIException(errorcode.SECURITY_ERR);
107475         }
107476
107477         t.NFCManager("getDefaultAdapter", arguments);
107478
107479         if (!_data.nfcAdapter) {
107480             throw new WebAPIException(errorcode.UNKNOWN_ERR);
107481         }
107482
107483         return _data.nfcAdapter;
107484     }
107485
107486     /* API Description:
107487      *   If it gets priority and it is in foreground, system doesn't
107488      *   send app controls that are usually sent when detecting NFC Tag
107489      *   or receiving NDEF Message from the connected NFC peer-to-peer target
107490      *
107491      * Implementation detail:
107492      *   due to simulator only support single running instance and doesn't have
107493      *   other app controls which be called by design. we just put some system
107494      *   exclusive mode info on the 'System Summary' panel
107495      */
107496     function setExclusiveMode(mode) {
107497         if (!_security.setExclusiveMode) {
107498             throw new WebAPIException(errorcode.SECURITY_ERR);
107499         }
107500
107501         t.NFCManager("setExclusiveMode", arguments);
107502
107503         _exclusiveMode = mode;
107504         jQuery("#NFCExclusiveModeValue").text(_exclusiveMode);
107505     }
107506
107507     function handleSubFeatures(subFeatures) {
107508         var i, subFeature;
107509
107510         for (subFeature in subFeatures) {
107511             for (i in _security[subFeature]) {
107512                 _security[_security[subFeature][i]] = true;
107513             }
107514         }
107515     }
107516
107517     nfc = {
107518         getDefaultAdapter: getDefaultAdapter,
107519         setExclusiveMode:  setExclusiveMode,
107520         handleSubFeatures: handleSubFeatures
107521     };
107522
107523     nfc.__defineGetter__("NFC_RECORD_TNF_EMPTY", function () {
107524         return 0;
107525     });
107526
107527     nfc.__defineGetter__("NFC_RECORD_TNF_WELL_KNOWN", function () {
107528         return 1;
107529     });
107530
107531     nfc.__defineGetter__("NFC_RECORD_TNF_MIME_MEDIA", function () {
107532         return 2;
107533     });
107534
107535     nfc.__defineGetter__("NFC_RECORD_TNF_URI", function () {
107536         return 3;
107537     });
107538
107539     nfc.__defineGetter__("NFC_RECORD_TNF_EXTERNAL_RTD", function () {
107540         return 4;
107541     });
107542
107543     nfc.__defineGetter__("NFC_RECORD_TNF_UNKNOWN", function () {
107544         return 5;
107545     });
107546
107547     nfc.__defineGetter__("NFC_RECORD_TNF_UNCHANGED", function () {
107548         return 6;
107549     });
107550
107551     return nfc;
107552 };
107553
107554 NFCAdapterPrototype = function () {
107555     var nfcAdapterPrototype,
107556         interval,
107557         powered = false, // Identify the device on or off
107558         polling = false; // Identify the device is polled
107559
107560     event.trigger("nfc-power-changed", [powered]);
107561     event.on("nfc-power-setting", function (status) {
107562         updatePowerStatus(status);
107563     });
107564     event.on("nfc-attach-setting", function (type, isAttached) {
107565         var isDetectTag;
107566
107567         isDetectTag = (type === "Tag");
107568         updateIsNear(isDetectTag, isAttached);
107569     });
107570     event.on("nfc-tag-send", function (status) {
107571         var tag;
107572
107573         if (status) {
107574             tag = db.retrieveObject(_data.DB_NFC_TAG);
107575             if (tag.isSupportedNDEF) {
107576                 _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF,
107577                         tag.ndefSize, null, true, tag.ndefs);
107578             } else {
107579                 _data.nfcTag = new NFCTag(tag.type, tag.isSupportedNDEF,
107580                         tag.ndefSize, null, true, tag.rawData);
107581             }
107582             if (_data.listener.onTagDetected) {
107583                 _data.listener.onTagDetected.onattach(_data.nfcTag);
107584             }
107585         } else {
107586             tag = {};
107587             if (_data.listener.onTagDetected) {
107588                 _data.listener.onTagDetected.ondetach();
107589             }
107590         }
107591     });
107592     event.on("nfc-peer-send", function (status) {
107593         if (status) {
107594             if (!_data.nfcPeer) {
107595                 _data.nfcPeer = new NFCPeer(true);
107596             }
107597             _data.isPeerConnected = true;
107598             if (_data.listener.onPeerDetected) {
107599                 _data.listener.onPeerDetected.onattach(_data.nfcPeer);
107600             }
107601         } else {
107602             _data.isPeerConnected = false;
107603             if (_data.listener.onPeerDetected) {
107604                 _data.listener.onPeerDetected.ondetach();
107605             }
107606         }
107607     });
107608     event.on("nfc-peer-sending-ndef", function () {
107609         var peer, _records = [], rec, _ndef, i;
107610
107611         if (_data.isPeerConnected) {
107612             peer = db.retrieveObject(_data.DB_NFC_PEER);
107613             for (i in peer.ndef.records) {
107614                 rec = peer.ndef.records[i];
107615                 _records.push(new NDEFRecord(rec.tnf, rec.type, rec.payload,
107616                         rec.id));
107617             }
107618             _ndef = new NDEFMessage(_records);
107619             if (_data.listener.onNDEFReceived) {
107620                 _data.listener.onNDEFReceived(_ndef);
107621             }
107622         }
107623     });
107624
107625     // private
107626     function updatePowerStatus(status) {
107627         if (powered === status) {
107628             return;
107629         }
107630         if (!status) {
107631             updateIsNear(_data.isDetectTag, false);
107632             _data.listener.onTagDetected = null;
107633             _data.listener.onPeerDetected = null;
107634             _data.listener.onNDEFReceived = null;
107635             _data.listener.onCardEmulationChanged = null;
107636         }
107637         powered = status;
107638         updatePollingStatus(status);
107639
107640         event.trigger("nfc-power-changed", [powered]);
107641     }
107642
107643     function updatePollingStatus(status) {
107644         if (!powered)
107645             return;
107646         if (polling === status) {
107647             return;
107648         }
107649         polling = status;
107650         event.trigger("nfc-polling-changed", [polling]);
107651         if (polling) {
107652             interval = setInterval(poll, _data.INTERVAL);
107653         } else {
107654             clearInterval(interval);
107655         }
107656     }
107657
107658     function updateIsNear(isDetectTag, isAttached) {
107659         _data.isDetectTag = isDetectTag;
107660         _data.isNear = isAttached;
107661         if (!_data.isNear) {
107662             _data.connectedState = false;
107663             event.trigger("nfc-connectedState-changed", [false]);
107664         }
107665     }
107666
107667     function poll() {
107668         if (!_data.isNear) {
107669             return;
107670         }
107671         if (!_data.connectedState) {
107672             _data.connectedState = true;
107673             event.trigger("nfc-connectedState-changed", [true]);
107674         }
107675     }
107676
107677     // public
107678     // Turns NFC adapter on or off.
107679     function setPowered(state, successCallback, errorCallback) {
107680         if (!_security.setPowered) {
107681             throw new WebAPIException(errorcode.SECURITY_ERR);
107682         }
107683
107684         t.NFCAdapter("setPowered", arguments);
107685
107686         window.setTimeout(function () {
107687             updatePowerStatus(state);
107688             if (successCallback) {
107689                 successCallback();
107690             }
107691         }, 1);
107692     }
107693
107694     // Registers a callback function to invoke when NFC tag is detected.
107695     function setTagListener(detectCallback, tagFilter) {
107696         if (!_security.setTagListener) {
107697             throw new WebAPIException(errorcode.SECURITY_ERR);
107698         }
107699
107700         t.NFCAdapter("setTagListener", arguments);
107701
107702         //TODO: tagFilter support
107703         if (!powered) {
107704             return;
107705         }
107706         _data.listener.onTagDetected = detectCallback;
107707     }
107708
107709     // Registers a callback function to be invoked when NFC peer-to-peer target is detected.
107710     function setPeerListener(detectCallback) {
107711         if (!_security.setPeerListener) {
107712             throw new WebAPIException(errorcode.SECURITY_ERR);
107713         }
107714
107715         t.NFCAdapter("setPeerListener", arguments);
107716
107717         if (!powered) {
107718             return;
107719         }
107720         _data.listener.onPeerDetected = detectCallback;
107721     }
107722
107723     // Unregisters the listener for detecting an NFC tag.
107724     function unsetTagListener() {
107725         if (!_security.unsetTagListener) {
107726             throw new WebAPIException(errorcode.SECURITY_ERR);
107727         }
107728
107729         if (!powered || !_data.listener.onTagDetected) {
107730             return;
107731         }
107732
107733         _data.listener.onTagDetected = null;
107734     }
107735
107736     // Unregisters the listener for detecting an NFC peer-to-peer target.
107737     function unsetPeerListener() {
107738         if (!_security.unsetPeerListener) {
107739             throw new WebAPIException(errorcode.SECURITY_ERR);
107740         }
107741
107742         if (!powered || !_data.listener.onPeerDetected) {
107743             return;
107744         }
107745
107746         _data.listener.onPeerDetected = null;
107747     }
107748
107749     // Gets NDEF message cached when the tag is detected.
107750     function getCachedMessage() {
107751         if (!_security.getCachedMessage) {
107752             throw new WebAPIException(errorcode.SECURITY_ERR);
107753         }
107754
107755         t.NFCAdapter("getCachedMessage", arguments);
107756
107757         return _data.pairedNFC || new NDEFMessage([]);
107758     }
107759
107760     nfcAdapterPrototype = {
107761         setPowered:        setPowered,
107762         setTagListener:    setTagListener,
107763         setPeerListener:   setPeerListener,
107764         unsetTagListener:  unsetTagListener,
107765         unsetPeerListener: unsetPeerListener,
107766         getCachedMessage:  getCachedMessage
107767     };
107768
107769     nfcAdapterPrototype.__defineGetter__("powered", function () {
107770         return powered;
107771     });
107772
107773     return nfcAdapterPrototype;
107774 };
107775
107776 NFCAdapter = function () {
107777     this.__defineGetter__("powered", function () {
107778         return this.__proto__.powered;
107779     });
107780 };
107781
107782 NFCAdapter.prototype = new NFCAdapterPrototype();
107783
107784 NFCTag = function (type, isSupportedNDEF, ndefSize, properties, isConnected, ndefs) {
107785     var nfcTag, i, j, _ndefs, rec, _records, _ndefs_index = 0;
107786
107787     type = type || null;
107788     isSupportedNDEF = isSupportedNDEF || false;
107789     ndefSize = ndefSize || 1;
107790     properties = null;
107791     isConnected = isConnected || false;
107792
107793     _ndefs = [];
107794     for (i in ndefs) {
107795         _records = [];
107796         for (j in ndefs[i].records) {
107797             rec = ndefs[i].records[j];
107798             _records.push(new NDEFRecord(rec.tnf, rec.type, rec.payload,
107799                     rec.id));
107800         }
107801         _ndefs.push(new NDEFMessage(_records));
107802     }
107803
107804     // Reads NDEF data.
107805     function readNDEF(readCallback, errorCallback) {
107806         if (!_security.readNDEF) {
107807             throw new WebAPIException(errorcode.SECURITY_ERR);
107808         }
107809
107810         t.NFCTag("readNDEF", arguments);
107811
107812         window.setTimeout(function () {
107813             if (!_data.isNear || !isSupportedNDEF ||
107814                     (_ndefs_index >= ndefSize)) {
107815                 if (errorCallback) {
107816                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
107817                 }
107818                 return;
107819             }
107820             _data.pairedNFC = _ndefs[_ndefs_index];
107821             readCallback(_ndefs[_ndefs_index]);
107822             _ndefs_index++;
107823         }, 1);
107824     }
107825
107826     // Writes NDEF data.
107827     function writeNDEF(ndefMessage, successCallback, errorCallback) {
107828         if (!_security.writeNDEF) {
107829             throw new WebAPIException(errorcode.SECURITY_ERR);
107830         }
107831
107832         t.NFCTag("writeNDEF", arguments, true);
107833
107834         window.setTimeout(function () {
107835             if (!_data.isNear || !isSupportedNDEF) {
107836                 if (errorCallback) {
107837                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
107838                 }
107839                 return;
107840             }
107841             db.saveObject(_data.DB_NFC_OUTPUT_MESSAGE, ndefMessage);
107842             event.trigger("nfc-output-msg", []);
107843             if (successCallback) {
107844                 successCallback();
107845             }
107846         }, 1);
107847     }
107848
107849     // Access the raw format card.
107850     function transceive(data, dataCallback, errorCallback) {
107851         if (!_security.transceive) {
107852             throw new WebAPIException(errorcode.SECURITY_ERR);
107853         }
107854
107855         t.NFCTag("transceive", arguments, true);
107856
107857         window.setTimeout(function () {
107858             if (!_data.isNear || isSupportedNDEF) {
107859                 if (errorCallback) {
107860                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
107861                 }
107862                 return;
107863             }
107864             db.saveObject(_data.DB_NFC_OUTPUT_MESSAGE, data);
107865             event.trigger("nfc-output-msg", []);
107866             dataCallback(ndefs);
107867         }, 1);
107868     }
107869
107870     // Formats the detected tag that can store NDEF messages.
107871     /*
107872     function formatNDEF(successCallback, errorCallback, key) {
107873
107874         tizen1_utils.validateCallbackType(successCallback, errorCallback);
107875
107876         if (key) {
107877             tizen1_utils.validateArgumentType(key, "array",
107878                 new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
107879         }
107880
107881         if (!isConnected || !isSupportedNDEF) {
107882             if (errorCallback) {
107883                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
107884             }
107885             return;
107886         }
107887
107888         successCallback();
107889     }
107890     */
107891
107892     nfcTag = {
107893         readNDEF:   readNDEF,
107894         writeNDEF:  writeNDEF,
107895         transceive: transceive
107896         //formatNDEF: formatNDEF
107897     };
107898
107899     nfcTag.__defineGetter__("type", function () {
107900         return type;
107901     });
107902
107903     nfcTag.__defineGetter__("isSupportedNDEF", function () {
107904         return isSupportedNDEF;
107905     });
107906
107907     nfcTag.__defineGetter__("ndefSize", function () {
107908         return ndefSize;
107909     });
107910
107911     nfcTag.__defineGetter__("properties", function () {
107912         return properties;
107913     });
107914
107915     nfcTag.__defineGetter__("isConnected", function () {
107916         return _data.isNear;
107917     });
107918
107919     return nfcTag;
107920 };
107921
107922 NFCPeer = function (isConnected) {
107923     var nfcPeer;
107924
107925     isConnected = isConnected || false;
107926
107927     // Registers a callback function to be invoked when NDEF message is received from NFC peer-to-peer target connected.
107928     function setReceiveNDEFListener(successCallback) {
107929         if (!_security.setReceiveNDEFListener) {
107930             throw new WebAPIException(errorcode.SECURITY_ERR);
107931         }
107932
107933         t.NFCPeer("setReceiveNDEFListener", arguments);
107934
107935         if (!_data.isPeerConnected) {
107936             return;
107937         }
107938         _data.listener.onNDEFReceived = successCallback;
107939     }
107940
107941     // Unregisters the listener for receiving NDEFMessage from NFC peer-to-peer target connected.
107942     function unsetReceiveNDEFListener() {
107943         if (!_security.unsetReceiveNDEFListener) {
107944             throw new WebAPIException(errorcode.SECURITY_ERR);
107945         }
107946
107947         _data.listener.onNDEFReceived = null;
107948     }
107949
107950     // Sends data to NFC peer-to-peer target.
107951     function sendNDEF(ndefMessage, successCallback, errorCallback) {
107952         if (!_security.sendNDEF) {
107953             throw new WebAPIException(errorcode.SECURITY_ERR);
107954         }
107955
107956         t.NFCPeer("sendNDEF", arguments, true);
107957
107958         window.setTimeout(function () {
107959             if (!_data.isPeerConnected) {
107960                 if (errorCallback) {
107961                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
107962                 }
107963                 return;
107964             }
107965
107966             db.saveObject(_data.DB_NFC_OUTPUT_MESSAGE, ndefMessage);
107967             event.trigger("nfc-output-msg", []);
107968             if (successCallback) {
107969                 successCallback();
107970             }
107971         }, 1);
107972     }
107973
107974     nfcPeer = {
107975         setReceiveNDEFListener:   setReceiveNDEFListener,
107976         unsetReceiveNDEFListener: unsetReceiveNDEFListener,
107977         sendNDEF:                 sendNDEF
107978     };
107979
107980     nfcPeer.__defineGetter__("isConnected", function () {
107981         return _data.isPeerConnected;
107982     });
107983
107984     return nfcPeer;
107985 };
107986
107987 function _initialize() {
107988     _data.nfcAdapter = new NFCAdapter();
107989 }
107990
107991 _initialize();
107992
107993 module.exports = _self;
107994
107995 });
107996 define('ripple/platform/tizen/2.0/power', function (require, exports, module) {
107997 /*
107998  *  Copyright 2012 Intel Corporation.
107999  *
108000  * Licensed under the Apache License, Version 2.0 (the "License");
108001  * you may not use this file except in compliance with the License.
108002  * You may obtain a copy of the License at
108003  *
108004  * http://www.apache.org/licenses/LICENSE-2.0
108005  *
108006  * Unless required by applicable law or agreed to in writing, software
108007  * distributed under the License is distributed on an "AS IS" BASIS,
108008  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108009  * See the License for the specific language governing permissions and
108010  * limitations under the License.
108011  */
108012 var event = require('ripple/event'),
108013     constants = require('ripple/constants'),
108014     deviceSettings = require('ripple/deviceSettings'),
108015     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
108016     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
108017     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
108018     _POWER_RESOURCE = constants.POWER_RESOURCE,
108019     _SCREEN_STATE = constants.POWER_RESOURCE.SCREEN.STATE,
108020     ScreenState = {"previous" : null, "current" : null},
108021     _listeners = [],
108022     _isScreenResourceOccupied = false,
108023     _originalBrightness,
108024     _isCPUAwake = false,
108025     _isScreenOn = true,
108026     _normalBrightness,
108027     _minimal_screen_state = null,
108028     _security = {
108029         "http://tizen.org/privilege/power": ["request", "setScreenBrightness", "turnScreenOn", "turnScreenOff"]
108030     },
108031     _self;
108032
108033 /**initialize**/
108034 function initState() {
108035     _normalBrightness = deviceSettings.retrieve("DISPLAY.brightness");
108036     updateResourceState();
108037 }
108038
108039 function getResourceState(value) {
108040     var state;
108041     value = Number(value);
108042     if (value <=  _SCREEN_STATE.SCREEN_OFF.MAX) {
108043         state = _SCREEN_STATE.SCREEN_OFF.NAME;
108044     } else if (value < _SCREEN_STATE.SCREEN_DIM.MAX) {
108045         state = _SCREEN_STATE.SCREEN_DIM.NAME;
108046     } else if (value < _SCREEN_STATE.SCREEN_NORMAL.MAX) {
108047         state = _SCREEN_STATE.SCREEN_NORMAL.NAME;
108048     } else {
108049         state = _SCREEN_STATE.SCREEN_BRIGHT.NAME;
108050     }
108051     return state;
108052 }
108053
108054 function updateResourceState() {
108055     var brightness, actualState;
108056     brightness = deviceSettings.retrieve("DISPLAY.brightness");
108057     actualState = getResourceState(brightness);
108058     ScreenState.previous = ScreenState.current;
108059     ScreenState.current = actualState;
108060 }
108061
108062 function callListeners(listeners, previousState, changedState) {
108063     listeners.forEach(function (listener) {
108064         setTimeout(function () {
108065             listener(previousState, changedState);
108066         }, 1);
108067     });
108068 }
108069
108070 function triggerListenerCB(stateObj) {
108071     if (stateObj.previous !== stateObj.current) {
108072         callListeners(_listeners, stateObj.previous, stateObj.current);
108073     }
108074 }
108075
108076 _self = function () {
108077     function request(resource, state) {
108078         if (!_security.request) {
108079             throw new WebAPIError(errorcode.SECURITY_ERR);
108080         }
108081         if (typeof resource !== 'string' || typeof state !== 'string') {
108082             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
108083         }
108084         //Check resource
108085         if (!_POWER_RESOURCE.hasOwnProperty(resource)) {
108086             throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
108087         }
108088         //Check state
108089         if (!_POWER_RESOURCE[resource].STATE.hasOwnProperty(state)) {
108090             throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
108091         }
108092         // Exception check: SCREEN_OFF is a state cannot be requested
108093         if (resource === "SCREEN" && state === "SCREEN_OFF") {
108094             throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
108095         }
108096         switch (resource) {
108097         case "SCREEN" :
108098             if ((_minimal_screen_state === null) ||
108099                (_minimal_screen_state === "SCREEN_DIM" && (state === "SCREEN_NORMAL" || state === "SCREEN_BRIGHT")) ||
108100                (_minimal_screen_state === "SCREEN_NORMAL" && state === "SCREEN_BRIGHT")) {
108101                 _minimal_screen_state = state;
108102             }
108103             break;
108104         case "CPU" :
108105             _isCPUAwake = true;
108106             break;
108107         default:
108108             break;
108109         }
108110     }
108111
108112     function release(resource) {
108113         switch (resource) {
108114         case "SCREEN" :
108115             if (_isScreenResourceOccupied) {
108116                 _isScreenResourceOccupied = false;
108117                 deviceSettings.persist("DISPLAY.brightness", _originalBrightness);
108118                 event.trigger("DisplayBrightnessChangedByPower", [_originalBrightness]);
108119                 updateResourceState();
108120                 triggerListenerCB(ScreenState);
108121             }
108122             _minimal_screen_state = null;
108123             break;
108124         case "CPU" :
108125             _isCPUAwake = false;
108126             break;
108127         default:
108128             if (typeof resource === "string") {
108129                 throw (new WebAPIError(errorcode.INVALID_VALUES_ERR));
108130             } else  {
108131                 throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
108132             }
108133         }
108134     }
108135
108136     function setScreenStateChangeListener(listener) {
108137         tizen1_utils.validateArgumentType(listener, "function",
108138                 new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
108139         _listeners.push(listener);
108140     }
108141
108142     function unsetScreenStateChangeListener() {
108143         _listeners = [];
108144     }
108145
108146     function getScreenBrightness() {
108147         var brightness = deviceSettings.retrieve("DISPLAY.brightness");
108148         return brightness;
108149     }
108150
108151     function setScreenBrightness(brightness) {
108152         if (!_security.setScreenBrightness) {
108153             throw new WebAPIError(errorcode.SECURITY_ERR);
108154         }
108155         if (typeof brightness !== 'number') {
108156             throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
108157         }
108158         if (brightness < 0 || brightness > 1) {
108159             throw new WebAPIError(errorcode.INVALID_VALUES_ERR);
108160         }
108161         if (!_isScreenResourceOccupied) {
108162             _originalBrightness = deviceSettings.retrieve("DISPLAY.brightness");
108163             _isScreenResourceOccupied = true;
108164         }
108165         deviceSettings.persist("DISPLAY.brightness", brightness);
108166         event.trigger("DisplayBrightnessChangedByPower", [brightness]);
108167         updateResourceState();
108168         triggerListenerCB(ScreenState);
108169     }
108170
108171     function isScreenOn() {
108172         return _isScreenOn;
108173     }
108174
108175     function restoreScreenBrightness() {
108176         if (_isScreenResourceOccupied) {
108177             _isScreenResourceOccupied = false;
108178             deviceSettings.persist("DISPLAY.brightness", _originalBrightness);
108179             event.trigger("DisplayBrightnessChangedByPower", [_originalBrightness]);
108180             updateResourceState();
108181             triggerListenerCB(ScreenState);
108182         }
108183     }
108184
108185     function turnScreenOn() {
108186         var brightness, value, flag = false;
108187         if (!_security.turnScreenOn) {
108188             throw new WebAPIError(errorcode.SECURITY_ERR);
108189         }
108190         brightness = deviceSettings.retrieve("DISPLAY.brightness");
108191         switch (_minimal_screen_state) {
108192         case "SCREEN_DIM":
108193             if (brightness <= _SCREEN_STATE.SCREEN_OFF.VALUE) {
108194                 if (!_isScreenResourceOccupied) {
108195                     _originalBrightness = brightness;
108196                     _isScreenResourceOccupied = true;
108197                 }
108198                 value = _SCREEN_STATE.SCREEN_DIM.VALUE;
108199                 flag = true;
108200             }
108201             break;
108202         case "SCREEN_NORMAL":
108203             if (brightness < _SCREEN_STATE.SCREEN_NORMAL.MIN) {
108204                 if (!_isScreenResourceOccupied) {
108205                     _originalBrightness = brightness;
108206                     _isScreenResourceOccupied = true;
108207                 }
108208                 value = _normalBrightness;
108209                 flag = true;
108210             }
108211             break;
108212         case "SCREEN_BRIGHT":
108213             if (brightness < _SCREEN_STATE.SCREEN_BRIGHT.MIN) {
108214                 if (!_isScreenResourceOccupied) {
108215                     _originalBrightness = brightness;
108216                     _isScreenResourceOccupied = true;
108217                 }
108218                 value = _SCREEN_STATE.SCREEN_BRIGHT.VALUE;
108219                 flag = true;
108220             }
108221             break;
108222         }
108223         if (flag) {
108224             deviceSettings.persist("DISPLAY.brightness", value);
108225             event.trigger("DisplayBrightnessChangedByPower", [value]);
108226             updateResourceState();
108227             triggerListenerCB(ScreenState);
108228         }
108229         _isScreenOn = true;
108230     }
108231
108232     function turnScreenOff() {
108233         if (!_security.turnScreenOff) {
108234             throw new WebAPIError(errorcode.SECURITY_ERR);
108235         }
108236         _isScreenOn = false;
108237     }
108238
108239     function handleSubFeatures(subFeatures) {
108240         var i, subFeature;
108241
108242         for (subFeature in subFeatures) {
108243             for (i in _security[subFeature]) {
108244                 _security[_security[subFeature][i]] = true;
108245             }
108246         }
108247     }
108248
108249     var power = {
108250         request: request,
108251         release: release,
108252         setScreenStateChangeListener: setScreenStateChangeListener,
108253         unsetScreenStateChangeListener: unsetScreenStateChangeListener,
108254         getScreenBrightness: getScreenBrightness,
108255         setScreenBrightness: setScreenBrightness,
108256         isScreenOn: isScreenOn,
108257         restoreScreenBrightness: restoreScreenBrightness,
108258         turnScreenOn: turnScreenOn,
108259         turnScreenOff: turnScreenOff,
108260         handleSubFeatures : handleSubFeatures
108261     };
108262
108263     return power;
108264 };
108265
108266 initState();
108267 event.on("CpuLoadChanged", function (value) {
108268     var load;
108269     if (_isCPUAwake && Number(value) === 0) {
108270         load = _POWER_RESOURCE.CPU.STATE.CPU_AWAKE.DEFAULT_VALUE;
108271         deviceSettings.persist("CPU.load", load);
108272         event.trigger("CpuLoadChangedByPower", [load]);
108273     }
108274 });
108275 event.on("DisplayBrightnessChanged", function () {
108276     _normalBrightness = deviceSettings.retrieve("DISPLAY.brightness");
108277     updateResourceState();
108278     triggerListenerCB(ScreenState);
108279 });
108280
108281 module.exports = _self;
108282
108283 });
108284 define('ripple/platform/tizen/2.0/SimpleCoordinates', function (require, exports, module) {
108285 /*
108286  *  Copyright 2013 Intel Corporation.
108287  *
108288  * Licensed under the Apache License, Version 2.0 (the "License");
108289  * you may not use this file except in compliance with the License.
108290  * You may obtain a copy of the License at
108291  *
108292  * http://www.apache.org/licenses/LICENSE-2.0
108293  *
108294  * Unless required by applicable law or agreed to in writing, software
108295  * distributed under the License is distributed on an "AS IS" BASIS,
108296  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108297  * See the License for the specific language governing permissions and
108298  * limitations under the License.
108299  */
108300
108301 var t = require('ripple/platform/tizen/2.0/typecast'),
108302     SimpleCoordinates;
108303
108304 SimpleCoordinates = function (latitude, longitude) {
108305     var simpleCoordinates = {};
108306
108307     t.SimpleCoordinates(arguments, this);
108308
108309     this.__defineGetter__("latitude", function () {
108310         return simpleCoordinates.latitude;
108311     });
108312     this.__defineSetter__("latitude", function (val) {
108313         try {
108314             simpleCoordinates.latitude = t.double(val);
108315         } catch (e) {
108316         }
108317     });
108318
108319     this.__defineGetter__("longitude", function () {
108320         return simpleCoordinates.longitude;
108321     });
108322     this.__defineSetter__("longitude", function (val) {
108323         try {
108324             simpleCoordinates.longitude = t.double(val);
108325         } catch (e) {
108326         }
108327     });
108328
108329     simpleCoordinates.latitude  = latitude;
108330     simpleCoordinates.longitude = longitude;
108331 };
108332
108333 module.exports = SimpleCoordinates;
108334
108335 });
108336 define('ripple/platform/tizen/2.0/MessageBody', function (require, exports, module) {
108337 /*
108338  *  Copyright 2012 Intel Corporation.
108339  *
108340  * Licensed under the Apache License, Version 2.0 (the "License");
108341  * you may not use this file except in compliance with the License.
108342  * You may obtain a copy of the License at
108343  *
108344  * http://www.apache.org/licenses/LICENSE-2.0
108345  *
108346  * Unless required by applicable law or agreed to in writing, software
108347  * distributed under the License is distributed on an "AS IS" BASIS,
108348  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108349  * See the License for the specific language governing permissions and
108350  * limitations under the License.
108351  */
108352
108353 module.exports = function (id, isloaded, _plainbody, _htmlbody, inlineattachments) {
108354     var msgbody, _id = id, _loaded = isloaded;
108355     msgbody = {
108356         plainBody: _plainbody,
108357         htmlBody: _htmlbody,
108358         inlineAttachments: [] // TODO: not support attachment yet
108359     };
108360     msgbody.__defineGetter__("messageId", function () {
108361         return _id;
108362     });
108363     msgbody.__defineGetter__("loaded", function () {
108364         return _loaded;
108365     });
108366     return msgbody;
108367 };
108368
108369 });
108370 define('ripple/platform/tizen/2.0/NotificationDetailInfo', function (require, exports, module) {
108371 /*
108372  *  Copyright 2013 Intel Corporation.
108373  *
108374  * Licensed under the Apache License, Version 2.0 (the "License");
108375  * you may not use this file except in compliance with the License.
108376  * You may obtain a copy of the License at
108377  *
108378  * http://www.apache.org/licenses/LICENSE-2.0
108379  *
108380  * Unless required by applicable law or agreed to in writing, software
108381  * distributed under the License is distributed on an "AS IS" BASIS,
108382  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108383  * See the License for the specific language governing permissions and
108384  * limitations under the License.
108385  */
108386
108387 var t = require('ripple/platform/tizen/2.0/typecast'),
108388     NotificationDetailInfo;
108389
108390 NotificationDetailInfo = function (mainText, subText) {
108391     var notificationDetailInfo = {};
108392
108393     t.NotificationDetailInfo(arguments, this);
108394
108395     notificationDetailInfo.mainText = mainText;
108396     notificationDetailInfo.subText  = subText || null;
108397
108398     this.__defineGetter__("mainText", function () {
108399         return notificationDetailInfo.mainText;
108400     });
108401     this.__defineSetter__("mainText", function (val) {
108402         try {
108403             notificationDetailInfo.mainText = t.DOMString(val);
108404         } catch (e) {
108405         }
108406     });
108407
108408     this.__defineGetter__("subText", function () {
108409         return notificationDetailInfo.subText;
108410     });
108411     this.__defineSetter__("subText", function (val) {
108412         try {
108413             notificationDetailInfo.subText = t.DOMString(val, "?");
108414         } catch (e) {
108415         }
108416     });
108417 };
108418
108419 module.exports = NotificationDetailInfo;
108420
108421 });
108422 define('ripple/platform/tizen/2.0/PrivMessage', function (require, exports, module) {
108423 /*
108424  *  Copyright 2012 Intel Corporation.
108425  *
108426  * Licensed under the Apache License, Version 2.0 (the "License"),
108427  * you may not use this file except in compliance with the License.
108428  * You may obtain a copy of the License at
108429  *
108430  * http://www.apache.org/licenses/LICENSE-2.0
108431  *
108432  * Unless required by applicable law or agreed to in writing, software
108433  * distributed under the License is distributed on an "AS IS" BASIS,
108434  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108435  * See the License for the specific language governing permissions and
108436  * limitations under the License.
108437  */
108438 var utils = require('ripple/utils');
108439
108440 module.exports = function (m, opt) {
108441     return {
108442 // readonly begin
108443         priv: {id: opt.id,
108444                serviceId: opt.serviceId,
108445                conversationId: opt.conversationId,
108446                folderId: opt.folderId,
108447                type: opt.type,
108448                timestamp: new Date(opt.timestamp),
108449                from: opt.from,
108450                hasAttachment: opt.hasAttachment,
108451                messageStatus: opt.messageStatus
108452         },
108453 // readonly end
108454         to: m.to.slice(0),
108455         cc: m.cc.slice(0),
108456         bcc: m.bcc.slice(0),
108457         body: utils.copy(m.body),
108458         isRead: m.isRead,
108459         isHighPriority: m.isHighPriority,
108460         subject: m.subject,
108461         inResponseTo: m.inResponseTo,
108462         attachments: utils.copy(m.attachments)
108463     };
108464 };
108465
108466 });
108467 define('ripple/platform/tizen/2.0/GeoRectBounds', function (require, exports, module) {
108468 /*
108469  *  Copyright 2012 Intel Corporation.
108470  *
108471  * Licensed under the Apache License, Version 2.0 (the "License");
108472  * you may not use this file except in compliance with the License.
108473  * You may obtain a copy of the License at
108474  *
108475  * http://www.apache.org/licenses/LICENSE-2.0
108476  *
108477  * Unless required by applicable law or agreed to in writing, software
108478  * distributed under the License is distributed on an "AS IS" BASIS,
108479  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108480  * See the License for the specific language governing permissions and
108481  * limitations under the License.
108482  */
108483
108484 module.exports = function (_southWest, _northEast) {
108485     var southWest, northEast;
108486     southWest = _southWest || null;
108487     northEast = _northEast || null;
108488
108489     this.__defineGetter__("southWest", function () {
108490         return southWest;
108491     });
108492
108493     this.__defineGetter__("northEast", function () {
108494         return northEast;
108495     });
108496 };
108497
108498 });
108499 define('ripple/platform/tizen/2.0/calendar', function (require, exports, module) {
108500 /*
108501  *  Copyright 2013 Intel Corporation.
108502  *
108503  * Licensed under the Apache License, Version 2.0 (the "License");
108504  * you may not use this file except in compliance with the License.
108505  * You may obtain a copy of the License at
108506  *
108507  * http://www.apache.org/licenses/LICENSE-2.0
108508  *
108509  * Unless required by applicable law or agreed to in writing, software
108510  * distributed under the License is distributed on an "AS IS" BASIS,
108511  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
108512  * See the License for the specific language governing permissions and
108513  * limitations under the License.
108514  */
108515
108516 var utils = require('ripple/utils'),
108517     db = require('ripple/db'),
108518     t = require('ripple/platform/tizen/2.0/typecast'),
108519     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
108520     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
108521     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
108522     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
108523     TZDate = require('ripple/platform/tizen/2.0/TZDate'),
108524     TDur = require('ripple/platform/tizen/2.0/TimeDuration'),
108525     CalendarItem = require('ripple/platform/tizen/2.0/CalendarItem'),
108526     CalendarEvent = require('ripple/platform/tizen/2.0/CalendarEvent'),
108527     CalendarEventId = require('ripple/platform/tizen/2.0/CalendarEventId'),
108528     CalendarTask = require('ripple/platform/tizen/2.0/CalendarTask'),
108529     Calendar,
108530     CalendarStorage,
108531     CalendarItemsStorage,
108532     _DB_CALENDARS_KEY = "tizen1-db-calendars",
108533     _watchers = [],
108534     _calendars = {
108535         EVENT: {},
108536         TASK: {}
108537     },
108538     _calendarsStorage,
108539     _security = {
108540         "http://tizen.org/privilege/calendar.read": ["getCalendars",
108541                 "getUnifiedCalendar", "getDefaultCalendar", "getCalendar",
108542                 "get", "find", "addChangeListener", "removeChangeListener",
108543                 "expandRecurrence", "convertToString", "clone"],
108544         "http://tizen.org/privilege/calendar.write": ["add", "addBatch",
108545                 "update", "updateBatch", "remove", "removeBatch"]
108546     },
108547     _self;
108548
108549 function _isValidId(id) {
108550     return (/[a-z]|[A-Z]|[0-9]|[\-]/).test(id);
108551 }
108552
108553 function retrieveCalendars() {
108554     _calendarsStorage = db.retrieveObject(_DB_CALENDARS_KEY) || {EVENT: {}, TASK: {}};
108555 }
108556
108557 function saveCalendars() {
108558     db.saveObject(_DB_CALENDARS_KEY, _calendarsStorage);
108559 }
108560
108561 _self = function () {
108562     var calendarManager;
108563
108564     // private
108565     function loadCalendars(type) {
108566         var calsStorage, defCalendar, id, i, item;
108567
108568         retrieveCalendars();
108569         calsStorage = _calendarsStorage[type];
108570
108571         if (tizen1_utils.isEmptyObject(calsStorage)) {
108572             defCalendar = new Calendar(type, "Default " + type.toLowerCase() + " calendar");
108573
108574             _calendars[type][defCalendar.id] = defCalendar;
108575             calsStorage[defCalendar.id] = new CalendarStorage(defCalendar);
108576         } else {
108577             for (id in calsStorage) {
108578                 for (i in calsStorage[id].items) {
108579                     item = calsStorage[id].items[i];
108580                 }
108581                 _calendars[type][id] = new Calendar(type, calsStorage[id].name,
108582                         calsStorage[id].items, id);
108583             }
108584         }
108585     }
108586
108587     // public
108588     function getCalendars(type, successCallback, errorCallback) {
108589         if (!_security.getCalendars) {
108590             throw new WebAPIException(errorcode.SECURITY_ERR);
108591         }
108592
108593         t.CalendarManager("getCalendars", arguments);
108594
108595         window.setTimeout(function () {
108596             var i, result = [];
108597
108598             if (tizen1_utils.isEmptyObject(_calendars[type])) {
108599                 loadCalendars(type);
108600             }
108601
108602             if (_calendars.length !== 0) {
108603                 for (i in _calendars[type]) {
108604                     result.push(_calendars[type][i]);
108605                 }
108606                 successCallback(result);
108607             } else if (errorCallback) {
108608                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
108609             }
108610         }, 1);
108611     }
108612
108613     function getUnifiedCalendar(type) {
108614         var id, calendar;
108615
108616         if (!_security.getUnifiedCalendar) {
108617             throw new WebAPIException(errorcode.SECURITY_ERR);
108618         }
108619
108620         t.CalendarManager("getUnifiedCalendar", arguments);
108621
108622         if (tizen1_utils.isEmptyObject(_calendars[type])) {
108623             loadCalendars(type);
108624         }
108625
108626         for (id in _calendars[type]) {
108627             calendar = _calendars[type][id];
108628             break;
108629         }
108630
108631         if (calendar === undefined)
108632             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
108633
108634         return calendar;
108635     }
108636
108637     function getDefaultCalendar(type) {
108638         var id, calendar;
108639
108640         if (!_security.getDefaultCalendar) {
108641             throw new WebAPIException(errorcode.SECURITY_ERR);
108642         }
108643
108644         t.CalendarManager("getDefaultCalendar", arguments);
108645
108646         if (tizen1_utils.isEmptyObject(_calendars[type])) {
108647             loadCalendars(type);
108648         }
108649
108650         for (id in _calendars[type]) {
108651             calendar = _calendars[type][id];
108652             break;
108653         }
108654
108655         if (calendar === undefined)
108656             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
108657
108658         return calendar;
108659     }
108660
108661     function getCalendar(type, id) {
108662         var calendar;
108663
108664         if (!_security.getCalendar) {
108665             throw new WebAPIException(errorcode.SECURITY_ERR);
108666         }
108667
108668         t.CalendarManager("getCalendar", arguments);
108669
108670         if (tizen1_utils.isEmptyObject(_calendars[type])) {
108671             loadCalendars(type);
108672         }
108673
108674         calendar = _calendars[type][id];
108675         if (calendar === undefined)
108676             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
108677
108678         return calendar;
108679     }
108680
108681     function handleSubFeatures(subFeatures) {
108682         var i, subFeature;
108683
108684         for (subFeature in subFeatures) {
108685             for (i in _security[subFeature]) {
108686                 _security[_security[subFeature][i]] = true;
108687             }
108688         }
108689     }
108690
108691     calendarManager = {
108692         getCalendars:       getCalendars,
108693         getUnifiedCalendar: getUnifiedCalendar,
108694         getDefaultCalendar: getDefaultCalendar,
108695         getCalendar:        getCalendar,
108696         handleSubFeatures:  handleSubFeatures
108697     };
108698
108699     return calendarManager;
108700 };
108701
108702 Calendar = function (type, name, storageItems, calendarId) {
108703     var privateItems = {},
108704         defaultWatchId = 0;
108705     calendarId = calendarId || Math.uuid(null, 16);
108706
108707     // private
108708     function createCalendarItem() {
108709         var calendarItem = null;
108710
108711         switch (type) {
108712         case "EVENT":
108713             calendarItem = new CalendarEvent();
108714             break;
108715
108716         case "TASK":
108717             calendarItem = new CalendarTask();
108718             break;
108719
108720         default:
108721             break;
108722         }
108723
108724         return calendarItem;
108725     }
108726
108727     function isValidCalendarItemId(itemId) {
108728         var i;
108729
108730         if (!_isValidId(itemId))
108731             return false;
108732
108733         for (i in privateItems) {
108734             if (i === itemId)
108735                 return true;
108736         }
108737
108738         return false;
108739     }
108740
108741     function loadCalendarItemInit(calendarItem, storageItem) {
108742         calendarItem.description    = utils.copy(storageItem.description);
108743         calendarItem.summary        = utils.copy(storageItem.summary);
108744         calendarItem.isAllDay       = utils.copy(storageItem.isAllDay);
108745         calendarItem.startDate      = storageItem.startDate;
108746         if (storageItem.startDate instanceof TZDate) {
108747             calendarItem.startDate      = storageItem.startDate.addDuration(new TDur(0, 'MSECS'));
108748         }
108749         if (typeof storageItem.startDate === 'string') {
108750             calendarItem.startDate      = new TZDate(new Date(storageItem.startDate));
108751         }
108752
108753         calendarItem.duration       = utils.copy(storageItem.duration);
108754         calendarItem.location       = utils.copy(storageItem.location);
108755         calendarItem.geolocation    = utils.copy(storageItem.geolocation);
108756         calendarItem.organizer      = utils.copy(storageItem.organizer);
108757         calendarItem.visibility     = utils.copy(storageItem.visibility);
108758         calendarItem.status         = utils.copy(storageItem.status);
108759         calendarItem.priority       = utils.copy(storageItem.priority);
108760         calendarItem.alarms         = utils.copy(storageItem.alarms);
108761         calendarItem.categories     = utils.copy(storageItem.categories);
108762         calendarItem.attendees      = utils.copy(storageItem.attendees);
108763     }
108764
108765     function loadCalendarEventInit(calendarItem, storageItem) {
108766         loadCalendarItemInit(calendarItem, storageItem);
108767
108768         calendarItem.endDate = storageItem.endDate;
108769         if (storageItem.endDate instanceof TZDate) {
108770             calendarItem.endDate = storageItem.endDate.addDuration(new TDur(0, 'MSECS'));
108771         }
108772         if (typeof storageItem.endDate === 'string') {
108773             calendarItem.endDate = new TZDate(new Date(storageItem.endDate));
108774         }
108775         calendarItem.availability = utils.copy(storageItem.availability);
108776         calendarItem.recurrenceRule = utils.copy(storageItem.recurrenceRule);
108777         calendarItem.expandRecurrence = function (startDate, endDate, successCallback, errorCallback) {
108778             if (!_security.expandRecurrence) {
108779                 throw new WebAPIException(errorcode.SECURITY_ERR);
108780             }
108781
108782             calendarItem.startDate = startDate;
108783             calendarItem.endDate   = endDate;
108784
108785             if (errorCallback) {
108786                 window.setTimeout(function () {
108787                     errorCallback(new WebAPIError(errorcode.NOT_SUPPORTED_ERR));
108788                 }, 1);
108789             }
108790         };
108791         calendarItem.frequency       = utils.copy(storageItem.frequency);
108792         calendarItem.interval        = utils.copy(storageItem.interval);
108793         calendarItem.untilDate = storageItem.untilDate;
108794         if (storageItem.untilDate instanceof TZDate) {
108795             calendarItem.untilDate = storageItem.untilDate.addDuration(new TDur(0, 'MSECS'));
108796         }
108797         if (typeof storageItem.untilDate === 'string') {
108798             calendarItem.untilDate = new TZDate(new Date(storageItem.untilDate));
108799         }
108800         calendarItem.occurrenceCount = utils.copy(storageItem.occurrenceCount);
108801         calendarItem.daysOfTheWeek   = utils.copy(storageItem.daysOfTheWeek);
108802         calendarItem.setPositions    = utils.copy(storageItem.setPositions);
108803         calendarItem.exceptions      = utils.copy(storageItem.exceptions);
108804     }
108805
108806     function loadCalendarTaskInit(calendarItem, storageItem) {
108807         loadCalendarItemInit(calendarItem, storageItem);
108808
108809         calendarItem.dueDate = storageItem.dueDate;
108810         if (storageItem.dueDate instanceof TZDate) {
108811             calendarItem.dueDate = storageItem.dueDate.addDuration(new TDur(0, 'MSECS'));
108812         }
108813         if (typeof storageItem.dueDate === 'string') {
108814             calendarItem.dueDate = new TZDate(new Date(storageItem.dueDate));
108815         }
108816         calendarItem.completeDate = storageItem.completeDate;
108817         if (storageItem.completeDate instanceof TZDate) {
108818             calendarItem.completeDate = storageItem.completeDate.addDuration(new TDur(0, 'MSECS'));
108819         }
108820         if (typeof storageItem.completeDate === 'string') {
108821             calendarItem.completeDate = new TZDate(new Date(storageItem.completeDate));
108822         }
108823         calendarItem.progress      = utils.copy(storageItem.progress);
108824     }
108825
108826     function loadCalendarItems() {
108827         var i, calendarItem;
108828
108829         if (storageItems === undefined)
108830             return;
108831
108832         for (i in storageItems) {
108833             calendarItem = new CalendarItem(type, i, storageItems[i].lastModificationDate? new TZDate(new Date(storageItems[i].lastModificationDate)) : null, _security);
108834
108835             if (type === "EVENT") {
108836                 loadCalendarEventInit(calendarItem, storageItems[i]);
108837             } else {
108838                 loadCalendarTaskInit(calendarItem, storageItems[i]);
108839             }
108840
108841             privateItems[i] = calendarItem;
108842         }
108843     }
108844
108845     function saveCalendarItems() {
108846         _calendarsStorage[type][calendarId] ||  (_calendarsStorage[type][calendarId] = {});
108847         _calendarsStorage[type][calendarId].items = new CalendarItemsStorage(privateItems);
108848         saveCalendars();
108849     }
108850
108851     // public
108852     function get(id) {
108853         var item, uid, CalendarItemType, external = {};
108854
108855         if (!_security.get) {
108856             throw new WebAPIException(errorcode.SECURITY_ERR);
108857         }
108858
108859         t.Calendar("get", arguments);
108860
108861         if (type === "EVENT") {
108862             t.CalendarEventId(id);
108863             uid = id.uid;
108864             CalendarItemType = CalendarEvent;
108865         } else {
108866             t.CalendarTaskId(id);
108867             uid = id;
108868             CalendarItemType = CalendarTask;
108869         }
108870
108871         if (!isValidCalendarItemId(uid))
108872             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
108873
108874         item = new CalendarItemType(privateItems[uid]);
108875         external.id                   = privateItems[uid].id;
108876         external.lastModificationDate = privateItems[uid].lastModificationDate;
108877
108878         item.__defineGetter__("calendarId", function () {
108879             return calendarId;
108880         });
108881
108882         item.__defineGetter__("id", function () {
108883             return external.id;
108884         });
108885
108886         item.__defineGetter__("lastModificationDate", function () {
108887             return external.lastModificationDate;
108888         });
108889
108890         return item;
108891     }
108892
108893     function add(item) {
108894         var uid, external = {};
108895
108896         if (!_security.add) {
108897             throw new WebAPIException(errorcode.SECURITY_ERR);
108898         }
108899
108900         t.Calendar("add", arguments);
108901
108902         uid = Math.uuid(null, 16);
108903         privateItems[uid] = t.CalendarItem(item, "+");
108904         if (type === "EVENT") {
108905             privateItems[uid].id = new CalendarEventId(uid);
108906         } else {
108907             privateItems[uid].id = uid;
108908         }
108909         privateItems[uid].lastModificationDate = new TZDate();
108910
108911         external.id = privateItems[uid].id;
108912         external.lastModificationDate = privateItems[uid].lastModificationDate;
108913
108914         saveCalendarItems();
108915
108916         // set the calendarId of the item
108917         item.__defineGetter__("calendarId", function () {
108918             return calendarId;
108919         });
108920
108921         item.__defineGetter__("id", function () {
108922             return external.id;
108923         });
108924
108925         item.__defineGetter__("lastModificationDate", function () {
108926             return external.lastModificationDate;
108927         });
108928
108929         window.setTimeout(function () {
108930             for (var i in _watchers) {
108931                 _watchers[i].onitemsadded([item]);
108932             }
108933         }, 1);
108934     }
108935
108936     function addBatch(items, successCallback, errorCallback) {
108937         if (!_security.addBatch) {
108938             throw new WebAPIException(errorcode.SECURITY_ERR);
108939         }
108940
108941         t.Calendar("addBatch", arguments, true);
108942
108943         window.setTimeout(function () {
108944             var i, j, uid, external = [];
108945
108946             for (i in items) {
108947                 uid = Math.uuid(null, 16);
108948                 privateItems[uid] = utils.copy(items[i]);
108949
108950                 if (type === "EVENT") {
108951                     privateItems[uid].id = new CalendarEventId(uid);
108952                 } else {
108953                     privateItems[uid].id = uid;
108954                 }
108955
108956                 external[i] = {};
108957                 external[i].id = privateItems[uid].id;
108958                 external[i].lastModificationDate = new TZDate();
108959
108960                 items[i].__defineGetter__("calendarId", function () {
108961                     return calendarId;
108962                 });
108963
108964                 items[i].__defineGetter__("id", function () {
108965                     return external[i].id;
108966                 });
108967
108968                 items[i].__defineGetter__("lastModificationDate", function () {
108969                     return external[i].lastModificationDate;
108970                 });
108971             }
108972
108973             saveCalendarItems();
108974
108975             if (successCallback) {
108976                 successCallback(items);
108977             }
108978             for (j in _watchers) {
108979                 _watchers[j].onitemsadded(items);
108980             }
108981         }, 1);
108982     }
108983
108984     function update(item, updateAllInstances) {
108985         var calendarItem, attr, uid;
108986
108987         if (!_security.update) {
108988             throw new WebAPIException(errorcode.SECURITY_ERR);
108989         }
108990
108991         t.Calendar("update", arguments);
108992
108993         uid = (type === "EVENT") ? item.id.uid : item.id;
108994         if (!isValidCalendarItemId(uid))
108995             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
108996
108997         if (updateAllInstances === undefined || updateAllInstances === null) {
108998             updateAllInstances = true;
108999         }
109000
109001         if ((type === "EVENT") && !updateAllInstances) {
109002             calendarItem = createCalendarItem();
109003
109004             for (attr in privateItems[uid]) {
109005                 if (attr !== "id" && attr !== "lastModificationDate") {
109006                     if (item[attr] !== undefined)
109007                         calendarItem[attr] = utils.copy(item[attr]);
109008                     else
109009                         calendarItem[attr] = utils.copy(privateItems[uid][attr]);
109010                 }
109011             }
109012
109013             add(calendarItem);
109014         } else {
109015             for (attr in privateItems[uid]) {
109016                 if ((attr !== "id") && (attr !== "lastModificationDate") && (item[attr] !== undefined))
109017                     privateItems[uid][attr] = utils.copy(item[attr]);
109018             }
109019             window.setTimeout(function () {
109020                 var i;
109021
109022                 for (i in _watchers) {
109023                     _watchers[i].onitemsupdated([utils.copy(privateItems[uid])]);
109024                 }
109025             }, 1);
109026         }
109027         saveCalendarItems();
109028     }
109029
109030     function updateBatch(items, successCallback, errorCallback,
109031             updateAllInstances) {
109032         if (!_security.updateBatch) {
109033             throw new WebAPIException(errorcode.SECURITY_ERR);
109034         }
109035
109036         t.Calendar("updateBatch", arguments, true);
109037
109038         window.setTimeout(function () {
109039             var i, j, attr, calendarItem, updatedItems = [], uid;
109040
109041             for (i in items) {
109042                 uid = (type === "EVENT") ? items[i].id.uid : items[i].id;
109043                 if (!uid || !privateItems[uid]) {
109044                     if (errorCallback) {
109045                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
109046                     }
109047                     return;
109048                 }
109049             }
109050
109051             if (updateAllInstances) {
109052                 for (i in privateItems) {
109053                     for (j in items) {
109054                         uid = (type === "EVENT") ? items[j].id.uid : items[j].id;
109055                         if (i === uid) {
109056                             for (attr in privateItems[i]) {
109057                                 if (attr !== "id" && attr !== "lastModificationDate" && items[j][attr] !== undefined)
109058                                     privateItems[i][attr] = utils.copy(items[j][attr]);
109059                             }
109060                             saveCalendarItems();
109061                             updatedItems.push(utils.copy(privateItems[i]));
109062                         }
109063                     }
109064                 }
109065             } else {
109066                 for (i in items) {
109067                     calendarItem = createCalendarItem();
109068
109069                     uid = (type === "EVENT") ? items[i].id.uid : items[i].id;
109070                     for (attr in privateItems[uid]) {
109071                         if (attr !== "id" && attr !== "lastModificationDate") {
109072                             if (items[i][attr] !== undefined)
109073                                 calendarItem[attr] = utils.copy(items[i][attr]);
109074                             else
109075                                 calendarItem[attr] = utils.copy(privateItems[uid][attr]);
109076                         }
109077                     }
109078
109079                     add(calendarItem);
109080                     updatedItems.push(utils.copy(calendarItem));
109081                 }
109082             }
109083
109084             saveCalendarItems();
109085             if (successCallback) {
109086                 successCallback();
109087             }
109088             for (i in _watchers) {
109089                 _watchers[i].onitemsupdated(utils.copy(updatedItems));
109090             }
109091         }, 1);
109092     }
109093
109094     function remove(id) {
109095         var isFound = false, i, uid;
109096
109097         if (!_security.remove) {
109098             throw new WebAPIException(errorcode.SECURITY_ERR);
109099         }
109100
109101         t.Calendar("remove", arguments);
109102
109103         if (type === "EVENT") {
109104             t.CalendarEventId(id);
109105             uid = id.uid;
109106         } else {
109107             t.CalendarTaskId(id);
109108             uid = id;
109109         }
109110
109111         for (i in privateItems) {
109112             if (i === uid) {
109113                 delete privateItems[i];
109114                 isFound = true;
109115                 break;
109116             }
109117         }
109118
109119         if (!isFound)
109120             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
109121
109122         saveCalendarItems();
109123
109124         window.setTimeout(function () {
109125             var i;
109126
109127             for (i in _watchers) {
109128                 _watchers[i].onitemsremoved([id]);
109129             }
109130         }, 1);
109131     }
109132
109133     function removeBatch(ids, successCallback, errorCallback) {
109134         if (!_security.removeBatch) {
109135             throw new WebAPIException(errorcode.SECURITY_ERR);
109136         }
109137
109138         t.Calendar("removeBatch", arguments, true);
109139
109140         window.setTimeout(function () {
109141             var i, uid;
109142
109143             for (i in ids) {
109144                 uid = (type === "EVENT") ? ids[i].uid : ids[i];
109145
109146                 if (!privateItems[uid]) {
109147                     if (errorCallback) {
109148                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
109149                     }
109150                     return;
109151                 }
109152             }
109153
109154             for (i in ids) {
109155                 uid = (type === "EVENT") ? ids[i].uid : ids[i];
109156                 delete privateItems[uid];
109157             }
109158             saveCalendarItems();
109159             if (successCallback) {
109160                 successCallback();
109161             }
109162
109163             for (i in _watchers) {
109164                 _watchers[i].onitemsremoved(utils.copy(ids));
109165             }
109166         }, 1);
109167     }
109168
109169     function find(successCallback, errorCallback, filter, sortMode) {
109170         if (!_security.find) {
109171             throw new WebAPIException(errorcode.SECURITY_ERR);
109172         }
109173
109174         t.Calendar("find", arguments, true);
109175
109176         window.setTimeout(function () {
109177             var i, calendarItems = [], result = [];
109178
109179             for (i in privateItems) {
109180                 calendarItems.push(privateItems[i]);
109181             }
109182             if (calendarItems.length > 0) {
109183                 result = tizen1_utils.query(calendarItems, filter, sortMode);
109184             }
109185             successCallback(result);
109186         }, 1);
109187     }
109188
109189     function addChangeListener(successCallback) {
109190         var watchId;
109191
109192         if (!_security.addChangeListener) {
109193             throw new WebAPIException(errorcode.SECURITY_ERR);
109194         }
109195
109196         t.Calendar("addChangeListener", arguments);
109197
109198         watchId = ++defaultWatchId;
109199         _watchers[watchId] = successCallback;
109200
109201         return watchId;
109202     }
109203
109204     function removeChangeListener(watchId) {
109205         if (!_security.removeChangeListener) {
109206             throw new WebAPIException(errorcode.SECURITY_ERR);
109207         }
109208
109209         if (!_watchers[watchId])
109210             return;
109211
109212         delete _watchers[watchId];
109213     }
109214
109215     loadCalendarItems(type, privateItems, storageItems);
109216
109217     this.__defineGetter__("id", function () {
109218         return calendarId;
109219     });
109220     this.__defineGetter__("name", function () {
109221         return name;
109222     });
109223
109224     this.get                  = get;
109225     this.add                  = add;
109226     this.addBatch             = addBatch;
109227     this.update               = update;
109228     this.updateBatch          = updateBatch;
109229     this.remove               = remove;
109230     this.removeBatch          = removeBatch;
109231     this.find                 = find;
109232     this.addChangeListener    = addChangeListener;
109233     this.removeChangeListener = removeChangeListener;
109234 };
109235
109236 CalendarStorage = function (calendar) {
109237     this.id   = calendar.id;
109238     this.name = calendar.name;
109239 };
109240
109241 CalendarItemsStorage = function (privateItems) {
109242     var itemsStorage = {}, i, attr;
109243
109244     for (i in privateItems) {
109245         itemsStorage[i] = {};
109246         for (attr in privateItems[i]) {
109247             //TODO: should be
109248             //      if (privateItems[i][attr] instanceof TZDate) {
109249             //But, we used "utils.copy" before store the item to privateItems list.
109250             //So the constructor information all lost
109251             if ((attr === "startDate" || attr === "endDate" || attr === "dueDate" || attr === "completedDate" || attr === "lastModificationDate") &&
109252                 (privateItems[i][attr])) {
109253
109254                 itemsStorage[i][attr] = privateItems[i][attr].toString();
109255             } else if (typeof privateItems[i] !== "function") {
109256                 itemsStorage[i][attr] = privateItems[i][attr];
109257             }
109258         }
109259     }
109260
109261     return itemsStorage;
109262 };
109263
109264 module.exports = _self;
109265
109266 });
109267 define('ripple/platform/tizen/2.0/DownloadRequest', function (require, exports, module) {
109268 /*
109269  *  Copyright 2013 Intel Corporation.
109270  *
109271  * Licensed under the Apache License, Version 2.0 (the "License");
109272  * you may not use this file except in compliance with the License.
109273  * You may obtain a copy of the License at
109274  *
109275  * http://www.apache.org/licenses/LICENSE-2.0
109276  *
109277  * Unless required by applicable law or agreed to in writing, software
109278  * distributed under the License is distributed on an "AS IS" BASIS,
109279  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
109280  * See the License for the specific language governing permissions and
109281  * limitations under the License.
109282  */
109283
109284 var t = require('ripple/platform/tizen/2.0/typecast'),
109285     DownloadRequest;
109286
109287 DownloadRequest = function (url, destination, fileName, networkType,
109288         httpHeader) {
109289     var downloadRequest = {};
109290
109291     t.DownloadRequest(arguments, this);
109292
109293     this.__defineGetter__("url", function () {
109294         return downloadRequest.url;
109295     });
109296     this.__defineSetter__("url", function (val) {
109297         try {
109298             downloadRequest.url = t.DOMString(val);
109299         } catch (e) {
109300         }
109301     });
109302
109303     this.__defineGetter__("networkType", function () {
109304         return downloadRequest.networkType;
109305     });
109306     this.__defineSetter__("networkType", function (val) {
109307         try {
109308             downloadRequest.networkType = t.DownloadNetworkType(val, "?");
109309         } catch (e) {
109310         }
109311     });
109312
109313     this.destination            = destination || "";
109314     this.fileName               = fileName || "";
109315     this.httpHeader             = httpHeader || {};
109316
109317     downloadRequest.url         = url;
109318     downloadRequest.networkType = networkType || "ALL";
109319 };
109320
109321 module.exports = DownloadRequest;
109322
109323 });
109324 define('ripple/platform/tizen/2.0/networkbearerselection', function (require, exports, module) {
109325 /*
109326  *  Copyright 2013 Intel Corporation.
109327  *
109328  * Licensed under the Apache License, Version 2.0 (the "License");
109329  * you may not use this file except in compliance with the License.
109330  * You may obtain a copy of the License at
109331  *
109332  * http://www.apache.org/licenses/LICENSE-2.0
109333  *
109334  * Unless required by applicable law or agreed to in writing, software
109335  * distributed under the License is distributed on an "AS IS" BASIS,
109336  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
109337  * See the License for the specific language governing permissions and
109338  * limitations under the License.
109339  */
109340
109341 var event = require('ripple/event'),
109342     t = require('ripple/platform/tizen/2.0/typecast'),
109343     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
109344     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
109345     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
109346     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
109347     _security = {
109348         "http://tizen.org/privilege/networkbearerselection":
109349             ["requestRouteToHost", "releaseRouteToHost"]
109350     },
109351     _self;
109352
109353 _self = function () {
109354     var networkBearerSelection;
109355
109356     function requestRouteToHost(networkType, domainName, successCallback, errorCallback) {
109357         var evNetworkOpened       = "NO_" + networkType + "_" + domainName,
109358             evNetworkDisconnected = "ND_" + networkType + "_" + domainName;
109359
109360         if (!_security.requestRouteToHost) {
109361             throw new WebAPIException(errorcode.SECURITY_ERR);
109362         }
109363
109364         t.NetworkBearerSelection("requestRouteToHost", arguments);
109365         
109366         if (!domainName) {
109367             if (errorCallback) {
109368                 errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
109369             }
109370             return;
109371         }
109372
109373         event.once(evNetworkOpened, function (isOpened) {
109374             if (!isOpened)
109375                 return;
109376
109377             successCallback.onsuccess();
109378         });
109379         event.once(evNetworkDisconnected, successCallback.ondisconnected);
109380         event.trigger("NetworkRequest", [networkType, domainName]);
109381     }
109382
109383     function releaseRouteToHost(networkType, domainName, successCallback, errorCallback) {
109384         var evNetworkDisconnected = "ND_" + networkType + "_" + domainName;
109385
109386         if (!_security.releaseRouteToHost) {
109387             throw new WebAPIException(errorcode.SECURITY_ERR);
109388         }
109389
109390         t.NetworkBearerSelection("releaseRouteToHost", arguments);
109391        
109392         if (!domainName) {
109393             if (errorCallback) {
109394                 errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
109395             }
109396             return;
109397         }
109398
109399         event.once(evNetworkDisconnected, successCallback);
109400         event.trigger("NetworkRelease", [networkType, domainName]);
109401     }
109402
109403     function handleSubFeatures(subFeatures) {
109404         var i, subFeature;
109405
109406         for (subFeature in subFeatures) {
109407             for (i in _security[subFeature]) {
109408                 _security[_security[subFeature][i]] = true;
109409             }
109410         }
109411     }
109412
109413     networkBearerSelection = {
109414         requestRouteToHost: requestRouteToHost,
109415         releaseRouteToHost: releaseRouteToHost,
109416         handleSubFeatures:  handleSubFeatures
109417     };
109418
109419     return networkBearerSelection;
109420 };
109421
109422 module.exports = _self;
109423
109424 });
109425 define('ripple/platform/tizen/2.0/geoBackend_local', function (require, exports, module) {
109426 /*
109427  *  Copyright 2012 Intel Corporation.
109428  *
109429  * Licensed under the Apache License, Version 2.0 (the "License");
109430  * you may not use this file except in compliance with the License.
109431  * You may obtain a copy of the License at
109432  *
109433  * http://www.apache.org/licenses/LICENSE-2.0
109434  *
109435  * Unless required by applicable law or agreed to in writing, software
109436  * distributed under the License is distributed on an "AS IS" BASIS,
109437  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
109438  * See the License for the specific language governing permissions and
109439  * limitations under the License.
109440  */
109441
109442 var db = require('ripple/db'),
109443     utils = require('ripple/utils'),
109444     lbs = require('ripple/platform/tizen/2.0/lbs_utils'),
109445     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
109446     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
109447     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
109448     PendingObject = require('ripple/platform/tizen/2.0/pendingObject'),
109449     PendingOperation = require('ripple/platform/tizen/2.0/pendingoperation'),
109450     GeocodeResult = require('ripple/platform/tizen/2.0/GeocodeResult'),
109451     _GEO_OBJECTS = "tizen1.0-geocode-objects",
109452     _get, _save, _geoList_init, GeoEntry,
109453     _checkAddressType, _transAddressStr,
109454     _geocodeByString, _findCoordsByString, _geocodeByAddress,
109455     _reverseGeocodeBySimple, _reverseGeocodeByGeo, _checkCoordsType,
109456     _geoList = [],
109457     _PENDING_TIME = 10;
109458
109459 function _get() {
109460     var geoList = [],
109461         data = db.retrieveObject(_GEO_OBJECTS);
109462
109463     utils.forEach(data, function (geo) {
109464         geoList.push(geo);
109465     });
109466     return geoList;
109467 }
109468
109469 function _save() {
109470     db.saveObject(_GEO_OBJECTS, _geoList);
109471 }
109472
109473 function _geoList_init() {
109474     var entry;
109475     _geoList = _get();
109476
109477     /* Put some default data if database is empty */
109478     if (_geoList.length === 0) {
109479         entry = new GeoEntry(new lbs.StructuredAddress({
109480             country : "UK",
109481             region : "London",
109482             county : "Lambeth",
109483             city : "London",
109484             street : "Westminster Bridge Road",
109485             streetNumber : "1",
109486             premises : "Riverside Building",
109487             additionalInformation : "London Eye",
109488             postalCode : "SE1 7PB"
109489         }),
109490             new lbs.GeoCoordinates({
109491             latitude : 51.510452,
109492             longitude : -0.119820,
109493             altitude : 0,
109494             accuracy : 0,
109495             altitudeAccuracy : 0,
109496             heading : 0,
109497             speed : 0
109498         }));
109499         _geoList.push(entry);
109500         entry = new GeoEntry(new lbs.StructuredAddress({
109501             country : "UK",
109502             city : "London",
109503             street : "Baker Street",
109504             streetNumber : "221B",
109505             postalCode : "NW1 6XE"
109506         }),
109507             new lbs.GeoCoordinates({
109508             latitude : 51.524552,
109509             longitude : -0.158615,
109510             altitude : 0,
109511             accuracy : 0,
109512             altitudeAccuracy : 0,
109513             heading : 0,
109514             speed : 0
109515         }));
109516         _geoList.push(entry);
109517         entry = new GeoEntry(new lbs.StructuredAddress({
109518             country : "US",
109519             region : "OR",
109520             city : "Portland",
109521             street : "SE Water Ave",
109522             streetNumber : "1945",
109523             additionalInformation : "OMSI",
109524         }),
109525             new lbs.GeoCoordinates({
109526             latitude : 45.508490,
109527             longitude : -122.665953,
109528             altitude : 0,
109529             accuracy : 0,
109530             altitudeAccuracy : 0,
109531             heading : 0,
109532             speed : 0
109533         }));
109534         _geoList.push(entry);
109535         entry = new GeoEntry(new lbs.StructuredAddress({
109536             country : "US",
109537             region : "OR",
109538             city : "Portland",
109539             street : "NW Pittock Drive",
109540             streetNumber : "3229",
109541             additionalInformation : "Pittock Mansion",
109542         }),
109543             new lbs.GeoCoordinates({
109544             latitude : 45.531365,
109545             longitude : -122.716255,
109546             altitude : 0,
109547             accuracy : 0,
109548             altitudeAccuracy : 0,
109549             heading : 0,
109550             speed : 0
109551         }));
109552         _geoList.push(entry);
109553         entry = new GeoEntry(new lbs.StructuredAddress({
109554             region : "OR",
109555             city : "Hillsboro",
109556             street : "NE 25th St",
109557             streetNumber : "2111",
109558             postalCode : "97124"
109559         }),
109560             new lbs.GeoCoordinates({
109561             latitude : 45.543479,
109562             longitude : -122.9621601,
109563             altitude : 0,
109564             accuracy : 0,
109565             altitudeAccuracy : 0,
109566             heading : 0,
109567             speed : 0
109568         }));
109569         _geoList.push(entry);
109570         _save();
109571     }
109572 }
109573
109574 function _pendingOperate(operate) {
109575     var pendingObj, pendingOperation, i, argumentVector = [];
109576
109577     for (i = 0; i < arguments.length - 1; i++)
109578         argumentVector[i] = arguments[i + 1];
109579
109580     pendingObj = new PendingObject();
109581
109582     pendingObj.pendingID = window.setTimeout(function () {
109583         pendingObj.setCancelFlag(false);
109584         operate.apply(this, argumentVector);
109585     }, _PENDING_TIME);
109586
109587     pendingOperation = new PendingOperation(pendingObj);
109588
109589     return pendingOperation;
109590 }
109591
109592 function GeoEntry(addr, coord) {
109593     var _self;
109594     _self = {
109595         address : addr || null,
109596         coordinate : coord || null
109597     };
109598     return _self;
109599 }
109600
109601 function SortMode() {
109602     var _self;
109603     _self = {
109604         attributeName : "",
109605         order : "ASC"
109606     };
109607     return _self;
109608 }
109609
109610 function _transAddressStr(addr) {
109611     var str = "";
109612     if (addr.additionalInformation !== null && addr.additionalInformation !== undefined)
109613         str = str + addr.additionalInformation + ", ";
109614     if (addr.premises !== null && addr.premises !== undefined)
109615         str = str + addr.premises + ", ";
109616     if (addr.streetNumber !== null && addr.streetNumber !== undefined)
109617         str = str + addr.streetNumber + " ";
109618     if (addr.street !== null && addr.street !== undefined)
109619         str = str + addr.street + ", ";
109620     if (addr.city !== null && addr.city !== undefined)
109621         str = str + addr.city + ", ";
109622     if (addr.county !== null && addr.county !== undefined)
109623         str = str + addr.county + ", ";
109624     if (addr.region !== null && addr.region !== undefined)
109625         str = str + addr.region + ", ";
109626     if (addr.country !== null && addr.country !== undefined)
109627         str = str + addr.country + ", ";
109628     if (addr.postalCode !== null && addr.postalCode !== undefined)
109629         str = str + addr.postalCode;
109630
109631     if (str.lastIndexOf(", ") === str.length - 2)
109632         str = str.slice(0, -2);
109633     return str;
109634 }
109635
109636 function _concatAddress(addr) {
109637     var str = "";
109638     if (addr.additionalInformation !== null && addr.additionalInformation !== undefined)
109639         str = str + addr.additionalInformation + " ";
109640     if (addr.premises !== null && addr.premises !== undefined)
109641         str = str + addr.premises + " ";
109642     if (addr.streetNumber !== null && addr.streetNumber !== undefined)
109643         str = str + addr.streetNumber + " ";
109644     if (addr.street !== null && addr.street !== undefined)
109645         str = str + addr.street + " ";
109646     if (addr.city !== null && addr.city !== undefined)
109647         str = str + addr.city + " ";
109648     if (addr.county !== null && addr.county !== undefined)
109649         str = str + addr.county + " ";
109650     if (addr.region !== null && addr.region !== undefined)
109651         str = str + addr.region + " ";
109652     if (addr.country !== null && addr.country !== undefined)
109653         str = str + addr.country + " ";
109654     if (addr.postalCode !== null && addr.postalCode !== undefined)
109655         str = str + addr.postalCode;
109656
109657     return str;
109658 }
109659
109660 function _findCoordsByString(address) {
109661     var array = [], reg, str, searchAddr, pieces, i;
109662     if (address.length === 0)
109663         return array;
109664
109665     pieces = address.split(",");
109666     searchAddr = "";
109667     for (i = 0; i < pieces.length; i++) {
109668         searchAddr = searchAddr + pieces[i];
109669     }
109670     reg = new RegExp(searchAddr, "i");
109671
109672     utils.forEach(_geoList, function (item) {
109673         str = _concatAddress(item.address);
109674         if (str.search(reg) !== -1)
109675             array.push(new GeocodeResult(item.coordinate.latitude, item.coordinate.longitude));
109676     });
109677
109678     return array;
109679 }
109680
109681 function _geocodeByString(address, successCB, errorCB, options) {
109682     var array;
109683     array = _findCoordsByString(address);
109684     successCB(array);
109685 }
109686
109687 function _findCoordsByAddress(addr) {
109688     var array = [], select = false, i;
109689     for (i = 0; i < _geoList.length; i++) {
109690         select = false;
109691         if (addr.country !== null && addr.country !== undefined) {
109692             if (addr.country === _geoList[i].address.country)
109693                 select = true;
109694             else
109695                 continue;
109696         }
109697
109698         if (addr.region !== null && addr.region !== undefined) {
109699             if (addr.region === _geoList[i].address.region)
109700                 select = true;
109701             else
109702                 continue;
109703         }
109704
109705         if (addr.county !== null && addr.county !== undefined) {
109706             if (addr.county === _geoList[i].address.county)
109707                 select = true;
109708             else
109709                 continue;
109710         }
109711
109712         if (addr.city !== null && addr.city !== undefined) {
109713             if (addr.city === _geoList[i].address.city)
109714                 select = true;
109715             else
109716                 continue;
109717         }
109718
109719         if (addr.street !== null && addr.street !== undefined) {
109720             if (addr.street === _geoList[i].address.street)
109721                 select = true;
109722             else
109723                 continue;
109724         }
109725
109726         if (addr.streetNumber !== null && addr.streetNumber !== undefined) {
109727             if (addr.streetNumber === _geoList[i].address.streetNumber)
109728                 select = true;
109729             else
109730                 continue;
109731         }
109732
109733         if (addr.premises !== null && addr.premises !== undefined) {
109734             if (addr.premises === _geoList[i].address.premises)
109735                 select = true;
109736             else
109737                 continue;
109738         }
109739
109740         if (addr.additionalInformation !== null &&
109741             addr.additionalInformation !== undefined) {
109742             if (addr.additionalInformation === _geoList[i].address.additionalInformation)
109743                 select = true;
109744             else
109745                 continue;
109746         }
109747
109748         if (addr.postalCode !== null && addr.postalCode !== undefined) {
109749             if (addr.postalCode === _geoList[i].address.postalCode)
109750                 select = true;
109751             else
109752                 continue;
109753         }
109754
109755         if (select === true) {
109756             array.push(new GeocodeResult(_geoList[i].coordinate.latitude, _geoList[i].coordinate.longitude));
109757         }
109758     }
109759
109760     return array;
109761 }
109762
109763 function _geocodeByAddress(address, successCB, errorCB, options) {
109764     var array;
109765     array = _findCoordsByAddress(address);
109766     successCB(array);
109767 }
109768
109769 function _checkAddressType(address) {
109770     var str;
109771     if (typeof address === "string") {
109772         str = "string";
109773     } else if (typeof address === "object") {
109774         str = "StructuredAddress";
109775     } else {
109776         str = "typeMismatch";
109777     }
109778     return str;
109779 }
109780
109781 function _checkCoordsType(coord) {
109782     var str;
109783     /* SimpleCoordinates is a subset of GeoCoordinates.
109784        SimpleCoordinates includes latitude, longitude as mandatory fields only.
109785        GeoCoordinates not only includes latitude, longitude as mandatory fields
109786        but also at least includes one more other optional fields */
109787     if (typeof coord !== "object") {
109788         str = "typeMismatch";
109789     } else if (typeof coord.latitude === "number" &&
109790                 typeof coord.longitude === "number") {
109791         str = "simpleCoordinates";
109792         if (typeof coord.altitude === "number" ||
109793             typeof coord.accuracy === "number" ||
109794             typeof coord.altitudeAccuracy === "number" ||
109795             typeof coord.heading === "number" ||
109796             typeof coord.speed === "number") {
109797             str = "geoCoordinates";
109798         }
109799     } else {
109800         str = "typeMismatch";
109801     }
109802
109803     return str;
109804 }
109805
109806 function _findReverseGeocode(coords, options) {
109807     var array = [], _isStructured = false, i;
109808     if (options !== null && options !== undefined) {
109809         if (options.resultType === "STRUCTURED") {
109810             _isStructured = true;
109811         }
109812     }
109813     for (i = 0; i < _geoList.length; i++) {
109814         if (_geoList[i].coordinate.latitude === coords.latitude &&
109815             _geoList[i].coordinate.longitude === coords.longitude) {
109816             if (coords.altitude) {
109817                 if (_geoList[i].coordinate.altitude !== coords.altitude)
109818                     continue;
109819             }
109820             if (coords.accuracy) {
109821                 if (_geoList[i].coordinate.accuracy !== coords.accuracy)
109822                     continue;
109823             }
109824             if (coords.altitudeAccuracy) {
109825                 if (_geoList[i].coordinate.altitudeAccuracy !== coords.altitudeAccuracy)
109826                     continue;
109827             }
109828             if (coords.heading) {
109829                 if (_geoList[i].coordinate.heading !== coords.heading)
109830                     continue;
109831             }
109832             if (coords.speed) {
109833                 if (_geoList[i].coordinate.speed !== coords.speed)
109834                     continue;
109835             }
109836
109837             if (_isStructured === true) {
109838                 array.push(new lbs.StructuredAddress(_geoList[i].address));
109839             } else {
109840                 array.push(_transAddressStr(_geoList[i].address));
109841             }
109842         }
109843     }
109844     return array;
109845 }
109846
109847 function _reverseGeocodeByGeo(coordinates, successCB, errorCB, options) {
109848     var array, coord;
109849     coord = new lbs.GeoCoordinates(coordinates);
109850     array = _findReverseGeocode(coord, options);
109851     return successCB(array);
109852 }
109853
109854 function _reverseGeocodeBySimple(coordinates, successCB, errorCB, options) {
109855     var array, coord;
109856     coord = new lbs.GeoCoordinates({
109857             latitude : coordinates.latitude,
109858             longitude : coordinates.longitude
109859         });
109860     array = _findReverseGeocode(coord, options);
109861     return successCB(array);
109862 }
109863
109864 module.exports = function (prop) {
109865     var _self = new lbs.LocationServiceProvider(prop);
109866     _geoList_init();
109867
109868     _self.geocode = function (address, successCB, errorCB, options) {
109869         function _geocode() {
109870             var ret;
109871
109872             ret = _pendingOperate(function () {
109873                 /* address: its type is AbstractAddress.
109874                    It could be StructuredAddress or String */
109875                 if (_checkAddressType(address) === "string") {
109876                     _geocodeByString(address, successCB, errorCB, options);
109877                 } else if (_checkAddressType(address) === "StructuredAddress") {
109878                     _geocodeByAddress(address, successCB, errorCB, options);
109879                 } else {
109880                     throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
109881                 }
109882             });
109883         }
109884
109885         tizen1_utils.validateTypeMismatch(successCB, errorCB, "geocode", _geocode);
109886     };
109887
109888     _self.reverseGeocode = function (coordinates, successCB, errorCB, options) {
109889         function _reverseGeocode() {
109890             var ret;
109891
109892             ret = _pendingOperate(function () {
109893                 /* coordinates: Its type is AbstractCoordinates.
109894                    It could be SimpleCoordinates or GeoCoordinates */
109895                 if (_checkCoordsType(coordinates) === "simpleCoordinates") {
109896                     _reverseGeocodeBySimple(coordinates, successCB, errorCB, options);
109897                 } else if (_checkCoordsType(coordinates) === "geoCoordinates") {
109898                     _reverseGeocodeByGeo(coordinates, successCB, errorCB, options);
109899                 } else {
109900                     throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
109901                 }
109902             });
109903         }
109904
109905         tizen1_utils.validateTypeMismatch(successCB, errorCB, "reverseGeocode", _reverseGeocode);
109906     };
109907
109908     return _self;
109909 };
109910
109911
109912 });
109913 define('ripple/platform/tizen/2.0/package', function (require, exports, module) {
109914 /*
109915  *  Copyright 2013 Intel Corporation.
109916  *
109917  * Licensed under the Apache License, Version 2.0 (the "License");
109918  * you may not use this file except in compliance with the License.
109919  * You may obtain a copy of the License at
109920  *
109921  * http://www.apache.org/licenses/LICENSE-2.0
109922  *
109923  * Unless required by applicable law or agreed to in writing, software
109924  * distributed under the License is distributed on an "AS IS" BASIS,
109925  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
109926  * See the License for the specific language governing permissions and
109927  * limitations under the License.
109928  */
109929
109930 var db = require('ripple/db'),
109931     app = require('ripple/app'),
109932     event = require('ripple/event'),
109933     utils = require('ripple/utils'),
109934     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
109935     t = require('ripple/platform/tizen/2.0/typecast'),
109936     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
109937     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
109938     PackageInformation = require('ripple/platform/tizen/2.0/PackageInformation'),
109939     _security = {
109940         "http://tizen.org/privilege/packagemanager.install": ["install", "uninstall"],
109941         "http://tizen.org/privilege/package.info": ["getPackagesInfo", "getPackageInfo",
109942                     "setPackageInfoEventListener", "unsetPackageInfoEventListener"]
109943     },
109944     DB_PACKAGE_KEY = "tizen-db-package",
109945     _listeners = [],
109946     _data = {
109947         packageList: {},
109948         installedList: {}
109949     },
109950     INTERVAL = 1000, // INTERVAL = 1sec
109951     INSTALL_AMOUNT = 3072, // installation speed amount = 3072 (KB/sec)
109952     PSEUDO_PACKAGE_ID = "pseudopack00",
109953     PSEUDO_APP_ID = "pseudoapp00",
109954     _self;
109955
109956 function _get() {
109957     _data = db.retrieveObject(DB_PACKAGE_KEY);
109958 }
109959
109960 function _save() {
109961     db.saveObject(DB_PACKAGE_KEY, _data);
109962 }
109963
109964 function _exec(callback, name, id, arg1) {
109965     switch (name) {
109966     case "onprogress":
109967         callback[name](id, arg1);
109968         break;
109969     case "oncomplete":
109970         callback[name](id);
109971         break;
109972     default:
109973         break;
109974     }
109975 }
109976
109977 function _setupCurrentPackage() {
109978     var info, id, item, tizenAppId;
109979     info = app.getInfo();
109980     tizenAppId = info.tizenAppId || PSEUDO_APP_ID;
109981     id = info.tizenPackageId;
109982     if (id !== undefined) {
109983         if (_data.installedList[id]) {
109984             // already installed
109985             return;
109986         }
109987
109988         item = null;
109989         utils.forEach(_data.packageList, function (p) {
109990             if (p.id === id) {
109991                 item = p;
109992             }
109993         });
109994
109995         if (item) {
109996             _data.installedList[item.id] = new PackageInformation(
109997                 item.id, item.name, item.iconPath, item.version,
109998                 item.totalSize, item.dataSize, new Date(),
109999                 item.author, item.description, item.appIds
110000             );
110001             event.trigger("install-current-package", [_data.installedList[item.id]]);
110002         } else {
110003             _data.installedList[id] = new PackageInformation(
110004                 id, "Tizen pseudo package", "icon.png", "2.2",
110005                 8264, 50, new Date(),
110006                 "TizenDev", "This is a description which is used in tests.", [tizenAppId]
110007             );
110008             event.trigger("install-current-package", [_data.installedList[id]]);
110009         }
110010     } else {
110011         _data.installedList[PSEUDO_PACKAGE_ID] = new PackageInformation(
110012             PSEUDO_PACKAGE_ID, "Tizen pseudo package", "icon.png", "2.2",
110013             8264, 50, new Date(),
110014             "TizenDev", "This is a description which is used in tests.", [tizenAppId]
110015         );
110016         event.trigger("install-current-package", [_data.installedList[PSEUDO_PACKAGE_ID]]);
110017     }
110018 }
110019
110020 function _updatePackage(path, updateFlag) {
110021     var item, p, info;
110022
110023     if (!_data.packageList[path]) {
110024         return;
110025     }
110026     _get();
110027     p = _data.packageList[path];
110028     item = _data.installedList[p.id];
110029     utils.forEach(_listeners, function (listener) {
110030         info = new PackageInformation(
110031             item.id, item.name, item.iconPath, item.version,
110032             item.totalSize, item.dataSize, item.lastModified,
110033             item.author, item.description, item.appIds);
110034         if (!updateFlag) {
110035             listener.oninstalled(info);
110036         } else {
110037             listener.onupdated(info);
110038         }
110039     });
110040 }
110041
110042 function _initialize() {
110043     _get();
110044
110045     if (!_data)
110046         return;
110047
110048     utils.forEach(_data.installedList, function (item) {
110049         item.lastModified = new Date(item.lastModified);
110050     });
110051
110052     _setupCurrentPackage();
110053
110054     event.on("install-packge", function (path) {
110055         _updatePackage(path, false);
110056     });
110057     event.on("update-package", function (path) {
110058         _updatePackage(path, true);
110059     });
110060
110061     event.on("uninstall-package", function (id) {
110062         _get();
110063         utils.forEach(_listeners, function (listener) {
110064             listener.onuninstalled(id);
110065         });
110066     });
110067 }
110068
110069 _self = function () {
110070     var package;
110071
110072     // public
110073     function install(path, progressCallback, errorCallback) {
110074         if (!_security.install) {
110075             throw new WebAPIException(errorcode.SECURITY_ERR);
110076         }
110077
110078         t.PackageManager("install", arguments);
110079
110080         window.setTimeout(function () {
110081             var intervalId, installedSize = 0, packageSize, updateFlag = false,
110082                 item, info, progress;
110083
110084             if (!_data.packageList[path]) {
110085                 if (errorCallback) {
110086                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
110087                 }
110088                 return;
110089             }
110090             item = _data.packageList[path];
110091             if (_data.installedList[item.id]) {
110092                 updateFlag = true;
110093             }
110094             packageSize = item.totalSize;
110095             intervalId = setInterval(function () {
110096                 if (installedSize >= packageSize) {
110097                     // Install complete
110098                     _data.installedList[item.id] = new PackageInformation(
110099                         item.id, item.name, item.iconPath, item.version,
110100                         item.totalSize, item.dataSize, new Date(),
110101                         item.author, item.description, item.appIds
110102                     );
110103                     event.trigger("install-apps", [item.appIds]);
110104                     _save();
110105                     _exec(progressCallback, "oncomplete", item.id);
110106                     clearInterval(intervalId);
110107                     item = _data.installedList[item.id];
110108                     utils.forEach(_listeners, function (listener) {
110109                         info = new PackageInformation(
110110                             item.id, item.name, item.iconPath, item.version,
110111                             item.totalSize, item.dataSize, item.lastModified,
110112                             item.author, item.description, item.appIds);
110113                         if (!updateFlag) {
110114                             listener.oninstalled(info);
110115                         } else {
110116                             listener.onupdated(info);
110117                         }
110118                     });
110119                     event.trigger("installedList-updated");
110120                 } else {
110121                     installedSize += INSTALL_AMOUNT;
110122                     progress = (installedSize > packageSize) ? 100 :
110123                             Math.floor(installedSize * 100 / packageSize);
110124                     _exec(progressCallback, "onprogress", item.id, progress);
110125                 }
110126             }, INTERVAL);
110127         }, 1);
110128     }
110129
110130     function uninstall(id, progressCallback, errorCallback) {
110131         if (!_security.uninstall) {
110132             throw new WebAPIException(errorcode.SECURITY_ERR);
110133         }
110134
110135         t.PackageManager("uninstall", arguments);
110136
110137         window.setTimeout(function () {
110138             var intervalId, removedSize = 0, packageSize, item, progress;
110139
110140             if (!_data.installedList[id]) {
110141                 if (errorCallback) {
110142                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
110143                 }
110144                 return;
110145             }
110146             item = _data.installedList[id];
110147             packageSize = item.totalSize;
110148             intervalId = setInterval(function () {
110149                 if (removedSize >= packageSize) {
110150                     utils.forEach(_data.packageList, function (package) {
110151                         if (package.id === id) {
110152                             event.trigger("remove-apps", [package.appIds]);
110153                         }
110154                     });
110155                     delete _data.installedList[item.id];
110156                     _save();
110157                     _exec(progressCallback, "oncomplete", item.id);
110158                     clearInterval(intervalId);
110159                     item = _data.installedList[item.id];
110160                     utils.forEach(_listeners, function (listener) {
110161                         listener.onuninstalled(id);
110162                     });
110163                     event.trigger("installedList-updated");
110164                 } else {
110165                     removedSize += INSTALL_AMOUNT * 10;
110166                     progress = (removedSize > packageSize) ? 100 :
110167                             Math.floor(removedSize * 100 / packageSize);
110168                     _exec(progressCallback, "onprogress", item.id, progress);
110169                 }
110170             }, INTERVAL);
110171         }, 1);
110172     }
110173
110174     function getPackagesInfo(successCallback, errorCallback) {
110175         if (!_security.getPackagesInfo) {
110176             throw new WebAPIException(errorcode.SECURITY_ERR);
110177         }
110178
110179         t.PackageManager("getPackagesInfo", arguments);
110180
110181         window.setTimeout(function () {
110182             var packageArray = [];
110183
110184             utils.forEach(_data.installedList, function (item) {
110185                 var i;
110186                 i = new PackageInformation(
110187                         item.id, item.name, item.iconPath, item.version,
110188                         item.totalSize, item.dataSize, item.lastModified,
110189                         item.author, item.description, item.appIds
110190                     );
110191                 packageArray.push(i);
110192             });
110193             successCallback(packageArray);
110194         }, 1);
110195     }
110196
110197     function getPackageInfo(id) {
110198         var p, item;
110199
110200         if (!_security.getPackageInfo) {
110201             throw new WebAPIException(errorcode.SECURITY_ERR);
110202         }
110203
110204         t.PackageManager("getPackageInfo", arguments);
110205
110206         id = id || "api1pack00";
110207
110208         if (!_data.installedList[id]) {
110209             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
110210         }
110211         item = _data.installedList[id];
110212         p = new PackageInformation(item.id, item.name, item.iconPath,
110213                 item.version, item.totalSize, item.dataSize, item.lastModified,
110214                 item.author, item.description, item.appIds);
110215
110216         return p;
110217     }
110218
110219     function setPackageInfoEventListener(eventCallback) {
110220         if (!_security.setPackageInfoEventListener) {
110221             throw new WebAPIException(errorcode.SECURITY_ERR);
110222         }
110223
110224         t.PackageManager("setPackageInfoEventListener", arguments);
110225
110226         _listeners.push(eventCallback);
110227     }
110228
110229     function unsetPackageInfoEventListener() {
110230         if (!_security.unsetPackageInfoEventListener) {
110231             throw new WebAPIException(errorcode.SECURITY_ERR);
110232         }
110233
110234         t.PackageManager("unsetPackageInfoEventListener", arguments);
110235
110236         _listeners = [];
110237     }
110238
110239     function handleSubFeatures(subFeatures) {
110240         var i, subFeature;
110241
110242         for (subFeature in subFeatures) {
110243             for (i in _security[subFeature]) {
110244                 _security[_security[subFeature][i]] = true;
110245             }
110246         }
110247     }
110248
110249     package = {
110250         install:                       install,
110251         uninstall:                     uninstall,
110252         getPackagesInfo:               getPackagesInfo,
110253         getPackageInfo:                getPackageInfo,
110254         setPackageInfoEventListener:   setPackageInfoEventListener,
110255         unsetPackageInfoEventListener: unsetPackageInfoEventListener,
110256         handleSubFeatures:             handleSubFeatures
110257     };
110258
110259     return package;
110260 };
110261
110262 _initialize();
110263
110264 module.exports = _self;
110265
110266 });
110267 define('ripple/platform/tizen/2.0/application', function (require, exports, module) {
110268 /*
110269  *  Copyright 2013 Intel Corporation.
110270  *
110271  * Licensed under the Apache License, Version 2.0 (the "License");
110272  * you may not use this file except in compliance with the License.
110273  * You may obtain a copy of the License at
110274  *
110275  * http://www.apache.org/licenses/LICENSE-2.0
110276  *
110277  * Unless required by applicable law or agreed to in writing, software
110278  * distributed under the License is distributed on an "AS IS" BASIS,
110279  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
110280  * See the License for the specific language governing permissions and
110281  * limitations under the License.
110282  */
110283
110284 var utils = require('ripple/utils'),
110285     event = require('ripple/event'),
110286     app = require('ripple/app'),
110287     db = require('ripple/db'),
110288     t = require('ripple/platform/tizen/2.0/typecast'),
110289     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
110290     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
110291     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
110292     ApplicationControl = require('ripple/platform/tizen/2.0/ApplicationControl'),
110293     Application,
110294     ApplicationInformation,
110295     ApplicationContext,
110296     ApplicationCertificate,
110297     RequestedApplicationControl,
110298     _DB_APPLICATION_KEY = "tizen1-db-application",
110299     PSEUDO_PACKAGE_ID = "pseudopack00",
110300     PSEUDO_APP_ID = "pseudoapp00",
110301     _security = {
110302         "http://tizen.org/privilege/application.launch": ["launch", "launchAppControl"],
110303         "http://tizen.org/privilege/appmanager.kill": ["kill"],
110304         "http://tizen.org/privilege/appmanager.certificate": ["getAppCerts"]
110305     },
110306     _data = {
110307         applications : {},
110308         applicationContexts : {},
110309         activeApp : null,
110310         listeners : {}
110311     },
110312     _appDialogTemplate = jQuery("#app-dialog-template").html(),
110313     _appDialogTemplate_short = jQuery("#app-dialog2-template").html(),
110314     _appDialogTemplate_exit_hide = jQuery("#app-dialog3-template").html(),
110315     reasonable_mimetype = {
110316         "application"   : true,
110317         "text"          : true,
110318         "video"         : true,
110319         "audio"         : true,
110320         "image"         : true
110321     },
110322     _self;
110323
110324 function _setupCurrentApp() {
110325     var info, contextId, packageId, appId;
110326     info = app.getInfo();
110327     packageId = info.tizenPackageId || PSEUDO_PACKAGE_ID;
110328     appId = info.tizenAppId || PSEUDO_APP_ID;
110329     contextId = Math.uuid(null, 16);
110330     _data.applications[appId] = {
110331         id: appId,
110332         name: info.name,
110333         iconPath: info.icon,
110334         version: info.version,
110335         show: true,
110336         categories: [],
110337         installDate: new Date(),
110338         size: 1024,
110339         packageId: packageId,
110340         sharedURI: "/usr/local/share/",
110341         operation: "",
110342         appControl: {
110343             uri: "",
110344             mime: "",
110345             category: "",
110346             data: []
110347         },
110348         type: "AUTHOR_ROOT",
110349         value: ""
110350     };
110351     event.trigger("install-current-app", [_data.applications[appId]]);
110352     _data.applicationContexts[contextId] = {id: contextId, appId: appId};
110353     _data.activeApp = _data.applicationContexts[contextId];
110354 }
110355
110356 function _translate(apps) {
110357     // translate string to Date after retrieving from DB,
110358     // it is a temporary sulusion
110359     var i;
110360     for (i in apps) {
110361         if (typeof apps[i].installDate === 'string') {
110362             apps[i].installDate = new Date(apps[i].installDate);
110363         }
110364     }
110365     return apps;
110366 }
110367
110368 function _initialize() {
110369     _data = {
110370         applications : {},
110371         applicationContexts : {},
110372         activeApp : null,
110373         listeners : {}
110374     };
110375
110376     if (!db.retrieveObject(_DB_APPLICATION_KEY))
110377         return;
110378
110379     _data.applications = _translate(db.retrieveObject(_DB_APPLICATION_KEY).installedAppList);
110380     _setupCurrentApp();
110381     $("#app-dialog").dialog({
110382         resizable: false,
110383         draggable: false,
110384         modal: true,
110385         autoOpen: false,
110386         position: 'center',
110387         minWidth: '500',
110388         minHeight: '262',
110389         open: function () { $(".ui-dialog-titlebar-close", $(this).parent()).hide(); }
110390     });
110391 }
110392
110393 _self = function () {
110394     // private
110395     function getHandle() {
110396         var handle;
110397         do {
110398             handle = Math.uuid(8, 10);
110399         } while (handle.toString().indexOf('0') === 0);
110400
110401         return parseInt(handle, 10);
110402     }
110403
110404     // public
110405     function getCurrentApplication() {
110406         var application, innerApp;
110407
110408         t.ApplicationManager("getCurrentApplication", arguments);
110409
110410         /* activeApp update (by WidgetInformationUpdate event) sometime will late after user calling getCurrentApplication()
110411            for example: load other application by omnibar */
110412         if (app.getInfo().id !== _data.activeApp.appId) {
110413             _data.applications = db.retrieveObject(_DB_APPLICATION_KEY).installedAppList;
110414             utils.forEach(_data.applications, function(item) {
110415                 item.installDate = new Date(item.installDate);
110416             });
110417             _setupCurrentApp();
110418         }
110419         innerApp = _data.applications[_data.activeApp.appId];
110420         application = new Application(
110421                 new ApplicationInformation(
110422                     innerApp.id,
110423                     innerApp.name,
110424                     innerApp.iconPath,
110425                     innerApp.version,
110426                     innerApp.show,
110427                     innerApp.categories,
110428                     innerApp.installDate,
110429                     innerApp.size,
110430                     innerApp.packageId),
110431                 _data.activeApp.id, innerApp);
110432         return application;
110433     }
110434
110435     function kill(contextId, successCallback, errorCallback) {
110436         if (!_security.kill) {
110437             throw new WebAPIException(errorcode.SECURITY_ERR);
110438         }
110439
110440         t.ApplicationManager("kill", arguments);
110441
110442         window.setTimeout(function () {
110443             if (!_data.applicationContexts[contextId]) {
110444                 if (errorCallback) {
110445                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
110446                 }
110447                 return;
110448             }
110449
110450             if (_data.activeApp && (_data.activeApp.id === contextId)) {
110451                 if (errorCallback) {
110452                     errorCallback(new WebAPIError(errorcode.INVALID_VALUES_ERR));
110453                 }
110454                 return;
110455             }
110456
110457             delete _data.applicationContexts[contextId];
110458             if (successCallback) {
110459                 successCallback();
110460             }
110461         }, 1);
110462     }
110463
110464     function launch(id, successCallback, errorCallback) {
110465         if (!_security.launch) {
110466             throw new WebAPIException(errorcode.SECURITY_ERR);
110467         }
110468
110469         t.ApplicationManager("launch", arguments);
110470
110471         window.setTimeout(function () {
110472             var htmlContent;
110473
110474             if (!_data.applications[id]) {
110475                 if (errorCallback) {
110476                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
110477                 }
110478                 return;
110479             }
110480
110481             htmlContent = _appDialogTemplate_short.replace(/#application-name/, _data.applications[id].name)
110482                 .replace(/#application-id/, id);
110483             jQuery("#app-dialog-box").html(htmlContent);
110484             $("#app-dialog").dialog("open");
110485
110486             if (successCallback) {
110487                 successCallback();
110488             }
110489         }, 1);
110490     }
110491
110492     function launchAppControl(appControl, id, successCallback, errorCallback, replyCallback) {
110493         if (!_security.launchAppControl) {
110494             throw new WebAPIException(errorcode.SECURITY_ERR);
110495         }
110496
110497         t.ApplicationManager("launchAppControl", arguments, true);
110498
110499         window.setTimeout(function () {
110500             var isFound = false, appId, htmlContent;
110501
110502             if (id) {
110503                 if (!_data.applications[id]) {
110504                     if (errorCallback) {
110505                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
110506                     }
110507                     return;
110508                 }
110509                 htmlContent = _appDialogTemplate.replace(/#application-name/, _data.applications[appId].name)
110510                     .replace(/#appControl-operation/, _data.applications[appId].operation)
110511                     .replace(/#appControl-uri/, _data.applications[appId].appControl.uri)
110512                     .replace(/#appControl-mime/, _data.applications[appId].appControl.mime)
110513                     .replace(/#appControl-category/, _data.applications[appId].appControl.category)
110514                     .replace(/#appControl-data/, JSON.stringify(_data.applications[appId].appControl.data));
110515                 jQuery("#app-dialog-box").html(htmlContent);
110516                 $("#app-dialog").dialog("open");
110517
110518                 _data.activeApp.replyCallback = replyCallback;
110519
110520                 if (successCallback) {
110521                     successCallback();
110522                 }
110523             } else {
110524                 utils.forEach(_data.applications, function (application) {
110525                     if (application.operation === appControl.operation) {
110526                         if (appControl.mime && (typeof appControl.mime === "string")) {
110527                             if (!reasonable_mimetype[appControl.mime.split("/")[0]]) {
110528                                 return;
110529                             }
110530                         }
110531                         appId = application.id;
110532                         isFound = true;
110533                     }
110534                 });
110535
110536                 if (!isFound) {
110537                     if (errorCallback) {
110538                         errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
110539                     }
110540                     return;
110541                 }
110542
110543                 htmlContent = _appDialogTemplate.replace(/#application-name/,
110544                         _data.applications[appId].name)
110545                     .replace(/#appControl-operation/, _data.applications[appId].operation)
110546                     .replace(/#appControl-uri/, _data.applications[appId].appControl.uri)
110547                     .replace(/#appControl-mime/, _data.applications[appId].appControl.mime)
110548                     .replace(/#appControl-category/, _data.applications[appId].appControl.category)
110549                     .replace(/#appControl-data/, JSON.stringify(_data.applications[appId].appControl.data));
110550                 jQuery("#app-dialog-box").html(htmlContent);
110551                 $("#app-dialog").dialog("open");
110552
110553                 _data.activeApp.replyCallback = replyCallback;
110554
110555                 if (successCallback) {
110556                     successCallback();
110557                 }
110558             }
110559         }, 1);
110560     }
110561
110562     function findAppControl(appControl, successCallback, errorCallback) {
110563         var appControlExternal = appControl;
110564
110565         t.ApplicationManager("findAppControl", arguments, true);
110566
110567         window.setTimeout(function () {
110568             var informationArray = [];
110569
110570             utils.forEach(_data.applications, function (application) {
110571                 if (application.operation === appControl.operation) {
110572                     informationArray.push(new ApplicationInformation(
110573                             application.id,
110574                             application.name,
110575                             application.iconPath,
110576                             application.version,
110577                             application.show,
110578                             application.categories,
110579                             application.installDate,
110580                             application.size,
110581                             application.packageId));
110582                 }
110583             });
110584
110585             successCallback(informationArray, appControlExternal);
110586         }, 1);
110587     }
110588
110589     function getAppsContext(successCallback, errorCallback) {
110590         t.ApplicationManager("getAppsContext", arguments);
110591
110592         window.setTimeout(function () {
110593             var contexts = [];
110594
110595             utils.forEach(_data.applicationContexts, function (context) {
110596                 contexts.push(new ApplicationContext(context.id, context.appId));
110597             });
110598
110599             successCallback(contexts);
110600         }, 1);
110601     }
110602
110603     function getAppContext(contextId) {
110604         var appContext;
110605
110606         if (contextId === null || contextId === undefined) {
110607             appContext = new ApplicationContext(_data.activeApp.id, _data.activeApp.appId);
110608             return (appContext);
110609         }
110610
110611         t.ApplicationManager("getAppContext", arguments);
110612
110613         if (_data.applicationContexts[contextId]) {
110614             appContext = new ApplicationContext(contextId, _data.applicationContexts[contextId].appId);
110615             return (appContext);
110616         }
110617         throw new WebAPIException(errorcode.NOT_FOUND_ERR);
110618     }
110619
110620     function getAppsInfo(successCallback, errorCallback) {
110621         t.ApplicationManager("getAppsInfo", arguments);
110622
110623         window.setTimeout(function () {
110624             var applications = [];
110625
110626             utils.forEach(_data.applications, function (application) {
110627                 applications.push(new ApplicationInformation(
110628                         application.id,
110629                         application.name,
110630                         application.iconPath,
110631                         application.version,
110632                         application.show,
110633                         application.categories,
110634                         application.installDate,
110635                         application.size,
110636                         application.packageId));
110637             });
110638
110639             successCallback(applications);
110640         }, 1);
110641     }
110642
110643     function getAppInfo(id) {
110644         var appId, appInfo, theApp;
110645
110646         t.ApplicationManager("getAppInfo", arguments);
110647
110648         if (arguments.length === 0) {
110649             appId = _data.activeApp.appId;
110650             theApp = _data.applications[appId];
110651
110652             appInfo = new ApplicationInformation(
110653                     theApp.id,
110654                     theApp.name,
110655                     theApp.iconPath,
110656                     theApp.version,
110657                     theApp.show,
110658                     theApp.categories,
110659                     theApp.installDate,
110660                     theApp.size,
110661                     theApp.packageId);
110662             return appInfo;
110663         }
110664
110665         if (!_data.applications[id]) {
110666             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
110667         }
110668
110669         theApp = _data.applications[id];
110670         appInfo = new ApplicationInformation(
110671                     theApp.id,
110672                     theApp.name,
110673                     theApp.iconPath,
110674                     theApp.version,
110675                     theApp.show,
110676                     theApp.categories,
110677                     theApp.installDate,
110678                     theApp.size,
110679                     theApp.packageId);
110680         return appInfo;
110681     }
110682
110683     function getAppCerts(id) {
110684         var certs = [];
110685
110686         if (!_security.getAppCerts) {
110687             throw new WebAPIException(errorcode.SECURITY_ERR);
110688         }
110689
110690         t.ApplicationManager("getAppCerts", arguments);
110691
110692         if (arguments.length === 0) {
110693             id = _data.activeApp.appId;
110694             certs.push(new ApplicationCertificate(_data.applications[id].type, _data.applications[id].value));
110695             return certs;
110696         }
110697
110698         if (!_data.applications[id]) {
110699             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
110700         }
110701         certs.push(new ApplicationCertificate(_data.applications[id].type, _data.applications[id].value));
110702         return certs;
110703     }
110704
110705     function getAppSharedURI(id) {
110706         var appId;
110707
110708         t.ApplicationManager("getAppSharedURI", arguments);
110709
110710         if (id === null || id === undefined) {
110711             appId = _data.activeApp.appId;
110712             return _data.applications[appId].sharedURI;
110713         }
110714
110715         if (!_data.applications[id]) {
110716             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
110717         }
110718
110719         return _data.applications[id].sharedURI;
110720     }
110721
110722     function addAppInfoEventListener(eventCallback) {
110723         var handle;
110724
110725         t.ApplicationManager("addAppInfoEventListener", arguments);
110726
110727         handle = getHandle();
110728         _data.listeners[handle] = eventCallback;
110729
110730         return handle;
110731     }
110732
110733     function removeAppInfoEventListener(listenerID) {
110734         if (!_data.listeners[listenerID])
110735             return;
110736
110737         delete _data.listeners[listenerID];
110738     }
110739
110740     function handleSubFeatures(subFeatures) {
110741         var i, subFeature;
110742
110743         for (subFeature in subFeatures) {
110744             for (i in _security[subFeature]) {
110745                 _security[_security[subFeature][i]] = true;
110746             }
110747         }
110748     }
110749
110750     var application = {
110751         getCurrentApplication : getCurrentApplication,
110752         kill : kill,
110753         launch : launch,
110754         launchAppControl : launchAppControl,
110755         findAppControl : findAppControl,
110756         getAppsContext : getAppsContext,
110757         getAppContext : getAppContext,
110758         getAppsInfo : getAppsInfo,
110759         getAppInfo : getAppInfo,
110760         getAppCerts : getAppCerts,
110761         getAppSharedURI: getAppSharedURI,
110762         addAppInfoEventListener : addAppInfoEventListener,
110763         removeAppInfoEventListener : removeAppInfoEventListener,
110764         handleSubFeatures : handleSubFeatures
110765     };
110766
110767     return application;
110768 };
110769
110770 Application = function (appInfo, contextId, metaData) {
110771     var application = {}, requestedAppControl;
110772
110773     application.appInfo   = appInfo;
110774     application.contextId = contextId;
110775
110776     requestedAppControl = new RequestedApplicationControl(
110777             new ApplicationControl(metaData.operation, metaData.appControl.uri,
110778                     metaData.appControl.mime, metaData.appControl.category,
110779                     metaData.appControl.data), application.appInfo.id);
110780
110781     this.__defineGetter__("appInfo", function () {
110782         return application.appInfo;
110783     });
110784
110785     this.__defineGetter__("contextId", function () {
110786         return application.contextId;
110787     });
110788
110789     this.exit = function () {
110790         event.trigger("tizen-application-exit", [contextId]);
110791     };
110792
110793     this.hide = function () {
110794         event.trigger("tizen-application-hide", [contextId]);
110795     };
110796
110797     this.getRequestedAppControl = function () {
110798         return requestedAppControl;
110799     };
110800 };
110801
110802 ApplicationInformation = function (id, name, iconPath, version, show,
110803         categories, installDate, size, packageId) {
110804     this.__defineGetter__("id", function () {
110805         return id;
110806     });
110807
110808     this.__defineGetter__("name", function () {
110809         return name;
110810     });
110811
110812     this.__defineGetter__("iconPath", function () {
110813         return iconPath;
110814     });
110815
110816     this.__defineGetter__("version", function () {
110817         return version;
110818     });
110819
110820     this.__defineGetter__("show", function () {
110821         return show;
110822     });
110823
110824     this.__defineGetter__("categories", function () {
110825         return categories;
110826     });
110827
110828     this.__defineGetter__("installDate", function () {
110829         return installDate;
110830     });
110831
110832     this.__defineGetter__("size", function () {
110833         return size;
110834     });
110835
110836     this.__defineGetter__("packageId", function () {
110837         return packageId;
110838     });
110839 };
110840
110841 ApplicationContext = function (id, appId) {
110842     this.__defineGetter__("id", function () {
110843         return id;
110844     });
110845
110846     this.__defineGetter__("appId", function () {
110847         return appId;
110848     });
110849 };
110850
110851 RequestedApplicationControl = function (appControl, callerAppId) {
110852     this.__defineGetter__("appControl", function () {
110853         return appControl;
110854     });
110855
110856     this.__defineGetter__("callerAppId", function () {
110857         return callerAppId;
110858     });
110859
110860     this.replyResult = function (data) {
110861         t.RequestedApplicationControl("replyResult", arguments);
110862
110863         event.trigger("appServiceReplied", "Result: " + data);
110864     };
110865
110866     this.replyFailure = function () {
110867         event.trigger("appServiceReplied", "Failure");
110868     };
110869 };
110870
110871 ApplicationCertificate = function (type, value) {
110872     this.__defineGetter__("type", function () {
110873         return type;
110874     });
110875
110876     this.__defineGetter__("value", function () {
110877         return value;
110878     });
110879 };
110880
110881 jQuery("#app-dialog-return-btn").live("click", function () {
110882     $("#app-dialog").dialog("close");
110883 });
110884
110885 jQuery("#app-dialog-reload-btn").live("click", function () {
110886     $("#app-dialog").dialog("close");
110887     window.tinyHipposReload = true;
110888     location.reload();
110889 });
110890
110891 jQuery("#app-dialog-generate-reply").live("click", function () {
110892     var type, data, ret = [];
110893     type = jQuery('input:radio[name="app-dialog-reply-type"]:checked').val();
110894     data = jQuery("#app-dialog-reply-json").val();
110895     $("#app-dialog").dialog("close");
110896     if (_data.activeApp.replyCallback) {
110897         switch (type) {
110898         case "replyResult":
110899             if (_data.activeApp.replyCallback.onsuccess) {
110900                 if (data === "") {
110901                     _data.activeApp.replyCallback.onsuccess();
110902                 } else {
110903                     try {
110904                         ret = JSON.parse(data);
110905                         _data.activeApp.replyCallback.onsuccess(ret);
110906                     } catch (e) {
110907                         console.log("replyResult: JSON parsing error: " + e.message);
110908                         _data.activeApp.replyCallback.onsuccess();
110909                     }
110910                 }
110911             }
110912             break;
110913         case "replyFailure":
110914             if (_data.activeApp.replyCallback.onfailure) {
110915                 _data.activeApp.replyCallback.onfailure();
110916             }
110917             break;
110918         }
110919     }
110920 });
110921
110922 event.on("ApplicationLoad", function () {
110923     _initialize();
110924 });
110925
110926 event.on("tizen-application-exit", function () {
110927     var htmlContent;
110928     htmlContent = _appDialogTemplate_exit_hide.replace(/#application-name/, _data.applications[_data.activeApp.appId].name)
110929         .replace(/#application-id/, _data.applications[_data.activeApp.appId].id)
110930         .replace(/#application-operation/g, "exit")
110931         .replace(/#application-verb/, "launch")
110932         .replace(/#next-command/g, "Launch")
110933         .replace(/#application-btn/, "app-dialog-reload-btn");
110934     jQuery("#app-dialog-box").html(htmlContent);
110935     $("#app-dialog").dialog("open");
110936 });
110937
110938 event.on("tizen-application-hide", function () {
110939     var htmlContent;
110940     htmlContent = _appDialogTemplate_exit_hide.replace(/#application-name/, _data.applications[_data.activeApp.appId].name)
110941         .replace(/#application-id/, _data.applications[_data.activeApp.appId].id)
110942         .replace(/#application-operation/g, "hide")
110943         .replace(/#application-verb/, "show")
110944         .replace(/#next-command/g, "Show")
110945         .replace(/#application-btn/, "app-dialog-return-btn");
110946     jQuery("#app-dialog-box").html(htmlContent);
110947     $("#app-dialog").dialog("open");
110948 });
110949
110950 event.on("programChanged", function (status, id) {
110951     var callback, data, innerApp;
110952     _data.applications = db.retrieveObject(_DB_APPLICATION_KEY).installedAppList;
110953     utils.forEach(_data.applications, function(item) {
110954         item.installDate = new Date(item.installDate);
110955     });
110956     _setupCurrentApp();
110957     switch (status) {
110958     case "installed":
110959     case "updated":
110960         innerApp = _data.applications[id];
110961         data = new ApplicationInformation(
110962                         innerApp.id,
110963                         innerApp.name,
110964                         innerApp.iconPath,
110965                         innerApp.version,
110966                         innerApp.show,
110967                         innerApp.categories,
110968                         innerApp.installDate,
110969                         innerApp.size,
110970                         innerApp.packageId);
110971         break;
110972     case "uninstalled":
110973         data = id;
110974         break;
110975
110976     default:
110977         return;
110978     }
110979     callback = "on" + status;
110980     utils.forEach(_data.listeners, function (listener) {
110981         listener[callback](data);
110982     });
110983 });
110984
110985 _initialize();
110986
110987 module.exports = _self;
110988
110989 });
110990 define('ripple/platform/tizen/2.0/ContactRef', function (require, exports, module) {
110991 /*
110992  *  Copyright 2013 Intel Corporation.
110993  *
110994  * Licensed under the Apache License, Version 2.0 (the "License");
110995  * you may not use this file except in compliance with the License.
110996  * You may obtain a copy of the License at
110997  *
110998  * http://www.apache.org/licenses/LICENSE-2.0
110999  *
111000  * Unless required by applicable law or agreed to in writing, software
111001  * distributed under the License is distributed on an "AS IS" BASIS,
111002  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
111003  * See the License for the specific language governing permissions and
111004  * limitations under the License.
111005  */
111006
111007 var t = require('ripple/platform/tizen/2.0/typecast'),
111008     ContactRef;
111009
111010 ContactRef = function (addressBookId, contactId) {
111011     var contactRef = {};
111012
111013     t.ContactRef(arguments, this);
111014
111015     contactRef.addressBookId = addressBookId;
111016     contactRef.contactId     = contactId;
111017
111018     this.__defineGetter__("addressBookId", function () {
111019         return contactRef.addressBookId;
111020     });
111021     this.__defineSetter__("addressBookId", function (val) {
111022         try {
111023             contactRef.addressBookId = t.AddressBookId(val);
111024         } catch (e) {
111025         }
111026     });
111027
111028     this.__defineGetter__("contactId", function () {
111029         return contactRef.contactId;
111030     });
111031     this.__defineSetter__("contactId", function (val) {
111032         try {
111033             contactRef.contactId = t.ContactId(val);
111034         } catch (e) {
111035         }
111036     });
111037 };
111038
111039 module.exports = ContactRef;
111040
111041 });
111042 define('ripple/platform/tizen/2.0/CalendarEventId', function (require, exports, module) {
111043 /*
111044  *  Copyright 2013 Intel Corporation.
111045  *
111046  * Licensed under the Apache License, Version 2.0 (the "License");
111047  * you may not use this file except in compliance with the License.
111048  * You may obtain a copy of the License at
111049  *
111050  * http://www.apache.org/licenses/LICENSE-2.0
111051  *
111052  * Unless required by applicable law or agreed to in writing, software
111053  * distributed under the License is distributed on an "AS IS" BASIS,
111054  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
111055  * See the License for the specific language governing permissions and
111056  * limitations under the License.
111057  */
111058
111059 var t = require('ripple/platform/tizen/2.0/typecast'),
111060     CalendarEventId;
111061
111062 CalendarEventId = function (uid, rid) {
111063     var calendarEventId = {};
111064
111065     t.CalendarEventId(arguments, this);
111066
111067     calendarEventId.uid = uid;
111068     calendarEventId.rid = rid || null;
111069
111070     this.__defineGetter__("uid", function () {
111071         return calendarEventId.uid;
111072     });
111073     this.__defineSetter__("uid", function (val) {
111074         try {
111075             calendarEventId.uid = t.DOMString(val);
111076         } catch (e) {
111077         }
111078     });
111079
111080     this.__defineGetter__("rid", function () {
111081         return calendarEventId.rid;
111082     });
111083     this.__defineSetter__("rid", function (val) {
111084         try {
111085             calendarEventId.rid = t.DOMString(val, "?");
111086         } catch (e) {
111087         }
111088     });
111089 };
111090
111091 module.exports = CalendarEventId;
111092
111093 });
111094 define('ripple/platform/tizen/2.0/content', function (require, exports, module) {
111095 /*
111096  *  Copyright 2013 Intel Corporation
111097  *
111098  * Licensed under the Apache License, Version 2.0 (the "License");
111099  * you may not use this file except in compliance with the License.
111100  * You may obtain a copy of the License at
111101  *
111102  * http://www.apache.org/licenses/LICENSE-2.0
111103  *
111104  * Unless required by applicable law or agreed to in writing, software
111105  * distributed under the License is distributed on an "AS IS" BASIS,
111106  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
111107  * See the License for the specific language governing permissions and
111108  * limitations under the License.
111109  */
111110
111111 var db = require('ripple/db'),
111112     utils = require('ripple/utils'),
111113     dbfs = require('ripple/platform/tizen/2.0/dbfs'),
111114     dbinit = require('ripple/platform/tizen/2.0/dbinit'),
111115     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
111116     t = require('ripple/platform/tizen/2.0/typecast'),
111117     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
111118     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
111119     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
111120     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
111121     Content,
111122     ContentDirectory,
111123     ContentFactory,
111124     ContentStorage,
111125     AudioContent,
111126     ImageContent,
111127     VideoContent,
111128     ContentInternal,
111129     ContentDirectoryInternal,
111130     AudioContentInternal,
111131     ImageContentInternal,
111132     VideoContentInternal,
111133     AudioContentLyrics,
111134     _data = {
111135         DB_CONTENT_KEY: "tizen1-db-content",
111136         content:        {},
111137         listener:       null,
111138         dbStorage:      null
111139     },
111140     _security = {
111141         "http://tizen.org/privilege/content.read": ["find",
111142             "setChangeListener", "unsetChangeListener"],
111143         "http://tizen.org/privilege/content.write": ["update", "updateBatch",
111144             "scanFile"]
111145     },
111146     _self;
111147
111148 function _get() {
111149     _data.dbStorage = db.retrieveObject(_data.DB_CONTENT_KEY) || dbinit.Content;
111150 }
111151
111152 function _save() {
111153     db.saveObject(_data.DB_CONTENT_KEY, _data.dbStorage);
111154 }
111155
111156 function _initialize() {
111157     _get();
111158
111159     if (!_data.dbStorage)
111160         return;
111161
111162     utils.forEach(_data.dbStorage, function (content) {
111163         _data.content[content.directoryURI] = new ContentStorage(content);
111164     });
111165
111166     _data.dbStorage = _data.content;
111167     _save();
111168 }
111169
111170 _self = function () {
111171     var content;
111172
111173     // private
111174     function getType(file) {
111175         var extName, type;
111176
111177         extName = file.substr(file.lastIndexOf(".") + 1).toLowerCase();
111178
111179         switch (extName) {
111180         case "bmp":
111181         case "gif":
111182         case "jpeg":
111183         case "jpg":
111184         case "png":
111185             type = "IMAGE";
111186             break;
111187
111188         case "avi":
111189         case "mpeg":
111190         case "mpg":
111191         case "wmv":
111192         case "mp4":
111193             type = "VIDEO";
111194             break;
111195
111196         case "wav":
111197         case "mp3":
111198             type = "AUDIO";
111199             break;
111200
111201         default:
111202             type = "OTHER";
111203             break;
111204         }
111205
111206         return type;
111207     }
111208
111209     function getMimeType(file) {
111210         var mimeTypeTab = {
111211             IMAGE: "image/x-msimage",
111212             VIDEO: "video/x-msvideo",
111213             AUDIO: "audio/x-msaudio",
111214             OTHER: "other/unknown"
111215         };
111216
111217         return mimeTypeTab[getType(file)];
111218     }
111219
111220     function getTitle(file) {
111221         var title;
111222
111223         title = file.substr(0, file.lastIndexOf("."));
111224         title = title.charAt(0).toUpperCase() + title.substr(1).toLowerCase();
111225
111226         return title;
111227     }
111228
111229     function getDirectoryURI(contentURI) {
111230         return contentURI.slice(0, contentURI.lastIndexOf("/") + 1)
111231                 .replace(/file:\/\//, "");
111232     }
111233
111234     function extractProperties(entry) {
111235         var contentInitDict = {};
111236
111237         contentInitDict.editableAttributes = ["name", "title", "description",
111238                 "rating"];
111239         contentInitDict.name               = entry.name;
111240         contentInitDict.type               = getType(entry.name);
111241         contentInitDict.mimeType           = getMimeType(entry.name);
111242         contentInitDict.title              = getTitle(entry.name);
111243         contentInitDict.contentURI         = entry.fullPath ?
111244                 "file://" + entry.fullPath : entry.fullPath;
111245         contentInitDict.thumbnailURIs      = [entry.fullPath];
111246         contentInitDict.releaseDate        = entry.lastModifiedDate;
111247         contentInitDict.modifiedDate       = entry.lastModifiedDate;
111248         contentInitDict.size               = 1048576;
111249
111250         return contentInitDict;
111251     }
111252
111253     function updateContents(contents, successCallback, errorCallback) {
111254         var i, isFound = false, dir, matched = [];
111255
111256         for (i in contents) {
111257             dir = getDirectoryURI(contents[i].contentURI);
111258
111259             isFound = ((dir in _data.content) && (contents[i].contentURI in
111260                     _data.content[dir].contents));
111261
111262             if (!isFound)
111263                 break;
111264
111265             matched.push(dir);
111266         }
111267
111268         if (!isFound) {
111269             if (errorCallback) {
111270                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
111271             }
111272             return;
111273         }
111274
111275         for (i in matched) {
111276             _data.content[matched[i]].contents[contents[i].contentURI] =
111277                     new ContentFactory(contents[i], true);
111278         }
111279
111280         _save();
111281
111282         if (successCallback) {
111283             successCallback();
111284         }
111285
111286         if (_data.listener !== null) {
111287             for (i in matched) {
111288                 _data.listener.oncontentupdated(new ContentFactory(_data
111289                         .content[matched[i]].contents[contents[i].contentURI],
111290                         false));
111291             }
111292         }
111293     }
111294
111295     // public
111296     function update(content) {
111297         if (!_security.update) {
111298             throw new WebAPIException(errorcode.SECURITY_ERR);
111299         }
111300
111301         t.ContentManager("update", arguments);
111302
111303         updateContents([content]);
111304     }
111305
111306     function updateBatch(contents, successCallback, errorCallback) {
111307         if (!_security.updateBatch) {
111308             throw new WebAPIException(errorcode.SECURITY_ERR);
111309         }
111310
111311         t.ContentManager("updateBatch", arguments, true);
111312
111313         window.setTimeout(function () {
111314             updateContents(contents, successCallback, errorCallback);
111315         }, 1);
111316     }
111317
111318     function getDirectories(successCallback, errorCallback) {
111319         t.ContentManager("getDirectories", arguments);
111320
111321         window.setTimeout(function () {
111322             var i, directories = [];
111323
111324             for (i in _data.content) {
111325                 directories.push(new ContentDirectory(_data.content[i]));
111326             }
111327
111328             if (directories.length === 0) {
111329                 if (errorCallback) {
111330                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
111331                 }
111332                 return;
111333             }
111334
111335             successCallback(directories);
111336         }, 1);
111337     }
111338
111339     function find(successCallback, errorCallback, directoryId, filter, sortMode,
111340             count, offset) {
111341         if (!_security.find) {
111342             throw new WebAPIException(errorcode.SECURITY_ERR);
111343         }
111344
111345         t.ContentManager("find", arguments, true);
111346
111347         window.setTimeout(function () {
111348             var i, dir, contents = [], results = [], matchedDir;
111349
111350             if (!directoryId) {
111351                 for (dir in _data.content) {
111352                     for (i in _data.content[dir].contents) {
111353                         contents.push(_data.content[dir].contents[i]);
111354                     }
111355                 }
111356             } else {
111357                 for (dir in _data.content) {
111358                     if (_data.content[dir].id === directoryId) {
111359                         matchedDir = dir;
111360                         break;
111361                     }
111362                 }
111363
111364                 if (!matchedDir) {
111365                     if (errorCallback) {
111366                         errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
111367                     }
111368                     return;
111369                 }
111370
111371                 for (i in _data.content[matchedDir].contents) {
111372                     contents.push(_data.content[matchedDir].contents[i]);
111373                 }
111374             }
111375
111376             if (contents.length === 0) {
111377                 if (errorCallback) {
111378                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
111379                 }
111380                 return;
111381             }
111382
111383             contents = tizen1_utils.query(contents, filter, sortMode, count,
111384                     offset);
111385
111386             contents.forEach(function (content) {
111387                 results.push(new ContentFactory(content, false));
111388             });
111389
111390             successCallback(results);
111391         }, 1);
111392     }
111393
111394     function scanFile(contentURI, successCallback, errorCallback) {
111395         var dir, isFound;
111396
111397         function onStatSuccess(entry) {
111398             var contentInitDict, content;
111399
111400             if (isFound) {
111401                 content = new ContentFactory(_data.content[dir]
111402                         .contents[contentURI], true);
111403             } else {
111404                 contentInitDict = extractProperties(entry);
111405                 content = new ContentFactory(contentInitDict, true);
111406                 _data.content[dir].contents[contentURI] = content;
111407             }
111408
111409             _save();
111410
111411             if (successCallback) {
111412                 successCallback(contentURI);
111413             }
111414
111415             if (_data.listener !== null) {
111416                 if (isFound) {
111417                     _data.listener.oncontentupdated(
111418                             new ContentFactory(content, false));
111419                 } else {
111420                     _data.listener.oncontentadded(
111421                             new ContentFactory(content, false));
111422                 }
111423             }
111424         }
111425
111426         function onStatError() {
111427             if (isFound) {
111428                 delete _data.content[dir].contents[contentURI];
111429                 _save();
111430
111431                 if (successCallback) {
111432                     successCallback(contentURI);
111433                 }
111434
111435                 if (_data.listener !== null) {
111436                     _data.listener.oncontentremoved(_data.content[dir]
111437                             .contents[contentURI].id);
111438                 }
111439             } else if (errorCallback) {
111440                 errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
111441             }
111442         }
111443
111444         if (!_security.scanFile) {
111445             throw new WebAPIException(errorcode.SECURITY_ERR);
111446         }
111447
111448         t.ContentManager("scanFile", arguments);
111449
111450         window.setTimeout(function () {
111451             dir = getDirectoryURI(contentURI);
111452
111453             isFound = ((dir in _data.content) &&
111454                     (contentURI in _data.content[dir].contents));
111455
111456             dbfs.stat(contentURI.replace(/file:\/\//, ""), onStatSuccess,
111457                     onStatError);
111458         }, 1);
111459     }
111460
111461     function setChangeListener(changeCallback) {
111462         if (!_security.setChangeListener) {
111463             throw new WebAPIException(errorcode.SECURITY_ERR);
111464         }
111465
111466         t.ContentManager("setChangeListener", arguments);
111467
111468         _data.listener = changeCallback;
111469     }
111470
111471     function unsetChangeListener() {
111472         if (!_security.unsetChangeListener) {
111473             throw new WebAPIException(errorcode.SECURITY_ERR);
111474         }
111475
111476         _data.listener = null;
111477     }
111478
111479     function handleSubFeatures(subFeatures) {
111480         var i, subFeature;
111481
111482         for (subFeature in subFeatures) {
111483             for (i in _security[subFeature]) {
111484                 _security[_security[subFeature][i]] = true;
111485             }
111486         }
111487     }
111488
111489     content = {
111490         update:              update,
111491         updateBatch:         updateBatch,
111492         getDirectories:      getDirectories,
111493         find:                find,
111494         scanFile:            scanFile,
111495         setChangeListener:   setChangeListener,
111496         unsetChangeListener: unsetChangeListener,
111497         handleSubFeatures:   handleSubFeatures
111498     };
111499
111500     return content;
111501 };
111502
111503 ContentDirectoryInternal = function (contentDirectoryInitDict) {
111504     this.id           = contentDirectoryInitDict.id || null;
111505     this.directoryURI = contentDirectoryInitDict.directoryURI || null;
111506     this.title        = contentDirectoryInitDict.title || "";
111507     this.storageType  = contentDirectoryInitDict.storageType || "INTERNAL";
111508     this.modifiedDate = contentDirectoryInitDict.modifiedDate ?
111509             new Date(contentDirectoryInitDict.modifiedDate) : null;
111510 };
111511
111512 ContentDirectory = function (contentDirectoryInitDict) {
111513     var contentDirectory = {};
111514
111515     contentDirectory.id           = contentDirectoryInitDict.id || null;
111516     contentDirectory.directoryURI = contentDirectoryInitDict.directoryURI || null;
111517     contentDirectory.title        = contentDirectoryInitDict.title || "";
111518     contentDirectory.storageType  = contentDirectoryInitDict.storageType || "INTERNAL";
111519     contentDirectory.modifiedDate = contentDirectoryInitDict.modifiedDate ?
111520             new Date(contentDirectoryInitDict.modifiedDate) : null;
111521
111522     this.__defineGetter__("id", function () {
111523         return contentDirectory.id;
111524     });
111525
111526     this.__defineGetter__("directoryURI", function () {
111527         return contentDirectory.directoryURI;
111528     });
111529
111530     this.__defineGetter__("title", function () {
111531         return contentDirectory.title;
111532     });
111533
111534     this.__defineGetter__("storageType", function () {
111535         return contentDirectory.storageType;
111536     });
111537
111538     this.__defineGetter__("modifiedDate", function () {
111539         return contentDirectory.modifiedDate;
111540     });
111541 };
111542
111543 ContentInternal = function (contentInitDict) {
111544     this.editableAttributes = contentInitDict.editableAttributes || [];
111545     this.id                 = contentInitDict.id || Math.uuid(null, 16);
111546     this.type               = contentInitDict.type || "IMAGE";
111547     this.mimeType           = contentInitDict.mimeType || "";
111548     this.title              = contentInitDict.title || "";
111549     this.contentURI         = contentInitDict.contentURI || "";
111550     this.thumbnailURIs      = contentInitDict.thumbnailURIs || null;
111551     this.releaseDate        = contentInitDict.releaseDate ?
111552             new Date(contentInitDict.releaseDate) : null;
111553     this.modifiedDate       = contentInitDict.modifiedDate ?
111554             new Date(contentInitDict.modifiedDate) : null;
111555     this.size               = contentInitDict.size || 0;
111556     this.name               = contentInitDict.name || "";
111557     this.description        = contentInitDict.description || null;
111558     this.rating             = contentInitDict.rating || 0;
111559 };
111560
111561 Content = function (contentInitDict) {
111562     var content = {};
111563
111564     content.editableAttributes = contentInitDict.editableAttributes || [];
111565     content.id                 = contentInitDict.id || Math.uuid(null, 16);
111566     content.name               = contentInitDict.name || "";
111567     content.type               = contentInitDict.type || "IMAGE";
111568     content.mimeType           = contentInitDict.mimeType || "";
111569     content.title              = contentInitDict.title || "";
111570     content.contentURI         = contentInitDict.contentURI || "";
111571     content.thumbnailURIs      = contentInitDict.thumbnailURIs || null;
111572     content.releaseDate        = contentInitDict.releaseDate ?
111573             new Date(contentInitDict.releaseDate) : null;
111574     content.modifiedDate       = contentInitDict.modifiedDate ?
111575             new Date(contentInitDict.modifiedDate) : null;
111576     content.size               = contentInitDict.size || 0;
111577     content.description        = contentInitDict.description || null;
111578     content.rating             = contentInitDict.rating || 0;
111579
111580     this.__defineGetter__("editableAttributes", function () {
111581         return content.editableAttributes;
111582     });
111583
111584     this.__defineGetter__("id", function () {
111585         return content.id;
111586     });
111587
111588     this.__defineGetter__("name", function () {
111589         return content.name;
111590     });
111591     this.__defineSetter__("name", function (val) {
111592         try {
111593             content.name = t.DOMString(val);
111594         } catch (e) {
111595         }
111596     });
111597
111598     this.__defineGetter__("type", function () {
111599         return content.type;
111600     });
111601
111602     this.__defineGetter__("mimeType", function () {
111603         return content.mimeType;
111604     });
111605
111606     this.__defineGetter__("title", function () {
111607         return content.title;
111608     });
111609
111610     this.__defineGetter__("contentURI", function () {
111611         return content.contentURI;
111612     });
111613
111614     this.__defineGetter__("thumbnailURIs", function () {
111615         return content.thumbnailURIs;
111616     });
111617
111618     this.__defineGetter__("releaseDate", function () {
111619         return content.releaseDate;
111620     });
111621
111622     this.__defineGetter__("modifiedDate", function () {
111623         return content.modifiedDate;
111624     });
111625
111626     this.__defineGetter__("size", function () {
111627         return content.size;
111628     });
111629
111630     this.__defineGetter__("description", function () {
111631         return content.description;
111632     });
111633     this.__defineSetter__("description", function (val) {
111634         try {
111635             content.description = t.DOMString(val, "?");
111636         } catch (e) {
111637         }
111638     });
111639
111640     this.__defineGetter__("rating", function () {
111641         return content.rating;
111642     });
111643     this.__defineSetter__("rating", function (val) {
111644         try {
111645             val = t.unsigned_long(val);
111646             if ((val < 0) || (val > 10))
111647                 return;
111648             content.rating = val;
111649         } catch (e) {
111650         }
111651     });
111652 };
111653
111654 VideoContentInternal = function (videoContentInitDict) {
111655     ContentInternal.call(this, videoContentInitDict);
111656
111657     this.album       = videoContentInitDict.album || null;
111658     this.artists     = videoContentInitDict.artists || null;
111659     this.duration    = videoContentInitDict.duration || 0;
111660     this.width       = videoContentInitDict.width || 0;
111661     this.height      = videoContentInitDict.height || 0;
111662     this.geolocation = null;
111663
111664     if (videoContentInitDict.geolocation) {
111665         this.geolocation = new SimpleCoordinates(
111666                 videoContentInitDict.geolocation.latitude || null,
111667                 videoContentInitDict.geolocation.longitude || null);
111668     }
111669 };
111670
111671 VideoContent = function (videoContentInitDict) {
111672     var videoContent = {};
111673
111674     Content.call(this, videoContentInitDict);
111675
111676     videoContent.album       = videoContentInitDict.album || null;
111677     videoContent.artists     = videoContentInitDict.artists || null;
111678     videoContent.duration    = videoContentInitDict.duration || 0;
111679     videoContent.width       = videoContentInitDict.width || 0;
111680     videoContent.height      = videoContentInitDict.height || 0;
111681     videoContent.geolocation = null;
111682
111683     if (videoContentInitDict.geolocation) {
111684         videoContent.geolocation = new SimpleCoordinates(
111685                 videoContentInitDict.geolocation.latitude,
111686                 videoContentInitDict.geolocation.longitude);
111687     }
111688
111689     this.__defineGetter__("geolocation", function () {
111690         return videoContent.geolocation;
111691     });
111692     this.__defineSetter__("geolocation", function (val) {
111693         try {
111694             videoContent.geolocation = t.SimpleCoordinates(val, "?");
111695         } catch (e) {
111696         }
111697     });
111698
111699     this.__defineGetter__("album", function () {
111700         return videoContent.album;
111701     });
111702
111703     this.__defineGetter__("artists", function () {
111704         return videoContent.artists;
111705     });
111706
111707     this.__defineGetter__("duration", function () {
111708         return videoContent.duration;
111709     });
111710
111711     this.__defineGetter__("width", function () {
111712         return videoContent.width;
111713     });
111714
111715     this.__defineGetter__("height", function () {
111716         return videoContent.height;
111717     });
111718 };
111719
111720 AudioContentInternal = function (audioContentInitDict) {
111721     ContentInternal.call(this, audioContentInitDict);
111722
111723     this.album       = audioContentInitDict.album || null;
111724     this.genres      = audioContentInitDict.genres || null;
111725     this.artists     = audioContentInitDict.artists || null;
111726     this.composers   = audioContentInitDict.composers || null;
111727     this.lyrics      = audioContentInitDict.lyrics ?
111728             new AudioContentLyrics(audioContentInitDict.lyrics) : null;
111729     this.copyright   = audioContentInitDict.copyright || null;
111730     this.bitrate     = audioContentInitDict.bitrate || 0;
111731     this.trackNumber = audioContentInitDict.trackNumber || null;
111732     this.duration    = audioContentInitDict.duration || 0;
111733 };
111734
111735 AudioContentLyrics = function (lyrics) {
111736     var audioContentLyrics = {};
111737
111738     audioContentLyrics.type       = lyrics.type;
111739     audioContentLyrics.texts      = lyrics.texts;
111740     audioContentLyrics.timestamps = (lyrics.type === "SYNCHRONIZED") ?
111741             lyrics.timestamps : undefined;
111742
111743     this.__defineGetter__("type", function () {
111744         return audioContentLyrics.type;
111745     });
111746
111747     this.__defineGetter__("texts", function () {
111748         return audioContentLyrics.texts;
111749     });
111750
111751     this.__defineGetter__("timestamps", function () {
111752         return audioContentLyrics.timestamps;
111753     });
111754 };
111755
111756 AudioContent = function (audioContentInitDict) {
111757     var audioContent = {};
111758
111759     Content.call(this, audioContentInitDict);
111760
111761     audioContent.album       = audioContentInitDict.album || null;
111762     audioContent.genres      = audioContentInitDict.genres || null;
111763     audioContent.artists     = audioContentInitDict.artists || null;
111764     audioContent.composers   = audioContentInitDict.composers || null;
111765     audioContent.lyrics      = audioContentInitDict.lyrics ?
111766             new AudioContentLyrics(audioContentInitDict.lyrics) : null;
111767     audioContent.copyright   = audioContentInitDict.copyright || null;
111768     audioContent.bitrate     = audioContentInitDict.bitrate || 0;
111769     audioContent.trackNumber = audioContentInitDict.trackNumber || null;
111770     audioContent.duration    = audioContentInitDict.duration || 0;
111771
111772     this.__defineGetter__("album", function () {
111773         return audioContent.album;
111774     });
111775
111776     this.__defineGetter__("genres", function () {
111777         return audioContent.genres;
111778     });
111779
111780     this.__defineGetter__("artists", function () {
111781         return audioContent.artists;
111782     });
111783
111784     this.__defineGetter__("composers", function () {
111785         return audioContent.composers;
111786     });
111787
111788     this.__defineGetter__("lyrics", function () {
111789         return audioContent.lyrics;
111790     });
111791
111792     this.__defineGetter__("copyright", function () {
111793         return audioContent.copyright;
111794     });
111795
111796     this.__defineGetter__("bitrate", function () {
111797         return audioContent.bitrate;
111798     });
111799
111800     this.__defineGetter__("trackNumber", function () {
111801         return audioContent.trackNumber;
111802     });
111803
111804     this.__defineGetter__("duration", function () {
111805         return audioContent.duration;
111806     });
111807 };
111808
111809 ImageContentInternal = function (imageContentInitDict) {
111810     ContentInternal.call(this, imageContentInitDict);
111811
111812     this.geolocation = null;
111813     this.width       = imageContentInitDict.width || 0;
111814     this.height      = imageContentInitDict.height || 0;
111815     this.orientation = imageContentInitDict.orientation || "NORMAL";
111816
111817     if (imageContentInitDict.geolocation) {
111818         this.geolocation = new SimpleCoordinates(
111819                 imageContentInitDict.geolocation.latitude,
111820                 imageContentInitDict.geolocation.longitude);
111821     }
111822 };
111823
111824 ImageContent = function (imageContentInitDict) {
111825     var imageContent = {};
111826
111827     Content.call(this, imageContentInitDict);
111828
111829     imageContent.width       = imageContentInitDict.width || 0;
111830     imageContent.height      = imageContentInitDict.height || 0;
111831     imageContent.geolocation = null;
111832     imageContent.orientation = imageContentInitDict.orientation || "NORMAL";
111833
111834     if (imageContentInitDict.geolocation) {
111835         imageContent.geolocation = new SimpleCoordinates(
111836                 imageContentInitDict.geolocation.latitude,
111837                 imageContentInitDict.geolocation.longitude);
111838     }
111839
111840     this.__defineGetter__("geolocation", function () {
111841         return imageContent.geolocation;
111842     });
111843     this.__defineSetter__("geolocation", function (val) {
111844         try {
111845             imageContent.geolocation = t.SimpleCoordinates(val, "?");
111846         } catch (e) {
111847         }
111848     });
111849
111850     this.__defineGetter__("width", function () {
111851         return imageContent.width;
111852     });
111853
111854     this.__defineGetter__("height", function () {
111855         return imageContent.height;
111856     });
111857
111858     this.__defineGetter__("orientation", function () {
111859         return imageContent.orientation;
111860     });
111861     this.__defineSetter__("orientation", function (val) {
111862         try {
111863             imageContent.orientation = t.ImageContentOrientation(val);
111864         } catch (e) {
111865         }
111866     });
111867 };
111868
111869 ContentFactory = function (contentInitDict, isInternal) {
111870     var ContentType;
111871
111872     switch (contentInitDict.type) {
111873     case "IMAGE":
111874         ContentType = isInternal ? ImageContentInternal : ImageContent;
111875         break;
111876
111877     case "VIDEO":
111878         ContentType = isInternal ? VideoContentInternal : VideoContent;
111879         break;
111880
111881     case "AUDIO":
111882         ContentType = isInternal ? AudioContentInternal : AudioContent;
111883         break;
111884
111885     default:
111886         ContentType = isInternal ? ContentInternal : Content;
111887         break;
111888     }
111889
111890     return new ContentType(contentInitDict);
111891 };
111892
111893 ContentStorage = function (content) {
111894     var i;
111895
111896     ContentDirectoryInternal.call(this, content);
111897     this.contents = {};
111898
111899     for (i in content.contents) {
111900         this.contents[i] = new ContentFactory(content.contents[i], true);
111901     }
111902 };
111903
111904 _initialize();
111905
111906 module.exports = _self;
111907
111908 });
111909 define('ripple/platform/tizen/2.0/GeoCircleBounds', function (require, exports, module) {
111910 /*
111911  *  Copyright 2012 Intel Corporation.
111912  *
111913  * Licensed under the Apache License, Version 2.0 (the "License");
111914  * you may not use this file except in compliance with the License.
111915  * You may obtain a copy of the License at
111916  *
111917  * http://www.apache.org/licenses/LICENSE-2.0
111918  *
111919  * Unless required by applicable law or agreed to in writing, software
111920  * distributed under the License is distributed on an "AS IS" BASIS,
111921  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
111922  * See the License for the specific language governing permissions and
111923  * limitations under the License.
111924  */
111925
111926 module.exports = function (_center, _radius) {
111927     var center, radius;
111928     center = _center || null;
111929     radius = _radius || 0;
111930
111931     this.__defineGetter__("center", function () {
111932         return center;
111933     });
111934
111935     this.__defineGetter__("radius", function () {
111936         return radius;
111937     });
111938 };
111939
111940 });
111941 define('ripple/platform/tizen/2.0/BluetoothServiceHandler', function (require, exports, module) {
111942 /*
111943  *  Copyright 2013 Intel Corporation
111944  *
111945  * Licensed under the Apache License, Version 2.0 (the "License");
111946  * you may not use this file except in compliance with the License.
111947  * You may obtain a copy of the License at
111948  *
111949  * http://www.apache.org/licenses/LICENSE-2.0
111950  *
111951  * Unless required by applicable law or agreed to in writing, software
111952  * distributed under the License is distributed on an "AS IS" BASIS,
111953  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
111954  * See the License for the specific language governing permissions and
111955  * limitations under the License.
111956  */
111957
111958 var event = require('ripple/event'),
111959     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
111960     t = require('ripple/platform/tizen/2.0/typecast'),
111961     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
111962     BluetoothServiceHandler,
111963     _security;
111964
111965 BluetoothServiceHandler = function (prop) {
111966     var bluetoothServiceHandler = {};
111967
111968     _security = prop.metaData;
111969
111970     bluetoothServiceHandler.uuid        = prop.uuid || "";
111971     bluetoothServiceHandler.name        = prop.name || "";
111972     bluetoothServiceHandler.isConnected = prop.isConnected || false;
111973     bluetoothServiceHandler.onconnect   = null;
111974
111975     this.__defineGetter__("uuid", function () {
111976         return bluetoothServiceHandler.uuid;
111977     });
111978
111979     this.__defineGetter__("name", function () {
111980         return bluetoothServiceHandler.name;
111981     });
111982
111983     this.__defineGetter__("isConnected", function () {
111984         return bluetoothServiceHandler.isConnected;
111985     });
111986
111987     this.__defineGetter__("onconnect", function () {
111988         return bluetoothServiceHandler.onconnect;
111989     });
111990     this.__defineSetter__("onconnect", function (val) {
111991         try {
111992             bluetoothServiceHandler.onconnect =
111993                     t.BluetoothSocketSuccessCallback(val, "?");
111994         } catch (e) {
111995         }
111996     });
111997
111998     this.unregister = function (successCallback, errorCallback) {
111999         if (!_security.unregister) {
112000             throw new WebAPIException(errorcode.SECURITY_ERR);
112001         }
112002
112003         t.BluetoothServiceHandler("unregister", arguments);
112004
112005         event.trigger("bt-unregister-service", [bluetoothServiceHandler.uuid,
112006                 successCallback, errorCallback]);
112007     };
112008 };
112009
112010 module.exports = BluetoothServiceHandler;
112011
112012 });
112013 define('ripple/platform/tizen/2.0/GeometryFilter', function (require, exports, module) {
112014 /*
112015  *  Copyright 2012 Intel Corporation.
112016  *
112017  * Licensed under the Apache License, Version 2.0 (the "License");
112018  * you may not use this file except in compliance with the License.
112019  * You may obtain a copy of the License at
112020  *
112021  * http://www.apache.org/licenses/LICENSE-2.0
112022  *
112023  * Unless required by applicable law or agreed to in writing, software
112024  * distributed under the License is distributed on an "AS IS" BASIS,
112025  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112026  * See the License for the specific language governing permissions and
112027  * limitations under the License.
112028  */
112029
112030 module.exports = function (criteria, geometry) {
112031     var _self;
112032
112033     _self = {
112034         criteria: criteria,
112035         geometry: geometry
112036     };
112037
112038     return _self;
112039 };
112040
112041 });
112042 define('ripple/platform/tizen/2.0/bookmark', function (require, exports, module) {
112043 /*
112044  *  Copyright 2013 Intel Corporation.
112045  *
112046  * Licensed under the Apache License, Version 2.0 (the "License");
112047  * you may not use this file except in compliance with the License.
112048  * You may obtain a copy of the License at
112049  *
112050  * http://www.apache.org/licenses/LICENSE-2.0
112051  *
112052  * Unless required by applicable law or agreed to in writing, software
112053  * distributed under the License is distributed on an "AS IS" BASIS,
112054  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112055  * See the License for the specific language governing permissions and
112056  * limitations under the License.
112057  */
112058
112059 var db = require('ripple/db'),
112060     utils = require('ripple/utils'),
112061     t = require('ripple/platform/tizen/2.0/typecast'),
112062     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
112063     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
112064     BookmarkFolder = require('ripple/platform/tizen/2.0/BookmarkFolder'),
112065     BookmarkItem = require('ripple/platform/tizen/2.0/BookmarkItem'),
112066     BookmarkExternal,
112067     BookmarkInternal,
112068     BookmarkStorage,
112069     _data = {
112070         DB_BOOKMARK_KEY: "tizen1-bookmark",
112071         bookmarks:       [],
112072         dbStorage:       []
112073     },
112074     _security = {
112075         "http://tizen.org/privilege/bookmark.read": ["get"],
112076         "http://tizen.org/privilege/bookmark.write": ["add", "remove"]
112077     },
112078     _self;
112079
112080 function _get() {
112081     _data.dbStorage = db.retrieveObject(_data.DB_BOOKMARK_KEY) || [];
112082 }
112083
112084 function _save() {
112085     db.saveObject(_data.DB_BOOKMARK_KEY, _data.dbStorage);
112086 }
112087
112088 function _initialize() {
112089     _get();
112090
112091     utils.forEach(_data.dbStorage, function (bookmark) {
112092         _data.bookmarks.push(new BookmarkInternal(bookmark, null));
112093     });
112094 }
112095
112096 function _persist() {
112097     _data.dbStorage = [];
112098
112099     utils.forEach(_data.bookmarks, function (bookmark) {
112100         _data.dbStorage.push(new BookmarkStorage(bookmark));
112101     });
112102
112103     _save();
112104 }
112105
112106 function _isFolder(bookmark) {
112107     return !bookmark.url;
112108 }
112109
112110 function _isExternal(bookmark) {
112111     return !("children" in bookmark);
112112 }
112113
112114 function _getChildren(bookmark, BookmarkType, parent) {
112115     var i, children = [];
112116
112117     if (!_isExternal(bookmark)) {
112118         for (i in bookmark.children) {
112119             children.push(new BookmarkType(bookmark.children[i], parent));
112120         }
112121     }
112122
112123     return children;
112124 }
112125
112126 _self = function () {
112127     var bookmark;
112128
112129     // private
112130     /*
112131      * map
112132      *    Map the external bookmark to the internal one in the tree
112133      *
112134      * bookmarkExternal
112135      *    External bookmark Object
112136      *
112137      * callback
112138      *    callback(index, peers). Optional.
112139      *
112140      *          Root    Bookmark        Not Found
112141      * ------------------------------------------
112142      *  index   0       index           -1
112143      *  peers   null    peers           null
112144      *
112145      * Return   null    peers[index]    undefined
112146      */
112147
112148     function map(bookmarkExternal, callback) {
112149         var trace = [], it, i, peers = null;
112150
112151         if (!bookmarkExternal) {
112152             if (callback) {
112153                 callback(0, null);
112154             }
112155             return null;
112156         }
112157
112158         for (it = bookmarkExternal; it; it = it.parent) {
112159             trace.push(it);
112160         }
112161
112162         for (it = _data.bookmarks; trace.length !== 0; it = it[i].children) {
112163             bookmarkExternal = trace.pop();
112164             peers = null;
112165
112166             if (it.length === 0)
112167                 break;
112168
112169             for (i in it) {
112170                 if (it[i].external === bookmarkExternal) {
112171                     peers = it;
112172                     break;
112173                 }
112174             }
112175         }
112176
112177         if (callback) {
112178             return callback((peers !== null) ? i : -1, peers);
112179         }
112180
112181         return (peers !== null) ? peers[i] : undefined;
112182     }
112183
112184     function traverse(bookmarks, trace, level) {
112185         for (var i in bookmarks) {
112186             trace.push(bookmarks[i].external);
112187             if ((level !== 0) && bookmarks[i].children) {
112188                 traverse(bookmarks[i].children, trace, --level);
112189             }
112190         }
112191     }
112192
112193     function findUrl(bookmarks, url) {
112194         var i, isFound = false;
112195
112196         for (i in bookmarks) {
112197             if (_isFolder(bookmarks[i])) {
112198                 isFound = findUrl(bookmarks[i].children, url);
112199             } else {
112200                 isFound = (bookmarks[i].url === url);
112201             }
112202
112203             if (isFound)
112204                 break;
112205         }
112206
112207         return isFound;
112208     }
112209
112210     function isExisting(bookmark, peers) {
112211         var i;
112212
112213         if (!_isFolder(bookmark)) {
112214             return findUrl(_data.bookmarks, bookmark.url);
112215         }
112216
112217         for (i in peers) {
112218             if (_isFolder(peers[i]) && (peers[i].title === bookmark.title)) {
112219                 return true;
112220             }
112221         }
112222
112223         return false;
112224     }
112225
112226     // public
112227     function get(parentFolder, recursive) {
112228         var bookmarks = [], parent, peers;
112229
112230         if (!_security.get) {
112231             throw new WebAPIException(errorcode.SECURITY_ERR);
112232         }
112233
112234         t.BookmarkManager("get", arguments);
112235
112236         parent = map(parentFolder);
112237         if ((parent === undefined) || (parent && !_isFolder(parent))) {
112238             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
112239         }
112240         peers = parent ? parent.children : _data.bookmarks;
112241         traverse(peers, bookmarks, recursive ? -1 : 0);
112242
112243         return bookmarks;
112244     }
112245
112246     function add(bookmark, parentFolder) {
112247         var parent, peers;
112248
112249         if (!_security.add) {
112250             throw new WebAPIException(errorcode.SECURITY_ERR);
112251         }
112252
112253         t.BookmarkManager("add", arguments);
112254
112255         parent = map(parentFolder);
112256         if ((parent === undefined) || (parent && !_isFolder(parent))) {
112257             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
112258         }
112259         peers = parent ? parent.children : _data.bookmarks;
112260         if (isExisting(bookmark, peers)) {
112261             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
112262         }
112263
112264         peers.push(new BookmarkInternal(bookmark));
112265
112266         _persist();
112267
112268         bookmark.__defineGetter__("parent", function () {
112269             return parent ? parent.external : null;
112270         });
112271     }
112272
112273     function remove(bookmark) {
112274         if (!_security.remove) {
112275             throw new WebAPIException(errorcode.SECURITY_ERR);
112276         }
112277
112278         t.BookmarkManager("remove", arguments);
112279
112280         if (!bookmark) {
112281             _data.bookmarks = [];
112282         } else {
112283             map(bookmark, function (index, peers) {
112284                 if (index === -1) {
112285                     throw new WebAPIException(errorcode.NOT_FOUND_ERR);
112286                 }
112287                 peers.splice(index, 1);
112288             });
112289
112290             bookmark.__defineGetter__("parent", function () {
112291                 return undefined;
112292             });
112293         }
112294
112295         _persist();
112296     }
112297
112298     function handleSubFeatures(subFeatures) {
112299         var i, subFeature;
112300
112301         for (subFeature in subFeatures) {
112302             for (i in _security[subFeature]) {
112303                 _security[_security[subFeature][i]] = true;
112304             }
112305         }
112306     }
112307
112308     bookmark = {
112309         get:               get,
112310         add:               add,
112311         remove:            remove,
112312         handleSubFeatures: handleSubFeatures
112313     };
112314
112315     return bookmark;
112316 };
112317
112318 /*
112319  * BookmarkInternal     BookmarkStorage     BookmarkExternal
112320  * ---------------------------------------------------------
112321  * title                title               title
112322  * url                  url                 url/-
112323  * children             children            -
112324  * external             -                   -
112325  * -                    -                   parent
112326  */
112327
112328 BookmarkInternal = function (bookmark, parent) {
112329     this.title    = bookmark.title;
112330     this.url      = _isFolder(bookmark) ? null : bookmark.url;
112331     this.children = _isFolder(bookmark) ?
112332         _getChildren(bookmark, BookmarkInternal, this) : null;
112333     this.external = _isExternal(bookmark) ? bookmark :
112334         new BookmarkExternal(bookmark, parent);
112335 };
112336
112337 BookmarkStorage = function (bookmark) {
112338     this.title    = bookmark.title;
112339     this.url      = _isFolder(bookmark) ? null : bookmark.url;
112340     this.children = _isFolder(bookmark) ?
112341         _getChildren(bookmark, BookmarkStorage) : null;
112342 };
112343
112344 BookmarkExternal = function (bookmark, parent) {
112345     var self;
112346
112347     if (_isFolder(bookmark)) {
112348         self = new BookmarkFolder(bookmark.title);
112349     } else {
112350         self = new BookmarkItem(bookmark.title, bookmark.url);
112351     }
112352
112353     self.__defineGetter__("parent", function () {
112354         return parent ? parent.external : null;
112355     });
112356
112357     return self;
112358 };
112359
112360 _initialize();
112361
112362 module.exports = _self;
112363
112364 });
112365 define('ripple/platform/tizen/2.0/CalendarItem', function (require, exports, module) {
112366 /*
112367  *  Copyright 2013 Intel Corporation.
112368  *
112369  * Licensed under the Apache License, Version 2.0 (the "License");
112370  * you may not use this file except in compliance with the License.
112371  * You may obtain a copy of the License at
112372  *
112373  * http://www.apache.org/licenses/LICENSE-2.0
112374  *
112375  * Unless required by applicable law or agreed to in writing, software
112376  * distributed under the License is distributed on an "AS IS" BASIS,
112377  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112378  * See the License for the specific language governing permissions and
112379  * limitations under the License.
112380  */
112381
112382 var t = require('ripple/platform/tizen/2.0/typecast'),
112383     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
112384     typedef = require('ripple/platform/tizen/2.0/typedef'),
112385     CalendarItem;
112386
112387 CalendarItem = function (itemInitDict) {
112388     var calendarItem = {}, attr;
112389
112390     // private
112391     function toDigit(number) {
112392         return ((number >= 10) ? "" : "0") + number;
112393     }
112394
112395     // public
112396     function convertToString(format) {
112397         var header = "BEGIN:VCALENDAR\r\nPRODID:-//Tizen.org//Tizen Calendar//EN\r\nVERSION:2.0\r\n",
112398             end = "END:VCALENDAR\r\n", str = "", pri, i, date, before, y, m, d,
112399             hh, mm, ss, dateStart = "", dateEnd = "";
112400
112401         t.CalendarItem("convertToString", arguments);
112402
112403         //TODO: vcalendar 1.0 doesn't support yet
112404         if (format === "VCALENDAR_10") {
112405             return;
112406         }
112407
112408         str = header + "BEGIN:#TYPE#\r\n";
112409
112410         if (this.isAllDay) {
112411             if (this.startDate) {
112412                 date = this.startDate;
112413                 y = date.getFullYear();
112414                 m = toDigit(date.getMonth() + 1);
112415                 d = toDigit(date.getDate());
112416                 str += "DTSTART;VALUE=DATE:" + y + m + d + "\r\n";
112417                 dateStart = "" + y + m + d + "T000000Z";
112418                 if (this.duration) {
112419                     date = date.addDuration(this.duration);
112420                     y = date.getFullYear();
112421                     m = toDigit(date.getMonth() + 1);
112422                     d = toDigit(date.getDate());
112423                     str += "DTEND;VALUE=DATE:" + y + m + d + "\r\n";
112424                     dateEnd = "" + y + m + d + "T000000Z";
112425                 }
112426             }
112427         } else {
112428             if (this.startDate) {
112429                 date = this.startDate;
112430                 y = date.getFullYear();
112431                 m = toDigit(date.getMonth() + 1);
112432                 d = toDigit(date.getDate());
112433                 hh = toDigit(date.getHours());
112434                 mm = toDigit(date.getMinutes());
112435                 ss = toDigit(date.getSeconds());
112436                 str += "DTSTART:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
112437                 dateStart = "" + y + m + d + "T" + hh + mm + ss + "Z";
112438                 if (this.duration && this.duration.length && this.duration.unit) {
112439                     date = date.addDuration(this.duration);
112440                     y = date.getFullYear();
112441                     m = toDigit(date.getMonth() + 1);
112442                     d = toDigit(date.getDate());
112443                     hh = toDigit(date.getHours());
112444                     mm = toDigit(date.getMinutes());
112445                     ss = toDigit(date.getSeconds());
112446                     str += "DTEND:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
112447                     dateEnd = "" + y + m + d + "T" + hh + mm + ss + "Z";
112448                 }
112449             }
112450         }
112451
112452         if (this.description) {
112453             str += "DESCRIPTION:" + this.description + "\r\n";
112454         }
112455         if (this.summary) {
112456             str += "SUMMARY:" + this.summary + "\r\n";
112457         }
112458         if (this.location) {
112459             str += "LOCATION:" + this.location + "\r\n";
112460         }
112461         if (this.geolocation) {
112462             // Don't need to check latitude and longitude due to they are mandatory attributes
112463             str += "GEO:" + this.geolocation.latitude + "," + this.geolocation.longitude + "\r\n";
112464         }
112465         if (this.organizer) {
112466             str += "ORGANIZER:" + this.organizer + "\r\n";
112467         }
112468         if (this.visibility) {
112469             str += "CLASS:" + this.visibility + "\r\n";
112470         }
112471         if (this.status) {
112472             str += "STATUS:" + this.status + "\r\n";
112473         }
112474         if (this.priority) {
112475             switch (this.priority) {
112476             case "HIGH":
112477                 pri = 2;
112478                 break;
112479             case "MEDIUM":
112480                 pri = 5;
112481                 break;
112482             case "LOW":
112483                 pri = 7;
112484                 break;
112485             }
112486             str += "PRIORITY:" + pri + "\r\n";
112487         }
112488         if (tizen1_utils.isValidArray(this.alarms)) {
112489             for (i = 0; i < this.alarms.length; i++) {
112490                 str += "BEGIN:VALARM\r\n";
112491                 // Don't need to check this.alarms[i].method due to it is a mandatory attribute
112492                 str += "ACTION:" + this.alarms[i].method + "\r\n";
112493                 if (this.alarms[i].description) {
112494                     str += "DESCRIPTION:" + this.alarms[i].description + "\r\n";
112495                 } else {
112496                     // description property MUST included if action is DISPLAY (RFC5545 3.6.6)
112497                     str += "DESCRIPTION:This is a reminder\r\n";
112498                 }
112499                 if (this.alarms[i].absoluteDate) {
112500                     date = this.alarms[i].absoluteDate;
112501                     y = date.getFullYear();
112502                     m = toDigit(date.getMonth() + 1);
112503                     d = toDigit(date.getDate());
112504                     hh = toDigit(date.getHours());
112505                     mm = toDigit(date.getMinutes());
112506                     ss = toDigit(date.getSeconds());
112507                     str += "TRIGGER;VALUE=DATE-TIME:" + y + m + d + "T" + hh + mm + ss + "Z" + "\r\n";
112508                 } else {
112509                     //it must be included before attribute
112510                     before = this.alarms[i].before;
112511                     switch (before.unit) {
112512                     case "DAYS":
112513                         str += "TRIGGER:-P" + before.length + "D" + "\r\n";
112514                         break;
112515                     case "HOURS":
112516                         str += "TRIGGER:-P0DT" + before.length + "H0M0S" + "\r\n";
112517                         break;
112518                     case "MINS":
112519                         str += "TRIGGER:-P0DT0H" + before.length + "M0S" + "\r\n";
112520                         break;
112521                     case "SECS":
112522                         str += "TRIGGER:-P0DT0H0M" + before.length + "S" + "\r\n";
112523                         break;
112524                     }
112525                 }
112526                 str += "END:VALARM\r\n";
112527             }
112528         }
112529         if (tizen1_utils.isValidArray(this.categories)) {
112530             str += "CATEGORIES:";
112531             for (i = 0; i < this.categories.length; i++) {
112532                 str += this.categories[i] + ",";
112533             }
112534             str = str.slice(0, -1);
112535             str += "\r\n";
112536         }
112537         if (tizen1_utils.isValidArray(this.attendees)) {
112538             for (i = 0; i < this.attendees.length; i++) {
112539                 //TODO: basic implementation
112540                 str += "ATTENDEE:mailto:" + this.attendees[i].uri + "\r\n";
112541             }
112542         }
112543
112544         if ((dateStart !== "") && (dateEnd !== "")) {
112545             str += "#AVAILABILITY#:" + dateStart + "/" + dateEnd + "\r\n";
112546         }
112547
112548         str += "#ENDDATE##RECURRENCERULE#";
112549         str += "#DUEDATE##COMPLETEDDATE##PROGRESS#";
112550         str += "END:#TYPE#\r\n" + end;
112551
112552         return str;
112553     }
112554
112555     calendarItem.description = "";
112556     calendarItem.summary     = "";
112557     calendarItem.isAllDay    = false;
112558     calendarItem.startDate   = null;
112559     calendarItem.duration    = null;
112560     calendarItem.location    = "";
112561     calendarItem.geolocation = null;
112562     calendarItem.organizer   = "";
112563     calendarItem.visibility  = "PUBLIC";
112564     calendarItem.status      = "TENTATIVE";
112565     calendarItem.priority    = "LOW";
112566     calendarItem.alarms      = [];
112567     calendarItem.categories  = [];
112568     calendarItem.attendees   = [];
112569
112570     if (itemInitDict) {
112571         for (attr in itemInitDict) {
112572             if (!(attr in typedef.CalendarItemInit))
112573                 continue;
112574
112575             switch (attr) {
112576             case "alarms":
112577                 calendarItem.alarms = t.CalendarAlarm(itemInitDict.alarms,
112578                         "[]+");
112579                 break;
112580
112581             case "categories":
112582                 calendarItem.categories = t.DOMString(itemInitDict.categories,
112583                         "[]+");
112584                 break;
112585
112586             case "attendees":
112587                 calendarItem.attendees = t.CalendarAttendee(
112588                         itemInitDict.attendees, "[]+");
112589                 break;
112590
112591             default:
112592                 calendarItem[attr] = itemInitDict[attr];
112593                 break;
112594             }
112595         }
112596     }
112597
112598     this.__defineGetter__("id", function () {
112599         return null;
112600     });
112601
112602     this.__defineGetter__("calendarId", function () {
112603         return null;
112604     });
112605
112606     this.__defineGetter__("lastModificationDate", function () {
112607         return null;
112608     });
112609
112610     this.__defineGetter__("description", function () {
112611         return calendarItem.description;
112612     });
112613     this.__defineSetter__("description", function (val) {
112614         try {
112615             calendarItem.description = t.DOMString(val, "?");
112616         } catch (e) {
112617         }
112618     });
112619
112620     this.__defineGetter__("summary", function () {
112621         return calendarItem.summary;
112622     });
112623     this.__defineSetter__("summary", function (val) {
112624         try {
112625             calendarItem.summary = t.DOMString(val, "?");
112626         } catch (e) {
112627         }
112628     });
112629
112630     this.__defineGetter__("isAllDay", function () {
112631         return calendarItem.isAllDay;
112632     });
112633     this.__defineSetter__("isAllDay", function (val) {
112634         try {
112635             calendarItem.isAllDay = t.boolean(val);
112636         } catch (e) {
112637         }
112638     });
112639
112640     this.__defineGetter__("startDate", function () {
112641         return calendarItem.startDate;
112642     });
112643     this.__defineSetter__("startDate", function (val) {
112644         try {
112645             calendarItem.startDate = t.TZDate(val, "?");
112646         } catch (e) {
112647         }
112648     });
112649
112650     this.__defineGetter__("duration", function () {
112651         return calendarItem.duration;
112652     });
112653     this.__defineSetter__("duration", function (val) {
112654         try {
112655             calendarItem.duration = t.TimeDuration(val, "?");
112656         } catch (e) {
112657         }
112658     });
112659
112660     this.__defineGetter__("location", function () {
112661         return calendarItem.location;
112662     });
112663     this.__defineSetter__("location", function (val) {
112664         try {
112665             calendarItem.location = t.DOMString(val, "?");
112666         } catch (e) {
112667         }
112668     });
112669
112670     this.__defineGetter__("geolocation", function () {
112671         return calendarItem.geolocation;
112672     });
112673     this.__defineSetter__("geolocation", function (val) {
112674         try {
112675             calendarItem.geolocation = t.SimpleCoordinates(val, "?");
112676         } catch (e) {
112677         }
112678     });
112679
112680     this.__defineGetter__("organizer", function () {
112681         return calendarItem.organizer;
112682     });
112683     this.__defineSetter__("organizer", function (val) {
112684         try {
112685             calendarItem.organizer = t.DOMString(val, "?");
112686         } catch (e) {
112687         }
112688     });
112689
112690     this.__defineGetter__("visibility", function () {
112691         return calendarItem.visibility;
112692     });
112693     this.__defineSetter__("visibility", function (val) {
112694         try {
112695             calendarItem.visibility = t.CalendarItemVisibility(val);
112696         } catch (e) {
112697         }
112698     });
112699
112700     this.__defineGetter__("status", function () {
112701         return calendarItem.status;
112702     });
112703     this.__defineSetter__("status", function (val) {
112704         try {
112705             calendarItem.status = t.CalendarItemStatus(val);
112706         } catch (e) {
112707         }
112708     });
112709
112710     this.__defineGetter__("priority", function () {
112711         return calendarItem.priority;
112712     });
112713     this.__defineSetter__("priority", function (val) {
112714         try {
112715             calendarItem.priority = t.CalendarItemPriority(val);
112716         } catch (e) {
112717         }
112718     });
112719
112720     this.__defineGetter__("alarms", function () {
112721         return calendarItem.alarms;
112722     });
112723     this.__defineSetter__("alarms", function (val) {
112724         try {
112725             calendarItem.alarms = t.CalendarAlarm(val, "[]");
112726         } catch (e) {
112727         }
112728     });
112729
112730     this.__defineGetter__("categories", function () {
112731         return calendarItem.categories;
112732     });
112733     this.__defineSetter__("categories", function (val) {
112734         try {
112735             calendarItem.categories = t.DOMString(val, "[]");
112736         } catch (e) {
112737         }
112738     });
112739
112740     this.__defineGetter__("attendees", function () {
112741         return calendarItem.attendees;
112742     });
112743     this.__defineSetter__("attendees", function (val) {
112744         try {
112745             calendarItem.attendees = t.CalendarAttendee(val, "[]");
112746         } catch (e) {
112747         }
112748     });
112749
112750     this.convertToString = convertToString;
112751 };
112752
112753 module.exports = CalendarItem;
112754
112755 });
112756 define('ripple/platform/tizen/2.0/BluetoothClassDeviceMinor', function (require, exports, module) {
112757 /*
112758  *  Copyright 2013 Intel Corporation.
112759  *
112760  * Licensed under the Apache License, Version 2.0 (the "License");
112761  * you may not use this file except in compliance with the License.
112762  * You may obtain a copy of the License at
112763  *
112764  * http://www.apache.org/licenses/LICENSE-2.0
112765  *
112766  * Unless required by applicable law or agreed to in writing, software
112767  * distributed under the License is distributed on an "AS IS" BASIS,
112768  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
112769  * See the License for the specific language governing permissions and
112770  * limitations under the License.
112771  */
112772
112773 var BluetoothClassDeviceMinor = function () {
112774     // COMPUTER
112775     this.__defineGetter__("COMPUTER_UNCATEGORIZED", function () {
112776         return 0x00;
112777     });
112778
112779     this.__defineGetter__("COMPUTER_DESKTOP", function () {
112780         return 0x01;
112781     });
112782
112783     this.__defineGetter__("COMPUTER_SERVER", function () {
112784         return 0x02;
112785     });
112786
112787     this.__defineGetter__("COMPUTER_LAPTOP", function () {
112788         return 0x03;
112789     });
112790
112791     this.__defineGetter__("COMPUTER_HANDHELD_PC_OR_PDA", function () {
112792         return 0x04;
112793     });
112794
112795     this.__defineGetter__("COMPUTER_PALM_PC_OR_PDA", function () {
112796         return 0x05;
112797     });
112798
112799     this.__defineGetter__("COMPUTER_WEARABLE", function () {
112800         return 0x06;
112801     });
112802
112803     // PHONE
112804     this.__defineGetter__("PHONE_UNCATEGORIZED", function () {
112805         return 0x00;
112806     });
112807
112808     this.__defineGetter__("PHONE_CELLULAR", function () {
112809         return 0x01;
112810     });
112811
112812     this.__defineGetter__("PHONE_CORDLESS", function () {
112813         return 0x02;
112814     });
112815
112816     this.__defineGetter__("PHONE_SMARTPHONE", function () {
112817         return 0x03;
112818     });
112819
112820     this.__defineGetter__("PHONE_MODEM_OR_GATEWAY", function () {
112821         return 0x04;
112822     });
112823
112824     this.__defineGetter__("PHONE_ISDN", function () {
112825         return 0x05;
112826     });
112827
112828     // AUDIO_VIDEO
112829     this.__defineGetter__("AV_UNRECOGNIZED", function () {
112830         return 0x00;
112831     });
112832
112833     this.__defineGetter__("AV_WEARABLE_HEADSET", function () {
112834         return 0x01;
112835     });
112836
112837     this.__defineGetter__("AV_HANDSFREE", function () {
112838         return 0x02;
112839     });
112840
112841     this.__defineGetter__("AV_MICROPHONE", function () {
112842         return 0x04;
112843     });
112844
112845     this.__defineGetter__("AV_LOUDSPEAKER", function () {
112846         return 0x05;
112847     });
112848
112849     this.__defineGetter__("AV_HEADPHONES", function () {
112850         return 0x06;
112851     });
112852
112853     this.__defineGetter__("AV_PORTABLE_AUDIO", function () {
112854         return 0x07;
112855     });
112856
112857     this.__defineGetter__("AV_CAR_AUDIO", function () {
112858         return 0x08;
112859     });
112860
112861     this.__defineGetter__("AV_SETTOP_BOX", function () {
112862         return 0x09;
112863     });
112864
112865     this.__defineGetter__("AV_HIFI", function () {
112866         return 0x0a;
112867     });
112868
112869     this.__defineGetter__("AV_VCR", function () {
112870         return 0x0b;
112871     });
112872
112873     this.__defineGetter__("AV_VIDEO_CAMERA", function () {
112874         return 0x0c;
112875     });
112876
112877     this.__defineGetter__("AV_CAMCORDER", function () {
112878         return 0x0d;
112879     });
112880
112881     this.__defineGetter__("AV_MONITOR", function () {
112882         return 0x0e;
112883     });
112884
112885     this.__defineGetter__("AV_DISPLAY_AND_LOUDSPEAKER", function () {
112886         return 0x0f;
112887     });
112888
112889     this.__defineGetter__("AV_VIDEO_CONFERENCING", function () {
112890         return 0x10;
112891     });
112892
112893     this.__defineGetter__("AV_GAMING_TOY", function () {
112894         return 0x12;
112895     });
112896
112897     // PERIPHERAL
112898     this.__defineGetter__("PERIPHERAL_UNCATEGORIZED", function () {
112899         return 0;
112900     });
112901
112902     this.__defineGetter__("PERIPHERAL_KEYBOARD", function () {
112903         return 0x10;
112904     });
112905
112906     this.__defineGetter__("PERIPHERAL_POINTING_DEVICE", function () {
112907         return 0x20;
112908     });
112909
112910     this.__defineGetter__("PERIPHERAL_KEYBOARD_AND_POINTING_DEVICE", function () {
112911         return 0x30;
112912     });
112913
112914     this.__defineGetter__("PERIPHERAL_JOYSTICK", function () {
112915         return 0x01;
112916     });
112917
112918     this.__defineGetter__("PERIPHERAL_GAMEPAD", function () {
112919         return 0x02;
112920     });
112921
112922     this.__defineGetter__("PERIPHERAL_REMOTE_CONTROL", function () {
112923         return 0x03;
112924     });
112925
112926     this.__defineGetter__("PERIPHERAL_SENSING_DEVICE", function () {
112927         return 0x04;
112928     });
112929
112930     this.__defineGetter__("PERIPHERAL_DEGITIZER_TABLET", function () {
112931         return 0x05;
112932     });
112933
112934     this.__defineGetter__("PERIPHERAL_CARD_READER", function () {
112935         return 0x06;
112936     });
112937
112938     this.__defineGetter__("PERIPHERAL_DIGITAL_PEN", function () {
112939         return 0x07;
112940     });
112941
112942     this.__defineGetter__("PERIPHERAL_HANDHELD_SCANNER", function () {
112943         return 0x08;
112944     });
112945
112946     this.__defineGetter__("PERIPHERAL_HANDHELD_INPUT_DEVICE", function () {
112947         return 0x09;
112948     });
112949
112950     // IMAGING
112951     this.__defineGetter__("IMAGING_UNCATEGORIZED", function () {
112952         return 0x00;
112953     });
112954
112955     this.__defineGetter__("IMAGING_DISPLAY", function () {
112956         return 0x04;
112957     });
112958
112959     this.__defineGetter__("IMAGING_CAMERA", function () {
112960         return 0x08;
112961     });
112962
112963     this.__defineGetter__("IMAGING_SCANNER", function () {
112964         return 0x10;
112965     });
112966
112967     this.__defineGetter__("IMAGING_PRINTER", function () {
112968         return 0x20;
112969     });
112970
112971     // WEARABLE
112972     this.__defineGetter__("WEARABLE_WRITST_WATCH", function () {
112973         return 0x01;
112974     });
112975
112976     this.__defineGetter__("WEARABLE_PAGER", function () {
112977         return 0x02;
112978     });
112979
112980     this.__defineGetter__("WEARABLE_JACKET", function () {
112981         return 0x03;
112982     });
112983
112984     this.__defineGetter__("WEARABLE_HELMET", function () {
112985         return 0x04;
112986     });
112987
112988     this.__defineGetter__("WEARABLE_GLASSES", function () {
112989         return 0x05;
112990     });
112991
112992     // TOY
112993     this.__defineGetter__("TOY_ROBOT", function () {
112994         return 0x01;
112995     });
112996
112997     this.__defineGetter__("TOY_VEHICLE", function () {
112998         return 0x02;
112999     });
113000
113001     this.__defineGetter__("TOY_DOLL", function () {
113002         return 0x03;
113003     });
113004
113005     this.__defineGetter__("TOY_CONTROLLER", function () {
113006         return 0x04;
113007     });
113008
113009     this.__defineGetter__("TOY_GAME", function () {
113010         return 0x05;
113011     });
113012
113013     // HEALTH
113014     this.__defineGetter__("HEALTH_UNDEFINED", function () {
113015         return 0x00;
113016     });
113017
113018     this.__defineGetter__("HEALTH_BLOOD_PRESSURE_MONITOR", function () {
113019         return 0x01;
113020     });
113021
113022     this.__defineGetter__("HEALTH_THERMOMETER", function () {
113023         return 0x02;
113024     });
113025
113026     this.__defineGetter__("HEALTH_WEIGHING_SCALE", function () {
113027         return 0x03;
113028     });
113029
113030     this.__defineGetter__("HEALTH_GLUCOSE_METER", function () {
113031         return 0x04;
113032     });
113033
113034     this.__defineGetter__("HEALTH_PULSE_OXIMETER", function () {
113035         return 0x05;
113036     });
113037
113038     this.__defineGetter__("HEALTH_PULSE_RATE_MONITOR", function () {
113039         return 0x06;
113040     });
113041
113042     this.__defineGetter__("HEALTH_DATA_DISPLAY", function () {
113043         return 0x07;
113044     });
113045
113046     this.__defineGetter__("HEALTH_STEP_COUNTER", function () {
113047         return 0x08;
113048     });
113049
113050     this.__defineGetter__("HEALTH_BODY_COMPOSITION_ANALYZER", function () {
113051         return 0x09;
113052     });
113053
113054     this.__defineGetter__("HEALTH_PEAK_FLOW_MONITOR", function () {
113055         return 0x0a;
113056     });
113057
113058     this.__defineGetter__("HEALTH_MEDICATION_MONITOR", function () {
113059         return 0x0b;
113060     });
113061
113062     this.__defineGetter__("HEALTH_KNEE_PROSTHESIS", function () {
113063         return 0x0c;
113064     });
113065
113066     this.__defineGetter__("HEALTH_ANKLE_PROSTHESIS", function () {
113067         return 0x0d;
113068     });
113069 };
113070
113071 module.exports = BluetoothClassDeviceMinor;
113072
113073 });
113074 define('ripple/platform/tizen/2.0/geocoder', function (require, exports, module) {
113075 /*
113076  *  Copyright 2012 Intel Corporation.
113077  *
113078  * Licensed under the Apache License, Version 2.0 (the "License");
113079  * you may not use this file except in compliance with the License.
113080  * You may obtain a copy of the License at
113081  *
113082  * http://www.apache.org/licenses/LICENSE-2.0
113083  *
113084  * Unless required by applicable law or agreed to in writing, software
113085  * distributed under the License is distributed on an "AS IS" BASIS,
113086  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113087  * See the License for the specific language governing permissions and
113088  * limitations under the License.
113089  */
113090
113091 var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
113092     ProviderLocal = require('ripple/platform/tizen/2.0/geoBackend_local'),
113093     ProviderNominatim = require('ripple/platform/tizen/2.0/geoBackend_nominatim'), // Nominatim geocode service
113094     _getProviders,
113095     _providers,
113096     _self;
113097
113098 function _initialize() {
113099     _providers = [new ProviderNominatim({name : "Nominatim", connectivity : "ONLINE"})
113100                   /* ,new ProviderLocal({name : "Tizen Database", connectivity : "OFFLINE"}) */];
113101 }
113102
113103 _initialize();
113104
113105 _self = {
113106     getDefaultProvider : function () {
113107         return _providers[0];
113108     },
113109     getProviders : function () {
113110         return _providers;
113111     }
113112 };
113113
113114 module.exports = _self;
113115
113116 });
113117 define('ripple/platform/tizen/2.0/timezone_info', function (require, exports, module) {
113118 /*
113119  *  Copyright 2012 Intel Corporation.
113120  *
113121  * Licensed under the Apache License, Version 2.0 (the "License");
113122  * you may not use this file except in compliance with the License.
113123  * You may obtain a copy of the License at
113124  *
113125  * http://www.apache.org/licenses/LICENSE-2.0
113126  *
113127  * Unless required by applicable law or agreed to in writing, software
113128  * distributed under the License is distributed on an "AS IS" BASIS,
113129  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113130  * See the License for the specific language governing permissions and
113131  * limitations under the License.
113132  */
113133
113134 var _timezone_data = {
113135     "UTC": {diff: 0, abbr: "UTC"},
113136     "Africa/Cairo": {diff: 2, abbr: "EET"},
113137     "Africa/Casablanca": {diff: 0, abbr: "UTC"},
113138     "Africa/Dakar": {diff: 0, abbr: "UTC"},
113139     "Africa/Freetown": {diff: 0, abbr: "UTC"},
113140     "Africa/Johannesburg": {diff: 2, abbr: "SAST"},
113141     "Africa/Luanda": {diff: 1, abbr: "WAT"},
113142     "America/Anchorage": {diff: -9, abbr: "AKDT"},
113143     "America/Antigua": {diff: -4, abbr: "AST"},
113144     "America/Aruba": {diff: -4, abbr: "AST"},
113145     "America/Barbados": {diff: -4, abbr: "AST"},
113146     "America/Belize": {diff: -6, abbr: "CST"},
113147     "America/Bogota": {diff: -5, abbr: "COT"},
113148     "America/Buenos_Aires": {diff: -3, abbr: "ART"},
113149     "America/Cancun": {diff: -6, abbr: "CDT"},
113150     "America/Cayenne": {diff: -3, abbr: "GFT"},
113151     "America/Cayman": {diff: -5, abbr: "EST"},
113152     "America/Chicago": {diff: -6, abbr: "CST"},
113153     "America/Chihuahua": {diff: -7, abbr: "MST"},
113154     "America/Costa_Rica": {diff: -6, abbr: "CST"},
113155     "America/Denver": {diff: -7, abbr: "MST"},
113156     "America/Detroit": {diff: -5, abbr: "EST"},
113157     "America/Dominica": {diff: -4, abbr: "AST"},
113158     "America/Edmonton": {diff: -7, abbr: "MST"},
113159     "America/El_Salvador": {diff: -6, abbr: "CST"},
113160     "America/Guatemala": {diff: -6, abbr: "CST"},
113161     "America/Havana": {diff: -5, abbr: "CST"},
113162     "America/Indianapolis": {diff: -5, abbr: "EST"},
113163     "America/Jamaica": {diff: -5, abbr: "EST"},
113164     "America/Lima": {diff: -5, abbr: "PET"},
113165     "America/Los_Angeles": {diff: -8, abbr: "PST"},
113166     "America/Louisville": {diff: -5, abbr: "EST"},
113167     "America/Mexico_City": {diff: -6, abbr: "CST"},
113168     "America/Montevideo": {diff: -2, abbr: "UYST"},
113169     "America/Montreal": {diff: -5, abbr: "EST"},
113170     "America/New_York": {diff: -5, abbr: "EST"},
113171     "America/Panama": {diff: -5, abbr: "EST"},
113172     "America/Phoenix": {diff: -7, abbr: "MST"},
113173     "America/Puerto_Rico": {diff: -4, abbr: "AST"},
113174     "America/Santiago": {diff: -3, abbr: "CLST"},
113175     "America/Santo_Domingo": {diff: -4, abbr: "AST"},
113176     "America/Sao_Paulo": {diff: -4, abbr: "AST"},
113177     "America/Tijuana": {diff: -8, abbr: "PST"},
113178     "America/Vancouver": {diff: -8, abbr: "PST"},
113179     "America/Winnipeg": {diff: -6, abbr: "CST"},
113180     "Antarctica/South_Pole": {diff: 13, abbr: "NZDT"},
113181     "Arctic/Longyearbyen": {diff: 13, abbr: "CET"},
113182     "Asia/Amman": {diff: 2, abbr: "EET"},
113183     "Asia/Baghdad": {diff: 3, abbr: "AST"},
113184     "Asia/Bahrain": {diff: 3, abbr: "AST"},
113185     "Asia/Bangkok": {diff: 7, abbr: "ICT"},
113186     "Asia/Beirut": {diff: 2, abbr: "EET"},
113187     "Asia/Chungking": {diff: 8, abbr: "CST"},
113188     "Asia/Dubai": {diff: 4, abbr: "GST", desc:"GMT+0400 United Arab Emirates Time"},
113189     "Asia/Harbin": {diff: 8, abbr: "CST"},
113190     "Asia/Ho_Chi_Minh": {diff: 7, abbr: "IST"},
113191     "Asia/Hong_Kong": {diff: 8, abbr: "HKT"},
113192     "Asia/Istanbul": {diff: 2, abbr: "EET"},
113193     "Asia/Jakarta": {diff: 7, abbr: "WIT"},
113194     "Asia/Jerusalem": {diff: 2, abbr: "IST"},
113195     "Asia/Karachi": {diff: 5, abbr: "PKT"},
113196     "Asia/Kuala_Lumpur": {diff: 8, abbr: "MYT"},
113197     "Asia/Kuwait": {diff: 3, abbr: "AST"},
113198     "Asia/Macao": {diff: 8, abbr: "CST"},
113199     "Asia/Manila": {diff: 8, abbr: "PHT"},
113200     "Asia/Pyongyang": {diff: 9, abbr: "KST"},
113201     "Asia/Qatar": {diff: 3, abbr: "AST"},
113202     "Asia/Saigon": {diff: 7, abbr: "ICT"},
113203     "Asia/Seoul": {diff: 9, abbr: "KST", desc:"GMT+0900 South Korea Time"},
113204     "Asia/Shanghai": {diff: 8, abbr: "CST"},
113205     "Asia/Singapore": {diff: 8, abbr: "SGT"},
113206     "Asia/Taipei": {diff: 8, abbr: "CST"},
113207     "Asia/Tel_Aviv": {diff: 2, abbr: "IST"},
113208     "Asia/Tokyo": {diff: 9, abbr: "JST"},
113209     "Asia/Urumqi": {diff: 8, abbr: "CST"},
113210     "Atlantic/Bermuda": {diff: -4, abbr: "AST"},
113211     "Atlantic/Canary": {diff: 0, abbr: "WET"},
113212     "Atlantic/Cape_Verde": {diff: -1, abbr: "CVT"},
113213     "Atlantic/Reykjavik": {diff: 0, abbr: "GMT"},
113214     "Australia/Brisbane": {diff: 10, abbr: "EST"},
113215     "Australia/Canberra": {diff: 11, abbr: "EST"},
113216     "Australia/Darwin": {diff: 9.5, abbr: "CST"},
113217     "Australia/Melbourne": {diff: 11, abbr: "EST"},
113218     "Australia/North": {diff: 9.5, abbr: "CST"},
113219     "Australia/Perth": {diff: 8, abbr: "WST"},
113220     "Australia/Queensland": {diff: 10, abbr: "EST"},
113221     "Australia/South": {diff: 10.5, abbr: "CST"},
113222     "Australia/Sydney": {diff: 11, abbr: "EST"},
113223     "Australia/West": {diff: 8, abbr: "WST"},
113224     "Australia/Victoria": {diff: 11, abbr: "EST"},
113225     "Europe/Amsterdam": {diff: 1, abbr: "CET"},
113226     "Europe/Athens": {diff: 2, abbr: "EET"},
113227     "Europe/Belgrade": {diff: 1, abbr: "CET"},
113228     "Europe/Berlin": {diff: 1, abbr: "CET"},
113229     "Europe/Brussels": {diff: 1, abbr: "CET"},
113230     "Europe/Bucharest": {diff: 2, abbr: "EET"},
113231     "Europe/Budapest": {diff: 1, abbr: "CET"},
113232     "Europe/Copenhagen": {diff: 1, abbr: "CET"},
113233     "Europe/Dublin": {diff: 0, abbr: "GMT"},
113234     "Europe/Helsinki": {diff: 2, abbr: "EET"},
113235     "Europe/Istanbul": {diff: 2, abbr: "EET"},
113236     "Europe/Kaliningrad": {diff: 3, abbr: "FET"},
113237     "Europe/Kiev": {diff: 2, abbr: "EET"},
113238     "Europe/Lisbon": {diff: 0, abbr: "WET"},
113239     "Europe/London": {diff: 0, abbr: "GMT"},
113240     "Europe/Luxembourg": {diff: 1, abbr: "CET"},
113241     "Europe/Madrid": {diff: 1, abbr: "CET"},
113242     "Europe/Minsk": {diff: 3, abbr: "FET"},
113243     "Europe/Monaco": {diff: 1, abbr: "CET"},
113244     "Europe/Moscow": {diff: 4, abbr: "MSK"},
113245     "Europe/Oslo": {diff: 1, abbr: "CET"},
113246     "Europe/Paris": {diff: 1, abbr: "CET"},
113247     "Europe/Prague": {diff: 1, abbr: "CET"},
113248     "Europe/Rome": {diff: 1, abbr: "CET"},
113249     "Europe/San_Marino": {diff: 1, abbr: "CET"},
113250     "Europe/Sarajevo": {diff: 1, abbr: "CET"},
113251     "Europe/Stockholm": {diff: 1, abbr: "CET"},
113252     "Europe/Vatican": {diff: 1, abbr: "CET"},
113253     "Europe/Vienna": {diff: 1, abbr: "CET"},
113254     "Europe/Warsaw": {diff: 1, abbr: "CET"},
113255     "Europe/Zurich": {diff: 2, abbr: "EET"},
113256     "Indian/Christmas": {diff: 7, abbr: "CXT"},
113257     "Indian/Maldives": {diff: 5, abbr: "MVT"},
113258     "Pacific/Auckland": {diff: 12, abbr: "NZST"},
113259     "Pacific/Easter": {diff: -6, abbr: "EAST"},
113260     "Pacific/Fiji": {diff: 12, abbr: "FJT"},
113261     "Pacific/Guam": {diff: 10, abbr: "ChST"},
113262     "Pacific/Honolulu": {diff: -10, abbr: "HST"},
113263     "Pacific/Midway": {diff: -11, abbr: "SST"},
113264     "Pacific/Saipan": {diff: 10, abbr: "ChST"},
113265     "Pacific/Samoa": {diff: -11, abbr: "SST"},
113266     "Pacific/Tahiti": {diff: -10, abbr: "TAHT"},
113267     "UCT": {diff: 0, abbr: "UCT"},
113268     "SST": {diff: 0, abbr: "SST"},
113269     "GMT": {diff: 0, abbr: "GMT"},
113270     "Greenwich": {diff: 0, abbr: "GMT"},
113271     "US/Alaska": {diff: -9, abbr: "AKST"},
113272     "US/Eastern": {diff: -5, abbr: "EST"},
113273     "US/Central": {diff: -6, abbr: "CST"},
113274     "US/Mountain": {diff: -7, abbr: "MST"},
113275     "US/Pacific": {diff: -8, abbr: "PST"},
113276     "Universal": {diff: 0, abbr: "UTC"},
113277     "Zulu": {diff: 0, abbr: "UTC"},
113278     "Etc/GMT": {diff: 0, abbr: "Etc/GMT"},
113279     "Etc/GMT+0": {diff: 0, abbr: "Etc/GMT+0"},
113280     "Etc/GMT+1": {diff: -1, abbr: "Etc/GMT+1"},
113281     "Etc/GMT+10": {diff: -10, abbr: "Etc/GMT+10"},
113282     "Etc/GMT+11": {diff: -11, abbr: "Etc/GMT+11"},
113283     "Etc/GMT+12": {diff: -12, abbr: "Etc/GMT+12"},
113284     "Etc/GMT+2": {diff: -2, abbr: "Etc/GMT+2"},
113285     "Etc/GMT+3": {diff: -3, abbr: "Etc/GMT+3"},
113286     "Etc/GMT+4": {diff: -4, abbr: "Etc/GMT+4"},
113287     "Etc/GMT+5": {diff: -5, abbr: "Etc/GMT+5"},
113288     "Etc/GMT+6": {diff: -6, abbr: "Etc/GMT+6"},
113289     "Etc/GMT+7": {diff: -7, abbr: "Etc/GMT+7"},
113290     "Etc/GMT+8": {diff: -8, abbr: "Etc/GMT+8"},
113291     "Etc/GMT+9": {diff: -9, abbr: "Etc/GMT+9"},
113292     "Etc/GMT-0": {diff: 0, abbr: "Etc/GMT-0"},
113293     "Etc/GMT-1": {diff: 1, abbr: "Etc/GMT-1"},
113294     "Etc/GMT-10": {diff: 10, abbr: "Etc/GMT-10"},
113295     "Etc/GMT-11": {diff: 11, abbr: "Etc/GMT-11"},
113296     "Etc/GMT-12": {diff: 12, abbr: "Etc/GMT-12"},
113297     "Etc/GMT-13": {diff: 13, abbr: "Etc/GMT-13"},
113298     "Etc/GMT-14": {diff: 14, abbr: "Etc/GMT-14"},
113299     "Etc/GMT-2": {diff: 2, abbr: "Etc/GMT-2"},
113300     "Etc/GMT-3": {diff: 3, abbr: "Etc/GMT-3"},
113301     "Etc/GMT-4": {diff: 4, abbr: "Etc/GMT-4"},
113302     "Etc/GMT-5": {diff: 5, abbr: "Etc/GMT-5"},
113303     "Etc/GMT-6": {diff: 6, abbr: "Etc/GMT-6"},
113304     "Etc/GMT-7": {diff: 7, abbr: "Etc/GMT-7"},
113305     "Etc/GMT-8": {diff: 8, abbr: "Etc/GMT-8"},
113306     "Etc/GMT-9": {diff: 9, abbr: "Etc/GMT-9"},
113307     "Etc/GMT0": {diff: 0, abbr: "Etc/GMT0"},
113308     "Etc/Greenwich": {diff: 0, abbr: "GMT"}
113309 };
113310
113311 module.exports = {
113312     getAllTimezone: function () {
113313         var i, ret = [];
113314         for (i in _timezone_data)
113315             ret.push(i);
113316         return ret;
113317     },
113318     getTimezoneDiff: function (zone) {
113319         return _timezone_data[zone].diff;
113320     },
113321     getTimezoneAbbr: function (zone) {
113322         return _timezone_data[zone].abbr;
113323     },
113324     getTimezoneDesc: function (zone) {
113325         if (_timezone_data[zone].desc) {
113326             return _timezone_data[zone].desc;
113327         } else {
113328             return null;
113329         }
113330     },
113331     isValidTimezone: function (zone) {
113332         return (_timezone_data[zone] === undefined) ? false : true;
113333     }
113334 };
113335
113336
113337 });
113338 define('ripple/platform/tizen/2.0/lbs_utils', function (require, exports, module) {
113339 /*
113340  *  Copyright 2012 Intel Corporation.
113341  *
113342  * Licensed under the Apache License, Version 2.0 (the "License");
113343  * you may not use this file except in compliance with the License.
113344  * You may obtain a copy of the License at
113345  *
113346  * http://www.apache.org/licenses/LICENSE-2.0
113347  *
113348  * Unless required by applicable law or agreed to in writing, software
113349  * distributed under the License is distributed on an "AS IS" BASIS,
113350  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113351  * See the License for the specific language governing permissions and
113352  * limitations under the License.
113353  */
113354
113355 var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
113356     _self;
113357
113358 function CoordinateProperties(prop) {
113359     var _self;
113360     _self = {
113361         latitude : prop.latitude || 0,
113362         longitude : prop.longitude || 0,
113363         altitude : prop.altitude || 0,
113364         accuracy : prop.accuracy || 0,
113365         altitudeAccuracy : prop.altitudeAccuracy || 0,
113366         heading : prop.heading || 0,
113367         speed : prop.speed || 0
113368     };
113369     return _self;
113370 }
113371
113372 function _checkAddressProperties(p, dst) {
113373     if (p.country !== null && p.country !== undefined)
113374         dst.country = String(p.country);
113375     if (p.region !== null && p.region !== undefined)
113376         dst.region = String(p.region);
113377     if (p.county !== null && p.county !== undefined)
113378         dst.county = String(p.county);
113379     if (p.city !== null && p.city !== undefined)
113380         dst.city = String(p.city);
113381     if (p.street !== null && p.street !== undefined)
113382         dst.street = String(p.street);
113383     if (p.streetNumber !== null && p.streetNumber !== undefined)
113384         dst.streetNumber = String(p.streetNumber);
113385     if (p.premises !== null && p.premises !== undefined)
113386         dst.premises = String(p.premises);
113387     if (p.additionalInformation !== null &&
113388         p.additionalInformation !== undefined)
113389         dst.additionalInformation = String(p.additionalInformation);
113390     if (p.postalCode !== null && p.postalCode !== undefined)
113391         dst.postalCode = String(p.postalCode);
113392 }
113393
113394 function AddressProperties(prop) {
113395     var _self;
113396     _self = {
113397         country : null,
113398         region : null,
113399         county : null,
113400         city : null,
113401         street : null,
113402         streetNumber : null,
113403         premises : null,
113404         additionalInformation : null,
113405         postalCode : null
113406     };
113407     if (prop) {
113408         if (_checkAddressProperties(prop, _self) === false)
113409             return undefined;
113410     }
113411     return _self;
113412 }
113413
113414 _self = {
113415     LocationServiceProvider : function (prop) {
113416         var _self;
113417         _self = {
113418             name : "",
113419             metaData : Object,
113420             attribution : "",
113421             supportedOptions : [],
113422             setOptions : function (options, successCB, errorCB) {},
113423             connectivity : "" // "ONLINE" "OFFLINE" "HYBRID"
113424         };
113425
113426         if (prop.name !== null && prop.name !== undefined)
113427             _self.name = String(prop.name);
113428         if (prop.metaData !== null && prop.metaData !== undefined)
113429             _self.metaData = prop.metaData;
113430
113431         if (prop.attribution !== null && prop.attribution !== undefined)
113432             _self.attribution = String(prop.attribution);
113433
113434         if (prop.supportedOptions !== null && prop.supportedOptions !== undefined)
113435             _self.supportedOptions = [prop.supportedOptions];
113436
113437         if (prop.setOptions !== null && prop.setOptions !== undefined)
113438             _self.setOptions = prop.setOptions;
113439
113440         if (prop.connectivity !== null && prop.connectivity !== undefined)
113441             _self.connectivity = String(prop.connectivity);
113442
113443         return _self;
113444     },
113445
113446     GeoCoordinates : function (prop) {
113447         var _self = new CoordinateProperties(prop);
113448         if (tizen1_utils.isEmptyObject(_self)) {
113449             return undefined;
113450         }
113451
113452         return _self;
113453     },
113454
113455     StructuredAddress : function (prop) {
113456         var _self;
113457         _self = new AddressProperties(prop);
113458         if (tizen1_utils.isEmptyObject(_self)) {
113459             return undefined;
113460         }
113461
113462         return _self;
113463     }
113464 };
113465
113466 module.exports = _self;
113467
113468 });
113469 define('ripple/platform/tizen/2.0/AccountBase', function (require, exports, module) {
113470 /*
113471  *  Copyright 2012 Intel Corporation.
113472  *
113473  * Licensed under the Apache License, Version 2.0 (the "License");
113474  * you may not use this file except in compliance with the License.
113475  * You may obtain a copy of the License at
113476  *
113477  * http://www.apache.org/licenses/LICENSE-2.0
113478  *
113479  * Unless required by applicable law or agreed to in writing, software
113480  * distributed under the License is distributed on an "AS IS" BASIS,
113481  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113482  * See the License for the specific language governing permissions and
113483  * limitations under the License.
113484  */
113485
113486 module.exports = function (appId, userName, displayName, service) {
113487     var _self,
113488         _id = Math.uuid(null, 16);
113489
113490     _self = {
113491         appId : appId || "",
113492         userName : userName || "",
113493         displayName : displayName || "",
113494         service : service || {}
113495     };
113496
113497     _self.__defineGetter__("id", function () {
113498         return _id;
113499     });
113500
113501     return _self;
113502 };
113503
113504 });
113505 define('ripple/platform/tizen/2.0/AlarmAbsolute', function (require, exports, module) {
113506 /*
113507  *  Copyright 2012 Intel Corporation.
113508  *
113509  * Licensed under the Apache License, Version 2.0 (the "License");
113510  * you may not use this file except in compliance with the License.
113511  * You may obtain a copy of the License at
113512  *
113513  * http://www.apache.org/licenses/LICENSE-2.0
113514  *
113515  * Unless required by applicable law or agreed to in writing, software
113516  * distributed under the License is distributed on an "AS IS" BASIS,
113517  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113518  * See the License for the specific language governing permissions and
113519  * limitations under the License.
113520  */
113521
113522 var AlarmBase = require('ripple/platform/tizen/2.0/AlarmBase'),
113523     t = require('ripple/platform/tizen/2.0/typecast'),
113524     _byDayValue = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"],
113525     PERIOD_WEEK = (7 * 24 * 60 * 60), MILLI_SECOND = 1000,
113526     AlarmAbsolute;
113527
113528 AlarmAbsolute = function () {
113529     var alarm, period = null, daysOfTheWeek = [], ascDays = [], voc, date;
113530
113531     function getScheduleDateByPeriod(current, date, period) {
113532         var diff = period * MILLI_SECOND,
113533             triggerDate = new Date(date);
113534
113535         while (current > (triggerDate - MILLI_SECOND)) { // In advance 1s - MILLI_SECOND
113536             triggerDate.setTime(triggerDate.getTime() + diff);
113537         }
113538         return triggerDate;
113539     }
113540
113541     function getSchedulteDateByDay(current, triggerTime, startDay, endDay) {
113542         startDay = (7 + (endDay - startDay)) % 7;
113543         current.setHours(triggerTime.getHours());
113544         current.setMinutes(triggerTime.getMinutes());
113545         current.setSeconds(triggerTime.getSeconds());
113546         current.setMilliseconds(triggerTime.getMilliseconds());
113547         current.setDate(current.getDate() + startDay);
113548         return current;
113549     }
113550
113551     function getAscDays() { // Get asc order array
113552         for (var i in daysOfTheWeek) {
113553             ascDays.push(_byDayValue.lastIndexOf(daysOfTheWeek[i]));
113554         }
113555         return ascDays.sort();
113556     }
113557
113558     /*
113559      * Return
113560      *     true:  A is bigger than B
113561      *     false: otherwise
113562      */
113563     function compareTime(current, triggerTime) {
113564         var diff = current.getHours() - triggerTime.getHours();
113565         if (diff !== 0)
113566             return (diff > 0);
113567
113568         diff = current.getMinutes() - triggerTime.getMinutes();
113569         if (diff !== 0)
113570             return (diff > 0);
113571
113572         diff = current.getSeconds() - triggerTime.getSeconds();
113573         if (diff < -1) // Delay 1s
113574             return false;
113575
113576         return true;
113577     }
113578
113579     alarm = new AlarmBase(this);
113580
113581     voc = [
113582         function (_date, _daysOfTheWeek) {
113583             date = _date;
113584             daysOfTheWeek = _daysOfTheWeek;
113585             period = PERIOD_WEEK;
113586         },
113587         function (_date, _period) {
113588             date = _date;
113589             period = _period;
113590         },
113591         function (_date) {
113592             date = _date;
113593         }
113594     ];
113595
113596     t.AlarmAbsolute(arguments, this, voc);
113597
113598     this.getNextScheduledDate = function () {
113599         var current = new Date(),
113600             diff, isPass, today, total, i, nextDate;
113601
113602         diff = current - date;
113603         if (diff < -1000) // Advance 1s
113604             return date; // Before first trigger, return date
113605
113606         if (period === null)
113607             return null;
113608
113609         if (period !== PERIOD_WEEK)
113610             return getScheduleDateByPeriod(current, date, period); // Repeat by period
113611
113612         today = current.getDay(); // 0~6
113613         ascDays = getAscDays();
113614         total = ascDays.length;
113615
113616         if ((ascDays[0] <= today) && (today <= ascDays[total - 1])) { // Today out of ascDays
113617             for (i in ascDays) { // Today in ascDays
113618                 if (ascDays[i] < today) {
113619                     continue;
113620                 } else if (ascDays[i] > today) {
113621                     nextDate = ascDays[i];
113622                     break;
113623                 } else {
113624                     isPass = compareTime(current, date); // Is triggerTime pass
113625                     if (isPass) {
113626                         nextDate = ascDays[(i < total - 1) ? (parseInt(i, 10) + 1) : 0];
113627                     } else {
113628                         nextDate = today;
113629                     }
113630                     break;
113631                 }
113632             }
113633         } else {
113634             nextDate = ascDays[0];
113635         }
113636
113637         return getSchedulteDateByDay(current, date, today, nextDate);
113638     };
113639
113640     this.__defineGetter__("date", function () {
113641         return new Date(date);
113642     });
113643
113644     this.__defineGetter__("period", function () {
113645         return period;
113646     });
113647
113648     this.__defineGetter__("daysOfTheWeek", function () {
113649         return daysOfTheWeek;
113650     });
113651 };
113652
113653 module.exports = AlarmAbsolute;
113654
113655 });
113656 define('ripple/platform/tizen/2.0/ContactPhoneNumber', function (require, exports, module) {
113657 /*
113658  *  Copyright 2013 Intel Corporation.
113659  *
113660  * Licensed under the Apache License, Version 2.0 (the "License");
113661  * you may not use this file except in compliance with the License.
113662  * You may obtain a copy of the License at
113663  *
113664  * http://www.apache.org/licenses/LICENSE-2.0
113665  *
113666  * Unless required by applicable law or agreed to in writing, software
113667  * distributed under the License is distributed on an "AS IS" BASIS,
113668  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113669  * See the License for the specific language governing permissions and
113670  * limitations under the License.
113671  */
113672
113673 var t = require('ripple/platform/tizen/2.0/typecast'),
113674     ContactPhoneNumber;
113675
113676 ContactPhoneNumber = function (number, types, isDefault) {
113677     var contactPhoneNumber = {};
113678
113679     t.ContactPhoneNumber(arguments, this);
113680
113681     contactPhoneNumber.number    = number;
113682     contactPhoneNumber.isDefault = isDefault || false;
113683     contactPhoneNumber.types     = (types && types[0]) ? types : ["VOICE"];
113684
113685     this.__defineGetter__("number", function () {
113686         return contactPhoneNumber.number;
113687     });
113688     this.__defineSetter__("number", function (val) {
113689         try {
113690             contactPhoneNumber.number = t.DOMString(val);
113691         } catch (e) {
113692         }
113693     });
113694
113695     this.__defineGetter__("isDefault", function () {
113696         return contactPhoneNumber.isDefault;
113697     });
113698     this.__defineSetter__("isDefault", function (val) {
113699         try {
113700             contactPhoneNumber.isDefault = t.boolean(val);
113701         } catch (e) {
113702         }
113703     });
113704
113705     this.__defineGetter__("types", function () {
113706         return contactPhoneNumber.types;
113707     });
113708     this.__defineSetter__("types", function (val) {
113709         try {
113710             contactPhoneNumber.types = t.DOMString(val, "[]");
113711         } catch (e) {
113712         }
113713     });
113714 };
113715
113716 module.exports = ContactPhoneNumber;
113717
113718 });
113719 define('ripple/platform/tizen/2.0/SyncInfo', function (require, exports, module) {
113720 /*
113721  *  Copyright 2013 Intel Corporation.
113722  *
113723  * Licensed under the Apache License, Version 2.0 (the "License");
113724  * you may not use this file except in compliance with the License.
113725  * You may obtain a copy of the License at
113726  *
113727  * http://www.apache.org/licenses/LICENSE-2.0
113728  *
113729  * Unless required by applicable law or agreed to in writing, software
113730  * distributed under the License is distributed on an "AS IS" BASIS,
113731  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113732  * See the License for the specific language governing permissions and
113733  * limitations under the License.
113734  */
113735
113736 var db = require('ripple/db'),
113737     t = require('ripple/platform/tizen/2.0/typecast'),
113738     SyncInfo,
113739     _accounts = {},
113740     _counter = 0;
113741
113742 SyncInfo = function () {
113743     var voc, syncInfo = {}, index;
113744
113745     function save() {
113746         _accounts[index] = {
113747             id:       syncInfo.id,
113748             password: syncInfo.password
113749         };
113750         db.saveObject("save-syncinfo", _accounts);
113751     }
113752
113753     function construct(url, id, password, mode) {
113754         syncInfo.url      = url;
113755         syncInfo.id       = id;
113756         syncInfo.password = password;
113757         syncInfo.mode     = mode;
113758         syncInfo.type     = null;
113759         syncInfo.interval = null;
113760
113761         this.__defineGetter__("url", function () {
113762             return syncInfo.url;
113763         });
113764         this.__defineSetter__("url", function (url) {
113765             try {
113766                 syncInfo.url = t.DOMString(url);
113767             } catch (e) {
113768             }
113769         });
113770
113771         this.__defineGetter__("id", function () {
113772             return null;
113773         });
113774         this.__defineSetter__("id", function (id) {
113775             try {
113776                 syncInfo.id = t.DOMString(id);
113777                 save();
113778             } catch (e) {
113779             }
113780         });
113781
113782         this.__defineGetter__("password", function () {
113783             return null;
113784         });
113785         this.__defineSetter__("password", function (password) {
113786             try {
113787                 syncInfo.password = t.DOMString(password);
113788                 save();
113789             } catch (e) {
113790             }
113791         });
113792
113793         this.__defineGetter__("mode", function () {
113794             return syncInfo.mode;
113795         });
113796         this.__defineSetter__("mode", function (mode) {
113797             try {
113798                 syncInfo.mode = t.SyncMode(mode);
113799             } catch (e) {
113800             }
113801         });
113802
113803         this.__defineGetter__("type", function () {
113804             return syncInfo.type;
113805         });
113806         this.__defineSetter__("type", function (type) {
113807             if (mode !== "MANUAL") {
113808                 return;
113809             }
113810             try {
113811                 syncInfo.type = t.SyncType(type);
113812             } catch (e) {
113813             }
113814         });
113815
113816         this.__defineGetter__("interval", function () {
113817             return syncInfo.interval;
113818         });
113819         this.__defineSetter__("interval", function (interval) {
113820             if (mode !== "PERIODIC") {
113821                 return;
113822             }
113823             try {
113824                 syncInfo.interval = t.SyncInterval(interval);
113825             } catch (e) {
113826             }
113827         });
113828     }
113829
113830     voc = [
113831         function (url, id, password, mode, type) {
113832             construct.apply(this, arguments);
113833
113834             if (mode === "MANUAL") {
113835                 syncInfo.type = type;
113836             }
113837         },
113838         function (url, id, password, mode, interval) {
113839             construct.apply(this, arguments);
113840
113841             if (mode === "PERIODIC") {
113842                 syncInfo.interval = interval;
113843             }
113844         },
113845         function (url, id, password, mode) {
113846             construct.apply(this, arguments);
113847         }
113848     ];
113849
113850     t.SyncInfo(arguments, this, voc);
113851
113852     index = _counter++;
113853     Object.defineProperty(this, "__syncInfoID__", {
113854         "configurable": false,
113855         "enumerable":   false,
113856         "get": (function (_id_) {
113857             return function () { return _id_; };
113858         })(index)
113859     });
113860     save();
113861 };
113862
113863 module.exports = SyncInfo;
113864
113865 });
113866 define('ripple/platform/tizen/2.0/alarm', function (require, exports, module) {
113867 /*
113868  *  Copyright 2012 Intel Corporation.
113869  *
113870  * Licensed under the Apache License, Version 2.0 (the "License");
113871  * you may not use this file except in compliance with the License.
113872  * You may obtain a copy of the License at
113873  *
113874  * http://www.apache.org/licenses/LICENSE-2.0
113875  *
113876  * Unless required by applicable law or agreed to in writing, software
113877  * distributed under the License is distributed on an "AS IS" BASIS,
113878  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
113879  * See the License for the specific language governing permissions and
113880  * limitations under the License.
113881  */
113882
113883 var db = require('ripple/db'),
113884     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
113885     event = require('ripple/event'),
113886     utils = require('ripple/utils'),
113887     t = require('ripple/platform/tizen/2.0/typecast'),
113888     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
113889     AlarmRelative = require('ripple/platform/tizen/2.0/AlarmRelative'),
113890     AlarmAbsolute = require('ripple/platform/tizen/2.0/AlarmAbsolute'),
113891     AlarmStore,
113892     _DB_ALARMS_KEY = "tizen1.0-db-alarms",
113893     PERIOD_MINUTE = 60,
113894     PERIOD_HOUR   = 60 * PERIOD_MINUTE,
113895     PERIOD_DAY    = 24 * PERIOD_HOUR,
113896     PERIOD_WEEK   = 7 * PERIOD_DAY,
113897     _alarms = {}, _alarmStack = [],
113898     _security = {
113899         "http://tizen.org/privilege/alarm": ["add", "remove", "removeAll"]
113900     },
113901     _isInitialized = false, _self;
113902
113903 function _initialize() {
113904     _alarms = db.retrieveObject(_DB_ALARMS_KEY);
113905     utils.forEach(_alarms, function (alarmStore) {
113906         alarmStore.date = new Date(alarmStore.date);
113907         _alarmStack.push(alarmStore);
113908     });
113909     _isInitialized = true;
113910 }
113911
113912 function _get() {
113913     if (!_isInitialized) {
113914         _initialize();
113915     }
113916 }
113917
113918 function _save() {
113919     db.saveObject(_DB_ALARMS_KEY, _alarmStack);
113920 }
113921
113922 function _updateDB(alarmStore) {
113923     _alarmStack.push(alarmStore);
113924     _save();
113925 }
113926
113927 function _getCurrentAppId() {
113928     return db.retrieve("current-url");
113929 }
113930
113931 function _checkTriggerAlarm(alarm) {
113932     var remainingTime, nextTriggerDate;
113933
113934     if (alarm.delay !== undefined) { // Alarm is relative
113935         if (alarm.period !== null)
113936             return false;
113937
113938         remainingTime = alarm.getRemainingSeconds();
113939         if (remainingTime === null)
113940             return true; // This alarm is triggered, remove it
113941     } else if (alarm.period !== undefined) { // Alarm is absolute,no repeat
113942         nextTriggerDate = alarm.getNextScheduledDate();
113943         if (nextTriggerDate === null)
113944             return true; // Already triggered
113945     }
113946
113947     return false; // Alarm is repeat, not expired
113948 }
113949
113950 function _convertToAlarm(alarmStore) {
113951     var alarm, frequency;
113952
113953     if (alarmStore.delay !== null) { // AlarmRelative
113954         alarm = new AlarmRelative(alarmStore.delay, alarmStore.period);
113955         alarm.date = alarmStore.date;
113956     } else { // AlarmAbsolute
113957         if (alarmStore.period !== null && alarmStore.period !== PERIOD_WEEK) {
113958             frequency = alarmStore.period;
113959         } else if (alarmStore.period === PERIOD_WEEK) {
113960             frequency = alarmStore.daysOfTheWeek;
113961         }
113962         alarm = new AlarmAbsolute(alarmStore.date, frequency);
113963     }
113964
113965     alarm.__defineGetter__("id", function () {
113966         return alarmStore.id;
113967     });
113968
113969     return alarm;
113970 }
113971
113972 function _eventCheckAlarm(id) {
113973     var alarm, diff;
113974
113975     _get();
113976     utils.forEach(_alarmStack, function (alarmStore) {
113977         if (alarmStore.id !== id)
113978             return;
113979
113980         alarm = _convertToAlarm(alarmStore);
113981         if (alarm.delay !== undefined) {
113982             diff = alarm.getRemainingSeconds();
113983             if (0 < diff && diff < 2) {
113984                 event.trigger("SendTriggerAppId", [alarmStore.applicationId]);
113985             }
113986         } else {
113987             diff = (new Date()) - alarm.getNextScheduledDate();
113988             if (-2000 < diff && diff < 2000) {
113989                 event.trigger("SendTriggerAppId", [alarmStore.applicationId]);
113990             }
113991         }
113992     });
113993 }
113994
113995
113996 _self = function () {
113997     var currentAppId, alarm;
113998
113999     alarm = {
114000         add: function (alarm, applicationId, appControl) {
114001             var id, alarmStore;
114002
114003             if (!_security.add) {
114004                 throw new WebAPIException(errorcode.SECURITY_ERR);
114005             }
114006
114007             t.AlarmManager("add", arguments);
114008
114009             alarm.__defineGetter__("id", function () {
114010                 return id;
114011             });
114012
114013             id = Math.uuid(null, 16);
114014             currentAppId = _getCurrentAppId(); // Update The Current URL.
114015             alarmStore = new AlarmStore(alarm, applicationId, currentAppId, appControl);
114016             _updateDB(alarmStore);
114017         },
114018
114019         remove: function (id) {
114020             var isFound = false, i;
114021
114022             if (!_security.remove) {
114023                 throw new WebAPIException(errorcode.SECURITY_ERR);
114024             }
114025
114026             t.AlarmManager("remove", arguments);
114027
114028             for (i in _alarmStack) {
114029                 if (_alarmStack[i].id !== id)
114030                     continue;
114031
114032                 _alarmStack.splice(i, 1);
114033                 _save();
114034                 isFound = true;
114035             }
114036
114037             if (!isFound) {
114038                 throw new WebAPIException(errorcode.NOT_FOUND_ERR);
114039             }
114040         },
114041
114042         removeAll: function () {
114043             var availableStack = [], i;
114044
114045             if (!_security.removeAll)
114046                 throw new WebAPIException(errorcode.SECURITY_ERR);
114047
114048             t.AlarmManager("removeAll", arguments);
114049
114050             for (i in _alarmStack) {
114051                 if (_alarmStack[i].currentAppId === currentAppId)
114052                     continue;
114053
114054                 availableStack.push(_alarmStack[i]);
114055             }
114056             _alarmStack = availableStack;
114057             _save();
114058         },
114059
114060         get: function (id) {
114061             var isFound = false, item, isExpired, alarm;
114062
114063             t.AlarmManager("get", arguments);
114064
114065             for (item in _alarmStack) {
114066                 if (_alarmStack[item].id === id) {
114067                     alarm = _convertToAlarm(_alarmStack[item]);
114068                     isExpired = _checkTriggerAlarm(alarm);
114069                     if (isExpired) {
114070                         _alarmStack.splice(item, 1);
114071                         _save();
114072                     } else {
114073                         isFound = true;
114074                     }
114075                     break;
114076                 }
114077             }
114078             if (!isFound) {
114079                 throw new WebAPIException(errorcode.NOT_FOUND_ERR);
114080             }
114081
114082             return alarm;
114083         },
114084
114085         getAll: function () {
114086             var availableStack = [], backAlarms = [], isExpired, alarm, i;
114087
114088             t.AlarmManager("getAll", arguments);
114089
114090             for (i in _alarmStack) {
114091                 alarm = _convertToAlarm(_alarmStack[i]); // alarmStore --> alarm
114092                 isExpired = _checkTriggerAlarm(alarm); // Check if the alarm is expired
114093                 if (isExpired)
114094                     continue;
114095
114096                 availableStack.push(_alarmStack[i]);
114097                 if (_alarmStack[i].currentAppId === currentAppId)
114098                     backAlarms.push(alarm);
114099             }
114100             _alarmStack = availableStack;
114101             _save();
114102             return backAlarms;
114103         },
114104
114105         handleSubFeatures: function (subFeatures) {
114106             var i, subFeature;
114107
114108             for (subFeature in subFeatures) {
114109                 for (i in _security[subFeature]) {
114110                     _security[_security[subFeature][i]] = true;
114111                 }
114112             }
114113         }
114114     };
114115
114116     currentAppId = _getCurrentAppId();
114117     _get();
114118
114119     alarm.__defineGetter__("PERIOD_MINUTE", function () {
114120         return PERIOD_MINUTE;
114121     });
114122
114123     alarm.__defineGetter__("PERIOD_HOUR", function () {
114124         return PERIOD_HOUR;
114125     });
114126
114127     alarm.__defineGetter__("PERIOD_DAY", function () {
114128         return PERIOD_DAY;
114129     });
114130
114131     alarm.__defineGetter__("PERIOD_WEEK", function () {
114132         return PERIOD_WEEK;
114133     });
114134
114135     return alarm;
114136 };
114137
114138 AlarmStore = function (alarmObject, applicationId, currentAppId, appControl) {
114139     var _self;
114140     _self = {
114141         id: alarmObject.id,
114142         delay: alarmObject.delay || null,
114143         date: alarmObject.date || null,
114144         period: alarmObject.period || null,
114145         daysOfTheWeek: alarmObject.daysOfTheWeek || null,
114146         applicationId: applicationId,
114147         currentAppId: currentAppId,
114148         appControl: appControl || null
114149     };
114150     return _self;
114151 };
114152
114153 event.on("CheckAlarm", function (id) {
114154     _eventCheckAlarm(id);
114155 });
114156
114157 module.exports = _self;
114158
114159 });
114160 define('ripple/platform/tizen/2.0/CalendarEvent', function (require, exports, module) {
114161 /*
114162  *  Copyright 2013 Intel Corporation.
114163  *
114164  * Licensed under the Apache License, Version 2.0 (the "License");
114165  * you may not use this file except in compliance with the License.
114166  * You may obtain a copy of the License at
114167  *
114168  * http://www.apache.org/licenses/LICENSE-2.0
114169  *
114170  * Unless required by applicable law or agreed to in writing, software
114171  * distributed under the License is distributed on an "AS IS" BASIS,
114172  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114173  * See the License for the specific language governing permissions and
114174  * limitations under the License.
114175  */
114176
114177 var t = require('ripple/platform/tizen/2.0/typecast'),
114178     typedef = require('ripple/platform/tizen/2.0/typedef'),
114179     CalendarItem = require('ripple/platform/tizen/2.0/CalendarItem'),
114180     CalendarEvent;
114181
114182 CalendarEvent = function () {
114183     var voc, calendarEvent = {};
114184
114185     // private
114186     function construct(eventInitDict) {
114187         CalendarItem.call(this, eventInitDict);
114188
114189         this.status = "CONFIRMED";
114190
114191         calendarEvent.convertToString  = this.convertToString;
114192         calendarEvent.isDetached       = false;
114193         calendarEvent.endDate          = null;
114194         calendarEvent.availability     = "BUSY";
114195         calendarEvent.recurrenceRule   = null;
114196
114197         this.__defineGetter__("isDetached", function () {
114198             return calendarEvent.isDetached;
114199         });
114200
114201         this.__defineGetter__("endDate", function () {
114202             return calendarEvent.endDate;
114203         });
114204         this.__defineSetter__("endDate", function (val) {
114205             try {
114206                 calendarEvent.endDate = t.TZDate(val, "?");
114207             } catch (e) {
114208             }
114209         });
114210
114211         this.__defineGetter__("availability", function () {
114212             return calendarEvent.availability;
114213         });
114214         this.__defineSetter__("availability", function (val) {
114215             try {
114216                 calendarEvent.availability = t.EventAvailability(val);
114217             } catch (e) {
114218             }
114219         });
114220
114221         this.__defineGetter__("recurrenceRule", function () {
114222             return calendarEvent.recurrenceRule;
114223         });
114224         this.__defineSetter__("recurrenceRule", function (val) {
114225             try {
114226                 calendarEvent.recurrenceRule = t.CalendarRecurrenceRule(val,
114227                         "?");
114228             } catch (e) {
114229             }
114230         });
114231
114232         this.convertToString  = convertToString;
114233         this.clone            = clone(this);
114234         this.expandRecurrence = expandRecurrence;
114235     }
114236
114237     function clone(self) {
114238         return function () {
114239             return new CalendarEvent(self);
114240         };
114241     }
114242
114243     // public
114244     function convertToString(format) {
114245         var str;
114246
114247         str = calendarEvent.convertToString.call(this, format);
114248         str = str.replace(/#TYPE#/g, "VEVENT");
114249
114250         // TODO: endDate is not supported
114251         // TODO: recurrenceRule is not supported
114252         str = str.replace(/#AVAILABILITY#/g, "FREEBUSY;FBTYPE=" +
114253                 calendarEvent.availability);
114254
114255         str = str.replace(/#[^#]*#/g, "");
114256
114257         return str;
114258     }
114259
114260     function expandRecurrence(startDate, endDate, successCallback,
114261             errorCallback) {
114262     }
114263
114264     // Constructor
114265     function CalendarEvent_CalendarEventInit(eventInitDict) {
114266         var attr;
114267
114268         construct.call(this, eventInitDict);
114269
114270         if (eventInitDict) {
114271             for (attr in eventInitDict) {
114272                 if (attr in typedef.CalendarEventInit) {
114273                     calendarEvent[attr] = eventInitDict[attr];
114274                 }
114275             }
114276         }
114277     }
114278
114279     function CalendarEvent_DOMString_CalendarTextFormat(stringRepresentation,
114280             format) {
114281     }
114282
114283     voc = [CalendarEvent_CalendarEventInit,
114284            CalendarEvent_DOMString_CalendarTextFormat];
114285     t.CalendarEvent(arguments, this, voc);
114286 };
114287
114288 module.exports = CalendarEvent;
114289
114290 });
114291 define('ripple/platform/tizen/2.0/ContactBase', function (require, exports, module) {
114292 /*
114293  *  Copyright 2013 Intel Corporation.
114294  *
114295  * Licensed under the Apache License, Version 2.0 (the "License");
114296  * you may not use this file except in compliance with the License.
114297  * You may obtain a copy of the License at
114298  *
114299  * http://www.apache.org/licenses/LICENSE-2.0
114300  *
114301  * Unless required by applicable law or agreed to in writing, software
114302  * distributed under the License is distributed on an "AS IS" BASIS,
114303  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114304  * See the License for the specific language governing permissions and
114305  * limitations under the License.
114306  */
114307
114308 var decorator = require('ripple/platform/tizen/2.0/decorator'),
114309     t = require('ripple/platform/tizen/2.0/typecast'),
114310     ContactName = require('ripple/platform/tizen/2.0/ContactName'),
114311     ContactAddress = require('ripple/platform/tizen/2.0/ContactAddress'),
114312     ContactPhoneNumber = require('ripple/platform/tizen/2.0/ContactPhoneNumber'),
114313     ContactEmailAddress = require('ripple/platform/tizen/2.0/ContactEmailAddress'),
114314     ContactAnniversary = require('ripple/platform/tizen/2.0/ContactAnniversary'),
114315     ContactOrganization = require('ripple/platform/tizen/2.0/ContactOrganization'),
114316     ContactWebSite = require('ripple/platform/tizen/2.0/ContactWebSite'),
114317     Contact;
114318
114319 Contact = function () {
114320     var voc;
114321
114322     // private
114323     function construct() {
114324         this.name          = null;
114325         this.addresses     = [];
114326         this.photoURI      = null;
114327         this.phoneNumbers  = [];
114328         this.emails        = [];
114329         this.birthday      = null;
114330         this.anniversaries = [];
114331         this.organizations = [];
114332         this.notes         = [];
114333         this.urls          = [];
114334         this.ringtoneURI   = null;
114335         this.groupIds      = [];
114336     }
114337
114338     // Constructor
114339     function Contact_ContactInit(contactInitDict) {
114340         var i, attr, arr;
114341
114342         construct.apply(this);
114343
114344         for (attr in contactInitDict) {
114345             switch (attr) {
114346             case "name":
114347                 this[attr] = new ContactName(contactInitDict[attr]);
114348                 break;
114349
114350             case "addresses":
114351                 arr = contactInitDict[attr];
114352                 if (arr) {
114353                     for (i in arr) {
114354                         this[attr][i] = new ContactAddress(arr[i]);
114355                     }
114356                 }
114357                 break;
114358
114359             case "phoneNumbers":
114360                 arr = contactInitDict[attr];
114361                 if (arr) {
114362                     for (i in arr) {
114363                         this[attr][i] = new ContactPhoneNumber(arr[i].number,
114364                                 arr[i].types || null, arr[i].isDefault || null);
114365                     }
114366                 }
114367                 break;
114368
114369             case "emails":
114370                 arr = contactInitDict[attr];
114371                 if (arr) {
114372                     for (i in arr) {
114373                         this[attr][i] = new ContactEmailAddress(arr[i].email,
114374                                 arr[i].types || null, arr[i].isDefault || null);
114375                     }
114376                 }
114377                 break;
114378
114379             case "birthday":
114380                 this[attr] = new Date(contactInitDict[attr]);
114381                 break;
114382
114383             case "anniversaries":
114384                 arr = contactInitDict[attr];
114385                 if (arr) {
114386                     for (i in arr) {
114387                         this[attr][i] = new ContactAnniversary(arr[i].date,
114388                                 arr[i].label || null);
114389                     }
114390                 }
114391                 break;
114392
114393             case "organizations":
114394                 arr = contactInitDict[attr];
114395                 if (arr) {
114396                     for (i in arr) {
114397                         this[attr][i] = new ContactOrganization(arr[i]);
114398                     }
114399                 }
114400                 break;
114401
114402             case "notes":
114403             case "groupIds":
114404                 arr = contactInitDict[attr];
114405                 if (arr) {
114406                     for (i in arr) {
114407                         this[attr][i] = arr[i];
114408                     }
114409                 }
114410                 break;
114411
114412             case "urls":
114413                 arr = contactInitDict[attr];
114414                 if (arr) {
114415                     for (i in arr) {
114416                         this[attr][i] = new ContactWebSite(arr[i].url,
114417                                 arr[i].type || null);
114418                     }
114419                 }
114420                 break;
114421
114422             default:
114423                 this[attr] = contactInitDict[attr];
114424                 break;
114425             }
114426         }
114427
114428         decorator.Contact(this);
114429     }
114430
114431     function Contact_DOMString(stringRepresentation) {
114432     }
114433
114434     voc = [Contact_ContactInit, Contact_DOMString];
114435     t.Contact(arguments, this, voc);
114436 };
114437
114438 module.exports = Contact;
114439
114440 });
114441 define('ripple/platform/tizen/2.0/ContactAnniversary', function (require, exports, module) {
114442 /*
114443  *  Copyright 2013 Intel Corporation.
114444  *
114445  * Licensed under the Apache License, Version 2.0 (the "License");
114446  * you may not use this file except in compliance with the License.
114447  * You may obtain a copy of the License at
114448  *
114449  * http://www.apache.org/licenses/LICENSE-2.0
114450  *
114451  * Unless required by applicable law or agreed to in writing, software
114452  * distributed under the License is distributed on an "AS IS" BASIS,
114453  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114454  * See the License for the specific language governing permissions and
114455  * limitations under the License.
114456  */
114457
114458 var t = require('ripple/platform/tizen/2.0/typecast'),
114459     ContactAnniversary;
114460
114461 ContactAnniversary = function (date, label) {
114462     var contactAnniversary = {};
114463
114464     t.ContactAnniversary(arguments, this);
114465
114466     contactAnniversary.date  = date;
114467     contactAnniversary.label = label || null;
114468
114469     this.__defineGetter__("date", function () {
114470         return contactAnniversary.date;
114471     });
114472     this.__defineSetter__("date", function (val) {
114473         try {
114474             contactAnniversary.date = t.Date(val);
114475         } catch (e) {
114476         }
114477     });
114478
114479     this.__defineGetter__("label", function () {
114480         return contactAnniversary.label;
114481     });
114482     this.__defineSetter__("label", function (val) {
114483         try {
114484             contactAnniversary.label = t.DOMString(val, "?");
114485         } catch (e) {
114486         }
114487     });
114488 };
114489
114490 module.exports = ContactAnniversary;
114491
114492 });
114493 define('ripple/platform/tizen/2.0/SortMode', function (require, exports, module) {
114494 /*
114495  *  Copyright 2013 Intel Corporation.
114496  *
114497  * Licensed under the Apache License, Version 2.0 (the "License");
114498  * you may not use this file except in compliance with the License.
114499  * You may obtain a copy of the License at
114500  *
114501  * http://www.apache.org/licenses/LICENSE-2.0
114502  *
114503  * Unless required by applicable law or agreed to in writing, software
114504  * distributed under the License is distributed on an "AS IS" BASIS,
114505  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114506  * See the License for the specific language governing permissions and
114507  * limitations under the License.
114508  */
114509
114510 var t = require('ripple/platform/tizen/2.0/typecast'),
114511     SortMode;
114512
114513 SortMode = function (attributeName, order) {
114514     var sortMode = {};
114515
114516     t.SortMode(arguments, this);
114517
114518     this.__defineGetter__("attributeName", function () {
114519         return sortMode.attributeName;
114520     });
114521     this.__defineSetter__("attributeName", function (val) {
114522         try {
114523             sortMode.attributeName = t.DOMString(val);
114524         } catch (e) {
114525         }
114526     });
114527
114528     this.__defineGetter__("order", function () {
114529         return sortMode.order;
114530     });
114531     this.__defineSetter__("order", function (val) {
114532         try {
114533             sortMode.order = t.SortModeOrder(val);
114534         } catch (e) {
114535         }
114536     });
114537
114538     sortMode.attributeName = attributeName;
114539     sortMode.order         = order || "ASC";
114540 };
114541
114542 module.exports = SortMode;
114543
114544 });
114545 define('ripple/platform/tizen/2.0/AlarmRelative', function (require, exports, module) {
114546 /*
114547  *  Copyright 2012 Intel Corporation.
114548  *
114549  * Licensed under the Apache License, Version 2.0 (the "License");
114550  * you may not use this file except in compliance with the License.
114551  * You may obtain a copy of the License at
114552  *
114553  * http://www.apache.org/licenses/LICENSE-2.0
114554  *
114555  * Unless required by applicable law or agreed to in writing, software
114556  * distributed under the License is distributed on an "AS IS" BASIS,
114557  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114558  * See the License for the specific language governing permissions and
114559  * limitations under the License.
114560  */
114561
114562 var AlarmBase = require('ripple/platform/tizen/2.0/AlarmBase'),
114563     t = require('ripple/platform/tizen/2.0/typecast'),
114564     AlarmRelative;
114565
114566 AlarmRelative = function (delay, period) {
114567     var alarm, date;
114568
114569     t.AlarmRelative(arguments, this);
114570
114571     alarm  = new AlarmBase(this);
114572     period = period || null;
114573     date   = new Date(); // Alarm settime
114574
114575     this.getRemainingSeconds = function () {
114576         var current, diff, triggerDate, MILLI_SECOND = 1000;
114577         current     = new Date();
114578         triggerDate = new Date(delay * MILLI_SECOND + date.getTime()); // First triggerDate
114579         diff        = Math.round((triggerDate - current) / MILLI_SECOND);
114580
114581         if (diff > 0) // Before first trigger
114582             return diff;
114583
114584         if (period === null)
114585             return null; // Alarm is expired
114586
114587         while (current - triggerDate >= 0) { // Trigger repeatly
114588             triggerDate = new Date(period * MILLI_SECOND + triggerDate.getTime());
114589         }
114590         diff = Math.round(((triggerDate - current) / MILLI_SECOND));
114591         return diff;
114592     };
114593
114594     this.__defineGetter__("delay", function () {
114595         return delay;
114596     });
114597
114598     this.__defineGetter__("period", function () {
114599         return period;
114600     });
114601 };
114602
114603 module.exports = AlarmRelative;
114604
114605 });
114606 define('ripple/platform/tizen/2.0/DeviceMotionEvent', function (require, exports, module) {
114607 /*
114608  *  Copyright 2012 Intel Corporation.
114609  *
114610  * Licensed under the Apache License, Version 2.0 (the "License");
114611  * you may not use this file except in compliance with the License.
114612  * You may obtain a copy of the License at
114613  *
114614  * http://www.apache.org/licenses/LICENSE-2.0
114615  *
114616  * Unless required by applicable law or agreed to in writing, software
114617  * distributed under the License is distributed on an "AS IS" BASIS,
114618  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114619  * See the License for the specific language governing permissions and
114620  * limitations under the License.
114621  */
114622
114623 var utils = require('ripple/utils'),
114624     Event = require('ripple/platform/tizen/2.0/EventBase');
114625
114626 module.exports = function () {
114627     var _self = {
114628             acceleration: {
114629                 x: null,
114630                 y: null,
114631                 z: null
114632             },
114633             accelerationIncludingGravity: {
114634                 x: null,
114635                 y: null,
114636                 z: null
114637             },
114638             rotationRate: {
114639                 alpha: null,
114640                 beta: null,
114641                 gamma: null
114642             },
114643             interval: 0
114644         };
114645
114646     Event.call(this);
114647
114648     this.__defineGetter__("acceleration", function () {
114649         return _self.acceleration;
114650     });
114651
114652     this.__defineGetter__("accelerationIncludingGravity", function () {
114653         return _self.accelerationIncludingGravity;
114654     });
114655
114656     this.__defineGetter__("rotationRate", function () {
114657         return _self.rotationRate;
114658     });
114659
114660     this.__defineGetter__("interval", function () {
114661         return _self.interval;
114662     });
114663
114664     this.initAccelerometerEvent = function (accelerometerType, accelerometerBubbles, accelerometerCancelable,
114665                                             accelerationData, accelerationGData, rotationRateData, intervalValue) {
114666         this.initEvent(accelerometerType, accelerometerBubbles, accelerometerCancelable);
114667
114668         _self.acceleration = utils.copy(accelerationData);
114669         _self.accelerationIncludingGravity = utils.copy(accelerationGData);
114670         _self.rotationRate = utils.copy(rotationRateData);
114671         _self.interval = intervalValue;
114672     };
114673 };
114674
114675
114676 });
114677 define('ripple/platform/tizen/2.0/sensors', function (require, exports, module) {
114678 /*
114679  *  Copyright 2012 Intel Corporation.
114680  *
114681  * Licensed under the Apache License, Version 2.0 (the "License");
114682  * you may not use this file except in compliance with the License.
114683  * You may obtain a copy of the License at
114684  *
114685  * http://www.apache.org/licenses/LICENSE-2.0
114686  *
114687  * Unless required by applicable law or agreed to in writing, software
114688  * distributed under the License is distributed on an "AS IS" BASIS,
114689  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114690  * See the License for the specific language governing permissions and
114691  * limitations under the License.
114692  */
114693
114694 var utils = require('ripple/utils'),
114695     sensors = require('ripple/platform/tizen/2.0/spec/sensor'),
114696     _sensors = ["Accelerometer", "MagneticField", "Rotation", "Orientation"],
114697     _permission = true,
114698     _isWriteable = false,
114699     _self;
114700
114701 function SensorError(code, msg) {
114702     this.__defineGetter__("message", function () {
114703         return msg;
114704     });
114705     this.__defineGetter__("code", function () {
114706         return code;
114707     });
114708
114709     this.PERMISSION_DENIED = -100;
114710 }
114711
114712 function SensorRequest() {
114713     var _self = {
114714         result: [],
114715         error: null,
114716         readyState: "processing"
114717     };
114718
114719     this.__defineGetter__("result", function () {
114720         return _self.result;
114721     });
114722     this.__defineSetter__("result", function (resultData) {
114723         if (_isWriteable) {
114724             _self.result = utils.copy(resultData);
114725             _isWriteable = false;
114726             return;
114727         }
114728     });
114729
114730     this.__defineGetter__("error", function () {
114731         return _self.error;
114732     });
114733     this.__defineSetter__("error", function (errorData) {
114734         if (_isWriteable) {
114735             _self.error = utils.copy(errorData);
114736             _isWriteable = false;
114737             return;
114738         }
114739     });
114740
114741     this.__defineGetter__("readyState", function () {
114742         return _self.readyState;
114743     });
114744     this.__defineSetter__("readyState", function (readyStateData) {
114745         if (_isWriteable) {
114746             _self.readyState = readyStateData;
114747             _isWriteable = false;
114748             return;
114749         }
114750     });
114751 }
114752
114753 _self = {
114754     findSensors: function (type) {
114755         var sensorRequest = new SensorRequest(), index, sensorName = "";
114756
114757         setTimeout(function () {
114758             if (_permission) {
114759                 for (index = 0; index < _sensors.length; index++) {
114760                     sensorName = _sensors[index];
114761                     if (type === null || type === undefined || type === sensorName) {
114762                         _isWriteable = true;
114763                         sensorRequest.result.push(sensors[sensorName]);
114764                     }
114765                 }
114766
114767                 _isWriteable = true;
114768                 sensorRequest.readyState = "done";
114769
114770                 if (sensorRequest.onsuccess) {
114771                     sensorRequest.onsuccess();
114772                 }
114773             }
114774             else {
114775                 // error event on the request with error code PERMISSION_DENIED must be fired.
114776                 sensorRequest.error = new SensorError(-100, "permission denied!");
114777                 if (sensorRequest.onerror) {
114778                     sensorRequest.onerror();
114779                 }
114780             }
114781         }, 1);
114782
114783         return sensorRequest;
114784     }
114785 };
114786
114787 module.exports = _self;
114788
114789
114790 });
114791 define('ripple/platform/tizen/2.0/callHistory', function (require, exports, module) {
114792 /*
114793  *  Copyright 2012 Intel Corporation.
114794  *
114795  * Licensed under the Apache License, Version 2.0 (the "License");
114796  * you may not use this file except in compliance with the License.
114797  * You may obtain a copy of the License at
114798  *
114799  * http://www.apache.org/licenses/LICENSE-2.0
114800  *
114801  * Unless required by applicable law or agreed to in writing, software
114802  * distributed under the License is distributed on an "AS IS" BASIS,
114803  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
114804  * See the License for the specific language governing permissions and
114805  * limitations under the License.
114806  */
114807
114808 var utils = require('ripple/utils'),
114809     db = require('ripple/db'),
114810     event = require('ripple/event'),
114811     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
114812     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
114813     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
114814     t = require('ripple/platform/tizen/2.0/typecast'),
114815     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
114816     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
114817     _DB_CALL_KEY = "tizen1-db-callhistory",
114818     _data = {
114819         observers: {},
114820         callHistory: []
114821     },
114822     _security = {
114823         "http://tizen.org/privilege/callhistory.read": ["find", "addChangeListener", "removeChangeListener"],
114824         "http://tizen.org/privilege/callhistory.write": ["remove", "removeBatch", "removeAll"]
114825     },
114826     _self;
114827
114828 function _getValue(inputValue, key) {
114829     var keys = key.split("."),
114830         value = inputValue[keys[0]],
114831         index;
114832
114833     for (index = 1; index < keys.length; index++) {
114834         if (value[keys[index]]) {
114835             value = value[keys[index]];
114836         }
114837     }
114838
114839     return value;
114840 }
114841
114842 function _filter(inputArray, filter) {
114843     var index, filterResults = [], compositeResultArray;
114844
114845     if (filter === null || filter === undefined) {
114846         return inputArray;
114847     }
114848
114849     if (filter.type && filter.filters) {
114850         filterResults = _filter(inputArray, filter.filters[0]);
114851         for (index = 1; index < filter.filters.length; index++) {
114852             compositeResultArray = _filter(inputArray, filter.filters[index]);
114853
114854             filterResults = tizen1_utils.arrayComposite(filter.type, filterResults, compositeResultArray);
114855         }
114856         return filterResults;
114857     }
114858
114859     if (filter.attributeName === null || filter.attributeName === undefined) {
114860         throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
114861     }
114862
114863     if (filter.matchFlag) {
114864         if (filter.attributeName === 'features') {
114865             filterResults = tizen1_utils.matchAttributeArrayFilter(inputArray, filter.attributeName, filter.matchFlag, filter.matchValue);
114866         } else {
114867             filterResults = tizen1_utils.matchAttributeFilter(inputArray, filter.attributeName, filter.matchFlag, filter.matchValue);
114868         }
114869     }
114870     else if (filter.initialValue || filter.endValue) {
114871         filterResults = tizen1_utils.matchAttributeRangeFilter(inputArray, filter.attributeName, filter.initialValue, filter.endValue);
114872     }
114873
114874     return filterResults;
114875 }
114876
114877 function _sort(inputArray, sortMode) {
114878     if (sortMode.attributeName === null || sortMode.attributeName === undefined) {
114879         throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
114880     }
114881
114882     inputArray.sort(function (a, b) {
114883         return sortMode.order === "ASC" ? _getValue(a, sortMode.attributeName) - _getValue(b, sortMode.attributeName) :
114884                _getValue(b, sortMode.attributeName) - _getValue(a, sortMode.attributeName);
114885     });
114886
114887     return inputArray;
114888 }
114889
114890 function _save() {
114891     db.saveObject(_DB_CALL_KEY, _data.callHistory);
114892 }
114893
114894 function _retrieve() {
114895     var index;
114896
114897     _data.callHistory = db.retrieveObject(_DB_CALL_KEY) || [];
114898
114899     for (index = 0; index < _data.callHistory.length; index++) {
114900         _data.callHistory[index].startTime = new Date(_data.callHistory[index].startTime);
114901     }
114902 }
114903
114904 function _isValidCallHistoryEntry(arg) {
114905     return arg && arg.hasOwnProperty("uid") && arg.hasOwnProperty("type") &&
114906            arg.hasOwnProperty("features") && arg.hasOwnProperty("remoteParties") &&
114907            arg.hasOwnProperty("startTime") && arg.hasOwnProperty("duration") &&
114908            arg.hasOwnProperty("direction");
114909 }
114910
114911 function _rtnRmtPty(pty) {
114912     var _remoteParty = pty.remoteParty,
114913         _personId = pty.personId,
114914         _self = {};
114915     _self.__defineGetter__("remoteParty", function () {
114916         return _remoteParty;
114917     });
114918     _self.__defineGetter__("personId", function () {
114919         return _personId;
114920     });
114921     return _self;
114922 }
114923
114924 function _rtnEntry(entry) {
114925     var _uid = entry.uid,
114926         _type = entry.type,
114927         _features = tizen1_utils.copy(entry.features),
114928         _remoteParties = [],
114929         _startTime = new Date(entry.startTime),
114930         _duration = entry.duration,
114931         _direction = entry.direction,
114932         _self = {}, i;
114933
114934     for (i = 0; i < entry.remoteParties.length; i++) {
114935         _remoteParties.push(_rtnRmtPty(entry.remoteParties[i]));
114936     }
114937     _self.__defineGetter__("uid", function () {
114938         return _uid;
114939     });
114940     _self.__defineGetter__("type", function () {
114941         return _type;
114942     });
114943     _self.__defineGetter__("features", function () {
114944         return _features;
114945     });
114946     _self.__defineGetter__("remoteParties", function () {
114947         return _remoteParties;
114948     });
114949     _self.__defineGetter__("startTime", function () {
114950         return _startTime;
114951     });
114952     _self.__defineGetter__("duration", function () {
114953         return _duration;
114954     });
114955     _self.direction = _direction;
114956
114957     return _self;
114958 }
114959
114960 function _initialize() {
114961     _retrieve();
114962
114963     event.on("CallInProgress", function () {
114964     });
114965
114966     event.on("CallRecorded", function (record) {
114967         var historyEntry = tizen1_utils.copy(record);
114968         historyEntry.uid = Math.uuid(8, 16);
114969
114970         _data.callHistory.push(historyEntry);
114971         _save();
114972
114973         utils.forEach(_data.observers, function (observer) {
114974             observer.onadded([historyEntry]);
114975         });
114976     });
114977 }
114978
114979 _self = function () {
114980     this.find = function (successCallback, errorCallback, filter, sortMode, limit, offset) {
114981         var i, rtn = [],
114982             filterResults,
114983             limitValue = limit | 0,
114984             offsetValue = offset | 0;
114985
114986         if (!_security.find) {
114987             throw new WebAPIException(errorcode.SECURITY_ERR);
114988         }
114989
114990         t.CallHistory("find", arguments);
114991
114992         filterResults = tizen1_utils.copy(_data.callHistory);
114993         if (filter !== null && filter !== undefined) {
114994             filterResults = _filter(filterResults, filter);
114995         }
114996
114997         if (sortMode !== null && sortMode !== undefined) {
114998             _sort(filterResults, sortMode);
114999         }
115000
115001         setTimeout(function () {
115002             if (limitValue > 0) {
115003                 offsetValue = offsetValue > 0 ? offsetValue : 0;
115004                 filterResults = filterResults.slice(offsetValue, limitValue);
115005             }
115006
115007             for (i = 0; i < filterResults.length; i++) {
115008                 rtn.push(_rtnEntry(filterResults[i]));
115009             }
115010             successCallback(rtn);
115011         }, 1);
115012     };
115013     this.remove = function (entry) {
115014         var isFound = false, rtn = [];
115015
115016         if (!_security.remove) {
115017             throw new WebAPIException(errorcode.SECURITY_ERR);
115018         }
115019
115020         t.CallHistory("remove", arguments);
115021
115022         _data.callHistory = _data.callHistory.filter(function (element) {
115023             return utils.some(element, function (value, key) {
115024                 if (tizen1_utils.isEqual(entry[key], value)) {
115025                     isFound = true;
115026                     return false;
115027                 }
115028                 return true;
115029             });
115030         });
115031
115032         if (!isFound) {
115033             throw new WebAPIException(errorcode.NOT_FOUND_ERR);
115034         }
115035
115036         _save();
115037         rtn.push(_rtnEntry(entry));
115038         utils.forEach(_data.observers, function (observer) {
115039             observer.onchanged(rtn);
115040         });
115041
115042     };
115043     this.removeBatch = function (entries, successCallback, errorCallback) {
115044         var isFound = false, i, rtn = [];
115045
115046         if (!_security.removeBatch) {
115047             throw new WebAPIException(errorcode.SECURITY_ERR);
115048         }
115049
115050         t.CallHistory("removeBatch", arguments);
115051
115052         setTimeout(function () {
115053             isFound = entries.every(function (element) {
115054                 return _data.callHistory.some(function (callHistory) {
115055                     return element.uid === callHistory.uid;
115056                 });
115057             });
115058
115059             if (!isFound) {
115060                 if (errorCallback) {
115061                     errorCallback(new WebAPIError(errorcode.NOT_FOUND_ERR));
115062                 }
115063                 return;
115064             }
115065
115066             _data.callHistory = _data.callHistory.filter(function (element) {
115067                 return !entries.some(function (entryValue, entryIndex) {
115068                     return tizen1_utils.isEqual(element, entryValue);
115069                 });
115070             });
115071
115072             _save();
115073
115074             if (successCallback) {
115075                 successCallback();
115076             }
115077             for (i = 0; i < entries.length; i++) {
115078                 rtn.push(_rtnEntry(entries[i]));
115079             }
115080             utils.forEach(_data.observers, function (observer) {
115081                 observer.onchanged(rtn);
115082             });
115083         }, 1);
115084     };
115085     this.removeAll = function (successCallback, errorCallback) {
115086         var i, rtn = [];
115087
115088         if (!_security.removeAll) {
115089             throw new WebAPIException(errorcode.SECURITY_ERR);
115090         }
115091
115092         t.CallHistory("removeAll", arguments);
115093
115094         for (i = 0; i < _data.callHistory.length; i++) {
115095             rtn.push(_rtnEntry(_data.callHistory[i]));
115096         }
115097
115098         _data.callHistory = [];
115099         _save();
115100
115101         utils.forEach(_data.observers, function (observer) {
115102             observer.onchanged(rtn);
115103         });
115104
115105         if (successCallback) {
115106             setTimeout(function () {
115107                 successCallback();
115108             }, 1);
115109         }
115110
115111     };
115112     this.addChangeListener = function (observerObj) {
115113         var handle = Number(Math.uuid(8, 10));
115114
115115         if (!_security.addChangeListener) {
115116             throw new WebAPIException(errorcode.SECURITY_ERR);
115117         }
115118
115119         t.CallHistory("addChangeListener", arguments);
115120
115121         _data.observers[handle] = observerObj;
115122
115123         return handle;
115124     };
115125     this.removeChangeListener = function (handle) {
115126         if (!_security.removeChangeListener) {
115127             throw new WebAPIException(errorcode.SECURITY_ERR);
115128         }
115129
115130         if (!_data.observers[handle])
115131             return;
115132
115133         delete _data.observers[handle];
115134     };
115135     this.handleSubFeatures = function (subFeatures) {
115136         function setSecurity(method) {
115137             _security[method] = true;
115138         }
115139
115140         for (var subFeature in subFeatures) {
115141             utils.forEach(_security[subFeature], setSecurity);
115142         }
115143     };
115144 };
115145
115146 _initialize();
115147
115148 module.exports = _self;
115149
115150 });
115151 define('ripple/platform/tizen/2.0/filesystem', function (require, exports, module) {
115152 /*
115153  *  Copyright 2012 Intel Corporation.
115154  *
115155  * Licensed under the Apache License, Version 2.0 (the "License");
115156  * you may not use this file except in compliance with the License.
115157  * You may obtain a copy of the License at
115158  *
115159  * http://www.apache.org/licenses/LICENSE-2.0
115160  *
115161  * Unless required by applicable law or agreed to in writing, software
115162  * distributed under the License is distributed on an "AS IS" BASIS,
115163  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
115164  * See the License for the specific language governing permissions and
115165  * limitations under the License.
115166  */
115167
115168 var event = require('ripple/event'),
115169     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
115170     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
115171     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
115172     utils = require('ripple/utils'),
115173     dbfs  = require('ripple/platform/tizen/2.0/dbfs'),
115174     tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
115175     _maxPathLength = 256,
115176     _virtualRoots = ["documents", "images", "music", "videos", "downloads", "wgt-package", "wgt-private", "wgt-private-tmp", "removable", "attachments"],
115177     _security = {
115178         "http://tizen.org/privilege/filesystem": [],
115179         "http://tizen.org/privilege/filesystem.read": ["copyTo", "moveTo", "createDirectory", "createFile", "deleteDirectory", "deleteFile", "openStreamR"],
115180         "http://tizen.org/privilege/filesystem.write": ["readAsText", "openStreamW"],
115181         all: true
115182     },
115183     _realRoots = dbfs.roots,
115184     _r2vmap = {},
115185     _v2rmap = {},
115186     _initialized = false,
115187     _readOnly  = false,
115188     _writeOnly = false,
115189     _defaultMode = "rw",
115190     _storages = [], // filesystem storages
115191     _observers = [],
115192     File,
115193     FileStream,
115194     FileFilter,
115195     FileSystemStorage;
115196
115197 function _isValidChar(c) {
115198     return  (c >= '0' && c <= '9') ||
115199         (c >= 'a' && c <= 'z') ||
115200         (c >= 'A' && c <= 'Z') ||
115201         (c === ' ') ||
115202         (c === '_') ||
115203         (c === '-') ||
115204         (c === '.');
115205 }
115206
115207 function _isValidFileName(name) {
115208     var _valid = true,
115209         _c;
115210
115211     if (name === '' || name === '.' || name === '..' || (name.length > _maxPathLength)) {
115212         _valid = false;
115213     } else {
115214         for (_c = 0; _c < name.length; _c++) {
115215             if (!_isValidChar(name[_c])) {
115216                 _valid = false;
115217                 break;
115218             }
115219         }
115220     }
115221
115222     return _valid;
115223 }
115224
115225 function _initialize() {
115226     var _i;
115227
115228     _storages.push(FileSystemStorage("InternalFlash", "INTERNAL", "MOUNTED" ));
115229     _storages.push(FileSystemStorage("MMC", "EXTERNAL", "REMOVED"));
115230     dbfs.initialize();
115231
115232     // set up the map between real path and virtual path
115233     for (_i = 0; _i < _virtualRoots.length; _i++) {
115234         _r2vmap[_realRoots[_i]] = _virtualRoots[_i];
115235     }
115236
115237     utils.forEach(_r2vmap, function (value, key) {
115238         _v2rmap[value] = key;
115239     });
115240 }
115241
115242 function _resolveSync(srcLocation, onSuccess, onError, accessMode) {
115243     var _parts = srcLocation.replace(/\/$/, '').split("/"),
115244         _header, _fullPath,
115245         _i;
115246
115247     // TODO: Initialize at bootstrap and emulatorBridge.link
115248     if (!_initialized) {
115249         _initialize();
115250         _initialized = true;
115251     }
115252
115253     for (_i = 0; _i < _parts.length; _i++) {
115254         if (!_isValidFileName(_parts[_i])) {
115255             if (onError) {
115256                 onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
115257             }
115258             return;
115259         }
115260     }
115261
115262     _header = _v2rmap[_parts[0]];
115263     if (_header === undefined) {
115264         if (onError) {
115265             onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
115266         }
115267         return;
115268     }
115269
115270     if (_parts.length === 1) {
115271         _fullPath = _header;
115272     } else {
115273         _fullPath = _header + "/" + _parts.splice(1, _parts.length - 1).join("/");
115274     }
115275
115276     dbfs.stat(_fullPath,
115277             function (entry) {
115278                 onSuccess(new File(entry, accessMode));
115279             },
115280             function () {
115281                 if (onError) {
115282                     onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
115283                 }
115284             });
115285 }
115286
115287 function _resolveAsync(onSuccess, onError, srcLocation, accessMode) {
115288     _resolveSync(srcLocation,
115289                 function (file) {
115290                     setTimeout(function () {
115291                         onSuccess(file);
115292                     }, 1);
115293                 },
115294                 function (e) {
115295                     setTimeout(function () {
115296                         onError(e);
115297                     }, 1);
115298                 },
115299                 accessMode);
115300 }
115301
115302 File = function (entry, mode) {
115303     var _entry = entry,
115304         _mode = mode,
115305         _parent,
115306         _self;
115307
115308     function _r2v(rpath) {
115309         var i, v, r, regExp;
115310
115311         for (i = 0; i < _virtualRoots.length; i++) {
115312             v = _virtualRoots[i];
115313             r = _v2rmap[v];
115314             if (rpath.match("^" + r)) {
115315                 regExp = new RegExp("^" + r);
115316                 return rpath.replace(regExp, v);
115317             }
115318         }
115319
115320         return "";
115321     }
115322
115323     function _v2r(vpath) {
115324         var i, v, r, regExp;
115325
115326         for (i = 0; i < _virtualRoots.length; i++) {
115327             v = _virtualRoots[i];
115328             r = _v2rmap[v];
115329             if (vpath.match("^" + v)) {
115330                 regExp = new RegExp("^" + v);
115331                 return vpath.replace(regExp, r);
115332             }
115333         }
115334
115335         return "";
115336     }
115337
115338     function _copyMoveInternal(onSuccess, onError, src, dst, overwrite, func) {
115339         var _srcName = String(src),
115340             _dstName = String(dst),
115341             _src = null,
115342             _dst = null,
115343             _error = false,
115344             _dstParent = null,
115345             _dstParts  = _dstName.split("/"),
115346             _dstParentName = _dstParts.splice(0, _dstParts.length - 1).join("/");
115347
115348         if (!_entry.isDirectory) {
115349             if (onError) {
115350                 setTimeout(function () {
115351                     onError(new WebAPIError(errorcode.IO_ERR));
115352                 }, 1);
115353             }
115354             return undefined;
115355         }
115356
115357         _resolveSync(_srcName,
115358                 function (file) {
115359                     _src = file;
115360                 },
115361                 function (e) {
115362                     setTimeout(function () {
115363                         onError(e);
115364                     }, 1);
115365                 },
115366                 _mode);
115367
115368         if (_src) {
115369             if (_src.parent.fullPath === _self.fullPath) {
115370                 if (!_readOnly && _mode !== "r") {
115371                     _resolveSync(_dstParentName,
115372                             function (file) {
115373                                 _dstParent = file;
115374                             },
115375                             function (e) {
115376                                 setTimeout(function () {
115377                                     onError(e);
115378                                 }, 1);
115379                             },
115380                             _mode);
115381
115382                     if (_dstParent === null) {
115383                         return undefined;
115384                     }
115385
115386                     _resolveSync(_dstName,
115387                             function (file) {
115388                                 _dst = file;
115389                             },
115390                             function (e) {
115391                                 if (e.code !== errorcode.NOT_FOUND_ERR) {
115392                                     setTimeout(function () {
115393                                         onError(e);
115394                                     }, 1);
115395                                     _error = true;
115396                                 }
115397                             },
115398                             _mode);
115399
115400                     if (_error) {
115401                         return undefined;
115402                     }
115403
115404                     if (_src.isFile) {
115405                         if (_dst === null) {
115406                             func(_v2r(_srcName), _v2r(_dstName),
115407                                     function () {
115408                                         setTimeout(function () {
115409                                             onSuccess();
115410                                         }, 1);
115411                                     },
115412                                     function () {});
115413                             return null;
115414                         } else {
115415                             if (_dst.isFile && Boolean(overwrite) && (_srcName !== _dstName)) {
115416                                 func(_v2r(_srcName), _v2r(_dstName),
115417                                         function () {
115418                                             setTimeout(function () {
115419                                                 onSuccess();
115420                                             }, 1);
115421                                         },
115422                                         function () {});
115423                                 return null;
115424                             } else {
115425                                 setTimeout(function () {
115426                                     onError(new WebAPIError(errorcode.IO_ERR));
115427                                 }, 1);
115428                             }
115429                         }
115430                     } else {
115431                         if (_dst === null) {
115432                             func(_v2r(_srcName), _v2r(_dstName),
115433                                 function () {
115434                                     setTimeout(function () {
115435                                         onSuccess();
115436                                     }, 1);
115437                                 },
115438                                 function () {});
115439                             return null;
115440                         } else {
115441                             setTimeout(function () {
115442                                 onError(new WebAPIError(errorcode.IO_ERR));
115443                             }, 1);
115444                         }
115445                     }
115446                 } else {
115447                     if (onError) {
115448                         setTimeout(function () {
115449                             onError(new WebAPIError(errorcode.SECURITY_ERR));
115450                         }, 1);
115451                     }
115452                 }
115453             } else {
115454                 if (onError) {
115455                     setTimeout(function () {
115456                         onError(new WebAPIError(errorcode.IO_ERR));
115457                     }, 1);
115458                 }
115459             }
115460         }
115461
115462         return undefined;
115463     }
115464
115465     _self = {
115466         toURI: function () {
115467             return "file://" + _entry.fullPath;
115468         },
115469         listFiles: function (onSuccess, onError, filter) {
115470             var _filter, _filterName, _startCreated, _endCreated, _startModified, _endModified;
115471
115472             if (filter !== null && filter !== undefined) {
115473
115474                 if (typeof filter === 'number' || typeof filter === 'string') {
115475                     throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
115476                 }
115477                 _filter = filter;
115478                 _filterName = _filter.name;
115479                 _startModified = _filter.startModified;
115480                 _endModified   = _filter.endModified;
115481                 _startCreated = _filter.startCreated;
115482                 _endCreated   = _filter.endCreated;
115483
115484             }
115485             if ((_filterName !== undefined && typeof _filterName !== 'string') ||
115486                 (_startModified !== undefined && !tizen1_utils.isValidDate(_startModified)) ||
115487                 (_endModified !== undefined && !tizen1_utils.isValidDate(_endModified)) ||
115488                 (_endCreated !== undefined && !tizen1_utils.isValidDate(_endCreated)) ||
115489                 (_startCreated !== undefined && !tizen1_utils.isValidDate(_startCreated))) {
115490                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
115491             }
115492
115493             function _matchName(fileName) {
115494                 var _matched = true,
115495                     _name1 = String(_filterName).toLowerCase(),
115496                     _name2 = fileName.toLowerCase(),
115497                     _pattern;
115498
115499                 if (_filterName !== undefined && _filterName !== null) {
115500                     if (!_name1.match("\\\\%")) {
115501                         if (_name1.match("%")) {
115502                             _pattern = new RegExp("^" + _name1.replace(/%/g, ".*") + "$");
115503                             _matched = _name2.match(_pattern) ? true : false;
115504                         } else {
115505                             _matched = (_name1 === _name2);
115506                         }
115507                     } else {
115508                         // % is not allowed as a part of file name
115509                         _matched = false;
115510                     }
115511                 }
115512
115513                 return _matched;
115514             }
115515
115516             function _matchDate(date) {
115517                 var _matched = true;
115518
115519                 if (date === undefined) return true;
115520
115521                 if (_startModified !== undefined && _startModified !== null) {
115522                     _matched = (date.getTime() >= _startModified.getTime());
115523                 }
115524
115525                 if (_matched && (_endModified !== undefined && _endModified !== null)) {
115526                     _matched = (date.getTime() <= _endModified.getTime());
115527                 }
115528
115529                 return _matched;
115530             }
115531
115532             function _matchFilter(entry) {
115533                 return _matchName(entry.name) && _matchDate(entry.lastModifiedDate) && _matchDate(entry.createdDate);
115534             }
115535
115536             function _listFiles() {
115537                 var _files = [];
115538
115539                 if (!_entry.isDirectory) {
115540                     if (onError) {
115541                         setTimeout(function () {
115542                             onError(new WebAPIError(errorcode.IO_ERR));
115543                         }, 1);
115544                     }
115545                     return undefined;
115546                 }
115547
115548                 utils.forEach(_entry.children, function (child) {
115549                     if (_matchFilter(child)) {
115550                         _files.push(new File(child, _mode));
115551                     }
115552                 });
115553
115554                 setTimeout(function () {
115555                     onSuccess(_files);
115556                 }, 1);
115557
115558                 return null;
115559             }
115560
115561             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listFiles", _listFiles);
115562         },
115563         openStream: function (mode, onSuccess, onError, encoding) {
115564             function _openStream() {
115565                 var  _openMode = String(mode),
115566                     _encoding = encoding ? String(encoding) : "UTF-8";
115567
115568                 if (_openMode !== "r" && _openMode !== "w" && _openMode !== "a") {
115569                     if (onError) {
115570                         setTimeout(function () {
115571                             onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
115572                         }, 1);
115573                     }
115574                     return undefined;
115575                 }
115576
115577                 if (!_security.all && ((!_security.openStreamR && _openMode === "r") || (!_security.openStreamW && _openMode === "w"))) {
115578                     throw new WebAPIException(errorcode.SECURITY_ERR);
115579                 }
115580
115581                 if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
115582                     if (onError) {
115583                         setTimeout(function () {
115584                             onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
115585                         }, 1);
115586                     }
115587                     return undefined;
115588                 }
115589
115590                 if (((_readOnly || _mode === "r") && (_openMode === "w" || _openMode === "a")) ||
115591                     (_writeOnly && _openMode === "r")) {
115592                     if (onError) {
115593                         setTimeout(function () {
115594                             onError(new WebAPIError(errorcode.SECURITY_ERR));
115595                         }, 1);
115596                     }
115597                     return undefined;
115598                 }
115599
115600                 setTimeout(function () {
115601                     onSuccess(new FileStream(_entry, _openMode, _encoding));
115602                 }, 1);
115603
115604                 return null;
115605             }
115606
115607             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "openStream", _openStream);
115608         },
115609         readAsText: function (onSuccess, onError, encoding) {
115610             if (!_security.all && !_security.readAsText) {
115611                 throw new WebAPIException(errorcode.SECURITY_ERR);
115612             }
115613
115614             function _readAsText() {
115615                 var _encoding = encoding ? String(encoding) : "UTF-8";
115616                 if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
115617                     if (onError) {
115618                         setTimeout(function () {
115619                             onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
115620                         }, 1);
115621                     }
115622                     return undefined;
115623                 }
115624
115625                 if (_writeOnly) {
115626                     if (onError) {
115627                         setTimeout(function () {
115628                             onError(new WebAPIError(errorcode.SECURITY_ERR));
115629                         }, 1);
115630                     }
115631                     return undefined;
115632                 }
115633
115634                 if (_self.isFile) {
115635                     dbfs.read(_entry.fullPath,
115636                             function (data) {
115637                                 setTimeout(function () {
115638                                     onSuccess(data);
115639                                 }, 1);
115640                             },
115641                             function () {});
115642                     return null;
115643                 } else {
115644                     if (onError) {
115645                         setTimeout(function () {
115646                             onError(new WebAPIError(errorcode.IO_ERR));
115647                         }, 1);
115648                     }
115649                 }
115650
115651                 return undefined;
115652             }
115653
115654             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "readAsText", _readAsText);
115655         },
115656         copyTo: function (src, dst, overwrite, onSuccess, onError) {
115657             if (!_security.all && !_security.copyTo) {
115658                 throw new WebAPIException(errorcode.SECURITY_ERR);
115659             }
115660
115661             function _copyTo() {
115662                 return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.cp);
115663             }
115664
115665             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "copyTo", _copyTo);
115666         },
115667         moveTo: function (src, dst, overwrite, onSuccess, onError) {
115668             if (!_security.all && !_security.moveTo) {
115669                 throw new WebAPIException(errorcode.SECURITY_ERR);
115670             }
115671
115672             function _moveTo() {
115673                 return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.mv);
115674             }
115675
115676             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "moveTo", _moveTo);
115677         },
115678         createDirectory: function (dirPath) {
115679             var _path  = String(dirPath),
115680                 _parts = _path.replace(/\/$/, "").split("/"),
115681                 _dir   = null,
115682                 _exist = null,
115683                 _current = _entry.fullPath,
115684                 _i;
115685
115686             if (!_security.all && !_security.createDirectory) {
115687                 throw new WebAPIException(errorcode.SECURITY_ERR);
115688             }
115689
115690             function onSuccess(entry) {
115691                 _dir = entry;
115692             }
115693
115694             for (_i = 0; _i < _parts.length; _i++) {
115695                 if (!_isValidFileName(_parts[_i])) {
115696                     throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
115697                 }
115698             }
115699
115700             if (!entry.isDirectory) {
115701                 throw new WebAPIException(errorcode.IO_ERR);
115702             }
115703
115704             _exist = _parts.reduce(function (obj, token) {
115705                 return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
115706             }, _entry);
115707
115708             if (_exist) {
115709                 throw new WebAPIException(errorcode.IO_ERR);
115710             }
115711
115712             if (_readOnly || _mode === "r") {
115713                 throw new WebAPIException(errorcode.SECURITY_ERR);
115714             }
115715
115716             for (_i = 0; _i < _parts.length; _i++) {
115717                 _current = _current + "/" + _parts[_i];
115718                 dbfs.mkdir(_current, onSuccess);
115719             }
115720
115721             return new File(_dir, _mode);
115722         },
115723         createFile: function (filePath) {
115724             var _name = String(filePath),
115725                 _file = null;
115726
115727             if (!_security.all && !_security.createFile) {
115728                 throw new WebAPIException(errorcode.SECURITY_ERR);
115729             }
115730
115731             if (!_isValidFileName(_name)) {
115732                 throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
115733             }
115734
115735             if (!entry.isDirectory || (_entry.children && _entry.children[_name])) {
115736                 throw new WebAPIException(errorcode.IO_ERR);
115737             }
115738
115739             if (_readOnly || _mode === "r") {
115740                 throw new WebAPIException(errorcode.SECURITY_ERR);
115741             }
115742
115743             dbfs.touch(_entry.fullPath + "/" + _name,
115744                         function (entry) {
115745                             _file = new File(entry, _mode);
115746                         },
115747                         function () {});
115748
115749             return _file;
115750         },
115751         resolve: function (filePath) {
115752             var _fullPath = _self.fullPath + "/" + String(filePath),
115753                 _file = null;
115754
115755             if (!_entry.isDirectory) {
115756                 throw new WebAPIException(errorcode.IO_ERR);
115757             }
115758
115759             _resolveSync(_fullPath,
115760                     function (file) {
115761                         _file = file;
115762                     },
115763                     function (e) {
115764                         throw (e);
115765                     },
115766                     _mode);
115767
115768             return _file;
115769         },
115770         deleteDirectory: function (directory, recursive, onSuccess, onError) {
115771             if (!_security.all && !_security.deleteDirectory) {
115772                 throw new WebAPIException(errorcode.SECURITY_ERR);
115773             }
115774
115775             function _deleteDirectory() {
115776                 var _dir = null,
115777                     _dirName = String(directory);
115778                 _resolveSync(_dirName,
115779                         function (file) {
115780                             _dir = file;
115781                         },
115782                         function (e) {
115783                             setTimeout(function () {
115784                                 onError(e);
115785                             }, 1);
115786                         },
115787                         _mode);
115788
115789                 if (_dir) {
115790                     if (_dir.isDirectory &&
115791                         _dir.parent.fullPath === _self.fullPath &&
115792                         (!recursive && _dir.length === 0)) {
115793                         if (!_readOnly && _mode !== "r") {
115794                             dbfs.rmdir(_v2r(_dirName),
115795                                     function () {
115796                                         setTimeout(function () {
115797                                             onSuccess();
115798                                         }, 1);
115799                                     },
115800                                     function () {});
115801                             return null;
115802                         } else {
115803                             if (onError) {
115804                                 setTimeout(function () {
115805                                     onError(new WebAPIError(errorcode.SECURITY_ERR));
115806                                 }, 1);
115807                             }
115808                         }
115809                     } else {
115810                         if (onError) {
115811                             setTimeout(function () {
115812                                 onError(new WebAPIError(errorcode.IO_ERR));
115813                             }, 1);
115814                         }
115815                     }
115816                 }
115817
115818                 return undefined;
115819             }
115820
115821             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteDirectory", _deleteDirectory);
115822         },
115823         deleteFile: function (fileName, onSuccess, onError) {
115824             if (!_security.all && !_security.deleteFile) {
115825                 throw new WebAPIException(errorcode.SECURITY_ERR);
115826             }
115827
115828             function _deleteFile() {
115829                 var _file = null;
115830                 _resolveSync(String(fileName),
115831                         function (file) {
115832                             _file = file;
115833                         },
115834                         function (e) {
115835                             if (onError) {
115836                                 setTimeout(function () {
115837                                     onError(e);
115838                                 }, 1);
115839                             }
115840                         },
115841                         _mode);
115842
115843                 if (_file) {
115844                     if (_file.isFile && _file.parent.fullPath === _self.fullPath) {
115845                         if (!_readOnly && _mode !== "r") {
115846                             dbfs.rm(_v2r(fileName),
115847                                     function () {
115848                                         setTimeout(function () {
115849                                             onSuccess();
115850                                         }, 1);
115851                                     },
115852                                     function () {});
115853                             return null;
115854                         } else {
115855                             if (onError) {
115856                                 setTimeout(function () {
115857                                     onError(new WebAPIError(errorcode.SECURITY_ERR));
115858                                 }, 1);
115859                             }
115860                         }
115861                     } else {
115862                         if (onError) {
115863                             setTimeout(function () {
115864                                 onError(new WebAPIError(errorcode.IO_ERR));
115865                             }, 1);
115866                         }
115867                     }
115868                 }
115869
115870                 return undefined;
115871             }
115872
115873             return tizen1_utils.validateTypeMismatch(onSuccess, onError, "deleteFile", _deleteFile);
115874         }
115875     };
115876
115877     _self.__defineGetter__("parent", function () {
115878         var _parts = _self.fullPath.split("/");
115879
115880         if (_parent === undefined) {
115881             if (_parts.length === 1) {
115882                 // virtual root's parent is null
115883                 _parent = null;
115884             } else {
115885                 _resolveSync(_parts.splice(0, _parts.length - 1).join("/"),
115886                         function (file) {
115887                             _parent = file;
115888                         },
115889                         function () {},
115890                         _mode);
115891             }
115892             return _parent;
115893         } else {
115894             return _parent;
115895         }
115896     });
115897
115898     _self.__defineGetter__("readOnly", function () {
115899         return false;
115900     });
115901
115902     _self.__defineGetter__("isFile", function () {
115903         return !_entry.isDirectory;
115904     });
115905
115906     _self.__defineGetter__("isDirectory", function () {
115907         return _entry.isDirectory;
115908     });
115909
115910     _self.__defineGetter__("created", function () {
115911         return _entry.createdDate;
115912     });
115913
115914     _self.__defineGetter__("modified", function () {
115915         return _entry.lastModifiedDate;
115916     });
115917
115918     _self.__defineGetter__("path", function () {
115919         var _parts = _self.fullPath.split("/");
115920
115921         if (_parts.length === 1) {
115922             // virtual root
115923             return _parts.join("");
115924         } else {
115925             return _parts.splice(0, _parts.length - 1).join("/") + "/";
115926         }
115927     });
115928
115929     _self.__defineGetter__("name", function () {
115930         return _entry.name;
115931     });
115932
115933     _self.__defineGetter__("fullPath", function () {
115934         return _r2v(_entry.fullPath);
115935     });
115936
115937     _self.__defineGetter__("fileSize", function () {
115938         if (_entry.isDirectory) {
115939             return undefined;
115940         } else {
115941             return _entry.data.length;
115942         }
115943     });
115944
115945     _self.__defineGetter__("length", function () {
115946         var _l = 0;
115947         if (_entry.isDirectory) {
115948             utils.forEach(_entry.children, function () {
115949                 _l++;
115950             });
115951             return _l;
115952         } else {
115953             return undefined;
115954         }
115955     });
115956
115957     return _self;
115958 };
115959
115960 FileStream = function (entry, mode, encoding) {
115961     var _entry = entry,
115962         _data = entry.data,
115963         _mode = mode,
115964         _position = (_mode === "a" ? _data.length : 0),
115965         _self;
115966
115967     _self = {
115968         close: function () {
115969             var _element;
115970             if (mode === "a" || mode === "w") {
115971                 dbfs.write(_entry.fullPath, _data, function () {}, function () {});
115972             }
115973             for (_element in _self) {
115974                 delete _self[_element];
115975             }
115976         },
115977         read: function (charCount) {
115978             var _count  = charCount | 0,
115979                 _substr = _data.substring(_position, _position + _count);
115980
115981             if (_position + _count > _data.length) {
115982                 _position = _data.length;
115983             } else {
115984                 _position += _count;
115985             }
115986
115987             return _substr;
115988         },
115989         readBytes: function (byteCount) {
115990             var _substr = _self.read(byteCount),
115991                 _bytes = [],
115992                 _i;
115993
115994             for (_i = 0; _i < _substr.length; _i++) {
115995                 _bytes.push(_substr.charCodeAt(_i));
115996             }
115997
115998             return _bytes;
115999         },
116000         readBase64: function (byteCount) {
116001             var _substr = _self.read(byteCount);
116002
116003             return window.atob(_substr);
116004         },
116005         write: function (stringData) {
116006             var _stringData = String(stringData),
116007                 _substr = _data.substring(0, _position);
116008
116009             _data = _substr.concat(_stringData);
116010             _position = _data.length;
116011         },
116012         writeBytes: function (byteData) {
116013             _self.write(String.fromCharCode.apply(String, byteData));
116014         },
116015         writeBase64: function (base64Data) {
116016             _self.write(window.btoa(String(base64Data)));
116017         }
116018     };
116019
116020     _self.__defineGetter__("eof", function () {
116021         return _position === _data.length;
116022     });
116023
116024     _self.__defineGetter__("position", function () {
116025         return _position;
116026     });
116027
116028     _self.__defineSetter__("position", function (value) {
116029         var _value = value | 0;
116030
116031         if (_value >= 0 && _value <= _data.length) {
116032             _position = _value;
116033         } else {
116034             throw new WebAPIException(errorcode.INVALID_VALUES_ERR);
116035         }
116036     });
116037
116038     _self.__defineGetter__("bytesAvailable", function () {
116039         return (_data.length - _position) || -1;
116040     });
116041
116042     return _self;
116043 };
116044
116045 FileFilter = function (name, startModified, endModified, startCreated, endCreated) {
116046     var _self = {
116047         name: name,
116048         startModified: utils.copy(startModified),
116049         endModified: utils.copy(endModified),
116050         endCreated: utils.copy(endCreated)
116051     };
116052
116053     return _self;
116054 };
116055
116056 FileSystemStorage = function (label, type, state) {
116057     var _self = {
116058         label: label,
116059         type: type,
116060         state: state
116061     };
116062
116063     return _self;
116064 };
116065
116066 module.exports = {
116067     maxPathLength: _maxPathLength,
116068     resolve: function (srcLocation, onSuccess, onError, accessMode) {
116069         function _resolve() {
116070             var _mode = accessMode ? String(accessMode) : _defaultMode;
116071
116072             if (_mode === "r" || _mode === "rw") {
116073                 _resolveAsync(onSuccess, onError, String(srcLocation), _mode);
116074                 return null;
116075             } else {
116076                 if (onError) {
116077                     setTimeout(function () {
116078                         onError(new WebAPIError(errorcode.INVALID_VALUES_ERR));
116079                     }, 1);
116080                 }
116081             }
116082             return undefined;
116083         }
116084
116085         return tizen1_utils.validateTypeMismatch(onSuccess, onError, "resolve", _resolve);
116086     },
116087
116088     getStorage: function (label, onSuccess, onError) {
116089         var storage = null, _label = String(label);
116090
116091         _storages.some(function (value) {
116092             if (value.label === _label) {
116093                 storage = utils.copy(value);
116094                 setTimeout(function () {
116095                     onSuccess(storage);
116096                 }, 1);
116097                 return true;
116098             }
116099         });
116100
116101         if (!storage) {
116102             if(onError) {
116103                 setTimeout(function () {
116104                     onError(new WebAPIError(errorcode.NOT_FOUND_ERR));
116105                 }, 1);
116106
116107             } else {
116108                 throw new WebAPIException(errorcode.NOT_FOUND_ERR);
116109             }
116110         }
116111     },
116112
116113     listStorages: function (onSuccess, onError) {
116114         function _listStorages() {
116115             setTimeout(function () {
116116                 onSuccess(utils.copy(_storages));
116117             }, 1);
116118         }
116119
116120         return tizen1_utils.validateTypeMismatch(onSuccess, onError, "listStorages", _listStorages);
116121     },
116122
116123     addStorageStateChangeListener: function(onSuccess, onError) {
116124         function _addStorageStateChangeListener() {
116125             var watchId = (new Date()).getTime() || 0;
116126                 _observers[watchId] = function(storage) {//storage is which state is changed
116127                 onSuccess(storage);
116128             };
116129
116130             // This event should be triggered from outside
116131             event.on("StateChange", _observers[watchId]);
116132             return Number(watchId);
116133         }
116134
116135         return tizen1_utils.validateTypeMismatch(onSuccess, onError, "addStorageStateChangeListener", _addStorageStateChangeListener);
116136     },
116137
116138     removeStorageStateChangeListener: function (watchId) {
116139         if (!_observers[watchId])
116140             return;
116141
116142         event.deleteEventHandler("StateChange", _observers[watchId]);
116143         delete _observers[watchId];
116144     },
116145
116146     handleSubFeatures: function (subFeatures) {
116147         function setSecurity(_security) {
116148             return function (method) {
116149                 _security[method] = true;
116150             };
116151         }
116152
116153         for (var subFeature in subFeatures) {
116154             if (_security[subFeature].length === 0) {
116155                 _security.all = true;
116156                 return;
116157             }
116158             _security.all = false;
116159             utils.forEach(_security[subFeature], setSecurity);
116160         }
116161     }
116162 };
116163
116164
116165 });
116166 define('ripple/platform/tizen/2.0/ContactName', function (require, exports, module) {
116167 /*
116168  *  Copyright 2013 Intel Corporation.
116169  *
116170  * Licensed under the Apache License, Version 2.0 (the "License");
116171  * you may not use this file except in compliance with the License.
116172  * You may obtain a copy of the License at
116173  *
116174  * http://www.apache.org/licenses/LICENSE-2.0
116175  *
116176  * Unless required by applicable law or agreed to in writing, software
116177  * distributed under the License is distributed on an "AS IS" BASIS,
116178  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
116179  * See the License for the specific language governing permissions and
116180  * limitations under the License.
116181  */
116182
116183 var t = require('ripple/platform/tizen/2.0/typecast'),
116184     ContactName;
116185
116186 ContactName = function (nameInitDict) {
116187     var contactName = {}, attr;
116188
116189     t.ContactName(arguments, this);
116190
116191     contactName.prefix            = null;
116192     contactName.suffix            = null;
116193     contactName.firstName         = null;
116194     contactName.middleName        = null;
116195     contactName.lastName          = null;
116196     contactName.nicknames         = [];
116197     contactName.phoneticFirstName = null;
116198     contactName.phoneticLastName  = null;
116199
116200     this.__defineGetter__("prefix", function () {
116201         return contactName.prefix;
116202     });
116203     this.__defineSetter__("prefix", function (val) {
116204         try {
116205             contactName.prefix = t.DOMString(val, "?");
116206         } catch (e) {
116207         }
116208     });
116209
116210     this.__defineGetter__("suffix", function () {
116211         return contactName.suffix;
116212     });
116213     this.__defineSetter__("suffix", function (val) {
116214         try {
116215             contactName.suffix = t.DOMString(val, "?");
116216         } catch (e) {
116217         }
116218     });
116219
116220     this.__defineGetter__("firstName", function () {
116221         return contactName.firstName;
116222     });
116223     this.__defineSetter__("firstName", function (val) {
116224         try {
116225             contactName.firstName = t.DOMString(val, "?");
116226         } catch (e) {
116227         }
116228     });
116229
116230     this.__defineGetter__("middleName", function () {
116231         return contactName.middleName;
116232     });
116233     this.__defineSetter__("middleName", function (val) {
116234         try {
116235             contactName.middleName = t.DOMString(val, "?");
116236         } catch (e) {
116237         }
116238     });
116239
116240     this.__defineGetter__("lastName", function () {
116241         return contactName.lastName;
116242     });
116243     this.__defineSetter__("lastName", function (val) {
116244         try {
116245             contactName.lastName = t.DOMString(val, "?");
116246         } catch (e) {
116247         }
116248     });
116249
116250     this.__defineGetter__("nicknames", function () {
116251         return contactName.nicknames;
116252     });
116253     this.__defineSetter__("nicknames", function (val) {
116254         try {
116255             contactName.nicknames = t.DOMString(val, "[]");
116256         } catch (e) {
116257         }
116258     });
116259
116260     this.__defineGetter__("phoneticFirstName", function () {
116261         return contactName.phoneticFirstName;
116262     });
116263     this.__defineSetter__("phoneticFirstName", function (val) {
116264         try {
116265             contactName.phoneticFirstName = t.DOMString(val, "?");
116266         } catch (e) {
116267         }
116268     });
116269
116270     this.__defineGetter__("phoneticLastName", function () {
116271         return contactName.phoneticLastName;
116272     });
116273     this.__defineSetter__("phoneticLastName", function (val) {
116274         try {
116275             contactName.phoneticLastName = t.DOMString(val, "?");
116276         } catch (e) {
116277         }
116278     });
116279
116280     this.__defineGetter__("displayName", function () {
116281         return null;
116282     });
116283
116284     if (nameInitDict) {
116285         for (attr in nameInitDict) {
116286             contactName[attr] = nameInitDict[attr];
116287         }
116288     }
116289 };
116290
116291 module.exports = ContactName;
116292
116293 });
116294 define('ripple/platform/tizen/2.0/Conversation', function (require, exports, module) {
116295 /*
116296  *  Copyright 2012 Intel Corporation.
116297  *
116298  * Licensed under the Apache License, Version 2.0 (the "License"),
116299  * you may not use this file except in compliance with the License.
116300  * You may obtain a copy of the License at
116301  *
116302  * http://www.apache.org/licenses/LICENSE-2.0
116303  *
116304  * Unless required by applicable law or agreed to in writing, software
116305  * distributed under the License is distributed on an "AS IS" BASIS,
116306  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
116307  * See the License for the specific language governing permissions and
116308  * limitations under the License.
116309  */
116310 var utils = require('ripple/utils');
116311
116312 module.exports = function (opt) {
116313     var conv = {}, priv = utils.copy(opt);
116314
116315     conv.__defineGetter__("id", function () {
116316         return priv.id;
116317     });
116318     conv.__defineGetter__("type", function () {
116319         return priv.type;
116320     });
116321     conv.__defineGetter__("timestamp", function () {
116322         return priv.timestamp;
116323     });
116324     conv.__defineGetter__("messageCount", function () {
116325         return priv.messageCount;
116326     });
116327     conv.__defineGetter__("unreadMessages", function () {
116328         return priv.unreadMessages;
116329     });
116330     conv.__defineGetter__("preview", function () {
116331         return priv.preview;
116332     });
116333     conv.__defineGetter__("subject", function () {
116334         return priv.subject;
116335     });
116336     conv.__defineGetter__("isRead", function () {
116337         return priv.isRead;
116338     });
116339     conv.__defineGetter__("from", function () {
116340         return priv.from;
116341     });
116342     conv.__defineGetter__("to", function () {
116343         return priv.to;
116344     });
116345     conv.__defineGetter__("cc", function () {
116346         return priv.cc;
116347     });
116348     conv.__defineGetter__("bcc", function () {
116349         return priv.bcc;
116350     });
116351     conv.__defineGetter__("lastMessageId", function () {
116352         return priv.lastMessageId;
116353     });
116354     return conv;
116355 };
116356
116357 });
116358 define('ripple/platform/tizen/2.0/push', function (require, exports, module) {
116359 /*
116360  *  Copyright 2013 Intel Corporation.
116361  *
116362  * Licensed under the Apache License, Version 2.0 (the "License");
116363  * you may not use this file except in compliance with the License.
116364  * You may obtain a copy of the License at
116365  *
116366  * http://www.apache.org/licenses/LICENSE-2.0
116367  *
116368  * Unless required by applicable law or agreed to in writing, software
116369  * distributed under the License is distributed on an "AS IS" BASIS,
116370  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
116371  * See the License for the specific language governing permissions and
116372  * limitations under the License.
116373  */
116374
116375 var event = require('ripple/event'),
116376     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
116377     t = require('ripple/platform/tizen/2.0/typecast'),
116378     Notification = require('ripple/platform/tizen/2.0/notification'),
116379     StatusNotification = require('ripple/platform/tizen/2.0/StatusNotification'),
116380     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
116381     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
116382     PushMessage,
116383     _data = {
116384         service: {
116385 /*          "ID_APPLICATION_0": {
116386  *              appId:          null,
116387  *              registrationId: null,
116388  *              appControl:     null,
116389  *              isRegistered:   false,
116390  *              isConnected:    false,
116391  *              onpushed:       null
116392  *          }
116393  */
116394         }
116395     },
116396     _security = {
116397         "http://tizen.org/privilege/push": ["registerService",
116398             "unregisterService", "connectService", "disconnectService",
116399             "getRegistrationId"]
116400     },
116401     _self;
116402
116403 function _initialize() {
116404     event.on("PushNotified", function (appId, pushMessage) {
116405         var appService, notificationDict, statusNotification, notification;
116406
116407         appService = _data.service[appId];
116408
116409         if (!appService)
116410             return;
116411
116412         if (appService.isConnected) {
116413             appService.onpushed(new PushMessage(pushMessage));
116414         } else {
116415             notificationDict = {
116416                 content: pushMessage.appData,
116417                 appControl: appService.appControl,
116418                 appId: appId
116419             };
116420             statusNotification = new StatusNotification("SIMPLE",
116421                 pushMessage.alertMessage, notificationDict);
116422             notification = new Notification();
116423
116424             notification.post(statusNotification);
116425         }
116426     });
116427 }
116428
116429 function _getCurrentApplicationId() {
116430     return "ID_APPLICATION_0";
116431 }
116432
116433 _self = function () {
116434     var push;
116435
116436     function registerService(appControl, successCallback, errorCallback) {
116437         if (!_security.registerService) {
116438             throw new WebAPIException(errorcode.SECURITY_ERR);
116439         }
116440
116441         t.PushManager("registerService", arguments, true);
116442
116443         window.setTimeout(function () {
116444             var appId, appService;
116445
116446             appId = _getCurrentApplicationId();
116447             appService = {
116448                 appId:          appId,
116449                 registrationId: null,
116450                 appControl:     appControl,
116451                 isRegistered:   false
116452             };
116453             _data.service[appId] = appService;
116454
116455             event.trigger("PushRequest", ["REGISTER", appService], true);
116456
116457             if (appService.registrationId === null) {
116458                 if (errorCallback) {
116459                     errorCallback(new WebAPIError(errorcode.UNKNOWN_ERR));
116460                 }
116461                 return;
116462             }
116463
116464             appService.isRegistered = true;
116465             successCallback(appService.registrationId);
116466         }, 1);
116467     }
116468
116469     function unregisterService(successCallback, errorCallback) {
116470         if (!_security.unregisterService) {
116471             throw new WebAPIException(errorcode.SECURITY_ERR);
116472         }
116473
116474         t.PushManager("unregisterService", arguments);
116475
116476         window.setTimeout(function () {
116477             var appId;
116478
116479             appId = _getCurrentApplicationId();
116480             delete _data.service[appId];
116481             event.trigger("PushRequest", ["UNREGISTER", appId]);
116482             if (successCallback) {
116483                 successCallback();
116484             }
116485         }, 1);
116486     }
116487
116488     function connectService(notificationCallback) {
116489         var appId, appService;
116490
116491         if (!_security.connectService) {
116492             throw new WebAPIException(errorcode.SECURITY_ERR);
116493         }
116494
116495         t.PushManager("connectService", arguments);
116496
116497         appId = _getCurrentApplicationId();
116498         appService = _data.service[appId];
116499         if (!appService || !appService.isRegistered) {
116500             throw new WebAPIException(errorcode.UNKNOWN_ERR);
116501         }
116502
116503         appService.isConnected = true;
116504         appService.onpushed    = notificationCallback;
116505         event.trigger("PushRequest", ["CONNECT", appId]);
116506     }
116507
116508     function disconnectService() {
116509         var appId, appService;
116510
116511         if (!_security.disconnectService) {
116512             throw new WebAPIException(errorcode.SECURITY_ERR);
116513         }
116514
116515         t.PushManager("disconnectService", arguments);
116516
116517         appId = _getCurrentApplicationId();
116518         appService = _data.service[appId];
116519         if (!appService || !appService.isRegistered ||
116520                 !appService.isConnected) {
116521             return;
116522         }
116523
116524         appService.onpushed    = null;
116525         appService.isConnected = false;
116526         event.trigger("PushRequest", ["DISCONNECT", appId]);
116527     }
116528
116529     function getRegistrationId() {
116530         var appService;
116531
116532         if (!_security.getRegistrationId) {
116533             throw new WebAPIException(errorcode.SECURITY_ERR);
116534         }
116535
116536         t.PushManager("getRegistrationId", arguments);
116537
116538         appService = _data.service[_getCurrentApplicationId()];
116539         if (!appService || !appService.isRegistered) {
116540             return null;
116541         }
116542
116543         return appService.registrationId;
116544     }
116545
116546     function handleSubFeatures(subFeatures) {
116547         var i, subFeature;
116548
116549         for (subFeature in subFeatures) {
116550             for (i in _security[subFeature]) {
116551                 _security[_security[subFeature][i]] = true;
116552             }
116553         }
116554     }
116555
116556     push = {
116557         registerService:   registerService,
116558         unregisterService: unregisterService,
116559         connectService:    connectService,
116560         disconnectService: disconnectService,
116561         getRegistrationId: getRegistrationId,
116562         handleSubFeatures: handleSubFeatures
116563     };
116564
116565     return push;
116566 };
116567
116568 _initialize();
116569
116570 PushMessage = function (pushMessageInitDict) {
116571     var appData, alertMessage, date;
116572
116573     this.__defineGetter__("appData", function () {
116574         return appData;
116575     });
116576
116577     this.__defineGetter__("alertMessage", function () {
116578         return alertMessage;
116579     });
116580
116581     this.__defineGetter__("date", function () {
116582         return date;
116583     });
116584
116585     appData      = pushMessageInitDict.appData || "";
116586     alertMessage = pushMessageInitDict.alertMessage || "";
116587     date         = pushMessageInitDict.date || new Date();
116588 };
116589
116590 module.exports = _self;
116591
116592 });
116593 define('ripple/platform/tizen/2.0/routeBackend_navigation', function (require, exports, module) {
116594 /*
116595  *  Copyright 2012 Intel Corporation.
116596  *
116597  * Licensed under the Apache License, Version 2.0 (the "License");
116598  * you may not use this file except in compliance with the License.
116599  * You may obtain a copy of the License at
116600  *
116601  * http://www.apache.org/licenses/LICENSE-2.0
116602  *
116603  * Unless required by applicable law or agreed to in writing, software
116604  * distributed under the License is distributed on an "AS IS" BASIS,
116605  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
116606  * See the License for the specific language governing permissions and
116607  * limitations under the License.
116608  */
116609
116610 var tizen1_utils = require('ripple/platform/tizen/2.0/tizen1_utils'),
116611     lbs_utils = require('ripple/platform/tizen/2.0/lbs_utils'),
116612     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
116613     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
116614     SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates'),
116615     RouteWaypoint,
116616     RouteDistance,
116617     RouteDuration,
116618     RouteStep,
116619     RouteSegment,
116620     RouteRequestOptions,
116621     RouteResultSummary,
116622     RouteResult,
116623     _data = {
116624         positionDistance: {},
116625         positionDuration: {},
116626         routeProvider: {},
116627         routes: [],
116628         RouteDistanceUnit: ["M", "KM", "MI", "FT"],
116629         providers: [],
116630         path: []
116631     },
116632     _self;
116633
116634 // The RouteWaypoint object
116635 RouteWaypoint = function () {
116636     return {
116637         position: {
116638             latitude: 0,
116639             longitude: 0
116640         },
116641         isStopover: true
116642     };
116643 };
116644
116645 // The RouteDistance object
116646 RouteDistance = function () {
116647     return {
116648         text : "Distance",
116649         value : "0",
116650         unit : "KM "
116651     };
116652 };
116653
116654 // The RouteDuration object
116655 RouteDuration = function () {
116656     return {
116657         text : "Duration",
116658         value : "0" // The duration in a seconds
116659     };
116660 };
116661
116662 // The RouteStep object
116663 RouteStep = function () {
116664     var _self = {
116665         mode: "",        // The way of the travel, for example: car, bike, foot
116666         instruction: "", // The instruction of this step
116667         points: []       // The points of this step
116668     };
116669
116670     _self.origin      = new SimpleCoordinates(0, 0);
116671     _self.destination = new SimpleCoordinates(0, 0);
116672     _self.distance    = new RouteDistance();
116673     _self.duration    = new RouteDuration();
116674
116675     return _self;
116676 };
116677 // The RouteSegment object
116678 RouteSegment = function () {
116679     var _self = {
116680         steps: []
116681     };
116682
116683     _self.origin      = new SimpleCoordinates(0, 0);
116684     _self.destination = new SimpleCoordinates(0, 0);
116685     _self.distance    = new RouteDistance();
116686     _self.duration    = new RouteDuration();
116687
116688     return _self;
116689 };
116690
116691 // The RouteRequestOptions object
116692 RouteRequestOptions = function () {
116693     return {
116694         mode: "", // CAR, BIKE
116695         unit: "KM",
116696         routeGoal: "SHORTEST",
116697         constraints: ["HIGHWAY", "TOLL", "UNPAVED"],
116698         wayPoints: [],
116699         maxResults: 1
116700     };
116701 };
116702
116703 // The RouteResultSummary object
116704 RouteResultSummary = function () {
116705     var _self = {};
116706
116707     _self.origin        = new SimpleCoordinates(0, 0);
116708     _self.destination   = new SimpleCoordinates(0, 0);
116709     _self.totalDistance = new RouteDistance();
116710     _self.totalDuration = new RouteDuration();
116711
116712     return _self;
116713 };
116714
116715 // The RouteResult object
116716 RouteResult = function () {
116717     var _self, jsonStr, jsonObj;
116718     jsonObj = {
116719             "type" : "Point",
116720             "coordinates" : []
116721         };
116722     jsonStr = JSON.stringify(jsonObj);
116723     _self = {
116724         segments : [],
116725         toGeoJSON : function () {
116726                 return jsonStr;
116727             }
116728     };
116729     _self.summary = new RouteResultSummary();
116730     return _self;
116731 };
116732
116733 function calcDegree(distance) {
116734     return distance * Math.PI / 180.0;
116735 }
116736
116737 //calcute the distance
116738 function  calculateDistance(lat1, lat2, lon1, lon2) {
116739     var R = 6371, dLat, dLon, a, c, distance; // km
116740     dLat = calcDegree(parseFloat(lat2) - parseFloat(lat1));
116741     dLon = calcDegree(parseFloat(lon2) - parseFloat(lon1));
116742
116743     lat1 = calcDegree(lat1);
116744     lat2 = calcDegree(lat2);
116745
116746     a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
116747              Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
116748     c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
116749     distance = R * c;
116750     return distance;
116751 }
116752
116753 function calculateDuration(mode, distance) {
116754     var duration, v;
116755     switch (mode) {
116756     case "motorcar" :
116757         v = 50;
116758         duration = distance / v;
116759         break;
116760     case "bicycle" :
116761         v = 20;
116762         duration = distance / v;
116763         break;
116764     case "foot" :
116765         v = 5;
116766         duration = distance / v;
116767         break;
116768     default:
116769         duration = 0;
116770     }
116771     return duration;
116772 }
116773
116774 function optimalWay(points, mode) {
116775     var steps = [], startLatitude, startLongitude, originLocation, endLatitude, endLongitude,
116776     destinationLocation, step, distance, i, routeDistance, routeDuration;
116777     for (i = 0;i < points.length - 1;i++) {
116778         startLatitude       = points[i].lat;
116779         startLongitude      = points[i].lon;
116780         originLocation      = new SimpleCoordinates(startLatitude, startLongitude);
116781         endLatitude         = points[i + 1].lat;
116782         endLongitude        = points[i + 1].lon;
116783         destinationLocation = new SimpleCoordinates(endLatitude, endLongitude);
116784         step                = new RouteStep();
116785         step.origin         = originLocation;
116786         step.destination    = destinationLocation;
116787         distance            = calculateDistance(startLatitude, endLatitude, startLongitude, endLongitude);
116788         routeDistance       = new RouteDistance();
116789         routeDistance.value = distance;
116790         routeDistance.unit  = "km";
116791         step.distance       = routeDistance;
116792         routeDuration       = new RouteDuration();
116793         routeDuration.value = calculateDuration(mode, distance);
116794         step.duration       = routeDuration;
116795         steps.push(step);
116796     }
116797     return steps;
116798 }
116799
116800 function existInSupports(str, array) {
116801     for (var i in array) {
116802         if (str === array[i]) {
116803             return true;
116804         }
116805     }
116806     return false;
116807 }
116808
116809 function navigation(searchStr, flat, flon, tlat, tlon, v, fast) {
116810     var positions = [];
116811
116812     _data.positionDistance = {};
116813     _data.positionDuration = {};
116814     jQuery.ajax({
116815         type : "get",
116816         async : false,
116817         url : searchStr,
116818         data : {
116819             flat : flat,
116820             flon : flon,
116821             tlat : tlat,
116822             tlon : tlon,
116823             v : v,
116824             fast : fast,
116825             layer : 'mapnik',
116826             format : "geojson"
116827         },
116828         contentType : "application/json; charset=utf-8",
116829         dataType : "json",
116830         cache : false,
116831         success : function (data) {
116832             $.each(data.coordinates, function (i, item) {
116833                 var point = {};
116834                 point.lon = item[0];
116835                 point.lat = item[1];
116836                 positions.push(point);
116837             });
116838             $.each(data.properties, function (i, item) {
116839                 if (typeof item === "number") {
116840                     _data.positionDistance = new RouteDistance();
116841                     _data.positionDistance.value = item;
116842                     _data.positionDistance.unit = "km";
116843                     _data.positionDuration = new RouteDuration();
116844                     _data.positionDuration.value = calculateDuration(v, item);
116845                 }
116846             });
116847         },
116848         error : function (errorCB) {
116849             if (errorCB) {
116850                 setTimeout(function () {
116851                     errorCB(new WebAPIError(errorcode.NETWORK_ERR));
116852                 }, 1);
116853             }
116854         }
116855     });
116856     return positions;
116857 }
116858
116859
116860 function filterWaypoints(routeWaypoints) {
116861     var mathWaypoints = [], i;
116862     for (i in routeWaypoints) {
116863         if (routeWaypoints[i].position.latitude !== "" &&
116864             routeWaypoints[i].position.latitude !== undefined &&
116865             routeWaypoints[i].position.latitude !== null &&
116866             routeWaypoints[i].position.longitude !== null &&
116867             routeWaypoints[i].position.longitude !== "" &&
116868             routeWaypoints[i].position.longitude !== undefined) {
116869             mathWaypoints.push(routeWaypoints[i]);
116870         }
116871     }
116872     return mathWaypoints;
116873 }
116874
116875 module.exports = function (prop) {
116876     var _self = new lbs_utils.LocationServiceProvider(prop);
116877
116878     _self.supportedGoals       = ["SHORTEST", "FASTEST", "MOST_SCENIC", "SIMPLEST", "CHEAPEST", "SAFEST" ];
116879     _self.supportedModes       = ["motorcar", "bicycle", "foot"];
116880     _self.supportedConstraints = ["HIGHWAY", "TOLL", "UNPAVED", "BORDER", "GRAVEL_PAVING", "TUNNEL", "BRIDGE", "LEFT_TURN", "CARPOOL", "HAZARDOUS_CARGO" ];
116881     _self.supportsWayPoints    = true;
116882     _self.find = function (origin, destination, successCallback, errorCallback, options) {
116883         function _find() {
116884             var flat, flon, tlat, tlon, v, fast, searchStr, result,
116885                 routeWaypoints = [],
116886                 segmentPositions = [],
116887                 positions = [],
116888                 segments = [],
116889                 totalDistances = 0, totalDurations = 0,
116890                 k, key, segment, startPosition, endPosition,
116891                 summary, distance, duration;
116892
116893             v = options.mode;
116894             //init
116895             if (!existInSupports(v, _self.supportedModes)) {
116896                 throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
116897             }
116898             if (!existInSupports(options.routeGoal, _self.supportedGoals)) {
116899                 throw new WebAPIError(errorcode.TYPE_MISMATCH_ERR);
116900             }
116901             switch (options.routeGoal) {
116902             case "SHORTEST":
116903                 fast = 0;
116904                 break;
116905
116906             case "FASTEST":
116907                 fast = 1;
116908                 break;
116909
116910             case "SIMPLEST":
116911                 break;
116912
116913             case "MOST_SCENIC":
116914                 break;
116915
116916             case "CHEAPEST":
116917                 break;
116918
116919             case "SAFEST":
116920                 break;
116921
116922             default:
116923                 fast = 0;
116924             }
116925             searchStr      = "http://www.yournavigation.org/api/dev/gosmore.php";
116926             routeWaypoints = options.wayPoints;
116927             routeWaypoints = filterWaypoints(routeWaypoints);
116928             segmentPositions.push(origin);
116929
116930             if (routeWaypoints.length > 0) {
116931                 for (k in routeWaypoints) {
116932                     segmentPositions.push(routeWaypoints[k].position);
116933                 }
116934             }
116935             segmentPositions.push(destination);
116936
116937             for (key = 0; key < segmentPositions.length - 1; key++) {
116938                 segment             = new RouteSegment();
116939                 startPosition       = segmentPositions[key];
116940                 endPosition         = segmentPositions[key + 1];
116941                 segment.origin      = startPosition;
116942                 segment.destination = endPosition;
116943                 flat                = startPosition.latitude;
116944                 flon                = startPosition.longitude;
116945                 tlat                = endPosition.latitude;
116946                 tlon                = endPosition.longitude;
116947                 positions           = navigation(searchStr, flat, flon, tlat, tlon, v, fast);
116948                 segment.steps       = optimalWay(positions, v);
116949                 segment.distance    = _data.positionDistance;
116950                 totalDistances     += _data.positionDistance.value;
116951                 segment.duration    = _data.positionDuration;
116952                 totalDurations     += _data.positionDuration.value;
116953                 segments.push(segment);
116954             }
116955             result                = new RouteResult();
116956             summary               = new RouteResultSummary();
116957             summary.origin        = segmentPositions[0];
116958             summary.destination   = segmentPositions[segmentPositions.length - 1];
116959             distance              = new RouteDistance();
116960             distance.value        = totalDistances;
116961             distance.unit         = "km";
116962             summary.totalDistance = distance;
116963             duration              = new RouteDuration();
116964             duration.value        = totalDurations;
116965             summary.totalDuration = duration;
116966             result.segments       = segments;
116967             result.summary        = summary;
116968             successCallback(result);
116969         }
116970
116971         tizen1_utils.validateTypeMismatch(successCallback, errorCallback, "find", _find);
116972     };
116973
116974     return _self;
116975 };
116976
116977 });
116978 define('ripple/platform/tizen/2.0/GeocodeOptions', function (require, exports, module) {
116979 /*      
116980  *  Copyright 2012 Intel Corporation.
116981  *  
116982  * Licensed under the Apache License, Version 2.0 (the "License");
116983  * you may not use this file except in compliance with the License.
116984  * You may obtain a copy of the License at
116985  *  
116986  * http://www.apache.org/licenses/LICENSE-2.0
116987  *  
116988  * Unless required by applicable law or agreed to in writing, software
116989  * distributed under the License is distributed on an "AS IS" BASIS,
116990  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
116991  * See the License for the specific language governing permissions and
116992  * limitations under the License.
116993  */
116994
116995 var errorcode = require('ripple/platform/tizen/2.0/errorcode'),
116996     WebAPIError = require('ripple/platform/tizen/2.0/WebAPIError'),
116997     SortMode = require('ripple/platform/tizen/2.0/SortMode');
116998
116999 module.exports = function (_sortMode, _maxResults) {
117000     var _self;
117001     if (_sortMode !== null && _sortMode !== undefined) {
117002         if (typeof _sortMode !== "object") {
117003             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
117004         }
117005         try {
117006             new SortMode(_sortMode.attributeName, _sortMode.order);
117007         } catch (e) {
117008             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
117009         }
117010     }
117011     if (_maxResults !== null && _maxResults !== undefined) {
117012         if (typeof _maxResults !== "number") {
117013             throw (new WebAPIError(errorcode.TYPE_MISMATCH_ERR));
117014         }
117015     }
117016
117017     _self = {
117018         sortMode : _sortMode,
117019         maxResults : _maxResults || 0
117020     };
117021
117022     return _self;
117023 };
117024
117025
117026 });
117027 define('ripple/platform/tizen/2.0/tizen1_utils', function (require, exports, module) {
117028 /*
117029  *  Copyright 2011 Intel Corporation.
117030  *
117031  * Licensed under the Apache License, Version 2.0 (the "License");
117032  * you may not use this file except in compliance with the License.
117033  * You may obtain a copy of the License at
117034  *
117035  * http://www.apache.org/licenses/LICENSE-2.0
117036  *
117037  * Unless required by applicable law or agreed to in writing, software
117038  * distributed under the License is distributed on an "AS IS" BASIS,
117039  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
117040  * See the License for the specific language governing permissions and
117041  * limitations under the License.
117042  */
117043
117044 var self,
117045     utils = require('ripple/utils'),
117046     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
117047     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException');
117048
117049 self = module.exports = {
117050     _wac2_regexSanitize: function (regexString) {
117051         var escapePattern = /([^\\]|^)(%)/g, percentPattern = /\\%/g;
117052         return regexString.replace("^", "\\^")
117053                 .replace("$", "\\$")
117054                 .replace("(", "\\(")
117055                 .replace(")", "\\)")
117056                 .replace("<", "\\<")
117057                 .replace("[", "\\[")
117058                 .replace("{", "\\{")
117059                 .replace(/\\([^%])/, "\\\\$1")    /* don't replace \\% */
117060                 .replace("|", "\\|")
117061                 .replace(">", "\\>")
117062                 .replace(".", "\\.")
117063                 .replace("*", "\\*")
117064                 .replace("+", "\\+")
117065                 .replace("?", "\\?")
117066                 .replace(escapePattern, "$1.*")  /* replace % with .* */
117067                 .replace(percentPattern, "%");   /* strip excape of % */
117068     },
117069
117070     isValidDate: function (d) {
117071         if (Object.prototype.toString.call(d) !== "[object Date]")
117072             return false;
117073         return !isNaN(d.getTime());
117074     },
117075     isValidTZDate: function (d) {
117076         if (d &&  (d instanceof tizen.TZDate)) {
117077             return true;
117078         }
117079         return false;
117080     },
117081     isValidArray: function (a) {
117082         return (Object.prototype.toString.call(a) === "[object Array]");
117083     },
117084
117085     matchOptionArrayString: function (src, attr, pattern) {
117086         /* src.obj[attr] is a StringArray */
117087         var _pattern, re, _stringMatch;
117088         _pattern = this._wac2_regexSanitize(pattern);
117089         re = new RegExp("^" + _pattern + "$", "i");
117090
117091         _stringMatch = function (obj, index) {
117092             if (pattern.search(/^%*$/i) === 0)
117093                 return true;
117094             if (obj[attr] === undefined || obj[attr] === null)
117095                 return false;
117096             return obj[attr].some(function (f) {
117097                 return f.search(re) !== -1;
117098             });
117099         };
117100         return utils.filter(src, _stringMatch);
117101     },
117102
117103     matchAttributeBooleanFilter: function (src, attr, value) {
117104         // only support EXACTLY matchFlag
117105         var _booleanMatch, atr = attr.split(".");
117106
117107         if (atr.length === 2) {
117108             _booleanMatch = function (obj, index) {
117109                 if (!obj[atr[0]])
117110                     return false;
117111
117112                 return (obj[atr[0]][atr[1]] === value);
117113             };
117114         } else {
117115             _booleanMatch = function (obj, index) {
117116                 return (obj[attr] === value);
117117             };
117118         }
117119
117120         return utils.filter(src, _booleanMatch);
117121     },
117122
117123     matchAttributeArrayFilter: function (src, attr, matchFlag, value) {
117124         var _re, _arrayMatch, atr = attr.split("."), _existMatch;
117125
117126         if (atr.length === 2) {
117127             _existMatch = function (obj, index) {
117128                 if (!obj[atr[0]])
117129                     return false;
117130
117131                 return (obj[atr[0]][atr[1]] !== undefined);
117132             };
117133         } else {
117134             _existMatch = function (obj, index) {
117135                 return (obj[attr] !== undefined);
117136             };
117137         }
117138
117139         if (value === undefined || value === null) {
117140             return utils.filter(src, _existMatch);
117141         }
117142
117143         switch (matchFlag)
117144         {
117145         case "EXACTLY":
117146             _re = new RegExp("^" + value + "$");
117147             break;
117148         case "FULLSTRING":
117149             _re = new RegExp("^" + value + "$", "i");
117150             break;
117151         case "CONTAINS":
117152             _re = new RegExp(value, "i");
117153             break;
117154         case "STARTSWITH":
117155             _re = new RegExp("^" + value, "i");
117156             break;
117157         case "ENDSWITH":
117158             _re = new RegExp(value + "$", "i");
117159             break;
117160         case "EXISTS":
117161             return utils.filter(src, _existMatch);
117162         default:
117163             return [];
117164         }
117165
117166         if (atr.length === 2) {
117167             _arrayMatch = function (obj, index) {
117168                 if (!obj[atr[0]])
117169                     return false;
117170
117171                 return (obj[atr[0]][atr[1]] && obj[atr[0]][atr[1]].some(function (o) {
117172                     return (o.search(_re) !== -1);
117173                 }));
117174             };
117175         } else {
117176             _arrayMatch = function (obj, index) {
117177                 return (obj[attr] && obj[attr].some(function (o) {
117178                     return (o.search(_re) !== -1);
117179                 }));
117180             };
117181         }
117182
117183         return utils.filter(src, _arrayMatch);
117184     },
117185
117186     matchAttributeRangeFilter: function (src, attr, low, high) {
117187         var _rangeMatch, atr = attr.split(".");
117188
117189         if (atr.length === 2) {
117190             _rangeMatch = function (obj, index) {
117191                 var matched = true;
117192
117193                 if (!obj[atr[0]])
117194                     return false;
117195
117196                 if (low !== null && low !== undefined) {
117197                     matched = (obj[atr[0]][atr[1]] >= low);
117198                 }
117199                 if (matched && (high !== null && high !== undefined)) {
117200                     matched = (obj[atr[0]][atr[1]] <= high);
117201                 }
117202                 return matched;
117203             };
117204         } else {
117205             _rangeMatch = function (obj, index) {
117206                 var matched = true;
117207
117208                 if (low !== null && low !== undefined) {
117209                     matched = (obj[attr] >= low);
117210                 }
117211                 if (matched && (high !== null && high !== undefined)) {
117212                     matched = (obj[attr] <= high);
117213                 }
117214                 return matched;
117215             };
117216         }
117217         return utils.filter(src, _rangeMatch);
117218     },
117219
117220     matchAttributeFilter: function (src, attr, matchFlag, value) {
117221         var _re, _stringMatch, atr = attr.split("."),
117222             _existMatch;
117223
117224         if (atr.length === 2) {
117225             _existMatch = function (obj, index) {
117226                 if (!obj[atr[0]])
117227                     return false;
117228
117229                 return (obj[atr[0]][atr[1]] !== undefined);
117230             };
117231         } else {
117232             _existMatch = function (obj, index) {
117233                 return (obj[attr] !== undefined);
117234             };
117235         }
117236
117237         if (value === undefined || value === null) {
117238             return utils.filter(src, _existMatch);
117239         }
117240
117241         switch (matchFlag)
117242         {
117243         case "EXACTLY":
117244             _re = new RegExp("^" + value + "$");
117245             break;
117246         case "FULLSTRING":
117247             _re = new RegExp("^" + value + "$", "i");
117248             break;
117249         case "CONTAINS":
117250             _re = new RegExp(value, "i");
117251             break;
117252         case "STARTSWITH":
117253             _re = new RegExp("^" + value, "i");
117254             break;
117255         case "ENDSWITH":
117256             _re = new RegExp(value + "$", "i");
117257             break;
117258         case "EXISTS":
117259             return utils.filter(src, _existMatch);
117260         default:
117261             return [];
117262         }
117263         if (atr.length === 2) {
117264             _stringMatch = function (obj, index) {
117265                 if (!obj[atr[0]])
117266                     return false;
117267
117268                 if (matchFlag === "EXACTLY") {
117269                     return (obj[atr[0]][atr[1]] === value);
117270                 } else if (typeof obj[atr[0]][atr[1]] !== 'string') {
117271                     return false;
117272                 }
117273
117274                 return (obj[atr[0]][atr[1]].search(_re) !== -1);
117275             };
117276         } else {
117277             _stringMatch = function (obj, index) {
117278                 if (matchFlag === "EXACTLY") {
117279                     return (obj[attr] === value);
117280                 } else if (typeof obj[attr] !== 'string') {
117281                     return false;
117282                 }
117283
117284                 return (obj[attr].search(_re) !== -1);
117285             };
117286         }
117287         return utils.filter(src, _stringMatch);
117288     },
117289
117290     matchOptionString: function (src, attr, pattern) {
117291         /* src.obj[attr] is a string */
117292         var _stringMatch, _pattern, _re;
117293         _pattern = this._wac2_regexSanitize(pattern);
117294         _re = new RegExp("^" + _pattern + "$", "mi");
117295
117296         _stringMatch = function (obj, index) {
117297             return (obj[attr].search(_re) !== -1);
117298         };
117299         return utils.filter(src, _stringMatch);
117300     },
117301
117302     matchOptionDate: function (src, attr, filterStart, filterEnd) {
117303         var _dateMatch;
117304         _dateMatch = function (obj, index) {
117305             var matched = true, valueDate = obj[attr];
117306
117307             if (filterStart !== undefined && filterStart !== null) {
117308                 matched = (valueDate.getTime() >= filterStart.getTime());
117309             }
117310             if (matched && (filterEnd !== undefined && filterEnd !== null)) {
117311                 matched = (valueDate.getTime() <= filterEnd.getTime());
117312             }
117313             return matched;
117314         };
117315         return utils.filter(src, _dateMatch);
117316     },
117317
117318     matchOptionShortArray: function (src, attr, filterArray) {
117319         /* src.obj[attr] is a short, filterArray is an array
117320            i.e. find status is [CONFRIMED or TENTATIVE] */
117321         var arraySome = function (obj, index) {
117322             return filterArray.some(function (f) {
117323                 return f === obj[attr];
117324             });
117325         };
117326         return utils.filter(src, arraySome);
117327     },
117328
117329     validateArgumentType: function (arg, argType, errorObj) {
117330         var invalidArg = false;
117331
117332         switch (argType) {
117333         case "array":
117334             if (!arg instanceof Array) {
117335                 invalidArg = true;
117336             }
117337             break;
117338         case "date":
117339             if (!arg instanceof Date) {
117340                 invalidArg = true;
117341             }
117342             break;
117343         case "integer":
117344             if (typeof Number(arg) !== "number" || Number(arg) !== Math.floor(arg)) {
117345                 invalidArg = true;
117346             }
117347             break;
117348         default:
117349             if (typeof arg !== argType) {
117350                 invalidArg = true;
117351             }
117352             break;
117353         }
117354
117355         if (invalidArg) {
117356             throw errorObj;
117357         }
117358     },
117359
117360     validateCallbackType: function (successCallback, errorCallback) {
117361         if (successCallback) {
117362             this.validateArgumentType(successCallback, "function",
117363                 new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
117364         }
117365         if (errorCallback) {
117366             this.validateArgumentType(errorCallback, "function",
117367                 new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
117368         }
117369     },
117370
117371     validateEqualArrays: function (arrayOne, arrayTwo) {
117372         var isEqual = false, i;
117373
117374         if (Object.prototype.toString.call(arrayTwo) === "[object Array]" &&
117375             Object.prototype.toString.call(arrayTwo) === "[object Array]" &&
117376             arrayOne.length === arrayTwo.length) {
117377             isEqual = true;
117378             for (i in arrayOne) {
117379                 if (arrayOne[i] !== arrayTwo[i]) {
117380                     isEqual = false;
117381                     break;
117382                 }
117383             }
117384         }
117385         return isEqual;
117386     },
117387
117388     validateTypeMismatch: function (onSuccess, onError, name, callback) {
117389
117390         if (onSuccess === undefined || onSuccess === null) {
117391             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
117392         }
117393         this.validateArgumentType(onSuccess, "function",
117394                                   new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
117395         if (onError !== null && onError !== undefined) {
117396             this.validateArgumentType(onError, "function",
117397                                       new WebAPIException(errorcode.TYPE_MISMATCH_ERR));
117398         }
117399
117400         return callback && callback();
117401     },
117402
117403     isEmptyObject: function (obj) {
117404         var prop;
117405
117406         for (prop in obj) {
117407             return false;
117408         }
117409         return true;
117410     },
117411
117412     arrayComposite: function (mode, arrayA, arrayB) {
117413         var combinedArray = arrayA.concat(arrayB),
117414             intersectionArray = arrayA.filter(function (value) {
117415                 if (utils.arrayContains(arrayB, value)) {
117416                     return true;
117417                 }
117418
117419                 return false;
117420             });
117421
117422         switch (mode) {
117423         case "AND":
117424         case "INTERSECTION":
117425             return intersectionArray;
117426         case "OR":
117427         case "UNION":
117428             return intersectionArray.concat(combinedArray.filter(function (value) {
117429                 if (utils.arrayContains(intersectionArray, value)) {
117430                     return false;
117431                 }
117432
117433                 return true;
117434             }));
117435         default:
117436             return undefined;
117437         }
117438     },
117439
117440     isEqual: function (srcObj, aimObj) {
117441         var i;
117442
117443         if (typeof srcObj !== typeof aimObj) {
117444             return false;
117445         }
117446
117447         if (srcObj === null || srcObj === undefined || typeof srcObj === 'number' ||
117448             typeof srcObj === 'string' || typeof srcObj === 'boolean') {
117449             return srcObj === aimObj;
117450         }
117451
117452         for (i in srcObj) {
117453             if (!aimObj.hasOwnProperty(i) || !self.isEqual(srcObj[i], aimObj[i])) {
117454                 return false;
117455             }
117456         }
117457
117458         return true;
117459     },
117460
117461     query: function (objects, filter, sortMode, count, offset) {
117462         function isCompositeFilter(filter) {
117463             return (filter.type) ? true : false;
117464         }
117465
117466         function isAttributeFilter(filter) {
117467             return (filter.matchFlag) ? true : false;
117468         }
117469
117470         function getValue(obj, key) {
117471             var keys = key.split("."),
117472                 value = obj[keys[0]],
117473                 i;
117474
117475             for (i = 1; i < keys.length; i++) {
117476                 if (value[keys[i]]) {
117477                     value = value[keys[i]];
117478                 }
117479             }
117480
117481             return value;
117482         }
117483
117484         function _filter(objects, filter) {
117485             var i, results, eachResult, filterFunc;
117486
117487             if (isCompositeFilter(filter)) {
117488                 for (i in filter.filters) {
117489                     eachResult = _filter(objects, filter.filters[i]);
117490                     results = (results === undefined) ? eachResult : self.arrayComposite(filter.type, results, eachResult);
117491                 }
117492                 return results;
117493             }
117494
117495             if (isAttributeFilter(filter)) {
117496                 for (i in objects) {
117497                     if (filter.attributeName in objects[i])
117498                         break;
117499                 }
117500                 filterFunc = self.isValidArray(objects[i][filter.attributeName]) ? self.matchAttributeArrayFilter : self.matchAttributeFilter;
117501                 results = filterFunc(objects, filter.attributeName, filter.matchFlag, filter.matchValue);
117502             } else {
117503                 results = self.matchAttributeRangeFilter(objects, filter.attributeName, filter.initialValue, filter.endValue);
117504             }
117505
117506             return results;
117507         }
117508
117509         function _sort(objects, sortMode) {
117510             objects.sort(function (a, b) {
117511                 return (sortMode.order === "ASC") ?
117512                     (getValue(a, sortMode.attributeName) < getValue(b, sortMode.attributeName) ? -1 : 1):
117513                     (getValue(a, sortMode.attributeName) > getValue(b, sortMode.attributeName) ? -1 : 1);
117514             });
117515
117516             return objects;
117517         }
117518
117519         var res = objects;
117520
117521         if (filter) {
117522             res = _filter(res, filter);
117523         }
117524
117525         if (sortMode) {
117526             _sort(res, sortMode);
117527         }
117528
117529         if (offset || count) {
117530             offset = (offset > 0) ? offset : 0;
117531             res = (count > 0) ? res.slice(offset, offset + count) : res.slice(offset);
117532         }
117533
117534         return res;
117535     },
117536
117537     copyString: function (str) {
117538         var newStr, charConvert = [], i;
117539
117540         if (typeof str !== 'string') {
117541             return str;
117542         }
117543         for (i = 0; i < str.length; i++) {
117544             charConvert[i] = str.charAt(i);
117545         }
117546         newStr = charConvert.join("");
117547
117548         return newStr;
117549     },
117550
117551     copy: function (obj) {
117552         var i,
117553             newObj = jQuery.isArray(obj) ? [] : {};
117554
117555         if (typeof obj === 'number' ||
117556             typeof obj === 'string' ||
117557             typeof obj === 'boolean' ||
117558             obj === null ||
117559             obj === undefined) {
117560             return obj;
117561         }
117562
117563         if (obj instanceof Date) {
117564             return new Date(obj);
117565         }
117566
117567         if (obj instanceof RegExp) {
117568             return new RegExp(obj);
117569         }
117570
117571         for (i in obj) {
117572             if (obj.hasOwnProperty(i)) {
117573                 if (obj.__lookupGetter__(i)) {
117574                     newObj.__defineGetter__(i, (function (key) {
117575                         return function () {
117576                             return self.copy(obj[key]);
117577                         };
117578                     }(i)));
117579                 }
117580                 else {
117581                     newObj[i] = self.copy(obj[i]);
117582                 }
117583             }
117584         }
117585
117586         return newObj;
117587     }
117588 };
117589
117590 });
117591 define('ripple/platform/tizen/2.0/typecoerce', function (require, exports, module) {
117592 /*
117593  *  Copyright 2013 Intel Corporation.
117594  *
117595  * Licensed under the Apache License, Version 2.0 (the "License");
117596  * you may not use this file except in compliance with the License.
117597  * You may obtain a copy of the License at
117598  *
117599  * http://www.apache.org/licenses/LICENSE-2.0
117600  *
117601  * Unless required by applicable law or agreed to in writing, software
117602  * distributed under the License is distributed on an "AS IS" BASIS,
117603  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
117604  * See the License for the specific language governing permissions and
117605  * limitations under the License.
117606  */
117607
117608 var t = require('ripple/platform/tizen/2.0/typedef'),
117609     _self;
117610
117611 _self = function (pattern) {
117612     var typeCoerce, typeOfPattern;
117613
117614     // private
117615     function getExtendedType(val) {
117616         var type = Object.prototype.toString.call(val), attr;
117617
117618         switch (type) {
117619         case "[object Array]":
117620             if ((typeof val[0] === "string") && (val[0].length > 0)) {
117621                 type = "enum";
117622             } else {
117623                 type = "Union";
117624             }
117625             return type;
117626
117627         case "[object Object]":
117628             if ("_dictionary" in val) {
117629                 return "dictionary";
117630             }
117631
117632             type = "Object";
117633
117634             for (attr in val) {
117635                 if (attr === "0") {
117636                     type = "Arguments";
117637                 } else if (val[attr] === "Callback") {
117638                     type = "Callback";
117639                 }
117640                 break;
117641             }
117642
117643             return type;
117644         }
117645
117646         switch (val) {
117647         case "Callback":
117648             type = "Function";
117649             break;
117650
117651         case "TZDate":
117652         case "any":
117653         case "byte":
117654         case "float":
117655         case "long":
117656         case "long long":
117657         case "octet":
117658         case "short":
117659         case "unsigned long":
117660         case "unsigned long long":
117661         case "unsigned short":
117662             type = val;
117663             break;
117664
117665         case "double":
117666             type = "float";
117667             break;
117668
117669         default:    // Derivative type name: e.g., "AbstractFilter"
117670             type = "";
117671             break;
117672         }
117673
117674         return type;
117675     }
117676
117677     function getType(val, isPattern) {
117678         var type = Object.prototype.toString.call(val);
117679
117680         switch (type) {
117681         case "[object Array]":
117682             type = (isPattern && (val.length > 1)) ? getExtendedType(val) :
117683                     "Array";
117684             break;
117685
117686         case "[object Arguments]":
117687             type = "Arguments";
117688             break;
117689
117690         case "[object Boolean]":
117691             type = "boolean";
117692             break;
117693
117694         case "[object Date]":
117695             type = "Date";
117696             break;
117697
117698         case "[object Function]":
117699             type = "Function";
117700             break;
117701
117702         case "[object Number]":
117703             type = "Number";
117704             break;
117705
117706         case "[object Object]":
117707             type = isPattern ? getExtendedType(val) : "Object";
117708             break;
117709
117710         case "[object String]":
117711             type = (isPattern && !!val) ? getExtendedType(val) : "DOMString";
117712             break;
117713         }
117714
117715         return type;
117716     }
117717
117718     function isConstructed(obj) {
117719         if (!("_constructor" in pattern))
117720             return true;
117721
117722         if (obj instanceof window.tizen[pattern._constructor])
117723             return true;
117724
117725         return false;
117726     }
117727
117728     function toInteger(x) {
117729         return (x < 0) ? Math.ceil(x) : Math.floor(x);
117730     }
117731
117732     function modulo(a, b) {
117733         return (a - Math.floor(a / b) * b);
117734     }
117735
117736     function toInt(x, bits) {
117737         var p;
117738
117739         x = Number(x);
117740
117741         if (isNaN(x) || !isFinite(x))
117742             return null;
117743
117744         p = Math.pow(2, bits);
117745         x = modulo(toInteger(x), p);
117746
117747         return (x >= Math.pow(2, bits - 1)) ? (x - p) : x;
117748     }
117749
117750     function toUInt(x, bits) {
117751         x = Number(x);
117752
117753         if (isNaN(x) || !isFinite(x))
117754             return null;
117755
117756         return modulo(toInteger(x), Math.pow(2, bits));
117757     }
117758
117759     function toInt8(x) {
117760         return toInt(x, 8);
117761     }
117762
117763     function toInt16(x) {
117764         return toInt(x, 16);
117765     }
117766
117767     function toInt32(x) {
117768         return toInt(x, 32);
117769     }
117770
117771     function toInt64(x) {
117772         return toInt(x, 64);
117773     }
117774
117775     function toUInt8(x) {
117776         return toUInt(x, 8);
117777     }
117778
117779     function toUInt16(x) {
117780         return toUInt(x, 16);
117781     }
117782
117783     function toUInt32(x) {
117784         return toUInt(x, 32);
117785     }
117786
117787     function toUInt64(x) {
117788         return toUInt(x, 64);
117789     }
117790
117791     // public
117792     function cast(obj) {
117793         var typeMap,
117794             typeOfObj = getType(obj, false);
117795
117796         typeMap = {
117797             "Arguments": function () {
117798                 var i, isNullable, ret;
117799
117800                 for (i in pattern) {
117801                     if (i === "_optional")
117802                         continue;
117803
117804                     isNullable = !!(pattern._optional && pattern._optional[i]);
117805
117806                     if (i > obj.length - 1) {
117807                         if (!isNullable) {
117808                             return null;
117809                         }
117810                         break;
117811                     }
117812
117813                     if (!isNullable || (obj[i] !== null)) {
117814                         ret = _self(pattern[i]).cast(obj[i]);
117815                         if (ret === null) {
117816                             return null;
117817                         }
117818                         obj[i] = ret;
117819                     }
117820                 }
117821
117822                 return obj;
117823             },
117824
117825             "Array": function () {
117826                 var elementType, i, ret;
117827
117828                 if (typeOfObj !== typeOfPattern) {
117829                     return null;
117830                 }
117831
117832                 elementType = _self(pattern[0]);
117833                 for (i in obj) {
117834                     ret = elementType.cast(obj[i]);
117835                     if (ret === null) {
117836                         return null;
117837                     }
117838                     obj[i] = ret;
117839                 }
117840
117841                 return obj;
117842             },
117843
117844             "Callback": function () {
117845                 var attr;
117846
117847                 if (typeOfObj !== "Object") {
117848                     return null;
117849                 }
117850
117851                 for (attr in pattern) {
117852                     if (attr in obj) {
117853                         obj[attr] = _self(pattern[attr]).cast(obj[attr]);
117854                         if (obj[attr] === null) {
117855                             return null;
117856                         }
117857                     }
117858                 }
117859
117860                 return obj;
117861             },
117862
117863             "DOMString": function () {
117864                 switch (typeOfObj) {
117865                 case "DOMString":
117866                 case "Date":
117867                 case "Number":
117868                 case "boolean":
117869                     obj = String(obj);
117870                     break;
117871
117872                 default:
117873                     if ((obj === null) || (obj === undefined)) {
117874                         obj = String(obj);
117875                     } else {
117876                         obj = null;
117877                     }
117878                     break;
117879                 }
117880
117881                 return obj;
117882             },
117883
117884             "Date": function () {
117885                 return (typeOfObj === typeOfPattern) ? obj : null;
117886             },
117887
117888             "Function": function () {
117889                 return (typeOfObj === typeOfPattern) ? obj : null;
117890             },
117891
117892             "Object": function () {
117893                 var ret, attr, i;
117894
117895                 if (typeOfObj !== typeOfPattern) {
117896                     if ((obj === null) || (obj === undefined)) {
117897                         return null;
117898                     }
117899                     if (!("_derived" in pattern)) {
117900                         return null;
117901                     }
117902                 }
117903
117904                 if (!isConstructed(obj)) {
117905                     return null;
117906                 }
117907
117908                 for (attr in pattern) {
117909                     switch (attr) {
117910                     case "_optional":
117911                     case "_constructor":
117912                         break;
117913
117914                     case "_derived":
117915                         for (i in pattern._derived) {
117916                             ret = _self(pattern._derived[i]).cast(obj);
117917                             if (ret !== null)
117918                                 break;
117919                         }
117920                         if (ret === null) {
117921                             return null;
117922                         }
117923                         break;
117924
117925                     default:
117926                         if (!pattern._optional || !pattern._optional[attr] ||
117927                                 (obj[attr] !== undefined) &&
117928                                 (obj[attr] !== null)) {
117929                             ret = _self(pattern[attr]).cast(obj[attr]);
117930                             if (ret === null) {
117931                                 return null;
117932                             }
117933                             obj[attr] = ret;
117934                         }
117935                         break;
117936                     }
117937                 }
117938
117939                 return obj;
117940             },
117941
117942             "TZDate": function () {
117943                 if (typeOfObj !== "Object") {
117944                     return null;
117945                 }
117946                 return (obj instanceof window.tizen.TZDate) ? obj : null;
117947             },
117948
117949             "Union": function () {
117950                 var ret, i;
117951
117952                 for (i in pattern) {
117953                     ret = _self(pattern[i]).cast(obj);
117954                     if (ret !== null)
117955                         break;
117956                 }
117957
117958                 return ret;
117959             },
117960
117961             "any": function () {
117962                 return obj;
117963             },
117964
117965             "boolean": function () {
117966                 return (typeOfObj === typeOfPattern) ? obj : null;
117967             },
117968
117969             "byte": function () {
117970                 return toInt8(obj);
117971             },
117972
117973             "dictionary": function () {
117974                 var attr, ret;
117975
117976                 if (typeOfObj !== "Object") {
117977                     return null;
117978                 }
117979
117980                 for (attr in pattern) {
117981                     switch (attr) {
117982                     case "_dictionary":
117983                         if (pattern._dictionary !== null) {
117984                             ret = _self(pattern._dictionary).cast(obj);
117985                             if (ret === null) {
117986                                 return null;
117987                             }
117988                         }
117989                         break;
117990
117991                     default:
117992                         if ((attr in obj) && (obj[attr] !== null) &&
117993                                 (obj[attr] !== undefined)) {
117994                             ret = _self(pattern[attr]).cast(obj[attr]);
117995                             if (ret === null) {
117996                                 return null;
117997                             }
117998                             obj[attr] = ret;
117999                         }
118000                         break;
118001                     }
118002                 }
118003
118004                 return obj;
118005             },
118006
118007             "enum": function () {
118008                 var i;
118009
118010                 obj = String(obj).trim();
118011                 for (i in pattern) {
118012                     if (obj === pattern[i]) {
118013                         return obj;
118014                     }
118015                 }
118016
118017                 return null;
118018             },
118019
118020             "float": function () {
118021                 var f = parseFloat(obj, 10);
118022
118023                 return (isNaN(f) ? null : f);
118024             },
118025
118026             "long": function () {
118027                 return toInt32(obj);
118028             },
118029
118030             "long long": function () {
118031                 return toInt64(obj);
118032             },
118033
118034             "octet": function () {
118035                 return toUInt8(obj);
118036             },
118037
118038             "short": function () {
118039                 return toInt16(obj);
118040             },
118041
118042             "unsigned long": function () {
118043                 return toUInt32(obj);
118044             },
118045
118046             "unsigned long long": function () {
118047                 return toUInt64(obj);
118048             },
118049
118050             "unsigned short": function () {
118051                 return toUInt16(obj);
118052             },
118053
118054             "": function () {
118055                 return _self(t[pattern]).cast(obj);
118056             }
118057         };
118058
118059         return typeMap[typeOfPattern]();
118060     }
118061
118062     function copy(obj) {
118063         var typeMap,
118064             typeOfObj = getType(obj, false);
118065
118066         typeMap = {
118067             "Arguments": function () {
118068                 var i, isNullable, ret = [];
118069
118070                 for (i in pattern) {
118071                     if (i === "_optional")
118072                         continue;
118073
118074                     isNullable = !!(pattern._optional && pattern._optional[i]);
118075
118076                     if (i > obj.length - 1) {
118077                         if (!isNullable) {
118078                             return null;
118079                         }
118080                         break;
118081                     }
118082
118083                     if (!isNullable || (obj[i] !== null)) {
118084                         ret[i] = _self(pattern[i]).copy(obj[i]);
118085                         if (ret[i] === null) {
118086                             return null;
118087                         }
118088                     }
118089                 }
118090
118091                 for (i in ret) {
118092                     obj[i] = ret[i];
118093                 }
118094
118095                 return obj;
118096             },
118097
118098             "Array": function () {
118099                 var arr = [], elementType, i;
118100
118101                 if (typeOfObj !== typeOfPattern) {
118102                     return null;
118103                 }
118104
118105                 elementType = _self(pattern[0]);
118106                 for (i in obj) {
118107                     if (obj[i]) {
118108                         arr[i] = elementType.copy(obj[i]);
118109                         if (arr[i] === null)
118110                             return null;
118111                     }
118112                 }
118113
118114                 return arr;
118115             },
118116
118117             "Callback": function () {
118118                 var ret = {}, attr;
118119
118120                 if (typeOfObj !== "Object") {
118121                     return null;
118122                 }
118123
118124                 for (attr in pattern) {
118125                     if (attr in obj) {
118126                         ret[attr] = _self(pattern[attr]).copy(obj[attr]);
118127                         if (ret[attr] === null) {
118128                             return null;
118129                         }
118130                     }
118131                 }
118132
118133                 return ret;
118134             },
118135
118136             "Object": function () {
118137                 var ret = {}, attr, i, derived;
118138
118139                 if (typeOfObj !== typeOfPattern) {
118140                     if ((obj === null) || (obj === undefined)) {
118141                         return null;
118142                     }
118143                     if (!("_derived" in pattern)) {
118144                         return null;
118145                     }
118146                 }
118147
118148                 if (!isConstructed(obj)) {
118149                     return null;
118150                 }
118151                 if ("_constructor" in pattern) {
118152                     ret.__proto__ = window.tizen[pattern._constructor].prototype;
118153                 }
118154
118155                 for (attr in pattern) {
118156                     switch (attr) {
118157                     case "_optional":
118158                     case "_constructor":
118159                         break;
118160
118161                     case "_derived":
118162                         for (i in pattern._derived) {
118163                             derived = _self(pattern._derived[i]).copy(obj);
118164                             if (derived !== null)
118165                                 break;
118166                         }
118167                         if (derived === null) {
118168                             return null;
118169                         }
118170                         for (attr in derived) {
118171                             ret[attr] = derived[attr];
118172                         }
118173                         break;
118174
118175                     default:
118176                         if (!pattern._optional || !pattern._optional[attr] ||
118177                                 (obj[attr] !== undefined) &&
118178                                 (obj[attr] !== null)) {
118179                             ret[attr] = _self(pattern[attr]).copy(obj[attr]);
118180                             if (ret[attr] === null) {
118181                                 return null;
118182                             }
118183                         }
118184                         break;
118185                     }
118186                 }
118187
118188                 return ret;
118189             },
118190
118191             "Union": function () {
118192                 var ret, i;
118193
118194                 for (i in pattern) {
118195                     ret = _self(pattern[i]).copy(obj);
118196                     if (ret !== null)
118197                         break;
118198                 }
118199
118200                 return ret;
118201             },
118202
118203             "dictionary": function () {
118204                 var ret = {}, attr, base, i;
118205
118206                 if (typeOfObj !== "Object") {
118207                     return null;
118208                 }
118209
118210                 for (attr in pattern) {
118211                     switch (attr) {
118212                     case "_dictionary":
118213                         if (pattern._dictionary !== null) {
118214                             base = _self(pattern._dictionary).copy(obj);
118215                             if (base === null) {
118216                                 return null;
118217                             }
118218                             for (i in base) {
118219                                 ret[i] = base[i];
118220                             }
118221                         }
118222                         break;
118223
118224                     default:
118225                         if ((attr in obj) && (obj[attr] !== null) &&
118226                                 (obj[attr] !== undefined)) {
118227                             ret[attr] = _self(pattern[attr]).copy(obj[attr]);
118228                             if (ret[attr] === null) {
118229                                 return null;
118230                             }
118231                         }
118232                         break;
118233                     }
118234                 }
118235
118236                 return ret;
118237             },
118238
118239             "": function () {
118240                 return _self(t[pattern]).copy(obj);
118241             }
118242         };
118243
118244         return (typeOfPattern in typeMap) ? typeMap[typeOfPattern]() :
118245                 cast(obj);
118246     }
118247
118248     function match(obj) {
118249         var typeMap,
118250             typeOfObj = getType(obj, false);
118251
118252         typeMap = {
118253             "Array": function () {
118254                 var elementType, i;
118255
118256                 if (typeOfObj !== typeOfPattern)
118257                     return false;
118258
118259                 elementType = _self(pattern[0]);
118260                 for (i in obj) {
118261                     if (!elementType.match(obj[i])) {
118262                         return false;
118263                     }
118264                 }
118265
118266                 return true;
118267             },
118268
118269             "Callback": function () {
118270                 var attr, isMatched = true;
118271
118272                 if (typeOfObj !== "Object") {
118273                     return false;
118274                 }
118275
118276                 for (attr in pattern) {
118277                     if (attr in obj) {
118278                         isMatched = _self(pattern[attr]).match(obj[attr]);
118279                         if (!isMatched) {
118280                             break;
118281                         }
118282                     }
118283                 }
118284
118285                 return isMatched;
118286             },
118287
118288             "DOMString": function () {
118289                 return (typeOfObj === typeOfPattern);
118290             },
118291
118292             "Date": function () {
118293                 return (typeOfObj === typeOfPattern);
118294             },
118295
118296             "Function": function () {
118297                 return (typeOfObj === typeOfPattern);
118298             },
118299
118300             "Object": function () {
118301                 var attr, isMatched = false, i;
118302
118303                 if (typeOfObj !== typeOfPattern) {
118304                     if ((obj === null) || (obj === undefined)) {
118305                         return false;
118306                     }
118307                     if (!("_derived" in pattern)) {
118308                         return false;
118309                     }
118310                     return false;
118311                 }
118312
118313                 if (!isConstructed(obj)) {
118314                     return false;
118315                 }
118316
118317                 for (attr in pattern) {
118318                     switch (attr) {
118319                     case "_optional":
118320                     case "_constructor":
118321                         break;
118322
118323                     case "_derived":
118324                         for (i in pattern._derived) {
118325                             isMatched = _self(pattern._derived[i]).match(obj);
118326                             if (isMatched)
118327                                 break;
118328                         }
118329                         break;
118330
118331                     default:
118332                         if (pattern._optional && pattern._optional[attr]) {
118333                             isMatched = ((obj[attr] === null) ||
118334                                     (obj[attr] === undefined) ||
118335                                     _self(pattern[attr]).match(obj[attr]));
118336                         } else {
118337                             isMatched = (obj[attr] !== undefined) &&
118338                                     _self(pattern[attr]).match(obj[attr]);
118339                         }
118340                         break;
118341                     }
118342
118343                     if (!isMatched)
118344                         break;
118345                 }
118346
118347                 /*// Check if verbose attributes are present
118348                 if (isMatched) {
118349                     for (attr in obj) {
118350                         if (pattern[attr] === undefined) {
118351                             isMatched = false;
118352                             break;
118353                         }
118354                     }
118355                 }*/
118356
118357                 return isMatched;
118358             },
118359
118360             "Union": function () {
118361                 var isMatched, i;
118362
118363                 for (i in pattern) {
118364                     isMatched = _self(pattern[i]).match(obj);
118365                     if (isMatched)
118366                         break;
118367                 }
118368
118369                 return isMatched;
118370             },
118371
118372             "any": function () {
118373                 return true;
118374             },
118375
118376             "boolean": function () {
118377                 return (typeOfObj === typeOfPattern);
118378             },
118379
118380             "byte": function () {
118381                 return (obj === toInt8(obj));
118382             },
118383
118384             "dictionary": function () {
118385                 var attr, isMatched = true;
118386
118387                 if (typeOfObj !== "Object") {
118388                     return false;
118389                 }
118390
118391                 for (attr in pattern) {
118392                     switch (attr) {
118393                     case "_dictionary":
118394                         if (pattern._dictionary !== null) {
118395                             isMatched = _self(pattern._dictionary).match(obj);
118396                             if (!isMatched)
118397                                 break;
118398                         }
118399                         break;
118400
118401                     default:
118402                         if ((attr in obj) && (obj[attr] !== null) &&
118403                                 (obj[attr] !== undefined)) {
118404                             isMatched = _self(pattern[attr]).match(obj[attr]);
118405                             if (!isMatched)
118406                                 break;
118407                         }
118408                         break;
118409                     }
118410                 }
118411
118412                 return isMatched;
118413             },
118414
118415             "enum": function () {
118416                 for (var i in pattern) {
118417                     if (obj === pattern[i]) {
118418                         return true;
118419                     }
118420                 }
118421
118422                 return false;
118423             },
118424
118425             "float": function () {
118426                 return (typeOfObj === "Number");
118427             },
118428
118429             "long": function () {
118430                 return (obj === toInt32(obj));
118431             },
118432
118433             "long long": function () {
118434                 return (obj === toInt64(obj));
118435             },
118436
118437             "octet": function () {
118438                 return (obj === toUInt8(obj));
118439             },
118440
118441             "short": function () {
118442                 return (obj === toInt16(obj));
118443             },
118444
118445             "unsigned long": function () {
118446                 return (obj === toUInt32(obj));
118447             },
118448
118449             "unsigned long long": function () {
118450                 return (obj === toUInt64(obj));
118451             },
118452
118453             "unsigned short": function () {
118454                 return (obj === toUInt16(obj));
118455             },
118456
118457             "Arguments": function () {
118458                 return true;
118459             },
118460
118461             "": function () {
118462                 return _self(t[pattern]).match(obj);
118463             }
118464         };
118465
118466         return typeMap[typeOfPattern]();
118467     }
118468
118469     typeOfPattern = getType(pattern, true);
118470
118471     typeCoerce = {
118472         cast:  cast,
118473         copy:  copy,
118474         match: match
118475     };
118476
118477     return typeCoerce;
118478 };
118479
118480 module.exports = _self;
118481
118482 });
118483 define('ripple/platform/tizen/2.0/SyncProfileInfo', function (require, exports, module) {
118484 /*
118485  *  Copyright 2013 Intel Corporation.
118486  *
118487  * Licensed under the Apache License, Version 2.0 (the "License");
118488  * you may not use this file except in compliance with the License.
118489  * You may obtain a copy of the License at
118490  *
118491  * http://www.apache.org/licenses/LICENSE-2.0
118492  *
118493  * Unless required by applicable law or agreed to in writing, software
118494  * distributed under the License is distributed on an "AS IS" BASIS,
118495  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118496  * See the License for the specific language governing permissions and
118497  * limitations under the License.
118498  */
118499
118500 var t = require('ripple/platform/tizen/2.0/typecast'),
118501     SyncProfileInfo;
118502
118503 SyncProfileInfo = function (profileName, syncInfo, serviceInfo) {
118504     var syncProfileInfo = {};
118505
118506     t.SyncProfileInfo(arguments, this);
118507
118508     syncProfileInfo.profileName = profileName;
118509     syncProfileInfo.syncInfo    = syncInfo;
118510     syncProfileInfo.serviceInfo = serviceInfo;
118511
118512     this.__defineGetter__("profileId", function () {
118513         return null;
118514     });
118515
118516     this.__defineGetter__("profileName", function () {
118517         return syncProfileInfo.profileName;
118518     });
118519     this.__defineSetter__("profileName", function (profileName) {
118520         try {
118521             syncProfileInfo.profileName = t.DOMString(profileName);
118522         } catch (e) {
118523         }
118524     });
118525
118526     this.__defineGetter__("syncInfo", function () {
118527         return syncProfileInfo.syncInfo;
118528     });
118529     this.__defineSetter__("syncInfo", function (syncInfo) {
118530         try {
118531             t.SyncInfo(syncInfo);
118532             syncProfileInfo.syncInfo = syncInfo;
118533         } catch (e) {
118534         }
118535     });
118536
118537     this.__defineGetter__("serviceInfo", function () {
118538         return syncProfileInfo.serviceInfo;
118539     });
118540     this.__defineSetter__("serviceInfo", function (serviceInfo) {
118541         try {
118542             t.SyncServiceInfo(serviceInfo, "[]?");
118543             syncProfileInfo.serviceInfo = serviceInfo;
118544         } catch (e) {
118545         }
118546     });
118547 };
118548
118549 module.exports = SyncProfileInfo;
118550
118551 });
118552 define('ripple/platform/tizen/2.0/typecast', function (require, exports, module) {
118553 /*
118554  *  Copyright 2013 Intel Corporation.
118555  *
118556  * Licensed under the Apache License, Version 2.0 (the "License");
118557  * you may not use this file except in compliance with the License.
118558  * You may obtain a copy of the License at
118559  *
118560  * http://www.apache.org/licenses/LICENSE-2.0
118561  *
118562  * Unless required by applicable law or agreed to in writing, software
118563  * distributed under the License is distributed on an "AS IS" BASIS,
118564  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118565  * See the License for the specific language governing permissions and
118566  * limitations under the License.
118567  */
118568
118569 var typedef = require('ripple/platform/tizen/2.0/typedef'),
118570     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
118571     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
118572     TypeCoerce = require('ripple/platform/tizen/2.0/typecoerce'),
118573     _self = {};
118574
118575 function _cast(pattern, obj, isDuplicate) {
118576     var tc, tcFunc;
118577
118578     if (pattern === null)
118579         return;
118580
118581     tc = new TypeCoerce(pattern);
118582     tcFunc = isDuplicate ? tc.copy : tc.cast;
118583
118584     if ((obj = tcFunc(obj)) === null) {
118585         throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
118586     }
118587
118588     return obj;
118589 }
118590
118591 function _castType(pattern) {
118592     /*
118593      * Type cast for each known type. The function name is the exact name of the
118594      * corresponding type.
118595      *
118596      * obj
118597      *    Variable to be casted
118598      *
118599      * aux
118600      *    Auxiliary descriptor of obj. It can be any one or combination of below
118601      *    strings, or ignored in most cases.
118602      *
118603      *    "?"     Nullable types
118604      *    "[]"    Array
118605      *    "+"     Deep copy
118606      *
118607      * Return
118608      *    Casted or duplicated object.
118609      */
118610
118611     return function (obj, aux) {
118612         var type, isNullable, isDuplicate;
118613
118614         aux = aux ? String(aux) : "";
118615         type = (aux.indexOf("[]") !== -1) ? [pattern] : pattern;
118616         isNullable = (aux.indexOf("?") !== -1);
118617         isDuplicate = (aux.indexOf("+") !== -1);
118618
118619         if (isNullable && ((obj === null) || (obj === undefined))) {
118620             return obj;
118621         }
118622
118623         return _cast(type, obj, isDuplicate);
118624     };
118625 }
118626
118627 function _castConstructor(name) {
118628     var constructors, hook, vtc, isOverloaded, castConstructor;
118629
118630     /*
118631      * Type cast for constructor. The function name is the exact name of the
118632      * object type.
118633      *
118634      * argv
118635      *    arguments. The keyword 'arguments' will always be passed in.
118636      */
118637
118638     function castUnique(argv) {
118639         _cast(constructors, argv, false);
118640     }
118641
118642     /*
118643      * Type cast for overloaded constructors. The function name is the exact
118644      * name of the object type.
118645      *
118646      * argv
118647      *    arguments. The keyword 'arguments' will always be passed in.
118648      *
118649      * scope
118650      *    'this' of the original constructor.
118651      *
118652      * voc
118653      *    Array of overloaded constructors callback
118654      */
118655
118656     function castOverload(argv, scope, voc) {
118657         var iOverload;
118658
118659         if (!vtc) {
118660             vtc = [];
118661             constructors.forEach(function (c) {
118662                 vtc.push((c === null) ? null : new TypeCoerce(c));
118663             });
118664         }
118665
118666         vtc.some(function (tc, index) {
118667             if (tc && (tc.cast(argv) === null))
118668                 return false;
118669
118670             iOverload = index;
118671             return true;
118672         });
118673
118674         if (iOverload === undefined) {
118675             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
118676         }
118677
118678         return (voc && voc[iOverload].apply(scope, argv));
118679     }
118680
118681     constructors = typedef.constructor[name];
118682
118683     if (name in _self) {
118684         hook = _self[name];
118685     }
118686
118687     isOverloaded = (Object.prototype.toString.call(constructors) ===
118688             "[object Array]");
118689     castConstructor = isOverloaded ? castOverload : castUnique;
118690
118691     return function (argv, scope) {
118692         if (Object.prototype.toString.call(argv) !== "[object Arguments]") {
118693             return (hook && hook.apply(this, arguments));
118694         }
118695
118696         if (!(scope instanceof argv.callee)) {
118697             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR, null, "TypeError");
118698         }
118699
118700         castConstructor.apply(this, arguments);
118701     };
118702 }
118703
118704 function _castInterface(name) {
118705     var interface, hook;
118706
118707     interface = typedef.interface[name];
118708
118709     if (name in _self) {
118710         hook = _self[name];
118711     }
118712
118713     /*
118714      * Type cast for each known method of interface. The function name is the
118715      * exact name of the corresponding interface.
118716      *
118717      * method
118718      *    String of method name
118719      *
118720      * argv
118721      *    arguments. The keyword 'arguments' will always be passed in.
118722      *
118723      * isDuplicate
118724      *    A boolean value to indicate whether arguments will be copied or not.
118725      */
118726
118727     return function (method, argv, isDuplicate) {
118728         if ((typeof method !== "string") || (typeof argv !== "object")) {
118729             return (hook && hook.apply(this, arguments));
118730         }
118731
118732         _cast(interface[method], argv, isDuplicate);
118733     };
118734 }
118735
118736 (function () {
118737     var i;
118738
118739     for (i in typedef) {
118740         _self[i] = _castType(typedef[i]);
118741     }
118742
118743     for (i in typedef.constructor) {
118744         _self[i] = _castConstructor(i);
118745         typedef[i]._constructor = i;
118746     }
118747
118748     for (i in typedef.interface) {
118749         _self[i] = _castInterface(i);
118750     }
118751 }());
118752
118753 module.exports = _self;
118754
118755 });
118756 define('ripple/platform/tizen/2.0/poi', function (require, exports, module) {
118757 /*
118758  *  Copyright 2012 Intel Corporation.
118759  *
118760  * Licensed under the Apache License, Version 2.0 (the "License");
118761  * you may not use this file except in compliance with the License.
118762  * You may obtain a copy of the License at
118763  *
118764  * http://www.apache.org/licenses/LICENSE-2.0
118765  *
118766  * Unless required by applicable law or agreed to in writing, software
118767  * distributed under the License is distributed on an "AS IS" BASIS,
118768  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118769  * See the License for the specific language governing permissions and
118770  * limitations under the License.
118771  */
118772
118773 var OpenMapQuestProvider = require('ripple/platform/tizen/2.0/poiBackend_openmapquest'), // opne.MapQuest.xapi service
118774     _providers,
118775     _security = {
118776         "http://tizen.org/api/poi": [],
118777         "http://tizen.org/api/poi.read": ["find"],
118778         "http://tizen.org/api/poi.write": ["add", "remove", "update"],
118779         all: true
118780     },
118781     _self;
118782
118783 function _initialize() {
118784     _providers = [new OpenMapQuestProvider({name : "MapQuest", connectivity : "ONLINE", metaData : _security})];
118785 }
118786
118787 _self = function () {
118788     var poi;
118789
118790     poi = {
118791         getDefaultProvider : function () {
118792             return _providers[0];
118793         },
118794         getProviders : function () {
118795             return _providers;
118796         },
118797         handleSubFeatures: function (subFeatures) {
118798             var i, subFeature;
118799             for (subFeature in subFeatures) {
118800                 if (_security[subFeature].length === 0) {
118801                     _security.all = true;
118802                     break;
118803                 }
118804                 _security.all = false;
118805                 for (i = 0; i < _security[subFeature].length; i++) {
118806                     _security[_security[subFeature][i]] = true;
118807                 }
118808             }
118809             _initialize();
118810         }
118811     };
118812
118813     return poi;
118814 };
118815
118816 module.exports = _self;
118817
118818 });
118819 define('ripple/platform/tizen/2.0/ContactGroup', function (require, exports, module) {
118820 /*
118821  *  Copyright 2013 Intel Corporation.
118822  *
118823  * Licensed under the Apache License, Version 2.0 (the "License");
118824  * you may not use this file except in compliance with the License.
118825  * You may obtain a copy of the License at
118826  *
118827  * http://www.apache.org/licenses/LICENSE-2.0
118828  *
118829  * Unless required by applicable law or agreed to in writing, software
118830  * distributed under the License is distributed on an "AS IS" BASIS,
118831  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118832  * See the License for the specific language governing permissions and
118833  * limitations under the License.
118834  */
118835
118836 var t = require('ripple/platform/tizen/2.0/typecast'),
118837     ContactGroup;
118838
118839 ContactGroup = function (name, ringtoneURI, photoURI) {
118840     var contactGroup = {};
118841
118842     t.ContactGroup(arguments, this);
118843
118844     contactGroup.name        = name;
118845     contactGroup.ringtoneURI = ringtoneURI || null;
118846     contactGroup.photoURI    = photoURI || null;
118847
118848     this.__defineGetter__("id", function () {
118849         return null;
118850     });
118851
118852     this.__defineGetter__("addressBookId", function () {
118853         return null;
118854     });
118855
118856     this.__defineGetter__("name", function () {
118857         return contactGroup.name;
118858     });
118859     this.__defineSetter__("name", function (val) {
118860         try {
118861             contactGroup.name = t.DOMString(val);
118862         } catch (e) {
118863         }
118864     });
118865
118866     this.__defineGetter__("ringtoneURI", function () {
118867         return contactGroup.ringtoneURI;
118868     });
118869     this.__defineSetter__("ringtoneURI", function (val) {
118870         try {
118871             contactGroup.ringtoneURI = t.DOMString(val, "?");
118872         } catch (e) {
118873         }
118874     });
118875
118876     this.__defineGetter__("photoURI", function () {
118877         return contactGroup.photoURI;
118878     });
118879     this.__defineSetter__("photoURI", function (val) {
118880         try {
118881             contactGroup.photoURI = t.DOMString(val, "?");
118882         } catch (e) {
118883         }
118884     });
118885
118886     this.__defineGetter__("readOnly", function () {
118887         return false;
118888     });
118889 };
118890
118891 module.exports = ContactGroup;
118892
118893 });
118894 define('ripple/platform/tizen/2.0/ContactWebSite', function (require, exports, module) {
118895 /*
118896  *  Copyright 2013 Intel Corporation.
118897  *
118898  * Licensed under the Apache License, Version 2.0 (the "License");
118899  * you may not use this file except in compliance with the License.
118900  * You may obtain a copy of the License at
118901  *
118902  * http://www.apache.org/licenses/LICENSE-2.0
118903  *
118904  * Unless required by applicable law or agreed to in writing, software
118905  * distributed under the License is distributed on an "AS IS" BASIS,
118906  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118907  * See the License for the specific language governing permissions and
118908  * limitations under the License.
118909  */
118910
118911 var t = require('ripple/platform/tizen/2.0/typecast'),
118912     ContactWebSite;
118913
118914 ContactWebSite = function (url, type) {
118915     var contactWebSite = {};
118916
118917     t.ContactWebSite(arguments, this);
118918
118919     contactWebSite.url  = url;
118920     contactWebSite.type = type || "HOMEPAGE";
118921
118922     this.__defineGetter__("url", function () {
118923         return contactWebSite.url;
118924     });
118925     this.__defineSetter__("url", function (val) {
118926         try {
118927             contactWebSite.url = t.DOMString(val);
118928         } catch (e) {
118929         }
118930     });
118931
118932     this.__defineGetter__("type", function () {
118933         return contactWebSite.type;
118934     });
118935     this.__defineSetter__("type", function (val) {
118936         try {
118937             contactWebSite.type = t.DOMString(val);
118938         } catch (e) {
118939         }
118940     });
118941 };
118942
118943 module.exports = ContactWebSite;
118944
118945 });
118946 define('ripple/platform/tizen/2.0/DeviceOrientationEvent', function (require, exports, module) {
118947 /*
118948  *  Copyright 2012 Intel Corporation.
118949  *
118950  * Licensed under the Apache License, Version 2.0 (the "License");
118951  * you may not use this file except in compliance with the License.
118952  * You may obtain a copy of the License at
118953  *
118954  * http://www.apache.org/licenses/LICENSE-2.0
118955  *
118956  * Unless required by applicable law or agreed to in writing, software
118957  * distributed under the License is distributed on an "AS IS" BASIS,
118958  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
118959  * See the License for the specific language governing permissions and
118960  * limitations under the License.
118961  */
118962
118963 var Event = require('ripple/platform/tizen/2.0/EventBase');
118964
118965 module.exports = function () {
118966     var _self = {
118967             alpha: null,
118968             beta: null,
118969             gamma: null,
118970             absolute: false,
118971         };
118972
118973     Event.call(this);
118974
118975     this.__defineGetter__("alpha", function () {
118976         return _self.alpha;
118977     });
118978
118979     this.__defineGetter__("beta", function () {
118980         return _self.beta;
118981     });
118982
118983     this.__defineGetter__("gamma", function () {
118984         return _self.gamma;
118985     });
118986
118987     this.__defineGetter__("absolute", function () {
118988         return _self.absolute;
118989     });
118990
118991     this.initDeviceOrientationEvent = function (orientationType, orientationBubbles, orientationCancelable,
118992                                                alphaData, betaData, gammaData, isAbsolute) {
118993         this.initEvent(orientationType, orientationBubbles, orientationCancelable);
118994
118995         _self.alpha    = alphaData;
118996         _self.beta     = betaData;
118997         _self.gamma    = gammaData;
118998         _self.absolute = isAbsolute;
118999     };
119000 };
119001
119002
119003 });
119004 define('ripple/platform/tizen/2.0/CompositeFilter', function (require, exports, module) {
119005 /*
119006  *  Copyright 2013 Intel Corporation.
119007  *
119008  * Licensed under the Apache License, Version 2.0 (the "License");
119009  * you may not use this file except in compliance with the License.
119010  * You may obtain a copy of the License at
119011  *
119012  * http://www.apache.org/licenses/LICENSE-2.0
119013  *
119014  * Unless required by applicable law or agreed to in writing, software
119015  * distributed under the License is distributed on an "AS IS" BASIS,
119016  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119017  * See the License for the specific language governing permissions and
119018  * limitations under the License.
119019  */
119020
119021 var t = require('ripple/platform/tizen/2.0/typecast'),
119022     CompositeFilter;
119023
119024 CompositeFilter = function (type, filters) {
119025     var compositeFilter = {};
119026
119027     t.CompositeFilter(arguments, this);
119028
119029     this.__defineGetter__("type", function () {
119030         return compositeFilter.type;
119031     });
119032     this.__defineSetter__("type", function (val) {
119033         try {
119034             compositeFilter.type = t.CompositeFilterType(val);
119035         } catch (e) {
119036         }
119037     });
119038
119039     this.__defineGetter__("filters", function () {
119040         return compositeFilter.filters;
119041     });
119042     this.__defineSetter__("filters", function (val) {
119043         try {
119044             compositeFilter.filters = t.AbstractFilter(val, "[]");
119045         } catch (e) {
119046         }
119047     });
119048
119049     compositeFilter.type    = type;
119050     compositeFilter.filters = filters || [];
119051 };
119052
119053 module.exports = CompositeFilter;
119054
119055 });
119056 define('ripple/platform/tizen/2.0/GeocodeResult', function (require, exports, module) {
119057 /*      
119058  *  Copyright 2012 Intel Corporation.
119059  *  
119060  * Licensed under the Apache License, Version 2.0 (the "License");
119061  * you may not use this file except in compliance with the License.
119062  * You may obtain a copy of the License at
119063  *  
119064  * http://www.apache.org/licenses/LICENSE-2.0
119065  *  
119066  * Unless required by applicable law or agreed to in writing, software
119067  * distributed under the License is distributed on an "AS IS" BASIS,
119068  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119069  * See the License for the specific language governing permissions and
119070  * limitations under the License.
119071  */
119072
119073 var SimpleCoordinates = require('ripple/platform/tizen/2.0/SimpleCoordinates');
119074
119075 module.exports = function (lat, lon) {
119076     var _self, _coordinates, jsonStr, jsonObj;
119077
119078     _coordinates = new SimpleCoordinates(lat, lon);
119079
119080     jsonObj = {
119081         "type" : "Point",
119082         "coordinates" : [lat, lon]
119083     };
119084
119085     jsonStr = JSON.stringify(jsonObj);
119086
119087     _self = {
119088         coordinates : _coordinates,
119089         toGeoJSON : function () {
119090             return jsonStr;
119091         }
119092     };
119093     return _self;
119094 };
119095
119096
119097 });
119098 define('ripple/platform/tizen/2.0/TimeDuration', function (require, exports, module) {
119099 /*
119100  *  Copyright 2012 Intel Corporation.
119101  *
119102  * Licensed under the Apache License, Version 2.0 (the "License");
119103  * you may not use this file except in compliance with the License.
119104  * You may obtain a copy of the License at
119105  *
119106  * http://www.apache.org/licenses/LICENSE-2.0
119107  *
119108  * Unless required by applicable law or agreed to in writing, software
119109  * distributed under the License is distributed on an "AS IS" BASIS,
119110  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119111  * See the License for the specific language governing permissions and
119112  * limitations under the License.
119113  */
119114
119115 var t = require('ripple/platform/tizen/2.0/typecast'),
119116     errorcode = require('ripple/platform/tizen/2.0/errorcode'),
119117     WebAPIException = require('ripple/platform/tizen/2.0/WebAPIException'),
119118     TimeDuration;
119119
119120 TimeDuration = function (_length, _unit) {
119121     var timeDuration = {},
119122         TimeDurationUnit = {"MSECS": 1,
119123                             "SECS": 1000,
119124                             "MINS": 60 * 1000,
119125                             "HOURS": 60 * 60 * 1000,
119126                             "DAYS": 24 * 60 * 60 * 1000
119127                            },
119128         _simplifyDuration = function (ms) {
119129             var TDur = require('ripple/platform/tizen/2.0/TimeDuration'),
119130                 uni = "MSECS";
119131             if ((ms % 1000) === 0) {
119132                 ms = ms / 1000;
119133                 uni = "SECS";
119134                 if ((ms % 60) === 0) {
119135                     ms = ms / 60;
119136                     uni = "MINS";
119137                     if ((ms % 60) === 0) {
119138                         ms = ms / 60;
119139                         uni = "HOURS";
119140                         if ((ms % 24) === 0) {
119141                             ms = ms / 24;
119142                             uni = "DAYS";
119143                         }
119144                     }
119145                 }
119146             }
119147             return (new TDur(ms, uni));
119148         },
119149         _toMSECS = function (unit) {
119150             if (TimeDurationUnit[unit] === undefined) {
119151                 throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
119152             } else {
119153                 return TimeDurationUnit[unit];
119154             }
119155         };
119156
119157     t.TimeDuration(arguments, this);
119158
119159     this.__defineGetter__("length", function () {
119160         return timeDuration.length;
119161     });
119162     this.__defineSetter__("length", function (val) {
119163         try {
119164             timeDuration.length = t.double(val);
119165         } catch (e) {
119166         }
119167     });
119168
119169     this.__defineGetter__("unit", function () {
119170         return timeDuration.unit;
119171     });
119172     this.__defineSetter__("unit", function (val) {
119173         try {
119174             timeDuration.unit = t.TimeDurationUnit(val);
119175         } catch (e) {
119176         }
119177     });
119178
119179     timeDuration.length = _length;
119180     timeDuration.unit = _unit || "MSECS";
119181
119182     this.difference = function (o) {
119183
119184         t.TimeDuration("difference", arguments);
119185
119186         var thisMS = timeDuration.length * _toMSECS(timeDuration.unit),
119187             otherMS = o.length * _toMSECS(o.unit);
119188         return _simplifyDuration(thisMS - otherMS);
119189     };
119190     this.equalsTo = function (o) {
119191
119192         t.TimeDuration("equalsTo", arguments);
119193
119194         var thisMS = timeDuration.length * _toMSECS(timeDuration.unit),
119195             otherMS = o.length * _toMSECS(o.unit);
119196         return (thisMS === otherMS);
119197     };
119198     this.lessThan = function (o) {
119199
119200         t.TimeDuration("lessThan", arguments);
119201
119202         var thisMS = timeDuration.length * _toMSECS(timeDuration.unit),
119203             otherMS = o.length * _toMSECS(o.unit);
119204         return (thisMS < otherMS);
119205     };
119206     this.greaterThan = function (o) {
119207
119208         t.TimeDuration("greaterThan", arguments);
119209
119210         var thisMS = timeDuration.length * _toMSECS(timeDuration.unit),
119211             otherMS = o.length * _toMSECS(o.unit);
119212         return (thisMS > otherMS);
119213     };
119214 };
119215
119216 module.exports = TimeDuration;
119217
119218 });
119219 define('ripple/platform/tizen/2.0/ApplicationControl', function (require, exports, module) {
119220 /*
119221  *  Copyright 2013 Intel Corporation.
119222  *
119223  * Licensed under the Apache License, Version 2.0 (the "License");
119224  * you may not use this file except in compliance with the License.
119225  * You may obtain a copy of the License at
119226  *
119227  * http://www.apache.org/licenses/LICENSE-2.0
119228  *
119229  * Unless required by applicable law or agreed to in writing, software
119230  * distributed under the License is distributed on an "AS IS" BASIS,
119231  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119232  * See the License for the specific language governing permissions and
119233  * limitations under the License.
119234  */
119235
119236 var t = require('ripple/platform/tizen/2.0/typecast'),
119237     ApplicationControlData = require('ripple/platform/tizen/2.0/ApplicationControlData');
119238
119239 var ApplicationControl = function (operation, uri, mime, category, data) {
119240     var applicationControl = {}, i;
119241
119242     t.ApplicationControl(arguments, this);
119243
119244     applicationControl.operation = operation;
119245     applicationControl.uri       = uri || null;
119246     applicationControl.mime      = mime || null;
119247     applicationControl.category  = category || null;
119248     applicationControl.data      = [];
119249
119250     if (data) {
119251         for (i in data) {
119252             applicationControl.data[i] = new ApplicationControlData(data[i].key,
119253                     data[i].value);
119254         }
119255     }
119256
119257     this.__defineGetter__("operation", function () {
119258         return applicationControl.operation;
119259     });
119260     this.__defineSetter__("operation", function (val) {
119261         try {
119262             applicationControl.operation = t.DOMString(val);
119263         } catch (e) {
119264         }
119265     });
119266
119267     this.__defineGetter__("uri", function () {
119268         return applicationControl.uri;
119269     });
119270     this.__defineSetter__("uri", function (val) {
119271         try {
119272             applicationControl.uri = t.DOMString(val, "?");
119273         } catch (e) {
119274         }
119275     });
119276
119277     this.__defineGetter__("mime", function () {
119278         return applicationControl.mime;
119279     });
119280     this.__defineSetter__("mime", function (val) {
119281         try {
119282             applicationControl.mime = t.DOMString(val, "?");
119283         } catch (e) {
119284         }
119285     });
119286
119287     this.__defineGetter__("category", function () {
119288         return applicationControl.category;
119289     });
119290     this.__defineSetter__("category", function (val) {
119291         try {
119292             applicationControl.category = t.DOMString(val, "?");
119293         } catch (e) {
119294         }
119295     });
119296
119297     this.__defineGetter__("data", function () {
119298         return applicationControl.data;
119299     });
119300     this.__defineSetter__("data", function (val) {
119301         var i;
119302
119303         try {
119304             t.ApplicationControlData(val, "[]");
119305             for (i in val) {
119306                 applicationControl.data[i] = new ApplicationControlData(
119307                         val[i].key, val[i].value);
119308             }
119309         } catch (e) {
119310         }
119311     });
119312 };
119313
119314 module.exports = ApplicationControl;
119315
119316 });
119317 define('ripple/platform/ivi/3.0/errorcode', function (require, exports, module) {
119318 /*
119319  *  Copyright 2013 Intel Corporation.
119320  *
119321  * Licensed under the Apache License, Version 2.0 (the "License"),
119322  * you may not use this file except in compliance with the License.
119323  * You may obtain a copy of the License at
119324  *
119325  * http://www.apache.org/licenses/LICENSE-2.0
119326  *
119327  * Unless required by applicable law or agreed to in writing, software
119328  * distributed under the License is distributed on an "AS IS" BASIS,
119329  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119330  * See the License for the specific language governing permissions and
119331  * limitations under the License.
119332  */
119333
119334 var _self = {};
119335
119336 _self.__defineGetter__("PERMISSION_DENIED", function () {
119337     return 1;
119338 });
119339
119340 _self.__defineGetter__("PROPERTY_UNAVAILABLE", function () {
119341     return 2;
119342 });
119343
119344 _self.__defineGetter__("TIMEOUT", function () {
119345     return 3;
119346 });
119347
119348 _self.__defineGetter__("UNKNOWN", function () {
119349     return 10;
119350 });
119351
119352 module.exports = _self;
119353
119354 });
119355 define('ripple/platform/ivi/3.0/VehiclePanelEngine', function (require, exports, module) {
119356
119357 /*
119358  *  Copyright 2013 Intel Corporation.
119359  *
119360  * Licensed under the Apache License, Version 2.0 (the "License");
119361  * you may not use this file except in compliance with the License.
119362  * You may obtain a copy of the License at
119363  *
119364  * http://www.apache.org/licenses/LICENSE-2.0
119365  *
119366  * Unless required by applicable law or agreed to in writing, software
119367  * distributed under the License is distributed on an "AS IS" BASIS,
119368  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
119369  * See the License for the specific language governing permissions and
119370  * limitations under the License.
119371  */
119372
119373 var utils = require('ripple/utils'),
119374     db = require('ripple/db'),
119375     dbinit = require('ripple/platform/ivi/3.0/dbinit'),
119376     _vehicleMapStack = {},
119377     _databaseName = "ivi-vehicle-database",
119378     VehiclePanelEngine;
119379
119380 function _save (data) {
119381     db.saveObject(_databaseName, data);
119382 }
119383
119384 function _get () {
119385     var database = db.retrieveObject(_databaseName);
119386
119387     if (!database) {
119388         db.saveObject(_databaseName, dbinit.Vehicle);
119389         database = db.retrieveObject(_databaseName);
119390     }
119391
119392     return database;
119393 }
119394
119395 VehiclePanelEngine = function () {
119396     var _CONFIGURATION = "configuration", _AUTO = "auto",
119397         _database,
119398         _configuration, _currentConfiguration,
119399         _supported, _settings, _autoRunning;
119400
119401     function _init () {
119402         _database = _get();
119403
119404         _settings = _database.settingData;
119405
119406         _configuration = _database.configurationData;
119407         _currentConfiguration = _database.currentConfiguration;
119408
119409         _supported = _database.supported;
119410
119411         _autoRunning = _database.autoRunningData;
119412     }
119413
119414     this.saveData = function (supported, currentConfiguration, configuration, settings, autoRunning) {
119415         _database.supported = supported;
119416         _database.currentConfiguration = currentConfiguration;
119417         _database.settingData = settings;
119418         _database.configurationData[currentConfiguration] = configuration;
119419         _database.autoRunningData[0] = autoRunning;
119420
119421         _save(_database);
119422     };
119423
119424     function _formatVehicleDB (map, db) {
119425         var formatSettings = {},
119426             VehicleMap = map, vehicleData = db,
119427             property, name, item, i = 0;
119428
119429         for (property in VehicleMap) {
119430             name = property.split("-")[0];
119431             item = property.split("-")[1];
119432
119433             if (!formatSettings[name]) {
119434                 formatSettings[name] = {};
119435             }
119436
119437             formatSettings[name][item] = utils.copy(VehicleMap[property]);
119438             formatSettings[name][item].value = vehicleData[i];
119439
119440             i++;
119441         }
119442
119443         return formatSettings;
119444     }
119445
119446     /**
119447      * get
119448      * @return {Object}
119449      */
119450     this.getConfiguration = function () {
119451         var configuration = {}, i, j, dataIndex, tempArray,
119452             configurationMap = _vehicleMapStack.vehicleConfigurationMap,
119453             configurationData = _configuration;
119454
119455         for (j = 0; j < configurationData.length; j++) {
119456             dataIndex = _CONFIGURATION + j;
119457             configuration[dataIndex] = {};
119458
119459             for (i = 0; i < configurationMap.length; i++) {
119460                 tempArray = configurationMap[i].split("-");
119461
119462                 if (!configuration[dataIndex][tempArray[0]]) {
119463                     configuration[dataIndex][tempArray[0]] = {};
119464                 }
119465                 configuration[dataIndex][tempArray[0]][tempArray[1]] = configurationData[j][i];
119466             }
119467         }
119468
119469         return configuration;
119470     };
119471
119472     /**
119473      * get
119474      * @return {String}
119475      */
119476     this.getCurrentConfiguration = function () {
119477         return _CONFIGURATION + _currentConfiguration;
119478     };
119479
119480     /**
119481      * get
119482      * @return {Array}
119483      */
119484     this.getProperties = function () {
119485         return _vehicleMapStack.vehicleProperties;
119486     };
119487
119488     /**
119489      * get supported vehicle properties name.
119490      * @return {Array}
119491      */
119492     this.getSupported = function () {
119493         return _supported;
119494     };
119495
119496     /**
119497      * get property unit.
119498      * @param property
119499      * @param item
119500      * @return {String}
119501      */
119502     this.getPropertyUnit = function (property, item) {
119503         var unitKey = property + "-" + item,
119504             propertyUnitMap = _vehicleMapStack.vehiclePropertyUnitsMap;
119505
119506         return !propertyUnitMap[unitKey] ? "" : "(" + propertyUnitMap[unitKey] + ")";
119507     };
119508
119509     this.getPropertyRange = function (property, item) {
119510         var rangeKey = property + "-" + item,
119511             propertyRangeMap = _vehicleMapStack.vehiclePropertyRangeMap;
119512
119513         return !propertyRangeMap[rangeKey] ? false : propertyRangeMap[rangeKey];
119514     };
119515
119516     /**
119517      * get
119518      * @param property
119519      * @param item
119520      * @return {*}
119521      */
119522     this.getPropertyConstant = function (property, item) {
119523         var propertyConstants = _vehicleMapStack.vehiclePropertyConstantsMap;
119524
119525         return !propertyConstants[property] ? null : propertyConstants[property][item];
119526     };
119527
119528     this.getSettings = function () {
119529         return _formatVehicleDB(_vehicleMapStack.vehicleSettingMap, _settings);
119530     };
119531
119532     this.getAutoRunning = function () {
119533         var autoRunning = {}, i,
119534             autoRunningMap = _vehicleMapStack.vehicleAutoRunningMap,
119535             autoRunningData = _autoRunning;
119536
119537         for (i = 0; i < _autoRunning.length; i++) {
119538             autoRunning[_AUTO + i] = _formatVehicleDB(autoRunningMap, autoRunningData[i]);
119539         }
119540         return autoRunning;
119541     };
119542
119543     _init();
119544 };
119545
119546 //can support all properties.
119547 _vehicleMapStack.vehicleProperties = [
119548     "VehicleSpeed", "EngineSpeed", "VehiclePowerMode", "TripMeter",
119549     "Acceleration", "Transmission", "CruiseControlStatus", "WheelBrake",
119550     "LightStatus", "InteriorLightStatus", "Horn", "Fuel", "EngineOil",
119551     "Location", "ExteriorBrightness", "Temperature", "RainSensor",
119552     "WindshieldWiper", "HVAC", "WindowStatus", "Sunroof", "ConvertibleRoof",
119553     "VehicleId", "Size", "FuelInfo", "VehicleType", "Doors",
119554     "TransmissionGearType", "WheelInformation", "Odometer", "Fluid", "Battery",
119555     "TirePressure", "TireTemperature", "SecurityAlert", "ParkingBrake",
119556     "ParkingLight", "HazardLight", "AntilockBrakingSystem", "TractionControlSystem",
119557     "VehicleTopSpeedLimit", "AirbagStatus", "DoorStatus", "SeatBeltStatus",
119558     "OccupantStatus", "ObstacleDistance", "NightMode", "DrivingMode",
119559     "TurnSignal", "ButtonEvent"
119560 ];
119561
119562 //Vehicle Configuration
119563 _vehicleMapStack.vehicleConfigurationMap = [
119564     "VehicleId-WMI", "VehicleId-VIN",
119565     "Size-width", "Size-height", "Size-length",
119566     "FuelInfo-type", "FuelInfo-refuelPosition",
119567     "VehicleType-type",
119568     "Doors-doorsPerRow",
119569     "TransmissionGearType-transmissionGearType",
119570     "WheelInformation-frontWheelRadius", "WheelInformation-rearWheelRadius", "WheelInformation-wheelTrack", "WheelInformation-ABS"
119571 ];
119572
119573 //all ranged attributes' min. max and step.
119574 _vehicleMapStack.vehiclePropertyRangeMap = {
119575     "VehicleSpeed-vehicleSpeed": [0, 400, 1],
119576     "EngineSpeed-engineSpeed": [0, 10000, 20],
119577     "Acceleration-x": [0, 200, 1],
119578     "Acceleration-y": [0, 200, 1],
119579     "Acceleration-z": [0, 200, 1],
119580     "Fuel-level": [0, 100, 1],
119581     "Fuel-range": [0, 1000, 1],
119582     "Fuel-instantConsumption": [0, 100, 1],
119583     "Fuel-instantEconomy": [0, 100, 1],
119584     "Fuel-averageEconomy": [0, 100, 1],
119585     "EngineOil-remaining": [0, 100, 1],
119586     "EngineOil-temperature": [0, 100, 1],
119587     "EngineOil-pressure": [0, 1000, 1],
119588     "Location-latitude": [-180, 180, 1],
119589     "Location-longitude": [-19, 90, 1],
119590     "Location-altitude": [0, 100, 1],
119591     "Location-direction": [0, 360, 1],
119592     "ExteriorBrightness-exteriorBrightness": [0, 100, 1],
119593     "Temperature-interior": [-5, 35, 1],
119594     "Temperature-exterior": [-40, 60, 1],
119595     "Odometer-odometer": [0, 10000, 10],
119596     "CruiseControlStatus-speed": [1, 100, 1],
119597     "HVAC-targetTemperature": [0, 35, 7],
119598     "Sunroof-openness": [0, 100, 1],
119599     "Sunroof-tilt": [0, 100, 1],
119600     "ConvertibleRoof-openness": [0, 100, 1],
119601     "WindowStatus-openness": [0, 100, 1],
119602     "VehicleTopSpeedLimit-vehicleTopSpeedLimit": [0, 400, 1],
119603     "ObstacleDistance-obstacleDistance": [0, 120, 1],
119604     "Fluid-transmission": [0, 100, 1],
119605     "Fluid-brake": [0, 100, 1],
119606     "Fluid-washer": [0, 100, 1],
119607     "Battery-voltage": [0, 12, 1],
119608     "Battery-current": [0, 200, 1],
119609     "TirePressure-leftFront": [0, 500, 1],
119610     "TirePressure-rightFront": [0, 500, 1],
119611     "TirePressure-leftRear": [0, 500, 1],
119612     "TirePressure-rightRear": [0, 500, 1],
119613     "TireTemperature-leftFront": [0, 60, 1],
119614     "TireTemperature-rightFront": [0, 60, 1],
119615     "TireTemperature-leftRear": [0, 60, 1],
119616     "TireTemperature-rightRear": [0, 60, 1],
119617     "TurnSignal-turnSignal": [0, 100, 1],
119618     "ButtonEvent-buttonEvent": [0, 100, 1]
119619 };
119620
119621 //simulate car running attributes' controller-types.
119622 _vehicleMapStack.vehicleAutoRunningMap = {
119623     "VehicleSpeed-vehicleSpeed": {
119624         "type": "range"
119625     },
119626     "EngineSpeed-engineSpeed": {
119627         "type": "range"
119628     },
119629     "VehiclePowerMode-vehiclePowerMode": {
119630         "type": "select",
119631         "options": [{"OFF": 0},{"ACCESSORY1": 1},{"ACCESSORY2": 2},{"RUN": 3}]
119632     },
119633     "TripMeter-tripMeters": {
119634         "type": "text"
119635     },
119636     "Acceleration-x": {
119637         "type": "range"
119638     },
119639     "Acceleration-y": {
119640         "type": "range"
119641     },
119642     "Acceleration-z": {
119643         "type": "range"
119644     },
119645     "Fuel-level": {
119646         "type": "range"
119647     },
119648     "Fuel-range": {
119649         "type": "range"
119650     },
119651     "Fuel-instantConsumption": {
119652         "type": "range"
119653     },
119654     "Fuel-instantEconomy": {
119655         "type": "range"
119656     },
119657     "Fuel-averageEconomy": {
119658         "type": "range"
119659     },
119660     "EngineOil-remaining": {
119661         "type": "range"
119662     },
119663     "EngineOil-temperature": {
119664         "type": "range"
119665     },
119666     "EngineOil-pressure": {
119667         "type": "range"
119668     },
119669     "Location-latitude": {
119670         "type": "range"
119671     },
119672     "Location-longitude": {
119673         "type": "range"
119674     },
119675     "Location-altitude": {
119676         "type": "range"
119677     },
119678     "Location-direction": {
119679         "type": "range"
119680     },
119681     "ExteriorBrightness-exteriorBrightness": {
119682         "type": "range"
119683     },
119684     "Temperature-interior": {
119685         "type": "range"
119686     },
119687     "Temperature-exterior": {
119688         "type": "range"
119689     },
119690     "RainSensor-rainSensor": {
119691         "type": "select",
119692         "options": [{"No Rain": 0},{"Rain 1": 1},{"Rain 2": 2},{"Rain 3": 3},{"Rain 4": 4},{"Rain 5": 5},
119693             {"Rain 6": 6},{"Rain 7": 7},{"Rain 8": 8},{"Rain 9": 9},{"Heaviest": 10}]
119694     },
119695     "Odometer-odometer": {
119696         "type": "range"
119697     },
119698     "TurnSignal-turnSignal": {
119699         "type": "range"
119700     },
119701     "ButtonEvent-buttonEvent": {
119702         "type": "range"
119703     }
119704 };
119705
119706 //Vehicle Setting attributes' controller-types.
119707 _vehicleMapStack.vehicleSettingMap = {
119708     "Transmission-gearPosition": {
119709         "type": "select",
119710         "options": [{"NEUTRAL": 0},{"FIRST": 1},{"SECOND": 2},{"THIRD": 3}, {"FORTH": 4},{"FIFTH": 5},
119711             {"SIXTH": 6},{"SEVENTH": 7}, {"EIGHTH": 8},{"NINTH": 9},{"TENTH": 10},{"CVT": 64},
119712             {"REVERSE": 128},{"PARK": 255}]
119713     },
119714     "Transmission-mode": {
119715         "type": "select",
119716         "options": [{"NORMAL": 0},{"SPORT": 1},{"ECONOMY": 2}, {"OEMCUSTOM1": 3},{"OEMCUSTOM2": 4}]
119717     },
119718     "CruiseControlStatus-activated": {
119719         "type": "radio",
119720         "options": [{"Active": true}, {"Inactive": false}]
119721     },
119722     "CruiseControlStatus-speed": {
119723         "type": "range"
119724     },
119725     "WheelBrake-engaged": {
119726         "type": "radio",
119727         "options": [{"Engaged": true}, {"Disengaged": false}]
119728     },
119729     "LightStatus-head": {
119730         "type": "radio",
119731         "options": [{"On": true}, {"Off": false}]
119732     },
119733     "LightStatus-rightTurn": {
119734         "type": "radio",
119735         "options": [{"On": true}, {"Off": false}]
119736     },
119737     "LightStatus-leftTurn": {
119738         "type": "radio",
119739         "options": [{"On": true}, {"Off": false}]
119740     },
119741     "LightStatus-brake": {
119742         "type": "radio",
119743         "options": [{"On": true}, {"Off": false}]
119744     },
119745     "LightStatus-fog": {
119746         "type": "radio",
119747         "options": [{"On": true}, {"Off": false}]
119748     },
119749     "LightStatus-hazard": {
119750         "type": "radio",
119751         "options": [{"On": true}, {"Off": false}]
119752     },
119753     "LightStatus-parking": {
119754         "type": "radio",
119755         "options": [{"On": true}, {"Off": false}]
119756     },
119757     "LightStatus-highBeam": {
119758         "type": "radio",
119759         "options": [{"On": true}, {"Off": false}]
119760     },
119761     "InteriorLightStatus-passenger": {
119762         "type": "radio",
119763         "options": [{"On": true}, {"Off": false}]
119764     },
119765     "InteriorLightStatus-driver": {
119766         "type": "radio",
119767         "options": [{"On": true}, {"Off": false}]
119768     },
119769     "InteriorLightStatus-center": {
119770         "type": "radio",
119771         "options": [{"On": true}, {"Off": false}]
119772     },
119773     "Horn-on": {
119774         "type": "radio",
119775         "options": [{"On": true}, {"Off": false}]
119776     },
119777     "WindshieldWiper-windshieldWiper": {
119778         "type": "select",
119779         "options": [{"OFF": 0},{"SLOWEST": 1},{"FASTEST": 5},{"AUTO": 10}]
119780     },
119781     "HVAC-airflowDirection": {
119782         "type": "select",
119783         "options": [{"FRONTPANEL": 0},{"FLOORDUCT": 1},{"FRONT": 0x02}, {"DEFROSTER": 0x04}]
119784     },
119785     "HVAC-fanSpeed": {
119786         "type": "select",
119787         "options": [{"0": 0},{"1": 1},{"2": 2},{"3": 3},{"4": 4},{"5": 5}, {"6": 6},{"7": 7}]
119788     },
119789     "HVAC-targetTemperature": {
119790         "type": "range"
119791     },
119792     "HVAC-airConditioning": {
119793         "type": "radio",
119794         "options": [{"On": true}, {"Off": false}]
119795     },
119796     "HVAC-airRecirculation": {
119797         "type": "radio",
119798         "options": [{"On": true}, {"Off": false}]
119799     },
119800     "HVAC-heater": {
119801         "type": "radio",
119802         "options": [{"On": true}, {"Off": false}]
119803     },
119804     "HVAC-steeringWheelHeater": {
119805         "type": "radio",
119806         "options": [{"On": true}, {"Off": false}]
119807     },
119808     "HVAC-seatHeater": {
119809         "type": "radio",
119810         "options": [{"On": true}, {"Off": false}]
119811     },
119812     "HVAC-seatCooler": {
119813         "type": "radio",
119814         "options": [{"On": true}, {"Off": false}]
119815     },
119816     "Sunroof-openness": {
119817         "type": "range"
119818     },
119819     "Sunroof-tilt": {
119820         "type": "range"
119821     },
119822     "ConvertibleRoof-openness": {
119823         "type": "range"
119824     },
119825     "SecurityAlert-securityAlert": {
119826         "type": "radio",
119827         "options": [{"On": true}, {"Off": false}]
119828     },
119829     "ParkingBrake-parkingBrake": {
119830         "type": "radio",
119831         "options": [{"Engaged": true}, {"Disengaged": false}]
119832     },
119833     "ParkingLight-parkingLight": {
119834         "type": "radio",
119835         "options": [{"Engaged": true}, {"Disengaged": false}]
119836     },
119837     "HazardLight-hazardLight": {
119838         "type": "radio",
119839         "options": [{"Engaged": true}, {"Disengaged": false}]
119840     },
119841     "AntilockBrakingSystem-antilockBrakingSystem": {
119842         "type": "radio",
119843         "options":[{"Engaged": true}, {"Idle": false}]
119844     },
119845     "TractionControlSystem-tractionControlSystem": {
119846         "type": "radio",
119847         "options": [{"On": true}, {"Off": false}]
119848     },
119849     "VehicleTopSpeedLimit-vehicleTopSpeedLimit": {
119850         "type": "range"
119851     },
119852     "WindowStatus-openness": {
119853         "type": "range"
119854     },
119855     "WindowStatus-defrost": {
119856         "type": "radio",
119857         "options": [{"On": true}, {"Off": false}]
119858     },
119859     "AirbagStatus-airbagStatus": {
119860         "type": "select",
119861         "options": [{"INACTIVE": 0},{"ACTIVE": 1},{"DEPLOYED": 2}]
119862     },
119863     "DoorStatus-doorStatus": {
119864         "type": "select",
119865         "options": [{"CLOSED": 0},{"OPEN": 1},{"AJAR": 2}]
119866     },
119867     "DoorStatus-doorLockStatus": {
119868         "type": "radio",
119869         "options": [{"Locked": true}, {"Unlocked": false}]
119870     },
119871     "DoorStatus-childLockStatus": {
119872         "type": "radio",
119873         "options": [{"On": true}, {"Off": false}]
119874     },
119875     "SeatBeltStatus-seatBeltStatus": {
119876         "type": "radio",
119877         "options": [{"Fasten": true}, {"Unfastened": false}]
119878     },
119879     "OccupantStatus-occupantStatus": {
119880         "type": "select",
119881         "options": [{"VACANT": 0},{"CHILD": 1},{"ADULT": 2}]
119882     },
119883     "ObstacleDistance-obstacleDistance": {
119884         "type": "range"
119885     },
119886     "NightMode-nightMode": {
119887         "type": "radio",
119888         "options": [{"Night": true}, {"Day": false}]
119889     },
119890     "DrivingMode-drivingMode": {
119891         "type": "select",
119892         "options": [{"Not Driving": 0},{"Driving": 1}]
119893     },
119894     "Fluid-transmission": {
119895         "type": "range"
119896     },
119897     "Fluid-brake": {
119898         "type": "range"
119899     },
119900     "Fluid-washer": {
119901         "type": "range"
119902     },
119903     "Battery-voltage": {
119904         "type": "range"
119905     },
119906     "Battery-current": {
119907         "type": "range"
119908     },
119909     "TirePressure-leftFront": {
119910         "type": "range"
119911     },
119912     "TirePressure-rightFront": {
119913         "type": "range"
119914     },
119915     "TirePressure-leftRear": {
119916         "type": "range"
119917     },
119918     "TirePressure-rightRear": {
119919         "type": "range"
119920     },
119921     "TireTemperature-leftFront": {
119922         "type": "range"
119923     },
119924     "TireTemperature-rightFront": {
119925         "type": "range"
119926     },
119927     "TireTemperature-leftRear": {
119928         "type": "range"
119929     },
119930     "TireTemperature-rightRear": {
119931         "type": "range"
119932     }
119933 };
119934
119935 //attributes units
119936 _vehicleMapStack.vehiclePropertyUnitsMap = {
119937     "VehicleSpeed-vehicleSpeed": "kph",
119938     "EngineSpeed-engineSpeed": "rpm",
119939     "TripMeter-tripMeters": "[m,...]",
119940     "CruiseControlStatus-speed": "kph",
119941     "Fuel-level": "%",
119942     "Fuel-instantConsumption": "ml/s",
119943     "Fuel-instantEconomy": "km/l",
119944     "Fuel-averageEconomy": "km/l",
119945     "EngineOil-remaining": "%",
119946     "EngineOil-temperature": "C",
119947     "EngineOil-pressure": "kpa",
119948     "ExteriorBrightness-exteriorBrightness": "lux",
119949     "Temperature-interior": "C",
119950     "Temperature-exterior": "C",
119951     "HVAC-targetTemperature": "C",
119952     "Sunroof-openness": "%",
119953     "Sunroof-tilt": "%",
119954     "ConvertibleRoof-openness": "%",
119955     "WindowStatus-openness": "%",
119956     "ObstacleDistance-obstacleDistance": "m",
119957     "Size-width": "mm",
119958     "Size-height": "mm",
119959     "Size-length": "mm",
119960     "WheelInformation-frontWheelRadius": "mm",
119961     "WheelInformation-rearWheelRadius": "mm",
119962     "WheelInformation-wheelTrack": "mm",
119963     "Odometer-odometer": "km",
119964     "Fluid-transmission": "%",
119965     "Fluid-brake": "%",
119966     "Fluid-washer": "%",
119967     "Battery-voltage": "V",
119968     "Battery-current": "A",
119969     "TirePressure-leftFront": "kpa",
119970     "TirePressure-rightFront": "kpa",
119971     "TirePressure-leftRear": "kpa",
119972     "TirePressure-rightRear": "kpa",
119973     "TireTemperature-leftFront": "C",
119974     "TireTemperature-rightFront": "C",
119975     "TireTemperature-leftRear": "C",
119976     "TireTemperature-rightRear": "C",
119977     "VehicleTopSpeedLimit-vehicleTopSpeedLimit": "kph"
119978 };
119979
119980 //key and value of select types in attributes
119981 _vehicleMapStack.vehiclePropertyConstantsMap = {
119982     "FuelInfo": {
119983         "type": {
119984             "val0": "GASOLINE",
119985             "val1": "HIGH_OCTANE",
119986             "val2": "DIESEL",
119987             "val3": "ELECTRIC",
119988             "val4": "HYDROGEN"
119989         },
119990         "refuelPosition": {
119991             "val0": "LEFT",
119992             "val1": "RIGHT",
119993             "val2": "FRONT",
119994             "val3": "REAR"
119995         }
119996     },
119997     "VehicleType": {
119998         "type": {
119999             "val0": "SEDAN",
120000             "val1": "COUPE",
120001             "val2": "CABRIOLE",
120002             "val3": "ROADSTER",
120003             "val4": "SUV",
120004             "val5": "TRUCK"
120005         }
120006     },
120007     "TransmissionGearType": {
120008         "transmissionGearType": {
120009             "val0": "AUTO",
120010             "val1": "MANUAL",
120011             "val2": "CV"
120012         }
120013     },
120014     "VehiclePowerMode": {
120015         "vehiclePowerMode": {
120016             "val0": "OFF",
120017             "val1": "ACCESSORY1",
120018             "val2": "ACCESSORY2",
120019             "val3": "RUN"
120020         }
120021     }
120022 };
120023
120024 exports.VehiclePanelEngine = new VehiclePanelEngine();
120025
120026 });
120027 define('ripple/platform/ivi/3.0/spec', function (require, exports, module) {
120028 /*
120029  *  Copyright 2012 Intel Corporation.
120030  *
120031  * Licensed under the Apache License, Version 2.0 (the "License");
120032  * you may not use this file except in compliance with the License.
120033  * You may obtain a copy of the License at
120034  *
120035  * http://www.apache.org/licenses/LICENSE-2.0
120036  *
120037  * Unless required by applicable law or agreed to in writing, software
120038  * distributed under the License is distributed on an "AS IS" BASIS,
120039  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120040  * See the License for the specific language governing permissions and
120041  * limitations under the License.
120042  */
120043
120044 module.exports = {
120045
120046     id: "ivi",
120047     version: "3.0",
120048     name: "IVI",
120049
120050     persistencePrefix: "ivi3-",
120051
120052     config: require('ripple/platform/ivi/3.0/spec/config'),
120053     ui: require('ripple/platform/ivi/3.0/spec/ui'),
120054     device: require('ripple/platform/ivi/3.0/spec/device'),
120055     sensor: require('ripple/platform/ivi/3.0/spec/sensor'),
120056     DeviceMotionEvent: require('ripple/platform/tizen/2.0/DeviceMotionEvent'),
120057     DeviceOrientationEvent: require('ripple/platform/tizen/2.0/DeviceOrientationEvent'),
120058
120059     objects: {
120060         Coordinates: {
120061             path: "w3c/1.0/Coordinates"
120062         },
120063         Position: {
120064             path: "w3c/1.0/Position"
120065         },
120066         PositionError: {
120067             path: "w3c/1.0/PositionError"
120068         },
120069         SensorConnection: {
120070             path: "w3c/1.0/SensorConnection"
120071         },
120072         navigator: {
120073             path: "tizen/2.0/navigator",
120074             children: {
120075                 geolocation: {
120076                     path: "wac/2.0/geolocation"
120077                 },
120078                 battery: {
120079                     path: "tizen/2.0/battery"
120080                 }
120081             }
120082         },
120083         tizen: {
120084             feature: "http://tizen.org/privilege/tizen",
120085             children: {
120086                 AlarmAbsolute: {
120087                     path: "tizen/2.0/AlarmAbsolute"
120088                 },
120089                 AlarmRelative: {
120090                     path: "tizen/2.0/AlarmRelative"
120091                 },
120092                 ApplicationControl: {
120093                     path: "tizen/2.0/ApplicationControl"
120094                 },
120095                 ApplicationControlData: {
120096                     path: "tizen/2.0/ApplicationControlData"
120097                 },
120098                 AttributeFilter: {
120099                     path: "tizen/2.0/AttributeFilter"
120100                 },
120101                 AttributeRangeFilter: {
120102                     path: "tizen/2.0/AttributeRangeFilter"
120103                 },
120104                 BookmarkFolder: {
120105                     path: "tizen/2.0/BookmarkFolder"
120106                 },
120107                 BookmarkItem: {
120108                     path: "tizen/2.0/BookmarkItem"
120109                 },
120110                 CalendarAlarm: {
120111                     path: "tizen/2.0/CalendarAlarm"
120112                 },
120113                 CalendarAttendee: {
120114                     path: "tizen/2.0/CalendarAttendee"
120115                 },
120116                 CalendarEvent: {
120117                     path: "tizen/2.0/CalendarEvent"
120118                 },
120119                 CalendarEventId: {
120120                     path: "tizen/2.0/CalendarEventId"
120121                 },
120122                 CalendarRecurrenceRule: {
120123                     path: "tizen/2.0/CalendarRecurrenceRule"
120124                 },
120125                 CalendarTask: {
120126                     path: "tizen/2.0/CalendarTask"
120127                 },
120128                 CompositeFilter: {
120129                     path: "tizen/2.0/CompositeFilter"
120130                 },
120131                 Contact: {
120132                     path: "tizen/2.0/ContactBase"
120133                 },
120134                 ContactAddress: {
120135                     path: "tizen/2.0/ContactAddress"
120136                 },
120137                 ContactAnniversary: {
120138                     path: "tizen/2.0/ContactAnniversary"
120139                 },
120140                 ContactEmailAddress: {
120141                     path: "tizen/2.0/ContactEmailAddress"
120142                 },
120143                 ContactGroup: {
120144                     path: "tizen/2.0/ContactGroup"
120145                 },
120146                 ContactName: {
120147                     path: "tizen/2.0/ContactName"
120148                 },
120149                 ContactOrganization: {
120150                     path: "tizen/2.0/ContactOrganization"
120151                 },
120152                 ContactPhoneNumber: {
120153                     path: "tizen/2.0/ContactPhoneNumber"
120154                 },
120155                 ContactRef: {
120156                     path: "tizen/2.0/ContactRef"
120157                 },
120158                 ContactWebSite: {
120159                     path: "tizen/2.0/ContactWebSite"
120160                 },
120161                 DownloadRequest: {
120162                     path: "tizen/2.0/DownloadRequest"
120163                 },
120164                 Message: {
120165                     path: "tizen/2.0/Message"
120166                 },
120167                 NDEFMessage: {
120168                     path: "tizen/2.0/NDEFMessage"
120169                 },
120170                 NDEFRecord: {
120171                     path: "tizen/2.0/NDEFRecord"
120172                 },
120173                 NDEFRecordMedia: {
120174                     path: "tizen/2.0/NDEFRecordMedia"
120175                 },
120176                 NDEFRecordText: {
120177                     path: "tizen/2.0/NDEFRecordText"
120178                 },
120179                 NDEFRecordURI: {
120180                     path: "tizen/2.0/NDEFRecordURI"
120181                 },
120182                 NotificationDetailInfo: {
120183                     path: "tizen/2.0/NotificationDetailInfo"
120184                 },
120185                 SimpleCoordinates: {
120186                     path: "tizen/2.0/SimpleCoordinates"
120187                 },
120188                 SortMode: {
120189                     path: "tizen/2.0/SortMode"
120190                 },
120191                 StatusNotification: {
120192                     path: "tizen/2.0/StatusNotification"
120193                 },
120194                 SyncInfo: {
120195                     path: "tizen/2.0/SyncInfo"
120196                 },
120197                 SyncServiceInfo: {
120198                     path: "tizen/2.0/SyncServiceInfo"
120199                 },
120200                 SyncProfileInfo: {
120201                     path: "tizen/2.0/SyncProfileInfo"
120202                 },
120203                 TZDate: {
120204                     path: "tizen/2.0/TZDate"
120205                 },
120206                 TimeDuration: {
120207                     path: "tizen/2.0/TimeDuration"
120208                 },
120209                 alarm: {
120210                     path: "tizen/2.0/alarm",
120211                     feature: "http://tizen.org/privilege/alarm",
120212                     handleSubfeatures: true
120213                 },
120214                 application: {
120215                     path: "tizen/2.0/application",
120216                     feature: "http://tizen.org/privilege/application.launch|http://tizen.org/privilege/appmanager.kill|http://tizen.org/privilege/appmanager.certificate",
120217                     handleSubfeatures: true
120218                 },
120219                 bluetooth: {
120220                     path: "tizen/2.0/bluetooth",
120221                     feature: "http://tizen.org/privilege/bluetoothmanager|http://tizen.org/privilege/bluetooth.admin|http://tizen.org/privilege/bluetooth.gap|http://tizen.org/privilege/bluetooth.spp",
120222                     handleSubfeatures: true
120223                 },
120224                 bookmark: {
120225                     path: "tizen/2.0/bookmark",
120226                     feature: "http://tizen.org/privilege/bookmark.read|http://tizen.org/privilege/bookmark.write",
120227                     handleSubfeatures: true
120228                 },
120229                 callhistory: {
120230                     path: "tizen/2.0/callHistory",
120231                     feature: "http://tizen.org/privilege/callhistory|http://tizen.org/privilege/callhistory.read|http://tizen.org/privilege/callhistory.write",
120232                     handleSubfeatures: true
120233                 },
120234                 calendar: {
120235                     path: "tizen/2.0/calendar",
120236                     feature: "http://tizen.org/privilege/calendar.read|http://tizen.org/privilege/calendar.write",
120237                     handleSubfeatures: true
120238                 },
120239                 contact: {
120240                     path: "tizen/2.0/contact",
120241                     feature: "http://tizen.org/privilege/contact.read|http://tizen.org/privilege/contact.write",
120242                     handleSubfeatures: true
120243                 },
120244                 content: {
120245                     path: "tizen/2.0/content",
120246                     feature: "http://tizen.org/privilege/content.read|http://tizen.org/privilege/content.write",
120247                     handleSubfeatures: true
120248                 },
120249                 datacontrol: {
120250                     path: "tizen/2.0/datacontrol",
120251                     feature: "http://tizen.org/privilege/datacontrol.consumer",
120252                     handleSubfeatures: true
120253                 },
120254                 datasync: {
120255                     path: "tizen/2.0/datasync",
120256                     feature: "http://tizen.org/privilege/datasync",
120257                     handleSubfeatures: true
120258                 },
120259                 download: {
120260                     path: "tizen/2.0/download",
120261                     feature: "http://tizen.org/privilege/download",
120262                     handleSubfeatures: true
120263                 },
120264                 filesystem: {
120265                     path: "tizen/2.0/filesystem",
120266                     feature: "http://tizen.org/privilege/filesystem.read|http://tizen.org/privilege/filesystem.write"
120267                 },
120268                 messageport: {
120269                     path: "tizen/2.0/messageport"
120270                 },
120271                 messaging: {
120272                     path: "tizen/2.0/messaging",
120273                     feature: "http://tizen.org/privilege/messaging.send|http://tizen.org/privilege/messaging.read|http://tizen.org/privilege/messaging.write",
120274                     handleSubfeatures: true
120275                 },
120276                 networkbearerselection: {
120277                     path: "tizen/2.0/networkbearerselection",
120278                     feature: "http://tizen.org/privilege/networkbearerselection",
120279                     handleSubfeatures: true
120280                 },
120281                 nfc: {
120282                     path: "tizen/2.0/nfc",
120283                     feature: "http://tizen.org/privilege/nfc.common|http://tizen.org/privilege/nfc.admin|http://tizen.org/privilege/nfc.tag|http://tizen.org/privilege/nfc.p2p",
120284                     handleSubfeatures: true
120285                 },
120286                 notification: {
120287                     path: "tizen/2.0/notification",
120288                     feature: "http://tizen.org/privilege/notification",
120289                     handleSubfeatures: true
120290                 },
120291                 package: {
120292                     path: "tizen/2.0/package",
120293                     feature: "http://tizen.org/privilege/packagemanager.install|http://tizen.org/privilege/package.info",
120294                     handleSubfeatures: true
120295                 },
120296                 power: {
120297                     path: "tizen/2.0/power",
120298                     feature: "http://tizen.org/privilege/power",
120299                     handleSubfeatures: true
120300                 },
120301                 push: {
120302                     path: "tizen/2.0/push",
120303                     feature: "http://tizen.org/privilege/push",
120304                     handleSubfeatures: true
120305                 },
120306                 seService: {
120307                     path: "tizen/2.0/secureelement",
120308                     feature: "http://tizen.org/privilege/secureelement",
120309                     handleSubfeatures: true
120310                 },
120311                 systeminfo: {
120312                     path: "tizen/2.0/systeminfo",
120313                     feature: "http://tizen.org/privilege/system|http://tizen.org/privilege/systemmanager",
120314                     handleSubfeatures: true
120315                 },
120316                 systemsetting: {
120317                     path: "tizen/2.0/systemsetting",
120318                     feature: "http://tizen.org/privilege/setting",
120319                     handleSubfeatures: true
120320                 },
120321                 time: {
120322                     path: "tizen/2.0/time",
120323                     feature: "http://tizen.org/privilege/time",
120324                     handleSubfeatures: true
120325                 },
120326                 websetting: {
120327                     path: "tizen/2.0/websetting",
120328                     feature: "http://tizen.org/privilege/websetting",
120329                     handleSubfeatures: true
120330                 },
120331                 vehicle: {
120332                     path: "ivi/3.0/vehicle",
120333                     feature: "http://tizen.org/privilege/vehicle",
120334                     handleSubfeatures: true
120335                 }
120336             }
120337         }
120338     }
120339 };
120340
120341 });
120342 define('ripple/platform/ivi/3.0/dbinit', function (require, exports, module) {
120343 /*
120344  *  Copyright 2013 Intel Corporation.
120345  *
120346  * Licensed under the Apache License, Version 2.0 (the "License");
120347  * you may not use this file except in compliance with the License.
120348  * You may obtain a copy of the License at
120349  *
120350  * http://www.apache.org/licenses/LICENSE-2.0
120351  *
120352  * Unless required by applicable law or agreed to in writing, software
120353  * distributed under the License is distributed on an "AS IS" BASIS,
120354  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120355  * See the License for the specific language governing permissions and
120356  * limitations under the License.
120357  */
120358
120359 var exception = require('ripple/exception'),
120360     DBBuilder,
120361     _data = {
120362         dbBuilder: null
120363     },
120364     _self = {};
120365
120366 function _initialize() {
120367     _data.dbBuilder = new DBBuilder();
120368
120369     _data.dbBuilder.register("Vehicle", "dbvehicle.json");
120370 }
120371
120372 DBBuilder = function () {
120373     var self;
120374
120375     // private
120376     function formatString(str) {
120377         return str.replace(/^\s+|[\t\n\r\v]+|\s+$/g, "").replace(/\s+/g, "");
120378     }
120379
120380     // private
120381     function formatHex(str) {
120382         return str.replace(/,(0x[0-9a-fA-F]+?),/g, ',"$1",');
120383     }
120384
120385     // public
120386     function register(type, dbFile, Extension) {
120387         _data[type] = Extension ? new Extension() : {};
120388
120389         if (!dbFile)
120390             return;
120391
120392         _self.__defineGetter__(type, function () {
120393             var fnInit;
120394
120395             if (!_data[type].db) {
120396                 fnInit = _data[type].initdb || initdb;
120397                 _data[type].db = fnInit(dbFile);
120398             }
120399
120400             return _data[type].db;
120401         });
120402     }
120403
120404     function initdb(dbFile) {
120405         var xmlHttp, res;
120406
120407         try {
120408             xmlHttp = new XMLHttpRequest();
120409             xmlHttp.open("GET", "dbsamples/" + dbFile, false);
120410             xmlHttp.send();
120411         } catch (e) {
120412             exception.handle(e);
120413         }
120414
120415         if (!xmlHttp.responseText) {
120416             return null;
120417         }
120418
120419         res = formatHex(formatString(xmlHttp.responseText));
120420
120421         return JSON.parse(res);
120422     }
120423
120424     self = {
120425         register: register,
120426         initdb:   initdb
120427     };
120428
120429     return self;
120430 };
120431
120432 _initialize();
120433
120434 module.exports = _self;
120435
120436 });
120437 define('ripple/platform/ivi/3.0/spec/config', function (require, exports, module) {
120438 /*
120439  *  Copyright 2011 Research In Motion Limited.
120440  *  Copyright 2011 Intel Corporation.
120441  *
120442  * Licensed under the Apache License, Version 2.0 (the "License");
120443  * you may not use this file except in compliance with the License.
120444  * You may obtain a copy of the License at
120445  *
120446  * http://www.apache.org/licenses/LICENSE-2.0
120447  *
120448  * Unless required by applicable law or agreed to in writing, software
120449  * distributed under the License is distributed on an "AS IS" BASIS,
120450  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120451  * See the License for the specific language governing permissions and
120452  * limitations under the License.
120453  */
120454 var utils = require('ripple/utils'),
120455     db = require('ripple/db'),
120456     constants = require('ripple/constants');
120457
120458 module.exports = {
120459     fileName: "config.xml",
120460     validateVersion: function (configValidationObject) {
120461         var valid = true;
120462         // no xmlns:JIL in wac 2.0 spec
120463         valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid;
120464
120465         return valid;
120466     },
120467     extractInfo: function (configValidationObject) {
120468         if (!configValidationObject) {
120469             return null;
120470         }
120471
120472         var widgetInfo = {},
120473             configFeatures,
120474             configPreferences,
120475             preferenceName,
120476             platform, rst, i, j,
120477             settingRst = {
120478                 'screen-orientation': 'portrait',
120479                 'context-menu': 'enable',
120480                 'background-support': 'disable',
120481                 encryption: 'disable',
120482                 'install-location': 'auto',
120483                 'hwkey-event': 'enable'
120484             };
120485
120486         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
120487         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
120488         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
120489         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
120490         if (configValidationObject.widget.children.application.validationResult[0].valid) {
120491             widgetInfo.tizenAppId = configValidationObject.widget.children.application.validationResult[0].attributes.id.value;
120492             widgetInfo.tizenPackageId = configValidationObject.widget.children.application.validationResult[0].attributes.package.value;
120493         }
120494
120495         widgetInfo.features = {};
120496
120497         if (configValidationObject.widget.children.setting.hasOwnProperty('validationResult') === true) {
120498             rst = configValidationObject.widget.children.setting.validationResult;
120499             // the first one has higher priority per platform implementation
120500             for (i = rst.length -1 ; i >= 0; i--) {
120501                 if (rst[i].valid === true) {
120502                     for (j in rst[i].attributes) {
120503                         if (rst[i].attributes[j].value !== undefined) {
120504                             settingRst[j] = rst[i].attributes[j].value;
120505                         }
120506                     }
120507                 }
120508             }
120509             db.save("layout", settingRst["screen-orientation"]);
120510         }
120511
120512         configFeatures = configValidationObject.widget.children.feature.validationResult;
120513         utils.forEach(configFeatures, function (f) {
120514             if (f.valid === true) {
120515                 var feature = {id: f.attributes.name.value,
120516                          required: f.attributes.required.valid};
120517                 widgetInfo.features[feature.id] = feature;
120518             }
120519         });
120520
120521         widgetInfo.preferences = {};
120522
120523         configPreferences = configValidationObject.widget.children.preference.validationResult;
120524
120525         platform = require('ripple/platform');
120526         utils.forEach(configPreferences, function (preference) {
120527             preferenceName = preference.attributes.name.value;
120528             if (preferenceName) {
120529                 widgetInfo.preferences[preferenceName] = {
120530                     "key": preferenceName,
120531                     "value": preference.attributes.value.value || "",
120532                     "readonly": preference.attributes.readonly.value === "true"
120533                 };
120534
120535                 db.save(preferenceName,
120536                         widgetInfo.preferences[preferenceName].value,
120537                         platform.getPersistencePrefix(widgetInfo.id));
120538             }
120539         });
120540
120541         return widgetInfo;
120542     },
120543     schema: {
120544         rootElement: "widget",
120545         widget: {
120546             nodeName: "widget",
120547             required: true,
120548             occurrence: 1,
120549             helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in the configuration document and may have the following child elments: name,description,icon,author,license,content,feature and preference.The \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir",
120550             attributes: {
120551                 xmlns: {
120552                     attributeName: "xmlns",
120553                     required: true,
120554                     type: "list",
120555                     listValues: ["http://www.w3.org/ns/widgets"]
120556                 },
120557                 "xmlns:tizen": {
120558                     attributeName: "xmlns:tizen",
120559                     required: false,
120560                     type: "list",
120561                     listValues: ["http://tizen.org/ns/widgets"]
120562                 },
120563                 "xml:lang": {
120564                     attributeName: "xml:lang",
120565                     required: false,
120566                     type: "iso-language"
120567                 },
120568                 dir: {
120569                     attributeName: "dir",
120570                     required: false,
120571                     type: "list",
120572                     listValues: ["ltr", "rtl", "lro", "rlo"]
120573                 },
120574                 id: {
120575                     attributeName: "id",
120576                     required: false,
120577                     type: "string"
120578                 },
120579                 version: {
120580                     attributeName: "version",
120581                     required: false,
120582                     type: "string"
120583                 },
120584                 height: {
120585                     attributeName: "height",
120586                     required: false,
120587                     type: "integer"
120588                 },
120589                 width: {
120590                     attributeName: "width",
120591                     required: false,
120592                     type: "integer"
120593                 },
120594                 viewmodes: {
120595                     attributeName: "viewmodes",
120596                     required: false,
120597                     type: "list",
120598                     listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"]
120599                 },
120600                 defaultlocale: {
120601                     attributeName: "defaultlocale",
120602                     required: false,
120603                     type: "iso-language"
120604                 }
120605             },
120606             children: {
120607                 name: {
120608                     nodeName: "name",
120609                     required: false,
120610                     occurrence: 0,
120611                     type: "string",
120612                     attributes: {
120613                         "xml:lang": {
120614                             attributeName: "xml:lang",
120615                             required: false,
120616                             type: "iso-language",
120617                             unique: true
120618                         },
120619                         dir: {
120620                             attributeName: "dir",
120621                             required: false,
120622                             type: "list",
120623                             listValues: ["ltr", "rtl", "lro", "rlo"]
120624                         },
120625                         "short": {
120626                             attributeName: "short",
120627                             required: false,
120628                             type: "string"
120629                         }
120630                     },
120631                     children: {
120632                         span: {
120633                             nodeName: "span",
120634                             required: false,
120635                             type: "string",
120636                             attributes: {
120637                                 "xml:lang": {
120638                                     attributeName: "xml:lang",
120639                                     required: false,
120640                                     type: "iso-language",
120641                                     unique: true
120642                                 },
120643                                 dir: {
120644                                     attributeName: "dir",
120645                                     required: false,
120646                                     type: "list",
120647                                     listValues: ["ltr", "rtl", "lro", "rlo"]
120648                                 }
120649                             }
120650                         }
120651                     }
120652                 },
120653                 description: {
120654                     nodeName: "description",
120655                     required: false,
120656                     occurrence: 0,
120657                     type: "string",
120658                     attributes: {
120659                         "xml:lang": {
120660                             attributeName: "xml:lang",
120661                             required: false,
120662                             type: "iso-language",
120663                             unique: true
120664                         },
120665                         dir: {
120666                             attributeName: "dir",
120667                             required: false,
120668                             type: "list",
120669                             listValues: ["ltr", "rtl", "lro", "rlo"]
120670                         }
120671                     },
120672                     children: {
120673                         span: {
120674                             nodeName: "span",
120675                             required: false,
120676                             type: "string",
120677                             attributes: {
120678                                 "xml:lang": {
120679                                     attributeName: "xml:lang",
120680                                     required: false,
120681                                     type: "iso-language",
120682                                     unique: true
120683                                 },
120684                                 dir: {
120685                                     attributeName: "dir",
120686                                     required: false,
120687                                     type: "list",
120688                                     listValues: ["ltr", "rtl", "lro", "rlo"]
120689                                 }
120690                             }
120691                         }
120692                     }
120693                 },
120694                 author: {
120695                     nodeName: "author",
120696                     required: false,
120697                     occurrence: 0,
120698                     type: "string",
120699                     attributes: {
120700                         "xml:lang": {
120701                             attributeName: "xml:lang",
120702                             required: false,
120703                             type: "iso-language"
120704                         },
120705                         dir: {
120706                             attributeName: "dir",
120707                             required: false,
120708                             type: "list",
120709                             listValues: ["ltr", "rtl", "lro", "rlo"]
120710                         },
120711                         href: {
120712                             attributeName: "href",
120713                             required: false,
120714                             type: "regex",
120715                             regex: constants.REGEX.URL
120716                         },
120717                         email: {
120718                             attributeName: "email",
120719                             required: false,
120720                             type: "regex",
120721                             regex: constants.REGEX.EMAIL
120722                         }
120723                     },
120724                     children: {
120725                         span: {
120726                             nodeName: "span",
120727                             required: false,
120728                             type: "string",
120729                             attributes: {
120730                                 "xml:lang": {
120731                                     attributeName: "xml:lang",
120732                                     required: false,
120733                                     type: "iso-language",
120734                                     unique: true
120735                                 },
120736                                 dir: {
120737                                     attributeName: "dir",
120738                                     required: false,
120739                                     type: "list",
120740                                     listValues: ["ltr", "rtl", "lro", "rlo"]
120741                                 }
120742                             }
120743                         }
120744                     }
120745                 },
120746                 license: {
120747                     nodeName: "license",
120748                     required: false,
120749                     occurrence: 0,
120750                     type: "string",
120751                     attributes: {
120752                         "xml:lang": {
120753                             attributeName: "xml:lang",
120754                             required: false,
120755                             type: "iso-language"
120756                         },
120757                         dir: {
120758                             attributeName: "dir",
120759                             required: false,
120760                             type: "list",
120761                             listValues: ["ltr", "rtl", "lro", "rlo"]
120762                         },
120763                         href: {
120764                             attributeName: "href",
120765                             type: "regex",
120766                             required: false,
120767                             regex: constants.REGEX.URL
120768                         }
120769                     },
120770                     children: {
120771                         span: {
120772                             nodeName: "span",
120773                             required: false,
120774                             type: "string",
120775                             attributes: {
120776                                 "xml:lang": {
120777                                     attributeName: "xml:lang",
120778                                     required: false,
120779                                     type: "iso-language",
120780                                     unique: true
120781                                 },
120782                                 dir: {
120783                                     attributeName: "dir",
120784                                     required: false,
120785                                     type: "list",
120786                                     listValues: ["ltr", "rtl", "lro", "rlo"]
120787                                 }
120788                             }
120789                         }
120790                     }
120791                 },
120792                 icon: {
120793                     nodeName: "icon",
120794                     required: false,
120795                     occurrence: 0,
120796                     attributes: {
120797                         "xml:lang": {
120798                             attributeName: "xml:lang",
120799                             required: false,
120800                             type: "iso-language"
120801                         },
120802                         dir: {
120803                             attributeName: "dir",
120804                             required: false,
120805                             type: "list",
120806                             listValues: ["ltr", "rtl", "lro", "rlo"]
120807                         },
120808                         src: {
120809                             attributeName: "src",
120810                             required: true,
120811                             type: "string"
120812                         },
120813                         width: {
120814                             attributeName: "width",
120815                             required: false,
120816                             type: "integer"
120817                         },
120818                         height: {
120819                             attributeName: "height",
120820                             required: false,
120821                             type: "integer"
120822                         }
120823                     }
120824                 },
120825                 content: {
120826                     nodeName: "content",
120827                     required: false,
120828                     occurrence: 1,
120829                     attributes: {
120830                         "xml:lang": {
120831                             attributeName: "xml:lang",
120832                             required: false,
120833                             type: "iso-language",
120834                             unique: true
120835                         },
120836                         dir: {
120837                             attributeName: "dir",
120838                             required: false,
120839                             type: "list",
120840                             listValues: ["ltr", "rtl", "lro", "rlo"]
120841                         },
120842                         src: {
120843                             attributeName: "src",
120844                             required: true,
120845                             type: "string"
120846                         },
120847                         encoding: {
120848                             attributeName: "encoding",
120849                             required: false,
120850                             type: "string"
120851                         },
120852                         type: {
120853                             attributeName: "type",
120854                             required: false,
120855                             type: "string"
120856                         }
120857                     }
120858                 },
120859                 setting: {
120860                     nodeName: "tizen:setting",
120861                     required: false,
120862                     occurrence: 0,
120863                     attributes: {
120864                         'screen-orientation': {
120865                             attributeName: "screen-orientation",
120866                             required: false,
120867                             type: "list",
120868                             listValues: ['portrait', 'landscape', 'auto']
120869                         },
120870                         'context-menu': {
120871                             attributeName: "context-menu",
120872                             required: false,
120873                             type: "list",
120874                             listValues: ['enable', 'disable']
120875                         },
120876                         'background-support': {
120877                             attributeName: "background-support",
120878                             required: false,
120879                             type: "list",
120880                             listValues: ['enable', 'disable']
120881                         },
120882                         'encryption': {
120883                             attributeName: "encryption",
120884                             required: false,
120885                             type: "list",
120886                             listValues: ['enable', 'disable']
120887                         },
120888                         'install-location': {
120889                             attributeName: "install-location",
120890                             required: false,
120891                             type: "list",
120892                             listValues: ['auto', 'internal-only', 'perfer-external']
120893                         },
120894                         'hwkey-event': {
120895                             attributeName: "hwkey-event",
120896                             required: false,
120897                             type: "list",
120898                             listValues: ['enable', 'disable']
120899                         }
120900                     }
120901                 },
120902                 application: {
120903                     nodeName: "tizen:application",
120904                     required: true,
120905                     occurrence: 1,
120906                     attributes: {
120907                         id: {
120908                             attributeName: "id",
120909                             required: true,
120910                             type: "string"
120911                         },
120912                         required_version: {
120913                             attributeName: "required_version",
120914                             required: true,
120915                             type: "list",
120916                             listValues: ['1.0', '2.0', '2.1', '2.2']
120917                         },
120918                         package: {
120919                             attributeName: "package",
120920                             required: false,
120921                             type: "string"
120922                         }
120923                     }
120924                 },
120925                 "tizen:content": {
120926                     nodeName: "tizen:content",
120927                     required: false,
120928                     occurrence: 1,
120929                     attributes: {
120930                         src: {
120931                             attributeName: "src",
120932                             required: true,
120933                             type: "string"
120934                         }
120935                     }
120936                 },
120937                 control: {
120938                     nodeName: "tizen:app-control",
120939                     required: false,
120940                     occurrence: 0,
120941                     children: {
120942                         src: {
120943                             nodeName: "tizen:src",
120944                             required: true,
120945                             occurence: 0,
120946                             attributes: {
120947                                 name: {
120948                                     attributeName: "name",
120949                                     required: false,
120950                                     type: "string"
120951                                 }
120952                             }
120953                         },
120954                         operation: {
120955                             nodeName: "tizen:operation",
120956                             required: true,
120957                             occurence: 0,
120958                             attributes: {
120959                                 name: {
120960                                     attributeName: "name",
120961                                     required: false,
120962                                     type: "string"
120963                                 }
120964                             }
120965                         },
120966                         uri: {
120967                             nodeName: "tizen:uri",
120968                             required: false,
120969                             occurence: 0,
120970                             attributes: {
120971                                 name: {
120972                                     attributeName: "name",
120973                                     required: false,
120974                                     type: "string"
120975                                 }
120976                             }
120977                         },
120978                         mime: {
120979                             nodeName: "tizen:mime",
120980                             required: false,
120981                             occurence: 0,
120982                             attributes: {
120983                                 name: {
120984                                     attributeName: "name",
120985                                     required: false,
120986                                     type: "string"
120987                                 }
120988                             }
120989                         }
120990                     }
120991                 },
120992                 "app-widget": {
120993                     nodeName: "tizen:app-widget",
120994                     required: false,
120995                     occurrence: 0,
120996                     attributes: {
120997                         id: {
120998                             attributeName: "id",
120999                             required: true,
121000                             type: "string"
121001                         },
121002                         primary: {
121003                             attributeName: "primary",
121004                             required: true,
121005                             type: "list",
121006                             listValues: ['true', 'false']
121007                         },
121008                         "auto-launch": {
121009                             attributeName: "auto-launch",
121010                             required: false,
121011                             type: "list",
121012                             listValues: ['true', 'false']
121013                         },
121014                         "update-period": {
121015                             attributeName: "update-period",
121016                             required: false,
121017                             type: "integer"
121018                         }
121019                     },
121020                     children: {
121021                         "box-label": {
121022                             nodeName: "tizen:box-label",
121023                             required: true,
121024                             occurence: 1
121025                         },
121026                         "box-icon": {
121027                             nodeName: "tizen:box-icon",
121028                             required: true,
121029                             occurence: 1,
121030                             attributes: {
121031                                 src: {
121032                                     attributeName: "src",
121033                                     required: true,
121034                                     type: "string"
121035                                 }
121036                             }
121037                         },
121038                         "box-content": {
121039                             nodeName: "tizen:box-content",
121040                             required: true,
121041                             occurence: 1,
121042                             attributes: {
121043                                 src: {
121044                                     attributeName: "src",
121045                                     required: true,
121046                                     type: "string"
121047                                 },
121048                                 "mouse-event": {
121049                                     attributeName: "mouse-event",
121050                                     required: false,
121051                                     type: "string"
121052                                 },
121053                                 "touch-event": {
121054                                     attributeName: "touch-event",
121055                                     required: false,
121056                                     type: "string"
121057                                 }
121058                             },
121059                             children: {
121060                                 "box-size": {
121061                                     nodeName: "tizen:box-size",
121062                                     required: false,
121063                                     occurence: 1,
121064                                     attributes: {
121065                                         "preview": {
121066                                             attributeName: "preview",
121067                                             required: false,
121068                                             type: "string"
121069                                         }
121070                                     }
121071                                 },
121072                                 pd: {
121073                                     nodeName: "tizen:pd",
121074                                     required: false,
121075                                     occurence: 1,
121076                                     attributes: {
121077                                         "src": {
121078                                             attributeName: "src",
121079                                             required: true,
121080                                             type: "string"
121081                                         },
121082                                         "width": {
121083                                             attributeName: "width",
121084                                             required: true,
121085                                             type: "integer"
121086                                         },
121087                                         "height": {
121088                                             attributeName: "height",
121089                                             required: true,
121090                                             type: "integer"
121091                                         }
121092                                     }
121093                                 }
121094                             }
121095                         }
121096                     }
121097                 },
121098                 account: {
121099                     nodeName: "tizen:account",
121100                     required: false,
121101                     occurrence: 0,
121102                     attributes: {
121103                         "multiple-account-support": {
121104                             attributeName: "multiple-account-support",
121105                             required: true,
121106                             type: "list",
121107                             listValues: ['true', 'false']
121108                         }
121109                     },
121110                     children: {
121111                         icon: {
121112                             nodeName: "tizen:icon",
121113                             required: false,
121114                             occurence: 1,
121115                             attributes: {
121116                                 section: {
121117                                     attributeName: "section",
121118                                     required: true,
121119                                     type: "string"
121120                                 }
121121                             }
121122                         },
121123                         "display-name": {
121124                             nodeName: "tizen:display-name",
121125                             required: false,
121126                             occurence: 1,
121127                             attributes: {
121128                                 "xml:lang": {
121129                                     attributeName: "xml:lang",
121130                                     required: false,
121131                                     type: "string"
121132                                 }
121133                             }
121134                         },
121135                         capability: {
121136                             nodeName: "capability",
121137                             required: false,
121138                             occurence: 1
121139                         }
121140                     }
121141                 },
121142                 feature: {
121143                     nodeName: "tizen:privilege",
121144                     required: false,
121145                     occurrence: 0,
121146                     attributes: {
121147                         "xml:lang": {
121148                             attributeName: "xml:lang",
121149                             required: false,
121150                             type: "iso-language"
121151                         },
121152                         dir: {
121153                             attributeName: "dir",
121154                             required: false,
121155                             type: "list",
121156                             listValues: ["ltr", "rtl", "lro", "rlo"]
121157                         },
121158                         name: {
121159                             attributeName: "name",
121160                             required: true,
121161                             type: "list",
121162                             listValues: ["http://www.w3.org/TR/battery-status/",
121163                                          "http://www.w3.org/TR/geolocation-API/",
121164                                          "http://www.w3.org/TR/touch-events/",
121165                                          "http://www.w3.org/TR/vibration/",
121166                                          "http://tizen.org/privilege/tizen",
121167                                          "http://tizen.org/privilege/alarm",
121168                                          "http://tizen.org/privilege/application.launch",
121169                                          "http://tizen.org/privilege/appmanager.kill", "http://tizen.org/privilege/appmanager.certificate",
121170                                          "http://tizen.org/privilege/bluetoothmanager", "http://tizen.org/privilege/bluetooth.admin",
121171                                          "http://tizen.org/privilege/bluetooth.gap", "http://tizen.org/privilege/bluetooth.spp",
121172                                          "http://tizen.org/privilege/bookmark.read", "http://tizen.org/privilege/bookmark.write",
121173                                          "http://tizen.org/privilege/calendar.read", "http://tizen.org/privilege/calendar.write",
121174                                          "http://tizen.org/privilege/callhistory.read", "http://tizen.org/privilege/callhistory.write",
121175                                          "http://tizen.org/privilege/contact.read", "http://tizen.org/privilege/contact.write",
121176                                          "http://tizen.org/privilege/content.read", "http://tizen.org/privilege/content.write",
121177                                          "http://tizen.org/privilege/datacontrol.consumer",
121178                                          "http://tizen.org/privilege/datasync",
121179                                          "http://tizen.org/privilege/download",
121180                                          "http://tizen.org/privilege/filesystem.read", "http://tizen.org/privilege/filesystem.write",
121181                                          "http://tizen.org/privilege/messaging.read", "http://tizen.org/privilege/messaging.write",
121182                                          "http://tizen.org/privilege/networkbearerselection",
121183                                          "http://tizen.org/privilege/nfc.common", "http://tizen.org/privilege/nfc.admin",
121184                                          "http://tizen.org/privilege/nfc.tag", "http://tizen.org/privilege/nfc.p2p",
121185                                          "http://tizen.org/privilege/notification",
121186                                          "http://tizen.org/privilege/packagemanager.install", "http://tizen.org/privilege/package.info",
121187                                          "http://tizen.org/privilege/power",
121188                                          "http://tizen.org/privilege/push",
121189                                          "http://tizen.org/privilege/secureelement",
121190                                          "http://tizen.org/privilege/setting",
121191                                          "http://tizen.org/privilege/system", "http://tizen.org/privilege/systemmanager",
121192                                          "http://tizen.org/privilege/time",
121193                                          "http://tizen.org/privilege/vehicle",
121194                                          "http://tizen.org/privilege/websetting"]
121195                         },
121196                         required: {
121197                             attributeName: "required",
121198                             type: "boolean",
121199                             required: false
121200                         }
121201                     },
121202                     children: {
121203                         param: {
121204                             nodeName: "param",
121205                             required: false,
121206                             occurrence: 0,
121207                             attributes: {
121208                                 "xml:lang": {
121209                                     attributeName: "xml:lang",
121210                                     required: false,
121211                                     type: "iso-language"
121212                                 },
121213                                 dir: {
121214                                     attributeName: "dir",
121215                                     required: false,
121216                                     type: "list",
121217                                     listValues: ["ltr", "rtl", "lro", "rlo"]
121218                                 },
121219                                 name: {
121220                                     attributeName: "name",
121221                                     required: true,
121222                                     type: "string"
121223                                 },
121224                                 value: {
121225                                     attributeName: "value",
121226                                     required: true,
121227                                     type: "string"
121228                                 }
121229                             }
121230                         }
121231                     }
121232                 },
121233                 preference: {
121234                     nodeName: "preference",
121235                     required: false,
121236                     occurrence: 0,
121237                     attributes: {
121238                         "xml:lang": {
121239                             attributeName: "xml:lang",
121240                             required: false,
121241                             type: "iso-language"
121242                         },
121243                         dir: {
121244                             attributeName: "dir",
121245                             required: false,
121246                             type: "list",
121247                             listValues: ["ltr", "rtl", "lro", "rlo"]
121248                         },
121249                         name: {
121250                             attributeName: "name",
121251                             required: true,
121252                             type: "string"
121253                         },
121254                         value: {
121255                             type: "string",
121256                             required: false,
121257                             attributeName: "value"
121258                         },
121259                         readonly: {
121260                             attributeName: "readonly",
121261                             type: "boolean",
121262                             required: false
121263                         }
121264                     }
121265                 }
121266             }
121267         }
121268     }
121269 };
121270
121271 });
121272 define('ripple/platform/ivi/3.0/spec/device', function (require, exports, module) {
121273 /*
121274  *  Copyright 2011 Intel Corporation.
121275  *
121276  * Licensed under the Apache License, Version 2.0 (the "License");
121277  * you may not use this file except in compliance with the License.
121278  * You may obtain a copy of the License at
121279  *
121280  * http://www.apache.org/licenses/LICENSE-2.0
121281  *
121282  * Unless required by applicable law or agreed to in writing, software
121283  * distributed under the License is distributed on an "AS IS" BASIS,
121284  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121285  * See the License for the specific language governing permissions and
121286  * limitations under the License.
121287  */
121288 var event = require('ripple/event'),
121289     utils = require('ripple/utils'),
121290     StorageTypeTable = {
121291         "UNKNOWN": "UNKNOWN",
121292         "INTERNAL": "INTERNAL",
121293         "MMC": "MMC",
121294         "USB_HOST": "USB_HOST"
121295     },
121296     NetworkTypeTable = {
121297         "NONE": "NONE",
121298         "2G": "2G",
121299         "2.5G": "2.5G",
121300         "3G": "3G",
121301         "4G": "4G",
121302         "WIFI": "WIFI",
121303         "ETHERNET": "ETHERNET",
121304         "UNKNOWN": "UNKNOWN"
121305     },
121306     LocaleTable = {
121307         "eng_USA": "eng_USA",
121308         "eng_CAN": "eng_CAN",
121309         "deu_DEU": "deu_DEU",
121310         "jpn_JPN": "jpn_JPN",
121311         "zho_CHN": "zho_CHN",
121312         "UNKNOWN": "UNKNOWN"
121313     },
121314     SimStateTable = {
121315         "ABSENT": "ABSENT",
121316         "INITIALIZING": "INITIALIZING",
121317         "READY": "READY",
121318         "PIN_REQUIRED": "PIN_REQUIRED",
121319         "PUK_REQUIRED":"PUK_REQUIRED",
121320         "NETWORK_LOCKED": "NETWORK_LOCKED",
121321         "SIM_LOCKED": "SIM_LOCKED",
121322         "UNKNOWN": "UNKNOWN"
121323     };
121324
121325 function deviceStatusEventTrigger(setting) {
121326     event.trigger("DeviceStatusChanged", [setting]);
121327 }
121328
121329 module.exports = {
121330     "Config": {
121331         "vibratingMode": {
121332             "name": "Vibrator",
121333             "control": {
121334                 "type": "checkbox",
121335                 "value": true
121336             },
121337             "callback": function (setting) {
121338                 event.trigger("VibratingModeChanged", [setting]);
121339             }
121340         },
121341         "lockScreen": {
121342             "name": "Lock Screen",
121343             "control": {
121344                 "type": "checkbox",
121345                 "value": false
121346             },
121347             "callback": function (setting) {
121348                 event.trigger("LockScreenChanged", [setting]);
121349             }
121350         }
121351     },
121352     "DEVICE_ORIENTATION": {
121353         "status": {
121354             "name": "Status",
121355             "control": {
121356                 "type": "label",
121357                 "innertext": "PORTRAIT_PRIMARY",
121358                 "value": "PORTRAIT_PRIMARY"
121359             },
121360             "event": "LayoutChanged"
121361         },
121362         "isAutoRotation": {
121363             "name": "Is Auto Rotation",
121364             "control": {
121365                 "type": "label",
121366                 "value": false
121367             }
121368         }
121369     },
121370     "CPU": {
121371         "load": {
121372             "name": "Load",
121373             "control": {
121374                 "type": "number",
121375                 "value": 0.1
121376             },
121377             "event": "CpuLoadChanged",
121378             "callback": function (setting) {
121379                 if (setting > 1) setting = 1;
121380                 if (setting < 0) setting = 0;
121381                 event.trigger("CpuLoadChanged", [setting]);
121382             }
121383         }
121384     },
121385     "STORAGE": {
121386         "type": {
121387             "name": "Type",
121388             "control": {
121389                 "type": "select",
121390                 "value": StorageTypeTable["INTERNAL"]
121391             },
121392             "options": (function () {
121393                 var optionList = {};
121394                 utils.forEach(StorageTypeTable, function (key, value) {
121395                     optionList[key] = StorageTypeTable[value];
121396                 });
121397
121398                 return optionList;
121399             }())
121400         },
121401         "capacity": {
121402             "name": "Capacity(bytes)",
121403             "control": {
121404                 "type": "label",
121405                 "value": 16000000000
121406             }
121407         },
121408         "availableCapacity": {
121409             "name": "AvailableCapacity(bytes)",
121410             "control": {
121411                 "type": "number",
121412                 "value": 12000000000
121413             },
121414             "callback": function (setting) {
121415                 event.trigger("AvailCapacityChanged", [setting]);
121416             }
121417         },
121418         "isRemovable": {
121419             "name": "IsRemovable",
121420             "control": {
121421                 "type": "checkbox",
121422                 "value": true
121423             }
121424         }
121425     },
121426     "BUILD": {
121427         "model": {
121428             "name": "Model",
121429             "control": {
121430                 "type": "label",
121431                 "innertext": "tizen-2.2 build",
121432                 "value": "tizen-2.2 build"
121433             }
121434         },
121435         "manufacturer": {
121436             "name": "Manufacturer",
121437             "control": {
121438                 "type": "label",
121439                 "innertext": "Tizen",
121440                 "value": "Tizen"
121441             }
121442         },
121443         "buildVersion": {
121444             "name": "Build Version",
121445             "control": {
121446                 "type": "label",
121447                 "innertext": "TIZEN_WEB_SIMULATOR_000001",
121448                 "value": "TIZEN_WEB_SIMULATOR_000001"
121449             }
121450         }
121451     },
121452     "LOCALE": {
121453         "language": {
121454             "name": "Language",
121455             "control": {
121456                 "type": "select",
121457                 "value": LocaleTable["eng_USA"]
121458             },
121459             "options": (function () {
121460                 var optionList = {};
121461                 utils.forEach(LocaleTable, function (key, value) {
121462                     optionList[key] = LocaleTable[value];
121463                 });
121464
121465                 return optionList;
121466             }())
121467         },
121468         "country": {
121469             "name": "Country",
121470             "control": {
121471                 "type": "select",
121472                 "value": LocaleTable["eng_USA"]
121473             },
121474             "options": (function () {
121475                 var optionList = {};
121476                 utils.forEach(LocaleTable, function (key, value) {
121477                     optionList[key] = LocaleTable[value];
121478                 });
121479
121480                 return optionList;
121481             }())
121482         }
121483     },
121484     "DISPLAY": {
121485         "resolutionWidth": {
121486             "name": "Resolution Width(pixels)",
121487             "control": {
121488                 "type": "label",
121489                 "value": 0
121490             }
121491         },
121492         "resolutionHeight": {
121493             "name": "Resolution Height(pixels)",
121494             "control": {
121495                 "type": "label",
121496                 "value": 0
121497             }
121498         },
121499         "dotsPerInchWidth": {
121500             "name": "DPI-X",
121501             "control": {
121502                 "type": "label",
121503                 "value": 0
121504             }
121505         },
121506         "dotsPerInchHeight": {
121507             "name": "DPI-Y",
121508             "control": {
121509                 "type": "label",
121510                 "value": 0
121511             }
121512         },
121513         "physicalWidth": {
121514             "name": "Physical Width(millimeters)",
121515             "control": {
121516                 "type": "label",
121517                 "value": 0
121518             }
121519         },
121520         "physicalHeight": {
121521             "name": "Physical Height(millimeters)",
121522             "control": {
121523                 "type": "label",
121524                 "value": 0
121525             }
121526         },
121527         "brightness": {
121528             "name": "Brightness",
121529             "control": {
121530                 "type": "number",
121531                 "value": 1
121532             },
121533             "event": "DisplayBrightnessChanged",
121534             "callback": function (setting) {
121535                 if (setting > 1) setting = 1;
121536                 if (setting < 0) setting = 0;
121537                 event.trigger("DisplayBrightnessChanged", [setting]);
121538             }
121539         }
121540     },
121541     "NETWORK": {
121542         "networkType": {
121543             "name": "Network Type",
121544             "control" : {
121545                 "type": "select",
121546                 "value": NetworkTypeTable["NONE"]
121547             },
121548             "options": (function () {
121549                 var optionList = {};
121550                 utils.forEach(NetworkTypeTable, function (key, value) {
121551                     optionList[key] = NetworkTypeTable[value];
121552                 });
121553
121554                 return optionList;
121555             }())
121556         }
121557     },
121558     "WIFI_NETWORK": {
121559         "status": {
121560             "name": "Status",
121561             "control": {
121562                 "type": "checkbox",
121563                 "value": false
121564             },
121565             "event": "WiFiNetworkStatusChanged",
121566             "callback": function (setting) {
121567                 event.trigger("WiFiNetworkStatusChanged", [setting]);
121568             }
121569         },
121570         "ssid": {
121571             "name": "SSID",
121572             "control": {
121573                 "type": "text",
121574                 "value": "Tizen WiFi"
121575             }
121576         },
121577         "ipAddress": {
121578             "name": "IP Address",
121579             "control": {
121580                 "type": "text",
121581                 "value": "192.168.0.1"
121582             }
121583         },
121584         "ipv6Address": {
121585             "name": "IPv6 Address",
121586             "control": {
121587                 "type": "text",
121588                 "value": "2001:db8:85a3:0:0:0:70:7334"
121589             }
121590         },
121591         "signalStrength": {
121592             "name": "Signal Strength",
121593             "control": {
121594                 "type": "select",
121595                 "value": 0
121596             },
121597             "options": (function () {
121598                 var i,
121599                     optionList = {};
121600
121601                 for (i = 0; i <= 10; i++) {
121602                     optionList[i] = i;
121603                 }
121604
121605                 return optionList;
121606             }())
121607         }
121608     },
121609     "CELLULAR_NETWORK": {
121610         "status": {
121611             "name": "Status",
121612             "control": {
121613                 "type": "checkbox",
121614                 "value": true
121615             },
121616             "event": "CellularNetworkStatusChanged",
121617             "callback": function (setting) {
121618                 event.trigger("CellularNetworkStatusChanged", [setting]);
121619             }
121620         },
121621         "apn": {
121622             "name": "APN",
121623             "control": {
121624                 "type": "text",
121625                 "value": "Tizen"
121626             }
121627         },
121628         "ipAddress": {
121629             "name": "IP Address",
121630             "control": {
121631                 "type": "text",
121632                 "value": "10.0.2.16"
121633             }
121634         },
121635         "ipv6Address": {
121636             "name": "IPv6 Address",
121637             "control": {
121638                 "type": "text",
121639                 "value": "2001:db8:85a3:0:0:0:70:7334"
121640             }
121641         },
121642         "mcc": {
121643             "name": "MCC",
121644             "control": {
121645                 "type": "number",
121646                 "value": 460
121647             }
121648         },
121649         "mnc": {
121650             "name": "MNC",
121651             "control": {
121652                 "type": "number",
121653                 "value": 0
121654             }
121655         },
121656         "cellId": {
121657             "name": "Cell ID",
121658             "control": {
121659                 "type": "number",
121660                 "value": 0
121661             }
121662         },
121663         "lac": {
121664             "name": "LAC",
121665             "control": {
121666                 "type": "number",
121667                 "value": 0
121668             }
121669         },
121670         "isRoaming": {
121671             "name": "Roaming",
121672             "control": {
121673                 "type": "checkbox",
121674                 "value": true
121675             }
121676         },
121677         "isFlightMode": {
121678             "name": "Flight Mode",
121679             "control": {
121680                 "type": "checkbox",
121681                 "value": false
121682             },
121683             "callback": function (setting) {
121684                 event.trigger("FlightModeChanged", [setting]);
121685             }
121686         },
121687         "imei": {
121688             "name": "IMEI",
121689             "control": {
121690                 "type": "text",
121691                 "value": "012417005203000"
121692             }
121693         }
121694     },
121695     "SIM": {
121696         "state": {
121697             "name": "State",
121698             "control": {
121699                 "type": "select",
121700                 "value": SimStateTable["READY"]
121701             },
121702             "options": (function () {
121703                 var optionList = {};
121704                 utils.forEach(SimStateTable, function (key, value) {
121705                     optionList[key] = SimStateTable[value];
121706                 });
121707
121708                 return optionList;
121709             }())
121710         },
121711         "operatorName": {
121712             "name": "Operator Name",
121713             "control": {
121714                 "type": "text",
121715                 "value": "Tizen"
121716             }
121717         },
121718         "msisdn": {
121719             "name": "MSISDN",
121720             "control": {
121721                 "type": "text",
121722                 "value": "088123456789"
121723             }
121724         },
121725         "iccid": {
121726             "name": "ICCID",
121727             "control": {
121728                 "type": "text",
121729                 "value": "123000MFSSYYGXXXXXXP"
121730             }
121731         },
121732         "mcc": {
121733             "name": "MCC",
121734             "control": {
121735                 "type": "number",
121736                 "value": 460
121737             }
121738         },
121739         "mnc": {
121740             "name": "MNC",
121741             "control": {
121742                 "type": "number",
121743                 "value": 0
121744             }
121745         },
121746         "msin": {
121747             "name": "MSIN",
121748             "control": {
121749                 "type": "text",
121750                 "value": "H1 H2 H3 S 12345"
121751             }
121752         },
121753         "spn": {
121754             "name": "SPN",
121755             "control": {
121756                 "type": "text",
121757                 "value": "TizenSPN"
121758             }
121759         }
121760     },
121761     "PERIPHERAL": {
121762         "isVideoOutputOn": {
121763             "name": "Video Output",
121764             "control": {
121765                 "type": "checkbox",
121766                 "value": false
121767             }
121768         }
121769     }
121770 };
121771
121772 });
121773 define('ripple/platform/ivi/3.0/spec/sensor', function (require, exports, module) {
121774 /*
121775  *  Copyright 2012 Intel Corporation.
121776  *
121777  * Licensed under the Apache License, Version 2.0 (the "License");
121778  * you may not use this file except in compliance with the License.
121779  * You may obtain a copy of the License at
121780  *
121781  * http://www.apache.org/licenses/LICENSE-2.0
121782  *
121783  * Unless required by applicable law or agreed to in writing, software
121784  * distributed under the License is distributed on an "AS IS" BASIS,
121785  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121786  * See the License for the specific language governing permissions and
121787  * limitations under the License.
121788  */
121789 var event = require('ripple/event');
121790
121791 function sensorStatusEventTrigger(setting) {
121792     event.trigger("SensorStatusChanged", [setting]);
121793 }
121794
121795 module.exports = {
121796     "Accelerometer": {
121797         "resolution": 0.039239998906850815,
121798         "minDelay": 20,
121799         "range": 20.051639556884766,
121800         "name": "Accelerometer",
121801         "type": "Accelerometer"
121802     },
121803     "MagneticField": {
121804         "x": {
121805             "name": "X",
121806             "control": {
121807                 "type": "range",
121808                 "value": 100.0000000000000000,
121809                 "min": 0.0000000000000000,
121810                 "max": 200.0000000000000000,
121811                 "step": 0.0000000000000001
121812             },
121813             "callback": function (setting) {
121814                 event.trigger("MagneticField-xChanged", [setting]);
121815             }
121816         },
121817
121818         "y": {
121819             "name": "Y",
121820             "control": {
121821                 "type": "range",
121822                 "value": 100.0000000000000000,
121823                 "min": 0.0000000000000000,
121824                 "max": 200.0000000000000000,
121825                 "step": 0.0000000000000001
121826             },
121827             "callback": function (setting) {
121828                 event.trigger("MagneticField-yChanged", [setting]);
121829             }
121830         },
121831
121832         "z": {
121833             "name": "Z",
121834             "control": {
121835                 "type": "range",
121836                 "value": 100.0000000000000000,
121837                 "min": 0.0000000000000000,
121838                 "max": 200.0000000000000000,
121839                 "step": 0.0000000000000001
121840             },
121841             "callback": function (setting) {
121842                 event.trigger("MagneticField-zChanged", [setting]);
121843             }
121844         },
121845
121846         "resolution": 1,
121847         "minDelay": 20,
121848         "range": 359,
121849         "name": "MagneticField",
121850         "type": "MagneticField"
121851     },
121852     "Rotation": {
121853         "resolution": 1,
121854         "minDelay": 20,
121855         "range": 359,
121856         "name": "Rotation",
121857         "type": "Rotation"
121858     },
121859     "Orientation": {
121860         "resolution": 1,
121861         "minDelay": 20,
121862         "range": 359,
121863         "name": "Orientation",
121864         "type": "Orientation"
121865     }
121866 };
121867
121868 });
121869 define('ripple/platform/ivi/3.0/spec/ui', function (require, exports, module) {
121870 /*
121871  *  Copyright 2011 Intel Corporation.
121872  *
121873  * Licensed under the Apache License, Version 2.0 (the "License");
121874  * you may not use this file except in compliance with the License.
121875  * You may obtain a copy of the License at
121876  *
121877  * http://www.apache.org/licenses/LICENSE-2.0
121878  *
121879  * Unless required by applicable law or agreed to in writing, software
121880  * distributed under the License is distributed on an "AS IS" BASIS,
121881  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121882  * See the License for the specific language governing permissions and
121883  * limitations under the License.
121884  */
121885 module.exports = {
121886     plugins: [
121887         "vehicle",
121888         "sensors",
121889         "communication",
121890         "geoView",
121891         "widgetConfig",
121892         "deviceSettings",
121893         "application",
121894         "network",
121895         "power",
121896         "download",
121897         "notifications",
121898         "package",
121899         "messagePort",
121900         "secureElement"
121901     ]
121902 };
121903
121904 });
121905 define('ripple/platform/ivi/3.0/WebAPIError', function (require, exports, module) {
121906 /*
121907  *  Copyright 2013 Intel Corporation.
121908  *
121909  * Licensed under the Apache License, Version 2.0 (the "License");
121910  * you may not use this file except in compliance with the License.
121911  * You may obtain a copy of the License at
121912  *
121913  * http://www.apache.org/licenses/LICENSE-2.0
121914  *
121915  * Unless required by applicable law or agreed to in writing, software
121916  * distributed under the License is distributed on an "AS IS" BASIS,
121917  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121918  * See the License for the specific language governing permissions and
121919  * limitations under the License.
121920  */
121921
121922 var errorcode = require('ripple/platform/ivi/3.0/errorcode');
121923
121924 var msg = {
121925     1: "Permission denied.",
121926     2: "Unsupported property.",
121927     3: "Timeout.",
121928     10: "Unknown."
121929 },
121930     errType = {
121931     1: "PermissionDeniedError",
121932     2: "PropertyUnavailableError",
121933     3: "TimeoutError",
121934     10: "UnknownError"
121935 };
121936
121937 module.exports = function (code, message, name) {
121938     var _code, _message, _name;
121939
121940     if (typeof code !== 'number') {
121941         _code = errorcode.UNKNOWN;
121942         _message = msg[_code];
121943         _name = errType[_code];
121944     } else {
121945         _code = code;
121946         if (typeof message === 'string') {
121947             _message = message;
121948         } else {
121949             _message = msg[_code];
121950         }
121951         if (typeof name === 'string') {
121952             _name = name;
121953         } else {
121954             _name = errType[_code];
121955         }
121956     }
121957
121958     this.__defineGetter__("code", function () {
121959         return _code;
121960     });
121961     this.__defineGetter__("message", function () {
121962         return _message;
121963     });
121964     this.__defineGetter__("name", function () {
121965         return _name;
121966     });
121967 };
121968
121969 });
121970 define('ripple/platform/ivi/3.0/typedef', function (require, exports, module) {
121971 /*
121972  *  Copyright 2013 Intel Corporation.
121973  *
121974  * Licensed under the Apache License, Version 2.0 (the "License");
121975  * you may not use this file except in compliance with the License.
121976  * You may obtain a copy of the License at
121977  *
121978  * http://www.apache.org/licenses/LICENSE-2.0
121979  *
121980  * Unless required by applicable law or agreed to in writing, software
121981  * distributed under the License is distributed on an "AS IS" BASIS,
121982  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121983  * See the License for the specific language governing permissions and
121984  * limitations under the License.
121985  */
121986
121987 var _t, _c, _i;
121988
121989 /*
121990  * Primitive type definition
121991  */
121992
121993 _t = {
121994     // Basic
121995     Callback:                           "Callback",
121996     DOMString:                          "",
121997     Date:                               new Date(),
121998     Function:                           function () {},
121999     TZDate:                             "TZDate",
122000     any:                                "any",
122001     boolean:                            false,
122002     byte:                               "byte",
122003     double:                             "double",
122004     float:                              "float",
122005     long:                               "long",
122006     octet:                              "octet",
122007     short:                              "short",
122008     long_long:                          "long long",
122009     unsigned_long:                      "unsigned long",
122010     unsigned_long_long:                 "unsigned long long",
122011     unsigned_short:                     "unsigned short"
122012 };
122013
122014 /*
122015  * Derivative type definition
122016  */
122017
122018 /*
122019  * Object attributes
122020  *     Contruct a prototype of an object. Specify a primitive type for each attribute.
122021  *
122022  * _optional
122023  *     Optional attributes table, which consists of two types of attributes,
122024  *
122025  *     nullable
122026  *         Nullable attributes, marked as '?' in IDL.
122027  *
122028  *     undefined
122029  *         Array type attributes, that not definitely specified to be
122030  *         initialized as an empty array, i.e., undefined-initialized array.
122031  *
122032  * _derived
122033  *     Derived types, which used in two cases of definition,
122034  *
122035  *     Subtype list
122036  *         An array consists of derived subtypes. It exists in the definition of
122037  *         a base type.
122038  *
122039  *     Union types
122040  *         An array consists of member types. It exists in the definition of
122041  *         a union type.
122042  *
122043  * _dictionary
122044  *     Dictionary type, which indicates that the object is a dictionary type.
122045  */
122046
122047 /*
122048  * Vehicle
122049  */
122050 _t.SupportedPropertiesSuccessCallback = _t.Function;
122051
122052 _t.VehiclePropertyErrorCallback = _t.Function;
122053
122054 _t.VehiclePropertyCallback = _t.Function;
122055
122056 _t.VehiclePropertyListCallback = _t.Function;
122057
122058 /*
122059  * VehicleSpeed
122060  */
122061 _t.VehicleSpeed = {
122062     vehicleSpeed: _t.unsigned_long
122063 };
122064
122065 /*
122066  * EngineSpeed
122067  */
122068 _t.EngineSpeed = {
122069     engineSpeed: _t.unsigned_long
122070 };
122071
122072 /*
122073  * VehiclePowerMode
122074  */
122075 _t.VehiclePowerMode = {
122076     vehiclePowerMode: _t.octet
122077 };
122078
122079 /*
122080  * TripMeters
122081  */
122082 _t.TripMeter = {
122083     tripMeters: [_t.unsigned_long]
122084 };
122085
122086 /*
122087  * Acceleration
122088  */
122089 _t.Acceleration = {
122090     x: _t.unsigned_long,
122091     y: _t.unsigned_long,
122092     z: _t.unsigned_long
122093 };
122094
122095 /*
122096  * Transmission
122097  */
122098 _t.Transmission = {
122099     gearPosition: _t.octet,
122100     mode: _t.octet
122101 };
122102
122103 /*
122104  * CruiseControlStatus
122105  */
122106 _t.CruiseControlStatus = {
122107     activated: _t.boolean,
122108     speed: _t.unsigned_short
122109 };
122110 /*
122111  * WheelBrake
122112  */
122113 _t.WheelBrake = {
122114     engaged: _t.boolean
122115 };
122116
122117 /*
122118  * LightStatus
122119  */
122120 _t.LightStatus = {
122121     head: _t.boolean,
122122     rightTurn: _t.boolean,
122123     leftTurn: _t.boolean,
122124     brake: _t.boolean,
122125     fog: _t.boolean,
122126     hazard: _t.boolean,
122127     parking: _t.boolean,
122128     highBeam: _t.boolean
122129 };
122130
122131 /*
122132  * InteriorLightStatus
122133  */
122134 _t.InteriorLightStatus = {
122135     passenger: _t.boolean,
122136     driver: _t.boolean,
122137     center: _t.boolean
122138 };
122139
122140 /*
122141  * Horn
122142  */
122143 _t.Horn = {
122144     on: _t.boolean
122145 };
122146
122147 /*
122148  * Fuel
122149  */
122150 _t.Fuel = {
122151     level: _t.unsigned_short,
122152     range: _t.unsigned_short,
122153     instantConsumption: _t.unsigned_short,
122154     instantEconomy: _t.unsigned_short,
122155     averageEconomy: _t.unsigned_short
122156 };
122157
122158 /*
122159  * EngineOil
122160  */
122161 _t.EngineOil = {
122162     remaining: _t.unsigned_short,
122163     temperature: _t.long,
122164     pressure: _t.unsigned_short
122165 };
122166
122167 /*
122168  * Location
122169  */
122170 _t.Location = {
122171     latitude: _t.double,
122172     longitude: _t.double,
122173     altitude: _t.double,
122174     direction: _t.unsigned_short
122175 };
122176
122177 /*
122178  * ExteriorBrightness
122179  */
122180 _t.ExteriorBrightness = {
122181     exteriorBrightness: _t.unsigned_long
122182 };
122183
122184 /*
122185  * Temperature
122186  */
122187 _t.Temperature = {
122188     interior: _t.short,
122189     exterior: _t.short
122190 };
122191
122192 /*
122193  * RainSensor
122194  */
122195 _t.RainSensor = {
122196     rainSensor: _t.unsigned_short
122197 };
122198
122199 /*
122200  * WindshieldWiper
122201  */
122202 _t.WindshieldWiper = {
122203     windshieldWiper: _t.unsigned_short
122204 };
122205
122206 /*
122207  * DefrostDictionary
122208  */
122209 _t.DefrostDictionary = {
122210     window: _t.unsigned_short,
122211     defrost: _t.boolean,
122212
122213     _dictionary: true
122214 };
122215
122216 /*
122217  * HVAC
122218  */
122219 _t.HVAC = {
122220     airflowDirection: _t.unsigned_short,
122221     fanSpeed: _t.unsigned_short,
122222     targetTemperature: _t.unsigned_short,
122223     airConditioning: _t.boolean,
122224     airRecirculation: _t.boolean,
122225     heater: _t.boolean,
122226     steeringWheelHeater: _t.boolean,
122227     seatHeater: _t.boolean,
122228     seatCooler: _t.boolean
122229 };
122230
122231 /*
122232  * WindowStatus
122233  */
122234 _t.WindowStatus = {
122235     openness: _t.unsigned_short,
122236     defrost: _t.boolean
122237 };
122238
122239 /*
122240  * Sunroof
122241  */
122242 _t.Sunroof = {
122243     openness: _t.unsigned_short,
122244     tilt: _t.unsigned_short
122245 };
122246
122247 /*
122248  * ConvertibleRoof
122249  */
122250 _t.ConvertibleRoof = {
122251     openness: _t.unsigned_short
122252 };
122253
122254 /*
122255  * VehicleId
122256  */
122257 _t.VehicleId = {
122258     WMI: _t.DOMString,
122259     VIN: _t.DOMString
122260 };
122261
122262 /*
122263  * Size
122264  */
122265 _t.Size = {
122266     width: _t.unsigned_long,
122267     height: _t.unsigned_long,
122268     length: _t.unsigned_long
122269 };
122270
122271 /*
122272  * FuelInfo
122273  */
122274 _t.FuelInfo = {
122275     type: _t.unsigned_short,
122276     refuelPosition: _t.unsigned_short
122277 };
122278
122279 /*
122280  * VehicleType
122281  */
122282 _t.VehicleType = {
122283     type: _t.unsigned_short
122284 };
122285
122286 /*
122287  * Doors
122288  */
122289 _t.Doors = {
122290     doorsPerRow: [_t.unsigned_short]
122291 };
122292
122293 /*
122294  * TransmissionGearType
122295  */
122296 _t.TransmissionGearType = {
122297     transmissionGearType: _t.unsigned_short
122298 };
122299
122300 /*
122301  * WheelInformation
122302  */
122303 _t.WheelInformation = {
122304     frontWheelRadius: _t.unsigned_short,
122305     rearWheelRadius: _t.unsigned_short,
122306     wheelTrack: _t.unsigned_long,
122307     ABS: _t.boolean
122308 };
122309
122310 /*
122311  * Odometer
122312  */
122313 _t.Odometer = {
122314     odometer: _t.unsigned_long
122315 };
122316
122317 /*
122318  * Fluid
122319  */
122320 _t.Fluid = {
122321     transmission: _t.unsigned_short,
122322     brake: _t.unsigned_short,
122323     washer: _t.unsigned_short
122324 };
122325
122326 /*
122327  * Battery
122328  */
122329 _t.Battery = {
122330     voltage: _t.double,
122331     current: _t.double
122332 };
122333
122334 /*
122335  * TirePressure
122336  */
122337 _t.TirePressure = {
122338     leftFront: _t.double,
122339     rightFront: _t.double,
122340     leftRear: _t.double,
122341     rightRear: _t.double
122342 };
122343
122344 /*
122345  * TireTemperature
122346  */
122347 _t.TireTemperature = {
122348     leftFront: _t.double,
122349     rightFront: _t.double,
122350     leftRear: _t.double,
122351     rightRear: _t.double
122352 };
122353
122354 /*
122355  * SecurityAlert
122356  */
122357 _t.SecurityAlert = {
122358     securityAlert: _t.boolean
122359 };
122360
122361 /*
122362  * ParkingBrake
122363  */
122364 _t.ParkingBrake = {
122365     parkingBrake: _t.boolean
122366 };
122367
122368 /*
122369  * ParkingLight
122370  */
122371 _t.ParkingLight = {
122372     parkingLight: _t.boolean
122373 };
122374
122375 /*
122376  * HazardLight
122377  */
122378 _t.HazardLight = {
122379     hazardLight: _t.boolean
122380 };
122381
122382 /*
122383  * AntilockBrakingSystem
122384  */
122385 _t.AntilockBrakingSystem = {
122386     antilockBrakingSystem: _t.boolean
122387 };
122388
122389 /*
122390  * TractionControlSystem
122391  */
122392 _t.TractionControlSystem = {
122393     tractionControlSystem: _t.boolean
122394 };
122395
122396 /*
122397  * VehicleTopSpeedLimit
122398  */
122399 _t.VehicleTopSpeedLimit = {
122400     vehicleTopSpeedLimit: _t.unsigned_short
122401 };
122402
122403 /*
122404  * AirbagStatus
122405  */
122406 _t.AirbagStatus = {
122407     airbagStatus: _t.unsigned_short
122408 };
122409
122410 /*
122411  * DoorStatus
122412  */
122413 _t.DoorStatus = {
122414     doorStatus: _t.unsigned_short,
122415     doorLockStatus: _t.boolean,
122416     childLockStatus: _t.boolean
122417 };
122418
122419 /*
122420  * SeatBeltStatus
122421  */
122422 _t.SeatBeltStatus = {
122423     seatBeltStatus: _t.boolean
122424 };
122425
122426 /*
122427  * OccupantStatus
122428  */
122429 _t.OccupantStatus = {
122430     occupantStatus: _t.unsigned_short
122431 };
122432
122433 /*
122434  * ObstacleDistance
122435  */
122436 _t.ObstacleDistance = {
122437     obstacleDistance: _t.double
122438 };
122439
122440 /*
122441  * NightMode
122442  */
122443 _t.NightMode = {
122444     nightMode: _t.boolean
122445 };
122446
122447 /*
122448  * DrivingMode
122449  */
122450 _t.DrivingMode = {
122451     drivingMode: _t.unsigned_short
122452 };
122453
122454 /*
122455  * TurnSignal
122456  */
122457 _t.TurnSignal = {
122458     turnSignal: _t.unsigned_short
122459 };
122460
122461 /*
122462  * ButtonEvent
122463  */
122464 _t.ButtonEvent = {
122465     buttonEvent: _t.unsigned_short
122466 };
122467
122468 /*
122469  * VehiclePropertyType
122470  */
122471 _t.VehiclePropertyType = {
122472     time: _t.unsigned_long_long,
122473     zone: _t.short,
122474     source: _t.DOMString,
122475
122476     _derived: [_t.VehicleSpeed, _t.EngineSpeed, _t.VehiclePowerMode,
122477         _t.TripMeter, _t.Acceleration, _t.Transmission,
122478         _t.CruiseControlStatus, _t.WheelBrake, _t.LightStatus,
122479         _t.InteriorLightStatus, _t.Horn, _t.Fuel, _t.EngineOil, _t.Location,
122480         _t.ExteriorBrightness, _t.Temperature, _t.RainSensor,
122481         _t.WindshieldWiper, _t.HVAC, _t.WindowStatus, _t.Sunroof,
122482         _t.ConvertibleRoof, _t.VehicleId, _t.Size, _t.FuelInfo, _t.VehicleType,
122483         _t.Doors, _t.TransmissionGearType, _t.WheelInformation, _t.Odometer,
122484         _t.Fluid, _t.Battery, _t.TirePressure, _t.TireTemperature,
122485         _t.SecurityAlert, _t.ParkingBrake, _t.ParkingLight, _t.HazardLight,
122486         _t.AntilockBrakingSystem, _t.TractionControlSystem,
122487         _t.VehicleTopSpeedLimit, _t.AirbagStatus, _t.DoorStatus,
122488         _t.SeatBeltStatus, _t.OccupantStatus, _t.ObstacleDistance,
122489         _t.NightMode, _t.TurnSignal, _t.ButtonEvent]
122490 };
122491
122492 /*
122493  * Constructor list definition
122494  */
122495
122496 /*
122497  * Generic constructor
122498  *     Construct a prototype of constructor. A fake array of arguments type is
122499  *     specified for constructor.
122500  *
122501  * Overloaded constructors
122502  *     Construct an array of prototype of constructor. Each array element is
122503  *     specified for one of constructors. The constructor with extra arguments
122504  *     are recommended to be defined ahead of the one with fewer same arguments
122505  *     for exact match.
122506  */
122507
122508 _c = {};
122509
122510 /*
122511  * Interface prototype definition
122512  */
122513
122514 _i = {
122515     // Vehicle
122516     Vehicle: {}
122517 };
122518
122519 _i.Vehicle.get = {
122520     0: _t.DOMString,
122521     1: _t.short,
122522
122523     _optional: {
122524         // nullable
122525         1: true
122526     }
122527 };
122528
122529 _i.Vehicle.getAsync = {
122530     0: _t.DOMString,
122531     1: _t.VehiclePropertyCallback,
122532     2: _t.VehiclePropertyErrorCallback,
122533     3: _t.short,
122534
122535     _optional: {
122536         // nullable
122537         2: true,
122538         3: true
122539     }
122540 };
122541
122542 _i.Vehicle.subscribe = {
122543     0: _t.DOMString,
122544     1: _t.VehiclePropertyCallback,
122545     2: _t.short,
122546     3: _t.VehiclePropertyErrorCallback,
122547
122548     _optional: {
122549         // nullable
122550         2: true,
122551         3: true
122552     }
122553 };
122554
122555 _i.Vehicle.set = {
122556     0: _t.DOMString,
122557     1: _t.VehiclePropertyType,
122558     2: _t.VehiclePropertyErrorCallback,
122559
122560     _optional: {
122561         // nullable
122562         2: true
122563     }
122564 };
122565
122566 _i.Vehicle.getHistory = {
122567     0: _t.DOMString,
122568     1: _t.short,
122569     2: _t.Date,
122570     3: _t.Date,
122571     4: _t.VehiclePropertyListCallback,
122572     5: _t.VehiclePropertyErrorCallback,
122573
122574     _optional: {
122575         // nullable
122576         5: true
122577     }
122578 };
122579
122580 _i.Vehicle.listZones = {
122581     0: _t.DOMString
122582 };
122583
122584 // Exports
122585 _t.constructor = _c;
122586 _t.interface   = _i;
122587
122588 module.exports = _t;
122589
122590 });
122591 define('ripple/platform/ivi/3.0/WebAPIException', function (require, exports, module) {
122592 /*
122593  *  Copyright 2013 Intel Corporation.
122594  *
122595  * Licensed under the Apache License, Version 2.0 (the "License");
122596  * you may not use this file except in compliance with the License.
122597  * You may obtain a copy of the License at
122598  *
122599  * http://www.apache.org/licenses/LICENSE-2.0
122600  *
122601  * Unless required by applicable law or agreed to in writing, software
122602  * distributed under the License is distributed on an "AS IS" BASIS,
122603  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122604  * See the License for the specific language governing permissions and
122605  * limitations under the License.
122606  */
122607
122608 var errorcode = require('ripple/platform/ivi/3.0/errorcode');
122609
122610 var msg = {
122611         1: "Permission denied.",
122612         2: "Unsupported property.",
122613         3: "Timeout.",
122614         10: "Unknown."
122615     },
122616     errType = {
122617         1: "PermissionDeniedError",
122618         2: "PropertyUnavailableError",
122619         3: "TimeoutError",
122620         10: "UnknownError"
122621     };
122622
122623 module.exports = function (code, message, name) {
122624     var g, c, _code, _message, _name;
122625
122626     for (c in errorcode) {
122627         g = errorcode.__lookupGetter__(c);
122628         if (g) {
122629             this.__defineGetter__(c, g);
122630         }
122631     }
122632
122633     if (typeof code !== 'number') {
122634         _code = errorcode.UNKNOWN;
122635         _message = msg[_code];
122636         _name = errType[_code];
122637     } else {
122638         _code = code;
122639         if (typeof message === 'string') {
122640             _message = message;
122641         } else {
122642             _message = msg[_code];
122643         }
122644         if (typeof name === 'string') {
122645             _name = name;
122646         } else {
122647             _name = errType[_code];
122648         }
122649     }
122650
122651     this.__defineGetter__("code", function () {
122652         return _code;
122653     });
122654     this.__defineGetter__("message", function () {
122655         return _message;
122656     });
122657     this.__defineGetter__("name", function () {
122658         return _name;
122659     });
122660 };
122661
122662 });
122663 define('ripple/platform/ivi/3.0/vehicle', function (require, exports, module) {
122664 /*
122665  *  Copyright 2013 Intel Corporation.
122666  *
122667  * Licensed under the Apache License, Version 2.0 (the "License");
122668  * you may not use this file except in compliance with the License.
122669  * You may obtain a copy of the License at
122670  *
122671  * http://www.apache.org/licenses/LICENSE-2.0
122672  *
122673  * Unless required by applicable law or agreed to in writing, software
122674  * distributed under the License is distributed on an "AS IS" BASIS,
122675  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122676  * See the License for the specific language governing permissions and
122677  * limitations under the License.
122678  */
122679
122680 var utils = require('ripple/utils'),
122681     event = require('ripple/event'),
122682     t = require('ripple/platform/ivi/3.0/typecast'),
122683     errorcode = require('ripple/platform/ivi/3.0/errorcode'),
122684     WebAPIError = require('ripple/platform/ivi/3.0/WebAPIError'),
122685     WebAPIException = require('ripple/platform/ivi/3.0/WebAPIException'),
122686     VehiclePropertyType,
122687     VehicleSpeed,
122688     EngineSpeed,
122689     VehiclePowerMode,
122690     TripMeter,
122691     Acceleration,
122692     Transmission,
122693     CruiseControlStatus,
122694     WheelBrake,
122695     LightStatus,
122696     InteriorLightStatus,
122697     Horn,
122698     Fuel,
122699     EngineOil,
122700     Location,
122701     ExteriorBrightness,
122702     Temperature,
122703     RainSensor,
122704     WindshieldWiper,
122705     HVAC,
122706     WindowStatus,
122707     Sunroof,
122708     ConvertibleRoof,
122709     VehicleId,
122710     Size,
122711     FuelInfo,
122712     VehicleType,
122713     Doors,
122714     TransmissionGearType,
122715     WheelInformation,
122716     Odometer,
122717     Fluid,
122718     Battery,
122719     TirePressure,
122720     TireTemperature,
122721     SecurityAlert,
122722     ParkingBrake,
122723     ParkingLight,
122724     HazardLight,
122725     AntilockBrakingSystem,
122726     TractionControlSystem,
122727     VehicleTopSpeedLimit,
122728     AirbagStatus,
122729     DoorStatus,
122730     SeatBeltStatus,
122731     OccupantStatus,
122732     ObstacleDistance,
122733     NightMode,
122734     DrivingMode,
122735     TurnSignal,
122736     ButtonEvent,
122737     VehicleFactory,
122738     _vehicleCacheData = {
122739         supported: null,
122740         data: null
122741     },
122742     _vehicleEvent = {subscribe: {}},
122743     _security = {
122744         "http://tizen.org/privilege/vehicle": ["supported", "get", "getAsync",
122745                 "set", "getHistory", "subscribe", "listZones"]
122746     },
122747     _self;
122748
122749 function _initialize () {
122750     event.on("vehicle-cache-refresh", function (supported, data) {
122751         _vehicleCacheData.supported = supported;
122752         _vehicleCacheData.data = data;
122753     });
122754
122755     event.trigger("vehicle-cache-request", [_vehicleCacheData]);
122756 }
122757
122758 _self = function () {
122759     var vehicle;
122760
122761     function supported () {
122762         if (!_security.supported) {
122763             throw new WebAPIException(errorcode.PERMISSION_DENIED);
122764         }
122765
122766         return _vehicleCacheData.supported;
122767     }
122768
122769     function get (property, zone) {
122770         if (!_security.get) {
122771             throw new WebAPIException(errorcode.PERMISSION_DENIED);
122772         }
122773
122774         t.Vehicle("get", arguments);
122775
122776         if (_vehicleCacheData.supported.indexOf(property) === -1) {
122777             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
122778         }
122779
122780         return new VehicleFactory(property, _vehicleCacheData.data[property]);
122781     }
122782
122783     function getAsync (property, successCallback, errorCallback, zone) {
122784         if (!_security.getAsync) {
122785             throw new WebAPIException(errorcode.PERMISSION_DENIED);
122786         }
122787
122788         t.Vehicle("getAsync", arguments);
122789
122790         if (_vehicleCacheData.supported.indexOf(property) === -1) {
122791             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
122792         }
122793
122794         window.setTimeout(function () {
122795             successCallback(new VehicleFactory(property,
122796                     _vehicleCacheData.data[property]));
122797         }, 1);
122798     }
122799
122800     function subscribe (property, successCallback, zone, errorCallback) {
122801         if (!_security.subscribe) {
122802             throw new WebAPIException(errorcode.PERMISSION_DENIED);
122803         }
122804
122805         t.Vehicle("subscribe", arguments);
122806
122807         if (_vehicleCacheData.supported.indexOf(property) === -1) {
122808             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
122809         }
122810
122811         _vehicleEvent.subscribe[property] = {
122812             successCallback: successCallback,
122813             errorCallback: errorCallback
122814         };
122815
122816         window.setTimeout(function () {
122817             if (! _vehicleEvent["vehicle-subscribe-response"]) {
122818                 event.on("vehicle-subscribe-response", function (propertyObj) {
122819                     var propertySub = _vehicleEvent.subscribe[propertyObj.type],
122820                         success = propertySub.successCallback,
122821                         error = propertySub.errorCallback;
122822
122823                     if (!propertyObj.supported) {
122824                         if (error) {
122825                             error(new WebAPIError(
122826                                     errorcode.PROPERTY_UNAVAILABLE));
122827                         }
122828                         return;
122829                     }
122830
122831                     success(new VehicleFactory(propertyObj.type,
122832                             propertyObj.val));
122833
122834                 });
122835                 _vehicleEvent["vehicle-subscribe-response"] = true;
122836             }
122837             event.trigger("vehicle-subscribe-request", [property, true, zone]);
122838         }, 1);
122839     }
122840
122841     function set (property, value, errorCallback) {
122842         var val = utils.copy(value);
122843
122844         if (!_security.set) {
122845             throw new WebAPIException(errorcode.PERMISSION_DENIED);
122846         }
122847
122848         t.Vehicle("set", arguments);
122849
122850         if (_vehicleCacheData.supported.indexOf(property) === -1) {
122851             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
122852         }
122853
122854         window.setTimeout(function () {
122855             event.once("vehicle-set-response", function (status) {
122856                 if (!status) {
122857                     if (errorCallback) {
122858                         errorCallback(new WebAPIError(
122859                                 errorcode.PROPERTY_UNAVAILABLE));
122860                     }
122861                 }
122862             });
122863             event.trigger("vehicle-set-request", [property, val]);
122864         }, 1);
122865     }
122866
122867     function getHistory (property, zone, startTime, endTime, successCallback,
122868             errorCallback) {
122869         var properties = [], i;
122870
122871         if (!_security.getHistory) {
122872             throw new WebAPIException(errorcode.PERMISSION_DENIED);
122873         }
122874
122875         t.Vehicle("getHistory", arguments);
122876
122877         if (_vehicleCacheData.supported.indexOf(property) === -1) {
122878             throw new WebAPIException(errorcode.PROPERTY_UNAVAILABLE);
122879         }
122880
122881         startTime = startTime.getTime();
122882         endTime = endTime.getTime();
122883
122884         window.setTimeout(function () {
122885             event.once("vehicle-history-response", function (values, status) {
122886                 if (!status) {
122887                     if (errorCallback) {
122888                         errorCallback(new WebAPIError(
122889                                 errorcode.PROPERTY_UNAVAILABLE));
122890                     }
122891                     return;
122892                 }
122893
122894                 for (i = 0; i < values.length; i++) {
122895                     properties.push(new VehicleFactory(property, values[i]));
122896                 }
122897                 successCallback(properties);
122898             });
122899             event.trigger("vehicle-history-request", [property, zone,
122900                     startTime, endTime]);
122901         }, 1);
122902     }
122903
122904     function listZones (property) {
122905         if (!_security.listZones) {
122906             throw new WebAPIException(errorcode.PERMISSION_DENIED);
122907         }
122908
122909         t.Vehicle("listZones", arguments);
122910
122911         return [0];
122912     }
122913
122914     function handleSubFeatures (subFeatures) {
122915         var i, subFeature;
122916
122917         for (subFeature in subFeatures) {
122918             for (i in _security[subFeature]) {
122919                 _security[_security[subFeature][i]] = true;
122920             }
122921         }
122922     }
122923
122924     vehicle = {
122925         supported: supported,
122926         get: get,
122927         getAsync: getAsync,
122928         subscribe: subscribe,
122929         set: set,
122930         getHistory: getHistory,
122931         listZones: listZones,
122932         handleSubFeatures: handleSubFeatures
122933     };
122934
122935     vehicle.__defineGetter__("ZONE_None", function () {
122936         return 0;
122937     });
122938
122939     vehicle.__defineGetter__("ZONE_Front", function () {
122940         return 0x01;
122941     });
122942
122943     vehicle.__defineGetter__("ZONE_Middle", function () {
122944         return 0x02;
122945     });
122946
122947     vehicle.__defineGetter__("ZONE_Right", function () {
122948         return 0x04;
122949     });
122950
122951     vehicle.__defineGetter__("ZONE_Left", function () {
122952         return 0x08;
122953     });
122954
122955     vehicle.__defineGetter__("ZONE_Rear", function () {
122956         return 0x10;
122957     });
122958
122959     vehicle.__defineGetter__("ZONE_Center", function () {
122960         return 0x20;
122961     });
122962
122963     return vehicle;
122964 };
122965
122966 VehicleFactory = function (vehicleType, value) {
122967     var instanceType;
122968
122969     switch (vehicleType) {
122970     case "VehicleSpeed":
122971         instanceType = new VehicleSpeed(value);
122972         break;
122973     case "EngineSpeed":
122974         instanceType = new EngineSpeed(value);
122975         break;
122976     case "VehiclePowerMode":
122977         instanceType = new VehiclePowerMode(value);
122978         break;
122979     case "TripMeter":
122980         instanceType = new TripMeter(value);
122981         break;
122982     case "Acceleration":
122983         instanceType = new Acceleration(value);
122984         break;
122985     case "Transmission":
122986         instanceType = new Transmission(value);
122987         break;
122988     case "CruiseControlStatus":
122989         instanceType = new CruiseControlStatus(value);
122990         break;
122991     case "WheelBrake":
122992         instanceType = new WheelBrake(value);
122993         break;
122994     case "LightStatus":
122995         instanceType = new LightStatus(value);
122996         break;
122997     case "InteriorLightStatus":
122998         instanceType = new InteriorLightStatus(value);
122999         break;
123000     case "Horn":
123001         instanceType = new Horn(value);
123002         break;
123003     case "Fuel":
123004         instanceType = new Fuel(value);
123005         break;
123006     case "EngineOil":
123007         instanceType = new EngineOil(value);
123008         break;
123009     case "Location":
123010         instanceType = new Location(value);
123011         break;
123012     case "ExteriorBrightness":
123013         instanceType = new ExteriorBrightness(value);
123014         break;
123015     case "Temperature":
123016         instanceType = new Temperature(value);
123017         break;
123018     case "RainSensor":
123019         instanceType = new RainSensor(value);
123020         break;
123021     case "WindshieldWiper":
123022         instanceType = new WindshieldWiper(value);
123023         break;
123024     case "HVAC":
123025         instanceType = new HVAC(value);
123026         break;
123027     case "WindowStatus":
123028         instanceType = new WindowStatus(value);
123029         break;
123030     case "Sunroof":
123031         instanceType = new Sunroof(value);
123032         break;
123033     case "ConvertibleRoof":
123034         instanceType = new ConvertibleRoof(value);
123035         break;
123036     case "VehicleId":
123037         instanceType = new VehicleId(value);
123038         break;
123039     case "Size":
123040         instanceType = new Size(value);
123041         break;
123042     case "FuelInfo":
123043         instanceType = new FuelInfo(value);
123044         break;
123045     case "VehicleType":
123046         instanceType = new VehicleType(value);
123047         break;
123048     case "Doors":
123049         instanceType = new Doors(value);
123050         break;
123051     case "TransmissionGearType":
123052         instanceType = new TransmissionGearType(value);
123053         break;
123054     case "WheelInformation":
123055         instanceType = new WheelInformation(value);
123056         break;
123057     case "Odometer":
123058         instanceType = new Odometer(value);
123059         break;
123060     case "Fluid":
123061         instanceType = new Fluid(value);
123062         break;
123063     case "Battery":
123064         instanceType = new Battery(value);
123065         break;
123066     case "TirePressure":
123067         instanceType = new TirePressure(value);
123068         break;
123069     case "TireTemperature":
123070         instanceType = new TireTemperature(value);
123071         break;
123072     case "SecurityAlert":
123073         instanceType = new SecurityAlert(value);
123074         break;
123075     case "ParkingBrake":
123076         instanceType = new ParkingBrake(value);
123077         break;
123078     case "ParkingLight":
123079         instanceType = new ParkingLight(value);
123080         break;
123081     case "HazardLight":
123082         instanceType = new HazardLight(value);
123083         break;
123084     case "AntilockBrakingSystem":
123085         instanceType = new AntilockBrakingSystem(value);
123086         break;
123087     case "TractionControlSystem":
123088         instanceType = new TractionControlSystem(value);
123089         break;
123090     case "VehicleTopSpeedLimit":
123091         instanceType = new VehicleTopSpeedLimit(value);
123092         break;
123093     case "AirbagStatus":
123094         instanceType = new AirbagStatus(value);
123095         break;
123096     case "DoorStatus":
123097         instanceType = new DoorStatus(value);
123098         break;
123099     case "SeatBeltStatus":
123100         instanceType = new SeatBeltStatus(value);
123101         break;
123102     case "OccupantStatus":
123103         instanceType = new OccupantStatus(value);
123104         break;
123105     case "ObstacleDistance":
123106         instanceType = new ObstacleDistance(value);
123107         break;
123108     case "NightMode":
123109         instanceType = new NightMode(value);
123110         break;
123111     case "DrivingMode":
123112         instanceType = new DrivingMode(value);
123113         break;
123114     case "TurnSignal":
123115         instanceType = new TurnSignal(value);
123116         break;
123117     case "ButtonEvent":
123118         instanceType = new ButtonEvent(value);
123119         break;
123120     }
123121
123122     function _construct () {
123123         var val;
123124
123125         for (val in value) {
123126             instanceType[val] = value[val];
123127         }
123128         return instanceType;
123129     }
123130
123131     return _construct();
123132 };
123133
123134 VehiclePropertyType = function (propertyTypes) {
123135     var vehiclePropertyType = {};
123136
123137     vehiclePropertyType.time = propertyTypes.time || undefined;
123138     vehiclePropertyType.zone = propertyTypes.zone || 0;
123139     vehiclePropertyType.source = propertyTypes.source || "";
123140
123141     this.__defineGetter__("time", function () {
123142         return vehiclePropertyType.time;
123143     });
123144
123145     this.__defineSetter__("time", function (val) {
123146         try {
123147             vehiclePropertyType.time = t.unsigned_long_long(val);
123148         } catch (err) {
123149         }
123150     });
123151
123152     this.__defineGetter__("zone", function () {
123153         return vehiclePropertyType.zone;
123154     });
123155
123156     this.__defineSetter__("zone", function (val) {
123157         try {
123158             vehiclePropertyType.zone = t.short(val);
123159         } catch (err) {
123160         }
123161     });
123162
123163     this.__defineGetter__("source", function () {
123164         return vehiclePropertyType.source;
123165     });
123166
123167     this.__defineSetter__("source", function (val) {
123168         try {
123169             vehiclePropertyType.source = t.DOMString(val);
123170         } catch (err) {
123171         }
123172     });
123173 };
123174
123175 VehicleSpeed = function (propertyTypes) {
123176     var vehicleSpeed = {};
123177
123178     VehiclePropertyType.call(this, propertyTypes);
123179
123180     vehicleSpeed.vehicleSpeed = propertyTypes.vehicleSpeed || 0;
123181
123182     this.__defineGetter__("vehicleSpeed", function () {
123183         return vehicleSpeed.vehicleSpeed;
123184     });
123185
123186     this.__defineSetter__("vehicleSpeed", function (val) {
123187         try {
123188             vehicleSpeed.vehicleSpeed = t.unsigned_long(val);
123189         } catch (err) {
123190         }
123191     });
123192 };
123193
123194 EngineSpeed = function (propertyTypes) {
123195     var engineSpeed = {};
123196
123197     VehiclePropertyType.call(this, propertyTypes);
123198
123199     engineSpeed.engineSpeed = propertyTypes.engineSpeed || 0;
123200
123201     this.__defineGetter__("engineSpeed", function () {
123202         return engineSpeed.engineSpeed;
123203     });
123204
123205     this.__defineSetter__("engineSpeed", function (val) {
123206         try {
123207             engineSpeed.engineSpeed = t.unsigned_long(val);
123208         } catch (err) {
123209         }
123210     });
123211 };
123212
123213 VehiclePowerMode = function (propertyTypes) {
123214     var vehiclePowerMode = {};
123215
123216     VehiclePropertyType.call(this, propertyTypes);
123217
123218     vehiclePowerMode.vehiclePowerMode = propertyTypes.vehiclePowerMode || 0;
123219
123220     this.__defineGetter__("VEHICLEPOWERMODE_OFF", function () {
123221         return 0;
123222     });
123223
123224     this.__defineGetter__("VEHICLEPOWERMODE_ACCESSORY1", function () {
123225         return 1;
123226     });
123227
123228     this.__defineGetter__("VEHICLEPOWERMODE_ACCESSORY2", function () {
123229         return 2;
123230     });
123231
123232     this.__defineGetter__("VEHICLEPOWERMODE_RUN", function () {
123233         return 3;
123234     });
123235
123236     this.__defineGetter__("vehiclePowerMode", function () {
123237         return vehiclePowerMode.vehiclePowerMode;
123238     });
123239
123240     this.__defineSetter__("vehiclePowerMode", function (val) {
123241         try {
123242             val = t.octet(val);
123243             if (val < 0 || val > 3) {
123244                 return;
123245             }
123246             vehiclePowerMode.vehiclePowerMode = val;
123247         } catch (err) {
123248         }
123249     });
123250 };
123251
123252 TripMeter = function (propertyTypes) {
123253     var tripMeter = {};
123254
123255     VehiclePropertyType.call(this, propertyTypes);
123256
123257     tripMeter.tripMeters = propertyTypes.tripMeters || [];
123258
123259     this.__defineGetter__("tripMeters", function () {
123260         return tripMeter.tripMeters;
123261     });
123262
123263     this.__defineSetter__("tripMeters", function (val) {
123264         try {
123265         //Changing any items in the array will reset the item's value to '0';
123266             tripMeter.tripMeters = t.unsigned_long(val, "[]");
123267         }
123268         catch (err) {
123269         }
123270     });
123271 };
123272
123273 Acceleration = function (propertyTypes) {
123274     var acceleration = {};
123275
123276     VehiclePropertyType.call(this, propertyTypes);
123277
123278     acceleration.x = propertyTypes.x || 0;
123279     acceleration.y = propertyTypes.y || 0;
123280     acceleration.z = propertyTypes.z || 0;
123281
123282     this.__defineGetter__("x", function () {
123283         return acceleration.x;
123284     });
123285
123286     this.__defineSetter__("x", function (val) {
123287         try {
123288             acceleration.x = t.unsigned_long(val);
123289         }
123290         catch (err) {
123291         }
123292     });
123293
123294     this.__defineGetter__("y", function () {
123295         return acceleration.y;
123296     });
123297
123298     this.__defineSetter__("y", function (val) {
123299         try {
123300             acceleration.y = t.unsigned_long(val);
123301         }
123302         catch (err) {
123303         }
123304     });
123305
123306     this.__defineGetter__("z", function () {
123307         return acceleration.z;
123308     });
123309
123310     this.__defineSetter__("z", function (val) {
123311         try {
123312             acceleration.z = t.unsigned_long(val);
123313         } catch (err) {
123314         }
123315     });
123316 };
123317
123318 Transmission = function (propertyTypes) {
123319     var transmission = {};
123320
123321     VehiclePropertyType.call(this, propertyTypes);
123322
123323     transmission.gearPosition = propertyTypes.gearPosition || 0;
123324     transmission.mode = propertyTypes.mode || 0;
123325
123326     this.__defineGetter__("TRANSMISSIONPOSITION_NEUTRAL", function () {
123327         return 0;
123328     });
123329
123330     this.__defineGetter__("TRANSMISSIONPOSITION_FIRST", function () {
123331         return 1;
123332     });
123333
123334     this.__defineGetter__("TRANSMISSIONPOSITION_SECOND", function () {
123335         return 2;
123336     });
123337
123338     this.__defineGetter__("TRANSMISSIONPOSITION_THIRD", function () {
123339         return 3;
123340     });
123341
123342     this.__defineGetter__("TRANSMISSIONPOSITION_FORTH", function () {
123343         return 4;
123344     });
123345
123346     this.__defineGetter__("TRANSMISSIONPOSITION_FIFTH", function () {
123347         return 5;
123348     });
123349
123350     this.__defineGetter__("TRANSMISSIONPOSITION_SIXTH", function () {
123351         return 6;
123352     });
123353
123354     this.__defineGetter__("TRANSMISSIONPOSITION_SEVENTH", function () {
123355         return 7;
123356     });
123357
123358     this.__defineGetter__("TRANSMISSIONPOSITION_EIGHTH", function () {
123359         return 8;
123360     });
123361
123362     this.__defineGetter__("TRANSMISSIONPOSITION_NINTH", function () {
123363         return 9;
123364     });
123365
123366     this.__defineGetter__("TRANSMISSIONPOSITION_TENTH", function () {
123367         return 10;
123368     });
123369
123370     this.__defineGetter__("TRANSMISSIONPOSITION_CVT", function () {
123371         return 64;
123372     });
123373
123374     this.__defineGetter__("TRANSMISSIONPOSITION_REVERSE", function () {
123375         return 128;
123376     });
123377
123378     this.__defineGetter__("TRANSMISSIONPOSITION_PARK", function () {
123379         return 255;
123380     });
123381
123382     this.__defineGetter__("TRANSMISSIONMODE_NORMAL", function () {
123383         return 0;
123384     });
123385
123386     this.__defineGetter__("TRANSMISSIONMODE_SPORT", function () {
123387         return 1;
123388     });
123389
123390     this.__defineGetter__("TRANSMISSIONMODE_ECONOMY", function () {
123391         return 2;
123392     });
123393
123394     this.__defineGetter__("TRANSMISSIONMODE_OEMCUSTOM1", function () {
123395         return 3;
123396     });
123397
123398     this.__defineGetter__("TRANSMISSIONMODE_OEMCUSTOM2", function () {
123399         return 4;
123400     });
123401
123402     this.__defineGetter__("gearPosition", function () {
123403         return transmission.gearPosition;
123404     });
123405
123406     this.__defineSetter__("gearPosition", function (val) {
123407         try {
123408             val = t.octet(val);
123409             if ((val >= 0 && val <= 10) || val === 64 || val === 128 ||
123410                 val === 255) {
123411                 transmission.gearPosition = val;
123412             }
123413         } catch (err) {
123414         }
123415     });
123416
123417     this.__defineGetter__("mode", function () {
123418         return transmission.mode;
123419     });
123420
123421     this.__defineSetter__("mode", function (val) {
123422         try {
123423             val = t.octet(val);
123424             if (val < 0 || val > 4) {
123425                 return;
123426             }
123427             transmission.mode = val;
123428         } catch (err) {
123429         }
123430     });
123431 };
123432
123433 CruiseControlStatus = function (propertyTypes) {
123434     var cruiseControlStatus = {};
123435
123436     VehiclePropertyType.call(this, propertyTypes);
123437
123438     cruiseControlStatus.activated = propertyTypes.activated || false;
123439     cruiseControlStatus.speed = propertyTypes.speed || 0;
123440
123441     this.__defineGetter__("activated", function () {
123442         return cruiseControlStatus.activated;
123443     });
123444
123445     this.__defineSetter__("activated", function (val) {
123446         try {
123447             cruiseControlStatus.activated = t.boolean(val);
123448         } catch (err) {
123449         }
123450     });
123451
123452     this.__defineGetter__("speed", function () {
123453         return cruiseControlStatus.speed;
123454     });
123455
123456     this.__defineSetter__("speed", function (val) {
123457         try {
123458             cruiseControlStatus.speed = t.unsigned_short(val);
123459         } catch (err) {
123460         }
123461     });
123462 };
123463
123464 WheelBrake = function (propertyTypes) {
123465     var wheelBrake = {};
123466
123467     VehiclePropertyType.call(this, propertyTypes);
123468
123469     wheelBrake.engaged = propertyTypes.engaged || false;
123470
123471     this.__defineGetter__("engaged", function () {
123472         return wheelBrake.engaged;
123473     });
123474
123475     this.__defineSetter__("engaged", function (val) {
123476         try {
123477             wheelBrake.engaged = t.boolean(val);
123478         } catch (err) {
123479         }
123480     });
123481 };
123482
123483 LightStatus = function (propertyTypes) {
123484     var lightStatus = {};
123485
123486     VehiclePropertyType.call(this, propertyTypes);
123487
123488     lightStatus.head = propertyTypes.head || false;
123489     lightStatus.rightTurn = propertyTypes.rightTurn || false;
123490     lightStatus.leftTurn = propertyTypes.leftTurn || false;
123491     lightStatus.brake = propertyTypes.brake || false;
123492     lightStatus.fog = propertyTypes.fog || false;
123493     lightStatus.hazard = propertyTypes.hazard || false;
123494     lightStatus.parking = propertyTypes.parking || false;
123495     lightStatus.highBeam = propertyTypes.highBeam || false;
123496
123497     this.__defineGetter__("head", function () {
123498         return lightStatus.head;
123499     });
123500
123501     this.__defineSetter__("head", function (val) {
123502         try {
123503             lightStatus.head = t.boolean(val);
123504         } catch (err) {
123505         }
123506     });
123507
123508     this.__defineGetter__("rightTurn", function () {
123509         return lightStatus.rightTurn;
123510     });
123511
123512     this.__defineSetter__("rightTurn", function (val) {
123513         try {
123514             lightStatus.rightTurn = t.boolean(val);
123515         } catch (err) {
123516         }
123517     });
123518
123519     this.__defineGetter__("leftTurn", function () {
123520         return lightStatus.leftTurn;
123521     });
123522
123523     this.__defineSetter__("leftTurn", function (val) {
123524         try {
123525             lightStatus.leftTurn = t.boolean(val);
123526         } catch (err) {
123527         }
123528     });
123529
123530     this.__defineGetter__("brake", function () {
123531         return lightStatus.brake;
123532     });
123533
123534     this.__defineSetter__("brake", function (val) {
123535         try {
123536             lightStatus.brake = t.boolean(val);
123537         } catch (err) {
123538         }
123539     });
123540
123541     this.__defineGetter__("fog", function () {
123542         return lightStatus.fog;
123543     });
123544
123545     this.__defineSetter__("fog", function (val) {
123546         try {
123547             lightStatus.fog = t.boolean(val);
123548         } catch (err) {
123549         }
123550     });
123551
123552     this.__defineGetter__("hazard", function () {
123553         return lightStatus.hazard;
123554     });
123555
123556     this.__defineSetter__("hazard", function (val) {
123557         try {
123558             lightStatus.hazard = t.boolean(val);
123559         } catch (err) {
123560         }
123561     });
123562
123563     this.__defineGetter__("parking", function () {
123564         return lightStatus.parking;
123565     });
123566
123567     this.__defineSetter__("parking", function (val) {
123568         try {
123569             lightStatus.parking = t.boolean(val);
123570         } catch (err) {
123571         }
123572     });
123573
123574     this.__defineGetter__("highBeam", function () {
123575         return lightStatus.highBeam;
123576     });
123577
123578     this.__defineSetter__("highBeam", function (val) {
123579         try {
123580             lightStatus.highBeam = t.boolean(val);
123581         } catch (err) {
123582         }
123583     });
123584 };
123585
123586 InteriorLightStatus = function (propertyTypes) {
123587     var interiorLightStatus = {};
123588
123589     VehiclePropertyType.call(this, propertyTypes);
123590
123591     interiorLightStatus.passenger = propertyTypes.passenger || false;
123592     interiorLightStatus.driver = propertyTypes.driver || false;
123593     interiorLightStatus.center = propertyTypes.center || false;
123594
123595     this.__defineGetter__("passenger", function () {
123596         return interiorLightStatus.passenger;
123597     });
123598
123599     this.__defineSetter__("passenger", function (val) {
123600         try {
123601             interiorLightStatus.passenger = t.boolean(val);
123602         } catch (err) {
123603         }
123604     });
123605
123606     this.__defineGetter__("driver", function () {
123607         return interiorLightStatus.driver;
123608     });
123609
123610     this.__defineSetter__("driver", function (val) {
123611         try {
123612             interiorLightStatus.driver = t.boolean(val);
123613         } catch (err) {
123614         }
123615     });
123616
123617     this.__defineGetter__("center", function () {
123618         return interiorLightStatus.center;
123619     });
123620
123621     this.__defineSetter__("center", function (val) {
123622         try {
123623             interiorLightStatus.center = t.boolean(val);
123624         } catch (err) {
123625         }
123626     });
123627 };
123628
123629 Horn = function (propertyTypes) {
123630     var horn = {};
123631
123632     VehiclePropertyType.call(this, propertyTypes);
123633
123634     horn.on = propertyTypes.on || false;
123635
123636     this.__defineGetter__("on", function () {
123637         return horn.on;
123638     });
123639
123640     this.__defineSetter__("on", function (val) {
123641         try {
123642             horn.on = t.boolean(val);
123643         } catch (err) {
123644         }
123645     });
123646 };
123647
123648 Fuel = function (propertyTypes) {
123649     var fuel = {};
123650
123651     VehiclePropertyType.call(this, propertyTypes);
123652
123653     fuel.level = propertyTypes.level || 0;
123654     fuel.range = propertyTypes.range || 0;
123655     fuel.instantConsumption = propertyTypes.instantConsumption || 0;
123656     fuel.instantEconomy = propertyTypes.instantEconomy || 0;
123657     fuel.averageEconomy = propertyTypes.averageEconomy || 0;
123658
123659     this.__defineGetter__("level", function () {
123660         return fuel.level;
123661     });
123662
123663     this.__defineSetter__("level", function (val) {
123664         try {
123665             fuel.level = t.unsigned_short(val);
123666         } catch (err) {
123667         }
123668     });
123669
123670     this.__defineGetter__("range", function () {
123671         return fuel.range;
123672     });
123673
123674     this.__defineSetter__("range", function (val) {
123675         try {
123676             fuel.range = t.unsigned_short(val);
123677         } catch (err) {
123678         }
123679     });
123680
123681     this.__defineGetter__("instantConsumption", function () {
123682         return fuel.instantConsumption;
123683     });
123684
123685     this.__defineSetter__("instantConsumption", function (val) {
123686         try {
123687             fuel.instantConsumption = t.unsigned_short(val);
123688         } catch (err) {
123689         }
123690     });
123691
123692     this.__defineGetter__("instantEconomy", function () {
123693         return fuel.instantEconomy;
123694     });
123695
123696     this.__defineSetter__("instantEconomy", function (val) {
123697         try {
123698             fuel.instantEconomy = t.unsigned_short(val);
123699         } catch (err) {
123700         }
123701     });
123702
123703     this.__defineGetter__("averageEconomy", function () {
123704         return fuel.averageEconomy;
123705     });
123706
123707     this.__defineSetter__("averageEconomy", function (val) {
123708         try {
123709             //Setting this to any value should reset the counter to '0'
123710             fuel.averageEconomy = t.unsigned_short(val);
123711         } catch (err) {
123712         }
123713     });
123714 };
123715
123716 EngineOil = function (propertyTypes) {
123717     var engineOil = {};
123718
123719     VehiclePropertyType.call(this, propertyTypes);
123720
123721     engineOil.remaining = propertyTypes.remaining || 0;
123722     engineOil.temperature = propertyTypes.temperature || 0;
123723     engineOil.pressure = propertyTypes.Pressure || 0;
123724
123725     this.__defineGetter__("remaining", function () {
123726         return engineOil.remaining;
123727     });
123728
123729     this.__defineSetter__("remaining", function (val) {
123730         try {
123731             engineOil.remaining = t.unsigned_short(val);
123732         } catch (err) {
123733         }
123734     });
123735
123736     this.__defineGetter__("temperature", function () {
123737         return engineOil.temperature;
123738     });
123739
123740     this.__defineSetter__("temperature", function (val) {
123741         try {
123742             engineOil.temperature = t.long(val);
123743         } catch (err) {
123744         }
123745     });
123746
123747     this.__defineGetter__("pressure", function () {
123748         return engineOil.pressure;
123749     });
123750
123751     this.__defineSetter__("pressure", function (val) {
123752         try {
123753             engineOil.pressure = t.unsigned_short(val);
123754         } catch (err) {
123755         }
123756     });
123757 };
123758
123759 Location = function (propertyTypes) {
123760     var location = {};
123761
123762     VehiclePropertyType.call(this, propertyTypes);
123763
123764     location.latitude = propertyTypes.latitude || 0;
123765     location.longitude = propertyTypes.longitude || 0;
123766     location.altitude = propertyTypes.altitude || 0;
123767     location.direction = propertyTypes.direction || 0;
123768
123769     this.__defineGetter__("latitude", function () {
123770         return location.latitude;
123771     });
123772
123773     this.__defineSetter__("latitude", function (val) {
123774         try {
123775             val = t.double(val);
123776             if (val >= -180 && val <= 180) {
123777                 location.latitude = val;
123778             }
123779         } catch (err) {
123780         }
123781     });
123782
123783     this.__defineGetter__("longitude", function () {
123784         return location.longitude;
123785     });
123786
123787     this.__defineSetter__("longitude", function (val) {
123788         try {
123789             val = t.double(val);
123790             if (val >= -90 && val <= 90) {
123791                 location.longitude = val;
123792             }
123793         } catch (err) {
123794         }
123795     });
123796
123797     this.__defineGetter__("altitude", function () {
123798         return location.altitude;
123799     });
123800
123801     this.__defineSetter__("altitude", function (val) {
123802         try {
123803             val = t.double(val);
123804             if (val >= 0) {
123805                 location.altitude = val;
123806             }
123807         } catch (err) {
123808         }
123809     });
123810
123811     this.__defineGetter__("direction", function () {
123812         return location.direction;
123813     });
123814
123815     this.__defineSetter__("direction", function (val) {
123816         try {
123817             val = t.unsigned_short(val);
123818             if (val >= 0 && val < 360) {
123819                 location.direction = val;
123820             }
123821         } catch (err) {
123822         }
123823     });
123824 };
123825
123826 ExteriorBrightness = function (propertyTypes) {
123827     var eb = {};
123828
123829     VehiclePropertyType.call(this, propertyTypes);
123830
123831     eb.exteriorBrightness = propertyTypes.exteriorBrightness || 0;
123832
123833     this.__defineGetter__("exteriorBrightness", function () {
123834         return eb.exteriorBrightness;
123835     });
123836
123837     this.__defineSetter__("exteriorBrightness", function (val) {
123838         try {
123839             eb.exteriorBrightness = t.unsigned_long(val);
123840         } catch (err) {
123841         }
123842     });
123843 };
123844
123845 Temperature = function (propertyTypes) {
123846     var temperature = {};
123847
123848     VehiclePropertyType.call(this, propertyTypes);
123849
123850     temperature.interior = propertyTypes.interior || 0;
123851     temperature.exterior = propertyTypes.exterior || 0;
123852
123853     this.__defineGetter__("interior", function () {
123854         return temperature.interior;
123855     });
123856
123857     this.__defineSetter__("interior", function (val) {
123858         try {
123859             temperature.interior = t.short(val);
123860         } catch (err) {
123861         }
123862     });
123863
123864     this.__defineGetter__("exterior", function () {
123865         return temperature.exterior;
123866     });
123867
123868     this.__defineSetter__("exterior", function (val) {
123869         try {
123870             temperature.exterior = t.short(val);
123871         } catch (err) {
123872         }
123873     });
123874 };
123875
123876 RainSensor = function (propertyTypes) {
123877     var rainSensor = {};
123878
123879     VehiclePropertyType.call(this, propertyTypes);
123880
123881     rainSensor.rainSensor = propertyTypes.rainSensor || 0;
123882
123883     this.__defineGetter__("rainSensor", function () {
123884         return rainSensor.rainSensor;
123885     });
123886
123887     this.__defineSetter__("rainSensor", function (val) {
123888         try {
123889             val = t.unsigned_short(val);
123890             if (val >= 0 && val <= 10) {
123891                 rainSensor.rainSensor = val;
123892             }
123893         } catch (err) {
123894         }
123895     });
123896 };
123897
123898 WindshieldWiper = function (propertyTypes) {
123899     var windshieldWiper = {};
123900
123901     VehiclePropertyType.call(this, propertyTypes);
123902
123903     windshieldWiper.windshieldWiper = propertyTypes.windshieldWiper || 0;
123904
123905     this.__defineGetter__("WIPERSPEED_OFF", function () {
123906         return 0;
123907     });
123908
123909     this.__defineGetter__("WIPERSPEED_SLOWEST", function () {
123910         return 1;
123911     });
123912
123913     this.__defineGetter__("WIPERSPEED_FASTEST", function () {
123914         return 5;
123915     });
123916
123917     this.__defineGetter__("WIPERSPEED_AUTO", function () {
123918         return 10;
123919     });
123920
123921     this.__defineGetter__("windshieldWiper", function () {
123922         return windshieldWiper.windshieldWiper;
123923     });
123924
123925     this.__defineSetter__("windshieldWiper", function (val) {
123926         try {
123927             val = t.unsigned_short(val);
123928             if (val === 0 || val === 1 || val === 5 || val === 10) {
123929                 windshieldWiper.windshieldWiper = val;
123930             }
123931         } catch (err) {
123932         }
123933     });
123934 };
123935
123936 HVAC = function (propertyTypes) {
123937     var hvac = {};
123938
123939     VehiclePropertyType.call(this, propertyTypes);
123940
123941     hvac.airflowDirection = propertyTypes.airflowDirection || 0;
123942     hvac.fanSpeed = propertyTypes.fanSpeed || 0;
123943     hvac.targetTemperature = propertyTypes.targetTemperature || 0;
123944     hvac.airConditioning = propertyTypes.airConditioning || false;
123945     hvac.airRecirculation = propertyTypes.airRecirculation || false;
123946     hvac.heater = propertyTypes.heater || false;
123947     hvac.steeringWheelHeater = propertyTypes.steeringWheelHeater || false;
123948     hvac.seatHeater = propertyTypes.seatHeater || false;
123949     hvac.seatCooler = propertyTypes.seatCooler || false;
123950
123951     this.__defineGetter__("AIRFLOWDIRECTION_FRONTPANEL", function () {
123952         return 0;
123953     });
123954
123955     this.__defineGetter__("AIRFLOWDIRECTION_FLOORDUCT", function () {
123956         return 1;
123957     });
123958
123959     this.__defineGetter__("AIRFLOWDIRECTION_FRONT", function () {
123960         return 0x02;
123961     });
123962
123963     this.__defineGetter__("AIRFLOWDIRECTION_DEFROSTER", function () {
123964         return 0x04;
123965     });
123966
123967     this.__defineGetter__("airflowDirection", function () {
123968         return hvac.airflowDirection;
123969     });
123970
123971     this.__defineSetter__("airflowDirection", function (val) {
123972         try {
123973             val = t.unsigned_short(val);
123974             if (val === 0 || val === 1 || val === 0x02 || val === 0x04) {
123975                 hvac.airflowDirection = val;
123976             }
123977         } catch (err) {
123978         }
123979     });
123980
123981     this.__defineGetter__("fanSpeed", function () {
123982         return hvac.fanSpeed;
123983     });
123984
123985     this.__defineSetter__("fanSpeed", function (val) {
123986         try {
123987             val = t.unsigned_short(val);
123988             if (val >= 0 && val <= 7) {
123989                 hvac.fanSpeed = val;
123990             }
123991         } catch (err) {
123992         }
123993     });
123994
123995     this.__defineGetter__("targetTemperature", function () {
123996         return hvac.targetTemperature;
123997     });
123998
123999     this.__defineSetter__("targetTemperature", function (val) {
124000         try {
124001             hvac.targetTemperature = t.unsigned_short(val);
124002         } catch (err) {
124003         }
124004     });
124005
124006     this.__defineGetter__("airConditioning", function () {
124007         return hvac.airConditioning;
124008     });
124009
124010     this.__defineSetter__("airConditioning", function (val) {
124011         try {
124012             hvac.airConditioning = t.boolean(val);
124013         } catch (err) {
124014         }
124015     });
124016
124017     this.__defineGetter__("airRecirculation", function () {
124018         return hvac.airRecirculation;
124019     });
124020
124021     this.__defineSetter__("airRecirculation", function (val) {
124022         try {
124023             hvac.airRecirculation = t.boolean(val);
124024         } catch (err) {
124025         }
124026     });
124027
124028     this.__defineGetter__("heater", function () {
124029         return hvac.heater;
124030     });
124031
124032     this.__defineSetter__("heater", function (val) {
124033         try {
124034             hvac.heater = t.boolean(val);
124035         } catch (err) {
124036         }
124037     });
124038
124039     this.__defineGetter__("steeringWheelHeater", function () {
124040         return hvac.steeringWheelHeater;
124041     });
124042
124043     this.__defineSetter__("steeringWheelHeater", function (val) {
124044         try {
124045             hvac.steeringWheelHeater = t.boolean(val);
124046         } catch (err) {
124047         }
124048     });
124049
124050     this.__defineGetter__("seatHeater", function () {
124051         return hvac.seatHeater;
124052     });
124053
124054     this.__defineSetter__("seatHeater", function (val) {
124055         try {
124056             hvac.seatHeater = t.boolean(val);
124057         } catch (err) {
124058         }
124059     });
124060
124061     this.__defineGetter__("seatCooler", function () {
124062         return hvac.seatCooler;
124063     });
124064
124065     this.__defineSetter__("seatCooler", function (val) {
124066         try {
124067             hvac.seatCooler = t.boolean(val);
124068         } catch (err) {
124069         }
124070     });
124071 };
124072
124073 WindowStatus = function (propertyTypes) {
124074     var windowStatus = {};
124075
124076     VehiclePropertyType.call(this, propertyTypes);
124077
124078     windowStatus.openness = propertyTypes.openness || 0;
124079     windowStatus.defrost = propertyTypes.defrost || false;
124080
124081     this.__defineGetter__("WINDOWLOCATION_DRIVER", function () {
124082         return 0;
124083     });
124084
124085     this.__defineGetter__("WINDOWLOCATION_PASSENGER", function () {
124086         return 1;
124087     });
124088
124089     this.__defineGetter__("WINDOWLOCATION_LEFTREAR", function () {
124090         return 2;
124091     });
124092
124093     this.__defineGetter__("WINDOWLOCATION_RIGHTREAR", function () {
124094         return 3;
124095     });
124096
124097     this.__defineGetter__("WINDOWLOCATION_REAR", function () {
124098         return 4;
124099     });
124100
124101     this.__defineGetter__("openness", function () {
124102         return windowStatus.openness;
124103     });
124104
124105     this.__defineSetter__("openness", function (val) {
124106         try {
124107             val = t.unsigned_short(val);
124108             if (val >= 0 && val <= 100) {
124109                 windowStatus.openness = val;
124110             }
124111         } catch (err) {
124112         }
124113     });
124114
124115     this.__defineGetter__("defrost", function () {
124116         return windowStatus.defrost;
124117     });
124118
124119     this.__defineSetter__("defrost", function (val) {
124120         try {
124121             windowStatus.defrost = t.boolean(val);
124122         } catch (err) {
124123         }
124124     });
124125 };
124126
124127 Sunroof = function (propertyTypes) {
124128     var sunroof = {};
124129
124130     VehiclePropertyType.call(this, propertyTypes);
124131
124132     sunroof.openness = propertyTypes.openness || 0;
124133     sunroof.tilt = propertyTypes.tilt || 0;
124134
124135     this.__defineGetter__("openness", function () {
124136         return sunroof.openness;
124137     });
124138
124139     this.__defineSetter__("openness", function (val) {
124140         try {
124141             sunroof.openness = t.unsigned_short(val);
124142         } catch (err) {
124143         }
124144     });
124145
124146     this.__defineGetter__("tilt", function () {
124147         return sunroof.tilt;
124148     });
124149
124150     this.__defineSetter__("tilt", function (val) {
124151         try {
124152             sunroof.tilt = t.unsigned_short(val);
124153         } catch (err) {
124154         }
124155     });
124156 };
124157
124158 ConvertibleRoof = function (propertyTypes) {
124159     var convertibleRoof = {};
124160
124161     VehiclePropertyType.call(this, propertyTypes);
124162
124163     convertibleRoof.openness = propertyTypes.openness || 0;
124164
124165     this.__defineGetter__("openness", function () {
124166         return convertibleRoof.openness;
124167     });
124168
124169     this.__defineSetter__("openness", function (val) {
124170         try {
124171             convertibleRoof.openness = t.unsigned_short(val);
124172         } catch (err) {
124173         }
124174     });
124175 };
124176
124177 VehicleId = function (propertyTypes) {
124178     var vehicleId = {};
124179
124180     VehiclePropertyType.call(this, propertyTypes);
124181
124182     vehicleId.WMI = propertyTypes.WMI || "";
124183     vehicleId.VIN = propertyTypes.VIN || "";
124184
124185     this.__defineGetter__("WMI", function () {
124186         return vehicleId.WMI;
124187     });
124188
124189     this.__defineSetter__("WMI", function (val) {
124190         try {
124191             //?
124192             vehicleId.WMI = t.DOMString(val);
124193         } catch (err) {
124194         }
124195     });
124196
124197     this.__defineGetter__("VIN", function () {
124198         return vehicleId.VIN;
124199     });
124200
124201     this.__defineSetter__("VIN", function (val) {
124202         try {
124203             //?
124204             vehicleId.VIN = t.DOMString(val);
124205         } catch (err) {
124206         }
124207     });
124208 };
124209
124210 Size = function (propertyTypes) {
124211     var size = {};
124212
124213     VehiclePropertyType.call(this, propertyTypes);
124214
124215     size.width = propertyTypes.width || 0;
124216     size.height = propertyTypes.height || 0;
124217     size.length = propertyTypes.length || 0;
124218
124219     this.__defineGetter__("width", function () {
124220         return size.width;
124221     });
124222
124223     this.__defineSetter__("width", function (val) {
124224         try {
124225             size.width = t.unsigned_long(val);
124226         } catch (err) {
124227         }
124228     });
124229
124230     this.__defineGetter__("height", function () {
124231         return size.height;
124232     });
124233
124234     this.__defineSetter__("height", function (val) {
124235         try {
124236             size.height = t.unsigned_long(val);
124237         } catch (err) {
124238         }
124239     });
124240
124241     this.__defineGetter__("length", function () {
124242         return size.length;
124243     });
124244
124245     this.__defineSetter__("length", function (val) {
124246         try {
124247             size.length = t.unsigned_long(val);
124248         } catch (err) {
124249         }
124250     });
124251 };
124252
124253 FuelInfo = function (propertyTypes) {
124254     var fuelInfo = {};
124255
124256     VehiclePropertyType.call(this, propertyTypes);
124257
124258     fuelInfo.type = propertyTypes.type || 0;
124259     fuelInfo.refuelPosition = propertyTypes.refuelPosition || 0;
124260
124261     this.__defineGetter__("FUELTYPE_GASOLINE", function () {
124262         return 0;
124263     });
124264
124265     this.__defineGetter__("FUELTYPE_HIGH_OCTANE", function () {
124266         return 1;
124267     });
124268
124269     this.__defineGetter__("FUELTYPE_DIESEL", function () {
124270         return 2;
124271     });
124272
124273     this.__defineGetter__("FUELTYPE_ELECTRIC", function () {
124274         return 3;
124275     });
124276
124277     this.__defineGetter__("FUELTYPE_HYDROGEN", function () {
124278         return 4;
124279     });
124280
124281     this.__defineGetter__("REFUELPOSITION_LEFT", function () {
124282         return 0;
124283     });
124284
124285     this.__defineGetter__("REFUELPOSITION_RIGHT", function () {
124286         return 1;
124287     });
124288
124289     this.__defineGetter__("REFUELPOSITION_FRONT", function () {
124290         return 2;
124291     });
124292
124293     this.__defineGetter__("REFUELPOSITION_REAR", function () {
124294         return 3;
124295     });
124296
124297     this.__defineGetter__("type", function () {
124298         return fuelInfo.type;
124299     });
124300
124301     this.__defineSetter__("type", function (val) {
124302         try {
124303             val = t.unsigned_short(val);
124304             if (val >= 0 && val <= 4) {
124305                 fuelInfo.type = val;
124306             }
124307         } catch (err) {
124308         }
124309     });
124310
124311     this.__defineGetter__("refuelPosition", function () {
124312         return fuelInfo.refuelPosition;
124313     });
124314
124315     this.__defineSetter__("refuelPosition", function (val) {
124316         try {
124317             val = t.unsigned_short(val);
124318             if (val >= 0 && val <= 3) {
124319                 fuelInfo.refuelPosition = val;
124320             }
124321         } catch (err) {
124322         }
124323     });
124324 };
124325
124326 VehicleType = function (propertyTypes) {
124327     var vehicleType = {};
124328
124329     VehiclePropertyType.call(this, propertyTypes);
124330
124331     vehicleType.type = propertyTypes.type || 0;
124332
124333     this.__defineGetter__("VEHICLETYPE_SEDAN", function () {
124334         return 0;
124335     });
124336
124337     this.__defineGetter__("VEHICLETYPE_COUPE", function () {
124338         return 1;
124339     });
124340
124341     this.__defineGetter__("VEHICLETYPE_CABRIOLE", function () {
124342         return 2;
124343     });
124344
124345     this.__defineGetter__("VEHICLETYPE_ROADSTER", function () {
124346         return 3;
124347     });
124348
124349     this.__defineGetter__("VEHICLETYPE_SUV", function () {
124350         return 4;
124351     });
124352
124353     this.__defineGetter__("VEHICLETYPE_TRUCK", function () {
124354         return 5;
124355     });
124356
124357     this.__defineGetter__("type", function () {
124358         return vehicleType.type;
124359     });
124360
124361     this.__defineSetter__("type", function (val) {
124362         try {
124363             val = t.unsigned_short(val);
124364             if (val >= 0 && val <= 5) {
124365                 vehicleType.type = val;
124366             }
124367         } catch (err) {
124368         }
124369     });
124370 };
124371
124372 Doors = function (propertyTypes) {
124373     var doors = {};
124374
124375     VehiclePropertyType.call(this, propertyTypes);
124376
124377     doors.doorsPerRow = propertyTypes.doorsPerRow || [];
124378
124379     this.__defineGetter__("doorsPerRow", function () {
124380         return doors.doorsPerRow;
124381     });
124382
124383     this.__defineSetter__("doorsPerRow", function (val) {
124384         try {
124385             doors.doorsPerRow = t.unsigned_short(val, "[]");
124386         } catch (err) {
124387         }
124388     });
124389 };
124390
124391 TransmissionGearType = function (propertyTypes) {
124392     var trans = {};
124393
124394     VehiclePropertyType.call(this, propertyTypes);
124395
124396     trans.transmissionGearType = propertyTypes.transmissionGearType || 0;
124397
124398     this.__defineGetter__("TRANSMISSIONGEARTYPE_AUTO", function () {
124399         return 0;
124400     });
124401
124402     this.__defineGetter__("TRANSMISSIONGEARTYPE_MANUAL", function () {
124403         return 1;
124404     });
124405
124406     this.__defineGetter__("TRANSMISSIONGEARTYPE_CV", function () {
124407         return 2;
124408     });
124409
124410     this.__defineGetter__("transmissionGearType", function () {
124411         return trans.transmissionGearType;
124412     });
124413
124414     this.__defineSetter__("transmissionGearType", function (val) {
124415         try {
124416             val = t.unsigned_short(val);
124417             if (val >= 0 && val <= 2) {
124418                 trans.transmissionGearType = val;
124419             }
124420         } catch (err) {
124421         }
124422     });
124423 };
124424
124425 WheelInformation = function (propertyTypes) {
124426     var wheelInfo = {};
124427
124428     VehiclePropertyType.call(this, propertyTypes);
124429
124430     wheelInfo.frontWheelRadius = propertyTypes.frontWheelRadius || 0;
124431     wheelInfo.rearWheelRadius = propertyTypes.rearWheelRadius || 0;
124432     wheelInfo.wheelTrack = propertyTypes.wheelTrack || 0;
124433     wheelInfo.ABS = propertyTypes.ABS || false;
124434
124435     this.__defineGetter__("frontWheelRadius", function () {
124436         return wheelInfo.frontWheelRadius;
124437     });
124438
124439     this.__defineSetter__("frontWheelRadius", function (val) {
124440         try {
124441             wheelInfo.frontWheelRadius =t.unsigned_short(val);
124442         } catch (err) {
124443         }
124444     });
124445
124446     this.__defineGetter__("rearWheelRadius", function () {
124447         return wheelInfo.rearWheelRadius;
124448     });
124449
124450     this.__defineSetter__("rearWheelRadius", function (val) {
124451         try {
124452             wheelInfo.rearWheelRadius =t.unsigned_short(val);
124453         } catch (err) {
124454         }
124455     });
124456
124457     this.__defineGetter__("wheelTrack", function () {
124458         return wheelInfo.wheelTrack;
124459     });
124460
124461     this.__defineSetter__("wheelTrack", function (val) {
124462         try {
124463             wheelInfo.wheelTrack =t.unsigned_long(val);
124464         } catch (err) {
124465         }
124466     });
124467
124468     this.__defineGetter__("ABS", function () {
124469         return wheelInfo.ABS;
124470     });
124471
124472     this.__defineSetter__("ABS", function (val) {
124473         try {
124474             wheelInfo.ABS =t.boolean(val);
124475         } catch (err) {
124476         }
124477     });
124478 };
124479
124480 Odometer = function (propertyTypes) {
124481     var odm = {};
124482
124483     VehiclePropertyType.call(this, propertyTypes);
124484
124485     odm.odometer = propertyTypes.odometer || 0;
124486
124487     this.__defineGetter__("odometer", function () {
124488         return odm.odometer;
124489     });
124490
124491     this.__defineSetter__("odometer", function (val) {
124492         try {
124493             odm.odometer = t.unsigned_long(val);
124494         } catch (err) {
124495         }
124496     });
124497 };
124498
124499 Fluid = function (propertyTypes) {
124500     var fluid = {};
124501
124502     VehiclePropertyType.call(this, propertyTypes);
124503
124504     fluid.transmission = propertyTypes.transmission || 0;
124505     fluid.brake = propertyTypes.brake || 0;
124506     fluid.washer = propertyTypes.washer || 0;
124507
124508     this.__defineGetter__("transmission", function () {
124509         return fluid.transmission;
124510     });
124511
124512     this.__defineSetter__("transmission", function (val) {
124513         try {
124514             val = t.unsigned_short(val);
124515             if (val >= 0 && val <= 100) {
124516                 fluid.transmission = val;
124517             }
124518         } catch (err) {
124519         }
124520     });
124521
124522     this.__defineGetter__("brake", function () {
124523         return fluid.brake;
124524     });
124525
124526     this.__defineSetter__("brake", function (val) {
124527         try {
124528             val = t.unsigned_short(val);
124529             if (val >= 0 && val <= 100) {
124530                 fluid.brake = val;
124531             }
124532         } catch (err) {
124533         }
124534     });
124535
124536     this.__defineGetter__("washer", function () {
124537         return fluid.washer;
124538     });
124539
124540     this.__defineSetter__("washer", function (val) {
124541         try {
124542             val = t.unsigned_short(val);
124543             if (val >= 0 && val <= 100) {
124544                 fluid.washer = val;
124545             }
124546         } catch (err) {
124547         }
124548     });
124549 };
124550
124551 Battery = function (propertyTypes) {
124552     var battery = {};
124553
124554     VehiclePropertyType.call(this, propertyTypes);
124555
124556     battery.voltage = propertyTypes.voltage || 0;
124557     battery.current = propertyTypes.current || 0;
124558
124559     this.__defineGetter__("voltage", function () {
124560         return battery.voltage;
124561     });
124562
124563     this.__defineSetter__("voltage", function (val) {
124564         try {
124565             battery.voltage = t.double(val);
124566         } catch (err) {
124567         }
124568     });
124569
124570     this.__defineGetter__("current", function () {
124571         return battery.current;
124572     });
124573
124574     this.__defineSetter__("current", function (val) {
124575         try {
124576             battery.current = t.double(val);
124577         } catch (err) {
124578         }
124579     });
124580 };
124581
124582 TirePressure = function (propertyTypes) {
124583     var tirePressure = {};
124584
124585     VehiclePropertyType.call(this, propertyTypes);
124586
124587     tirePressure.leftFront = propertyTypes.leftFront || 0;
124588     tirePressure.rightFront = propertyTypes.rightFront || 0;
124589     tirePressure.leftRear = propertyTypes.leftRear || 0;
124590     tirePressure.rightRear = propertyTypes.rightRear || 0;
124591
124592     this.__defineGetter__("leftFront", function () {
124593         return tirePressure.leftFront;
124594     });
124595
124596     this.__defineSetter__("leftFront", function (val) {
124597         try {
124598             tirePressure.leftFront = t.double(val);
124599         } catch (err) {
124600         }
124601     });
124602
124603     this.__defineGetter__("rightFront", function () {
124604         return tirePressure.rightFront;
124605     });
124606
124607     this.__defineSetter__("rightFront", function (val) {
124608         try {
124609             tirePressure.rightFront = t.double(val);
124610         } catch (err) {
124611         }
124612     });
124613
124614     this.__defineGetter__("leftRear", function () {
124615         return tirePressure.leftRear;
124616     });
124617
124618     this.__defineSetter__("leftRear", function (val) {
124619         try {
124620             tirePressure.leftRear = t.double(val);
124621         } catch (err) {
124622         }
124623     });
124624
124625     this.__defineGetter__("rightRear", function () {
124626         return tirePressure.rightRear;
124627     });
124628
124629     this.__defineSetter__("rightRear", function (val) {
124630         try {
124631             tirePressure.rightRear = t.double(val);
124632         } catch (err) {
124633         }
124634     });
124635 };
124636
124637 TireTemperature = function (propertyTypes) {
124638     var tireTemperature = {};
124639
124640     VehiclePropertyType.call(this, propertyTypes);
124641
124642     tireTemperature.leftFront = propertyTypes.leftFront || 0;
124643     tireTemperature.rightFront = propertyTypes.rightFront || 0;
124644     tireTemperature.leftRear = propertyTypes.leftRear || 0;
124645     tireTemperature.rightRear = propertyTypes.rightRear || 0;
124646
124647     this.__defineGetter__("leftFront", function () {
124648         return tireTemperature.leftFront;
124649     });
124650
124651     this.__defineSetter__("leftFront", function (val) {
124652         try {
124653             tireTemperature.leftFront = t.double(val);
124654         } catch (err) {
124655         }
124656     });
124657
124658     this.__defineGetter__("rightFront", function () {
124659         return tireTemperature.rightFront;
124660     });
124661
124662     this.__defineSetter__("rightFront", function (val) {
124663         try {
124664             tireTemperature.rightFront = t.double(val);
124665         } catch (err) {
124666         }
124667     });
124668
124669     this.__defineGetter__("leftRear", function () {
124670         return tireTemperature.leftRear;
124671     });
124672
124673     this.__defineSetter__("leftRear", function (val) {
124674         try {
124675             tireTemperature.leftRear = t.double(val);
124676         } catch (err) {
124677         }
124678     });
124679
124680     this.__defineGetter__("rightRear", function () {
124681         return tireTemperature.rightRear;
124682     });
124683
124684     this.__defineSetter__("rightRear", function (val) {
124685         try {
124686             tireTemperature.rightRear = t.double(val);
124687         } catch (err) {
124688         }
124689     });
124690 };
124691
124692 SecurityAlert = function (propertyTypes) {
124693     var securityAlert = {};
124694
124695     VehiclePropertyType.call(this, propertyTypes);
124696
124697     securityAlert.securityAlert = propertyTypes.securityAlert || false;
124698
124699     this.__defineGetter__("securityAlert", function () {
124700         return securityAlert.securityAlert;
124701     });
124702
124703     this.__defineSetter__("securityAlert", function (val) {
124704         try {
124705             securityAlert.securityAlert = t.boolean(val);
124706         } catch (err) {
124707         }
124708     });
124709 };
124710
124711 ParkingBrake = function (propertyTypes) {
124712     var parkingBrake = {};
124713
124714     VehiclePropertyType.call(this, propertyTypes);
124715
124716     parkingBrake.parkingBrake = propertyTypes.parkingBrake || false;
124717
124718     this.__defineGetter__("parkingBrake", function () {
124719         return parkingBrake.parkingBrake;
124720     });
124721
124722     this.__defineSetter__("parkingBrake", function (val) {
124723         try {
124724             parkingBrake.parkingBrake = t.boolean(val);
124725         } catch (err) {
124726         }
124727     });
124728 };
124729
124730 ParkingLight = function (propertyTypes) {
124731     var parkingLight = {};
124732
124733     VehiclePropertyType.call(this, propertyTypes);
124734
124735     parkingLight.parkingLight = propertyTypes.parkingLight || false;
124736
124737     this.__defineGetter__("parkingLight", function () {
124738         return parkingLight.parkingLight;
124739     });
124740
124741     this.__defineSetter__("parkingLight", function (val) {
124742         try {
124743             parkingLight.parkingLight = t.boolean(val);
124744         } catch (err) {
124745         }
124746     });
124747 };
124748
124749 HazardLight = function (propertyTypes) {
124750     var hazardLight = {};
124751
124752     VehiclePropertyType.call(this, propertyTypes);
124753
124754     hazardLight.hazardLight = propertyTypes.hazardLight || false;
124755
124756     this.__defineGetter__("hazardLight", function () {
124757         return hazardLight.hazardLight;
124758     });
124759
124760     this.__defineSetter__("hazardLight", function (val) {
124761         try {
124762             hazardLight.hazardLight = t.boolean(val);
124763         } catch (err) {
124764         }
124765     });
124766 };
124767
124768 AntilockBrakingSystem = function (propertyTypes) {
124769     var abs = {};
124770
124771     VehiclePropertyType.call(this, propertyTypes);
124772
124773     abs.antilockBrakingSystem = propertyTypes.antilockBrakingSystem || false;
124774
124775     this.__defineGetter__("antilockBrakingSystem", function () {
124776         return abs.antilockBrakingSystem;
124777     });
124778
124779     this.__defineSetter__("antilockBrakingSystem", function (val) {
124780         try {
124781             abs.antilockBrakingSystem = t.boolean(val);
124782         } catch (err) {
124783         }
124784     });
124785 };
124786
124787 TractionControlSystem = function (propertyTypes) {
124788     var tcs = {};
124789
124790     VehiclePropertyType.call(this, propertyTypes);
124791
124792     tcs.tractionControlSystem = propertyTypes.tractionControlSystem || false;
124793
124794     this.__defineGetter__("tractionControlSystem", function () {
124795         return tcs.tractionControlSystem;
124796     });
124797
124798     this.__defineSetter__("tractionControlSystem", function (val) {
124799         try {
124800             tcs.tractionControlSystem = t.boolean(val);
124801         } catch (err) {
124802         }
124803     });
124804 };
124805
124806 VehicleTopSpeedLimit = function (propertyTypes) {
124807     var vtl = {};
124808
124809     VehiclePropertyType.call(this, propertyTypes);
124810
124811     vtl.vehicleTopSpeedLimit = propertyTypes.vehicleTopSpeedLimit || false;
124812
124813     this.__defineGetter__("vehicleTopSpeedLimit", function () {
124814         return vtl.vehicleTopSpeedLimit;
124815     });
124816
124817     this.__defineSetter__("vehicleTopSpeedLimit", function (val) {
124818         try {
124819             vtl.vehicleTopSpeedLimit = t.unsigned_short(val);
124820         } catch (err) {
124821         }
124822     });
124823 };
124824
124825 AirbagStatus = function (propertyTypes) {
124826     var airbagStatus = {};
124827
124828     VehiclePropertyType.call(this, propertyTypes);
124829
124830     airbagStatus.airbagStatus = propertyTypes.airbagStatus || 0;
124831
124832     this.__defineGetter__("AIRBAGSTATUS_INACTIVE", function () {
124833         return 0;
124834     });
124835
124836     this.__defineGetter__("AIRBAGSTATUS_ACTIVE", function () {
124837         return 1;
124838     });
124839
124840     this.__defineGetter__("AIRBAGSTATUS_DEPLOYED", function () {
124841         return 2;
124842     });
124843
124844     this.__defineGetter__("airbagStatus", function () {
124845         return airbagStatus.airbagStatus;
124846     });
124847
124848     this.__defineSetter__("airbagStatus", function (val) {
124849         try {
124850             val = t.unsigned_short(val);
124851             if (val === 0 || val === 1 || val === 2) {
124852                 airbagStatus.airbagStatus = val;
124853             }
124854         } catch (err) {
124855         }
124856     });
124857 };
124858
124859 DoorStatus = function (propertyTypes) {
124860     var doorStatus = {};
124861
124862     VehiclePropertyType.call(this, propertyTypes);
124863
124864     doorStatus.doorStatus = propertyTypes.doorStatus || 0;
124865     doorStatus.doorLockStatus = propertyTypes.doorLockStatus || false;
124866     doorStatus.childLockStatus = propertyTypes.childLockStatus || false;
124867
124868     this.__defineGetter__("DOORSTATUS_CLOSED", function () {
124869         return 0;
124870     });
124871
124872     this.__defineGetter__("DOORSTATUS_OPEN", function () {
124873         return 1;
124874     });
124875
124876     this.__defineGetter__("DOORSTATUS_AJAR", function () {
124877         return 2;
124878     });
124879
124880     this.__defineGetter__("doorStatus", function () {
124881         return doorStatus.doorStatus;
124882     });
124883
124884     this.__defineSetter__("doorStatus", function (val) {
124885         try {
124886             val = t.unsigned_short(val);
124887             if (val === 0 || val === 1 || val === 2) {
124888                 doorStatus.doorStatus = val;
124889             }
124890         } catch (err) {
124891         }
124892     });
124893
124894     this.__defineGetter__("doorLockStatus", function () {
124895         return doorStatus.doorLockStatus;
124896     });
124897
124898     this.__defineSetter__("doorLockStatus", function (val) {
124899         try {
124900             doorStatus.doorLockStatus = t.boolean(val);
124901         } catch (err) {
124902         }
124903     });
124904
124905     this.__defineGetter__("childLockStatus", function () {
124906         return doorStatus.childLockStatus;
124907     });
124908
124909     this.__defineSetter__("childLockStatus", function (val) {
124910         try {
124911             doorStatus.childLockStatus = t.boolean(val);
124912         } catch (err) {
124913         }
124914     });
124915 };
124916
124917 SeatBeltStatus = function (propertyTypes) {
124918     var seatBeltStatus = {};
124919
124920     VehiclePropertyType.call(this, propertyTypes);
124921
124922     seatBeltStatus.seatBeltStatus = propertyTypes.seatBeltStatus || false;
124923
124924     this.__defineGetter__("seatBeltStatus", function () {
124925         return seatBeltStatus.seatBeltStatus;
124926     });
124927
124928     this.__defineSetter__("seatBeltStatus", function (val) {
124929         try {
124930             seatBeltStatus.seatBeltStatus = t.boolean(val);
124931         } catch (err) {
124932         }
124933     });
124934 };
124935
124936 OccupantStatus = function (propertyTypes) {
124937     var occupantStatus = {};
124938
124939     VehiclePropertyType.call(this, propertyTypes);
124940
124941     occupantStatus.occupantStatus = propertyTypes.occupantStatus || 0;
124942
124943     this.__defineGetter__("OCCUPANTSTATUS_VACANT", function () {
124944         return 0;
124945     });
124946
124947     this.__defineGetter__("OCCUPANTSTATUS_CHILD", function () {
124948         return 1;
124949     });
124950
124951     this.__defineGetter__("OCCUPANTSTATUS_ADULT", function () {
124952         return 2;
124953     });
124954
124955     this.__defineGetter__("occupantStatus", function () {
124956         return occupantStatus.occupantStatus;
124957     });
124958
124959     this.__defineSetter__("occupantStatus", function (val) {
124960         try {
124961             val = t.unsigned_short(val);
124962             if (val === 0 || val === 1 || val === 2) {
124963                 occupantStatus.occupantStatus = val;
124964             }
124965         } catch (err) {
124966         }
124967     });
124968 };
124969
124970 ObstacleDistance = function (propertyTypes) {
124971     var obstacleDistance = {};
124972
124973     VehiclePropertyType.call(this, propertyTypes);
124974
124975     obstacleDistance.obstacleDistance = propertyTypes.obstacleDistance || 0;
124976
124977     this.__defineGetter__("DISTANCESENSORLOCATION_LEFTFRONT", function () {
124978         return 0;
124979     });
124980
124981     this.__defineGetter__("DISTANCESENSORLOCATION_RIGHTFRONT", function () {
124982         return 1;
124983     });
124984
124985     this.__defineGetter__("DISTANCESENSORLOCATION_LEFTREAR", function () {
124986         return 2;
124987     });
124988
124989     this.__defineGetter__("DISTANCESENSORLOCATION_RIGHTREAR", function () {
124990         return 3;
124991     });
124992
124993     this.__defineGetter__("DISTANCESENSORLOCATION_LEFTBLINDSPOT",
124994             function () {
124995         return 4;
124996     });
124997
124998     this.__defineGetter__("DISTANCESENSORLOCATION_RIGHTBLINDSPOT",
124999             function () {
125000         return 5;
125001     });
125002
125003     this.__defineGetter__("obstacleDistance", function () {
125004         return obstacleDistance.obstacleDistance;
125005     });
125006
125007     this.__defineSetter__("obstacleDistance", function (val) {
125008         try {
125009             obstacleDistance.obstacleDistance = t.double(val);
125010         } catch (err) {
125011         }
125012     });
125013 };
125014
125015 NightMode = function (propertyTypes) {
125016     var nightMode = {};
125017
125018     VehiclePropertyType.call(this, propertyTypes);
125019
125020     nightMode.nightMode = propertyTypes.nightMode || false;
125021
125022     this.__defineGetter__("nightMode", function () {
125023         return nightMode.nightMode;
125024     });
125025
125026     this.__defineSetter__("nightMode", function (val) {
125027         try {
125028             nightMode.nightMode = t.boolean(val);
125029         } catch (err) {
125030         }
125031     });
125032 };
125033
125034 DrivingMode = function (propertyTypes) {
125035     var drivingMode = {};
125036
125037     VehiclePropertyType.call(this, propertyTypes);
125038
125039     drivingMode.drivingMode = propertyTypes.drivingMode || 0;
125040
125041     this.__defineGetter__("drivingMode", function () {
125042         return drivingMode.drivingMode;
125043     });
125044
125045     this.__defineSetter__("drivingMode", function (val) {
125046         try {
125047             val = t.unsigned_short(val);
125048             if (val === 0 || val === 1) {
125049                 drivingMode.drivingMode = val;
125050             }
125051         } catch (err) {
125052         }
125053     });
125054 };
125055
125056 TurnSignal = function (propertyTypes) {
125057     var turnSignal = {};
125058
125059     VehiclePropertyType.call(this, propertyTypes);
125060
125061     turnSignal.turnSignal = propertyTypes.turnSignal || 0;
125062
125063     this.__defineGetter__("turnSignal", function () {
125064         return turnSignal.turnSignal;
125065     });
125066
125067     this.__defineSetter__("turnSignal", function (val) {
125068         try {
125069             turnSignal.turnSignal = t.unsigned_short(val);
125070         } catch (err) {
125071         }
125072     });
125073 };
125074
125075 ButtonEvent = function (propertyTypes) {
125076     var buttonEvent = {};
125077
125078     VehiclePropertyType.call(this, propertyTypes);
125079
125080     buttonEvent.buttonEvent = propertyTypes.buttonEvent || 0;
125081
125082     this.__defineGetter__("buttonEvent", function () {
125083         return buttonEvent.buttonEvent;
125084     });
125085
125086     this.__defineSetter__("buttonEvent", function (val) {
125087         try {
125088             buttonEvent.buttonEvent = t.unsigned_short(val);
125089         } catch (err) {
125090         }
125091     });
125092 };
125093
125094 _initialize();
125095
125096 module.exports = _self;
125097
125098 });
125099 define('ripple/platform/ivi/3.0/typecoerce', function (require, exports, module) {
125100 /*
125101  *  Copyright 2013 Intel Corporation.
125102  *
125103  * Licensed under the Apache License, Version 2.0 (the "License");
125104  * you may not use this file except in compliance with the License.
125105  * You may obtain a copy of the License at
125106  *
125107  * http://www.apache.org/licenses/LICENSE-2.0
125108  *
125109  * Unless required by applicable law or agreed to in writing, software
125110  * distributed under the License is distributed on an "AS IS" BASIS,
125111  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125112  * See the License for the specific language governing permissions and
125113  * limitations under the License.
125114  */
125115
125116 var t = require('ripple/platform/ivi/3.0/typedef'),
125117     _self;
125118
125119 _self = function (pattern) {
125120     var typeCoerce, typeOfPattern;
125121
125122     // private
125123     function getExtendedType(val) {
125124         var type = Object.prototype.toString.call(val), attr;
125125
125126         switch (type) {
125127         case "[object Array]":
125128             if ((typeof val[0] === "string") && (val[0].length > 0)) {
125129                 type = "enum";
125130             } else {
125131                 type = "Union";
125132             }
125133             return type;
125134
125135         case "[object Object]":
125136             if ("_dictionary" in val) {
125137                 return "dictionary";
125138             }
125139
125140             type = "Object";
125141
125142             for (attr in val) {
125143                 if (attr === "0") {
125144                     type = "Arguments";
125145                 } else if (val[attr] === "Callback") {
125146                     type = "Callback";
125147                 }
125148                 break;
125149             }
125150
125151             return type;
125152         }
125153
125154         switch (val) {
125155         case "Callback":
125156             type = "Function";
125157             break;
125158
125159         case "TZDate":
125160         case "any":
125161         case "byte":
125162         case "float":
125163         case "long":
125164         case "long long":
125165         case "octet":
125166         case "short":
125167         case "unsigned long":
125168         case "unsigned long long":
125169         case "unsigned short":
125170             type = val;
125171             break;
125172
125173         case "double":
125174             type = "float";
125175             break;
125176
125177         default:    // Derivative type name: e.g., "AbstractFilter"
125178             type = "";
125179             break;
125180         }
125181
125182         return type;
125183     }
125184
125185     function getType(val, isPattern) {
125186         var type = Object.prototype.toString.call(val);
125187
125188         switch (type) {
125189         case "[object Array]":
125190             type = (isPattern && (val.length > 1)) ? getExtendedType(val) :
125191                     "Array";
125192             break;
125193
125194         case "[object Arguments]":
125195             type = "Arguments";
125196             break;
125197
125198         case "[object Boolean]":
125199             type = "boolean";
125200             break;
125201
125202         case "[object Date]":
125203             type = "Date";
125204             break;
125205
125206         case "[object Function]":
125207             type = "Function";
125208             break;
125209
125210         case "[object Number]":
125211             type = "Number";
125212             break;
125213
125214         case "[object Object]":
125215             type = isPattern ? getExtendedType(val) : "Object";
125216             break;
125217
125218         case "[object String]":
125219             type = (isPattern && !!val) ? getExtendedType(val) : "DOMString";
125220             break;
125221         }
125222
125223         return type;
125224     }
125225
125226     function isConstructed(obj) {
125227         if (!("_constructor" in pattern))
125228             return true;
125229
125230         if (obj instanceof window.tizen[pattern._constructor])
125231             return true;
125232
125233         return false;
125234     }
125235
125236     function toInteger(x) {
125237         return (x < 0) ? Math.ceil(x) : Math.floor(x);
125238     }
125239
125240     function modulo(a, b) {
125241         return (a - Math.floor(a / b) * b);
125242     }
125243
125244     function toInt(x, bits) {
125245         var p;
125246
125247         x = Number(x);
125248
125249         if (isNaN(x) || !isFinite(x))
125250             return null;
125251
125252         p = Math.pow(2, bits);
125253         x = modulo(toInteger(x), p);
125254
125255         return (x >= Math.pow(2, bits - 1)) ? (x - p) : x;
125256     }
125257
125258     function toUInt(x, bits) {
125259         x = Number(x);
125260
125261         if (isNaN(x) || !isFinite(x))
125262             return null;
125263
125264         return modulo(toInteger(x), Math.pow(2, bits));
125265     }
125266
125267     function toInt8(x) {
125268         return toInt(x, 8);
125269     }
125270
125271     function toInt16(x) {
125272         return toInt(x, 16);
125273     }
125274
125275     function toInt32(x) {
125276         return toInt(x, 32);
125277     }
125278
125279     function toInt64(x) {
125280         return toInt(x, 64);
125281     }
125282
125283     function toUInt8(x) {
125284         return toUInt(x, 8);
125285     }
125286
125287     function toUInt16(x) {
125288         return toUInt(x, 16);
125289     }
125290
125291     function toUInt32(x) {
125292         return toUInt(x, 32);
125293     }
125294
125295     function toUInt64(x) {
125296         return toUInt(x, 64);
125297     }
125298
125299     // public
125300     function cast(obj) {
125301         var typeMap,
125302             typeOfObj = getType(obj, false);
125303
125304         typeMap = {
125305             "Arguments": function () {
125306                 var i, isNullable, ret;
125307
125308                 for (i in pattern) {
125309                     if (i === "_optional")
125310                         continue;
125311
125312                     isNullable = !!(pattern._optional && pattern._optional[i]);
125313
125314                     if (i > obj.length - 1) {
125315                         if (!isNullable) {
125316                             return null;
125317                         }
125318                         break;
125319                     }
125320
125321                     if (!isNullable || (obj[i] !== null)) {
125322                         ret = _self(pattern[i]).cast(obj[i]);
125323                         if (ret === null) {
125324                             return null;
125325                         }
125326                         obj[i] = ret;
125327                     }
125328                 }
125329
125330                 return obj;
125331             },
125332
125333             "Array": function () {
125334                 var elementType, i, ret;
125335
125336                 if (typeOfObj !== typeOfPattern) {
125337                     return null;
125338                 }
125339
125340                 elementType = _self(pattern[0]);
125341                 for (i in obj) {
125342                     ret = elementType.cast(obj[i]);
125343                     if (ret === null) {
125344                         return null;
125345                     }
125346                     obj[i] = ret;
125347                 }
125348
125349                 return obj;
125350             },
125351
125352             "Callback": function () {
125353                 var attr;
125354
125355                 if (typeOfObj !== "Object") {
125356                     return null;
125357                 }
125358
125359                 for (attr in pattern) {
125360                     if (attr in obj) {
125361                         obj[attr] = _self(pattern[attr]).cast(obj[attr]);
125362                         if (obj[attr] === null) {
125363                             return null;
125364                         }
125365                     }
125366                 }
125367
125368                 return obj;
125369             },
125370
125371             "DOMString": function () {
125372                 switch (typeOfObj) {
125373                 case "DOMString":
125374                 case "Date":
125375                 case "Number":
125376                 case "boolean":
125377                     obj = String(obj);
125378                     break;
125379
125380                 default:
125381                     if ((obj === null) || (obj === undefined)) {
125382                         obj = String(obj);
125383                     } else {
125384                         obj = null;
125385                     }
125386                     break;
125387                 }
125388
125389                 return obj;
125390             },
125391
125392             "Date": function () {
125393                 return (typeOfObj === typeOfPattern) ? obj : null;
125394             },
125395
125396             "Function": function () {
125397                 return (typeOfObj === typeOfPattern) ? obj : null;
125398             },
125399
125400             "Object": function () {
125401                 var ret, attr, i;
125402
125403                 if (typeOfObj !== typeOfPattern) {
125404                     if ((obj === null) || (obj === undefined)) {
125405                         return null;
125406                     }
125407                     if (!("_derived" in pattern)) {
125408                         return null;
125409                     }
125410                 }
125411
125412                 if (!isConstructed(obj)) {
125413                     return null;
125414                 }
125415
125416                 for (attr in pattern) {
125417                     switch (attr) {
125418                     case "_optional":
125419                     case "_constructor":
125420                         break;
125421
125422                     case "_derived":
125423                         for (i in pattern._derived) {
125424                             ret = _self(pattern._derived[i]).cast(obj);
125425                             if (ret !== null)
125426                                 break;
125427                         }
125428                         if (ret === null) {
125429                             return null;
125430                         }
125431                         break;
125432
125433                     default:
125434                         if (!pattern._optional || !pattern._optional[attr] ||
125435                                 (obj[attr] !== undefined) &&
125436                                 (obj[attr] !== null)) {
125437                             ret = _self(pattern[attr]).cast(obj[attr]);
125438                             if (ret === null) {
125439                                 return null;
125440                             }
125441                             obj[attr] = ret;
125442                         }
125443                         break;
125444                     }
125445                 }
125446
125447                 return obj;
125448             },
125449
125450             "TZDate": function () {
125451                 if (typeOfObj !== "Object") {
125452                     return null;
125453                 }
125454                 return (obj instanceof window.tizen.TZDate) ? obj : null;
125455             },
125456
125457             "Union": function () {
125458                 var ret, i;
125459
125460                 for (i in pattern) {
125461                     ret = _self(pattern[i]).cast(obj);
125462                     if (ret !== null)
125463                         break;
125464                 }
125465
125466                 return ret;
125467             },
125468
125469             "any": function () {
125470                 return obj;
125471             },
125472
125473             "boolean": function () {
125474                 return (typeOfObj === typeOfPattern) ? obj : null;
125475             },
125476
125477             "byte": function () {
125478                 return toInt8(obj);
125479             },
125480
125481             "dictionary": function () {
125482                 var attr, ret;
125483
125484                 if (typeOfObj !== "Object") {
125485                     return null;
125486                 }
125487
125488                 for (attr in pattern) {
125489                     switch (attr) {
125490                     case "_dictionary":
125491                         if (pattern._dictionary !== null) {
125492                             ret = _self(pattern._dictionary).cast(obj);
125493                             if (ret === null) {
125494                                 return null;
125495                             }
125496                         }
125497                         break;
125498
125499                     default:
125500                         if ((attr in obj) && (obj[attr] !== null) &&
125501                                 (obj[attr] !== undefined)) {
125502                             ret = _self(pattern[attr]).cast(obj[attr]);
125503                             if (ret === null) {
125504                                 return null;
125505                             }
125506                             obj[attr] = ret;
125507                         }
125508                         break;
125509                     }
125510                 }
125511
125512                 return obj;
125513             },
125514
125515             "enum": function () {
125516                 var i;
125517
125518                 obj = String(obj).trim();
125519                 for (i in pattern) {
125520                     if (obj === pattern[i]) {
125521                         return obj;
125522                     }
125523                 }
125524
125525                 return null;
125526             },
125527
125528             "float": function () {
125529                 var f = parseFloat(obj, 10);
125530
125531                 return (isNaN(f) ? null : f);
125532             },
125533
125534             "long": function () {
125535                 return toInt32(obj);
125536             },
125537
125538             "long long": function () {
125539                 return toInt64(obj);
125540             },
125541
125542             "octet": function () {
125543                 return toUInt8(obj);
125544             },
125545
125546             "short": function () {
125547                 return toInt16(obj);
125548             },
125549
125550             "unsigned long": function () {
125551                 return toUInt32(obj);
125552             },
125553
125554             "unsigned long long": function () {
125555                 return toUInt64(obj);
125556             },
125557
125558             "unsigned short": function () {
125559                 return toUInt16(obj);
125560             },
125561
125562             "": function () {
125563                 return _self(t[pattern]).cast(obj);
125564             }
125565         };
125566
125567         return typeMap[typeOfPattern]();
125568     }
125569
125570     function copy(obj) {
125571         var typeMap,
125572             typeOfObj = getType(obj, false);
125573
125574         typeMap = {
125575             "Arguments": function () {
125576                 var i, isNullable, ret = [];
125577
125578                 for (i in pattern) {
125579                     if (i === "_optional")
125580                         continue;
125581
125582                     isNullable = !!(pattern._optional && pattern._optional[i]);
125583
125584                     if (i > obj.length - 1) {
125585                         if (!isNullable) {
125586                             return null;
125587                         }
125588                         break;
125589                     }
125590
125591                     if (!isNullable || (obj[i] !== null)) {
125592                         ret[i] = _self(pattern[i]).copy(obj[i]);
125593                         if (ret[i] === null) {
125594                             return null;
125595                         }
125596                     }
125597                 }
125598
125599                 for (i in ret) {
125600                     obj[i] = ret[i];
125601                 }
125602
125603                 return obj;
125604             },
125605
125606             "Array": function () {
125607                 var arr = [], elementType, i;
125608
125609                 if (typeOfObj !== typeOfPattern) {
125610                     return null;
125611                 }
125612
125613                 elementType = _self(pattern[0]);
125614                 for (i in obj) {
125615                     if (obj[i]) {
125616                         arr[i] = elementType.copy(obj[i]);
125617                         if (arr[i] === null)
125618                             return null;
125619                     }
125620                 }
125621
125622                 return arr;
125623             },
125624
125625             "Callback": function () {
125626                 var ret = {}, attr;
125627
125628                 if (typeOfObj !== "Object") {
125629                     return null;
125630                 }
125631
125632                 for (attr in pattern) {
125633                     if (attr in obj) {
125634                         ret[attr] = _self(pattern[attr]).copy(obj[attr]);
125635                         if (ret[attr] === null) {
125636                             return null;
125637                         }
125638                     }
125639                 }
125640
125641                 return ret;
125642             },
125643
125644             "Object": function () {
125645                 var ret = {}, attr, i, derived;
125646
125647                 if (typeOfObj !== typeOfPattern) {
125648                     if ((obj === null) || (obj === undefined)) {
125649                         return null;
125650                     }
125651                     if (!("_derived" in pattern)) {
125652                         return null;
125653                     }
125654                 }
125655
125656                 if (!isConstructed(obj)) {
125657                     return null;
125658                 }
125659                 if ("_constructor" in pattern) {
125660                     ret.__proto__ = window.tizen[pattern._constructor].prototype;
125661                 }
125662
125663                 for (attr in pattern) {
125664                     switch (attr) {
125665                     case "_optional":
125666                     case "_constructor":
125667                         break;
125668
125669                     case "_derived":
125670                         for (i in pattern._derived) {
125671                             derived = _self(pattern._derived[i]).copy(obj);
125672                             if (derived !== null)
125673                                 break;
125674                         }
125675                         if (derived === null) {
125676                             return null;
125677                         }
125678                         for (attr in derived) {
125679                             ret[attr] = derived[attr];
125680                         }
125681                         break;
125682
125683                     default:
125684                         if (!pattern._optional || !pattern._optional[attr] ||
125685                                 (obj[attr] !== undefined) &&
125686                                 (obj[attr] !== null)) {
125687                             ret[attr] = _self(pattern[attr]).copy(obj[attr]);
125688                             if (ret[attr] === null) {
125689                                 return null;
125690                             }
125691                         }
125692                         break;
125693                     }
125694                 }
125695
125696                 return ret;
125697             },
125698
125699             "Union": function () {
125700                 var ret, i;
125701
125702                 for (i in pattern) {
125703                     ret = _self(pattern[i]).copy(obj);
125704                     if (ret !== null)
125705                         break;
125706                 }
125707
125708                 return ret;
125709             },
125710
125711             "dictionary": function () {
125712                 var ret = {}, attr, base, i;
125713
125714                 if (typeOfObj !== "Object") {
125715                     return null;
125716                 }
125717
125718                 for (attr in pattern) {
125719                     switch (attr) {
125720                     case "_dictionary":
125721                         if (pattern._dictionary !== null) {
125722                             base = _self(pattern._dictionary).copy(obj);
125723                             if (base === null) {
125724                                 return null;
125725                             }
125726                             for (i in base) {
125727                                 ret[i] = base[i];
125728                             }
125729                         }
125730                         break;
125731
125732                     default:
125733                         if ((attr in obj) && (obj[attr] !== null) &&
125734                                 (obj[attr] !== undefined)) {
125735                             ret[attr] = _self(pattern[attr]).copy(obj[attr]);
125736                             if (ret[attr] === null) {
125737                                 return null;
125738                             }
125739                         }
125740                         break;
125741                     }
125742                 }
125743
125744                 return ret;
125745             },
125746
125747             "": function () {
125748                 return _self(t[pattern]).copy(obj);
125749             }
125750         };
125751
125752         return (typeOfPattern in typeMap) ? typeMap[typeOfPattern]() :
125753                 cast(obj);
125754     }
125755
125756     function match(obj) {
125757         var typeMap,
125758             typeOfObj = getType(obj, false);
125759
125760         typeMap = {
125761             "Array": function () {
125762                 var elementType, i;
125763
125764                 if (typeOfObj !== typeOfPattern)
125765                     return false;
125766
125767                 elementType = _self(pattern[0]);
125768                 for (i in obj) {
125769                     if (!elementType.match(obj[i])) {
125770                         return false;
125771                     }
125772                 }
125773
125774                 return true;
125775             },
125776
125777             "Callback": function () {
125778                 var attr, isMatched = true;
125779
125780                 if (typeOfObj !== "Object") {
125781                     return false;
125782                 }
125783
125784                 for (attr in pattern) {
125785                     if (attr in obj) {
125786                         isMatched = _self(pattern[attr]).match(obj[attr]);
125787                         if (!isMatched) {
125788                             break;
125789                         }
125790                     }
125791                 }
125792
125793                 return isMatched;
125794             },
125795
125796             "DOMString": function () {
125797                 return (typeOfObj === typeOfPattern);
125798             },
125799
125800             "Date": function () {
125801                 return (typeOfObj === typeOfPattern);
125802             },
125803
125804             "Function": function () {
125805                 return (typeOfObj === typeOfPattern);
125806             },
125807
125808             "Object": function () {
125809                 var attr, isMatched = false, i;
125810
125811                 if (typeOfObj !== typeOfPattern) {
125812                     if ((obj === null) || (obj === undefined)) {
125813                         return false;
125814                     }
125815                     if (!("_derived" in pattern)) {
125816                         return false;
125817                     }
125818                     return false;
125819                 }
125820
125821                 if (!isConstructed(obj)) {
125822                     return false;
125823                 }
125824
125825                 for (attr in pattern) {
125826                     switch (attr) {
125827                     case "_optional":
125828                     case "_constructor":
125829                         break;
125830
125831                     case "_derived":
125832                         for (i in pattern._derived) {
125833                             isMatched = _self(pattern._derived[i]).match(obj);
125834                             if (isMatched)
125835                                 break;
125836                         }
125837                         break;
125838
125839                     default:
125840                         if (pattern._optional && pattern._optional[attr]) {
125841                             isMatched = ((obj[attr] === null) ||
125842                                     (obj[attr] === undefined) ||
125843                                     _self(pattern[attr]).match(obj[attr]));
125844                         } else {
125845                             isMatched = (obj[attr] !== undefined) &&
125846                                     _self(pattern[attr]).match(obj[attr]);
125847                         }
125848                         break;
125849                     }
125850
125851                     if (!isMatched)
125852                         break;
125853                 }
125854
125855                 /*// Check if verbose attributes are present
125856                 if (isMatched) {
125857                     for (attr in obj) {
125858                         if (pattern[attr] === undefined) {
125859                             isMatched = false;
125860                             break;
125861                         }
125862                     }
125863                 }*/
125864
125865                 return isMatched;
125866             },
125867
125868             "Union": function () {
125869                 var isMatched, i;
125870
125871                 for (i in pattern) {
125872                     isMatched = _self(pattern[i]).match(obj);
125873                     if (isMatched)
125874                         break;
125875                 }
125876
125877                 return isMatched;
125878             },
125879
125880             "any": function () {
125881                 return true;
125882             },
125883
125884             "boolean": function () {
125885                 return (typeOfObj === typeOfPattern);
125886             },
125887
125888             "byte": function () {
125889                 return (obj === toInt8(obj));
125890             },
125891
125892             "dictionary": function () {
125893                 var attr, isMatched = true;
125894
125895                 if (typeOfObj !== "Object") {
125896                     return false;
125897                 }
125898
125899                 for (attr in pattern) {
125900                     switch (attr) {
125901                     case "_dictionary":
125902                         if (pattern._dictionary !== null) {
125903                             isMatched = _self(pattern._dictionary).match(obj);
125904                             if (!isMatched)
125905                                 break;
125906                         }
125907                         break;
125908
125909                     default:
125910                         if ((attr in obj) && (obj[attr] !== null) &&
125911                                 (obj[attr] !== undefined)) {
125912                             isMatched = _self(pattern[attr]).match(obj[attr]);
125913                             if (!isMatched)
125914                                 break;
125915                         }
125916                         break;
125917                     }
125918                 }
125919
125920                 return isMatched;
125921             },
125922
125923             "enum": function () {
125924                 for (var i in pattern) {
125925                     if (obj === pattern[i]) {
125926                         return true;
125927                     }
125928                 }
125929
125930                 return false;
125931             },
125932
125933             "float": function () {
125934                 return (typeOfObj === "Number");
125935             },
125936
125937             "long": function () {
125938                 return (obj === toInt32(obj));
125939             },
125940
125941             "long long": function () {
125942                 return (obj === toInt64(obj));
125943             },
125944
125945             "octet": function () {
125946                 return (obj === toUInt8(obj));
125947             },
125948
125949             "short": function () {
125950                 return (obj === toInt16(obj));
125951             },
125952
125953             "unsigned long": function () {
125954                 return (obj === toUInt32(obj));
125955             },
125956
125957             "unsigned long long": function () {
125958                 return (obj === toUInt64(obj));
125959             },
125960
125961             "unsigned short": function () {
125962                 return (obj === toUInt16(obj));
125963             },
125964
125965             "Arguments": function () {
125966                 return true;
125967             },
125968
125969             "": function () {
125970                 return _self(t[pattern]).match(obj);
125971             }
125972         };
125973
125974         return typeMap[typeOfPattern]();
125975     }
125976
125977     typeOfPattern = getType(pattern, true);
125978
125979     typeCoerce = {
125980         cast:  cast,
125981         copy:  copy,
125982         match: match
125983     };
125984
125985     return typeCoerce;
125986 };
125987
125988 module.exports = _self;
125989
125990 });
125991 define('ripple/platform/ivi/3.0/typecast', function (require, exports, module) {
125992 /*
125993  *  Copyright 2013 Intel Corporation.
125994  *
125995  * Licensed under the Apache License, Version 2.0 (the "License");
125996  * you may not use this file except in compliance with the License.
125997  * You may obtain a copy of the License at
125998  *
125999  * http://www.apache.org/licenses/LICENSE-2.0
126000  *
126001  * Unless required by applicable law or agreed to in writing, software
126002  * distributed under the License is distributed on an "AS IS" BASIS,
126003  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126004  * See the License for the specific language governing permissions and
126005  * limitations under the License.
126006  */
126007
126008 var typedef = require('ripple/platform/ivi/3.0/typedef'),
126009     errorcode = require('ripple/platform/ivi/3.0/errorcode'),
126010     WebAPIException = require('ripple/platform/ivi/3.0/WebAPIException'),
126011     TypeCoerce = require('ripple/platform/ivi/3.0/typecoerce'),
126012     _self = {};
126013
126014 function _cast(pattern, obj, isDuplicate) {
126015     var tc, tcFunc;
126016
126017     if (pattern === null)
126018         return;
126019
126020     tc = new TypeCoerce(pattern);
126021     tcFunc = isDuplicate ? tc.copy : tc.cast;
126022
126023     if ((obj = tcFunc(obj)) === null) {
126024         throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
126025     }
126026
126027     return obj;
126028 }
126029
126030 function _castType(pattern) {
126031     /*
126032      * Type cast for each known type. The function name is the exact name of the
126033      * corresponding type.
126034      *
126035      * obj
126036      *    Variable to be casted
126037      *
126038      * aux
126039      *    Auxiliary descriptor of obj. It can be any one or combination of below
126040      *    strings, or ignored in most cases.
126041      *
126042      *    "?"     Nullable types
126043      *    "[]"    Array
126044      *    "+"     Deep copy
126045      *
126046      * Return
126047      *    Casted or duplicated object.
126048      */
126049
126050     return function (obj, aux) {
126051         var type, isNullable, isDuplicate;
126052
126053         aux = aux ? String(aux) : "";
126054         type = (aux.indexOf("[]") !== -1) ? [pattern] : pattern;
126055         isNullable = (aux.indexOf("?") !== -1);
126056         isDuplicate = (aux.indexOf("+") !== -1);
126057
126058         if (isNullable && ((obj === null) || (obj === undefined))) {
126059             return obj;
126060         }
126061
126062         return _cast(type, obj, isDuplicate);
126063     };
126064 }
126065
126066 function _castConstructor(name) {
126067     var constructors, hook, vtc, isOverloaded, castConstructor;
126068
126069     /*
126070      * Type cast for constructor. The function name is the exact name of the
126071      * object type.
126072      *
126073      * argv
126074      *    arguments. The keyword 'arguments' will always be passed in.
126075      */
126076
126077     function castUnique(argv) {
126078         _cast(constructors, argv, false);
126079     }
126080
126081     /*
126082      * Type cast for overloaded constructors. The function name is the exact
126083      * name of the object type.
126084      *
126085      * argv
126086      *    arguments. The keyword 'arguments' will always be passed in.
126087      *
126088      * scope
126089      *    'this' of the original constructor.
126090      *
126091      * voc
126092      *    Array of overloaded constructors callback
126093      */
126094
126095     function castOverload(argv, scope, voc) {
126096         var iOverload;
126097
126098         if (!vtc) {
126099             vtc = [];
126100             constructors.forEach(function (c) {
126101                 vtc.push((c === null) ? null : new TypeCoerce(c));
126102             });
126103         }
126104
126105         vtc.some(function (tc, index) {
126106             if (tc && (tc.cast(argv) === null))
126107                 return false;
126108
126109             iOverload = index;
126110             return true;
126111         });
126112
126113         if (iOverload === undefined) {
126114             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR);
126115         }
126116
126117         return (voc && voc[iOverload].apply(scope, argv));
126118     }
126119
126120     constructors = typedef.constructor[name];
126121
126122     if (name in _self) {
126123         hook = _self[name];
126124     }
126125
126126     isOverloaded = (Object.prototype.toString.call(constructors) ===
126127             "[object Array]");
126128     castConstructor = isOverloaded ? castOverload : castUnique;
126129
126130     return function (argv, scope) {
126131         if (Object.prototype.toString.call(argv) !== "[object Arguments]") {
126132             return (hook && hook.apply(this, arguments));
126133         }
126134
126135         if (!(scope instanceof argv.callee)) {
126136             throw new WebAPIException(errorcode.TYPE_MISMATCH_ERR, null, "TypeError");
126137         }
126138
126139         castConstructor.apply(this, arguments);
126140     };
126141 }
126142
126143 function _castInterface(name) {
126144     var interface, hook;
126145
126146     interface = typedef.interface[name];
126147
126148     if (name in _self) {
126149         hook = _self[name];
126150     }
126151
126152     /*
126153      * Type cast for each known method of interface. The function name is the
126154      * exact name of the corresponding interface.
126155      *
126156      * method
126157      *    String of method name
126158      *
126159      * argv
126160      *    arguments. The keyword 'arguments' will always be passed in.
126161      *
126162      * isDuplicate
126163      *    A boolean value to indicate whether arguments will be copied or not.
126164      */
126165
126166     return function (method, argv, isDuplicate) {
126167         if ((typeof method !== "string") || (typeof argv !== "object")) {
126168             return (hook && hook.apply(this, arguments));
126169         }
126170
126171         _cast(interface[method], argv, isDuplicate);
126172     };
126173 }
126174
126175 (function () {
126176     var i;
126177
126178     for (i in typedef) {
126179         _self[i] = _castType(typedef[i]);
126180     }
126181
126182     for (i in typedef.constructor) {
126183         _self[i] = _castConstructor(i);
126184         typedef[i]._constructor = i;
126185     }
126186
126187     for (i in typedef.interface) {
126188         _self[i] = _castInterface(i);
126189     }
126190 }());
126191
126192 module.exports = _self;
126193
126194 });
126195 define('ripple/platform/spec', function (require, exports, module) {
126196 /*
126197  *  Copyright 2011 Research In Motion Limited.
126198  *
126199  * Licensed under the Apache License, Version 2.0 (the "License");
126200  * you may not use this file except in compliance with the License.
126201  * You may obtain a copy of the License at
126202  *
126203  * http://www.apache.org/licenses/LICENSE-2.0
126204  *
126205  * Unless required by applicable law or agreed to in writing, software
126206  * distributed under the License is distributed on an "AS IS" BASIS,
126207  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126208  * See the License for the specific language governing permissions and
126209  * limitations under the License.
126210  */
126211 module.exports = {
126212     //"phonegap": {"1.0.0": require('ripple/platform/phonegap/1.0.0/spec')},
126213     "tizen": {"2.0": require('ripple/platform/tizen/2.0/spec')},
126214     "ivi": {"3.0": require('ripple/platform/ivi/3.0/spec')},
126215     //"cordova": {"2.0.0": require('ripple/platform/cordova/2.0.0/spec')},
126216     //"webworks.bb10": {"1.0.0": require('ripple/platform/webworks.bb10/1.0.0/spec')},
126217     //"webworks.handset": {"2.0.0": require('ripple/platform/webworks.handset/2.0.0/spec')},
126218     //"webworks.tablet": {"2.0.0": require('ripple/platform/webworks.tablet/2.0.0/spec')},
126219     //"web": {"default": require('ripple/platform/web/default/spec')},
126220
126221     "get": function (name, version) {
126222         var platform = module.exports[name] || {};
126223         return (platform[version] || platform[Object.keys(platform)[0]]);
126224     }
126225 };
126226
126227 });
126228 define('ripple/platform/builder', function (require, exports, module) {
126229 /*
126230  *  Copyright 2011 Research In Motion Limited.
126231  *
126232  * Licensed under the Apache License, Version 2.0 (the "License");
126233  * you may not use this file except in compliance with the License.
126234  * You may obtain a copy of the License at
126235  *
126236  * http://www.apache.org/licenses/LICENSE-2.0
126237  *
126238  * Unless required by applicable law or agreed to in writing, software
126239  * distributed under the License is distributed on an "AS IS" BASIS,
126240  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126241  * See the License for the specific language governing permissions and
126242  * limitations under the License.
126243  */
126244
126245 var utils = require('ripple/utils'),
126246     app = require('ripple/app');
126247
126248 function _objectFactory(context, objects/*, allowed*/) {
126249     utils.forEach(objects, function (obj, key) {
126250         var result = {}, objFeatures = {}, rst, f, widgetFeatures;
126251
126252 //        if (allowed(obj)) {
126253         result = obj.path ? require('ripple/platform/' + obj.path) : {};
126254         if (typeof result === "function" && obj.handleSubfeatures && obj.handleSubfeatures === true) {
126255             rst = new result();
126256             if (obj.feature) {
126257                 objFeatures = obj.feature.split('|');
126258                 if (rst.handleSubFeatures) {
126259                     widgetFeatures = app.getInfo().features; // features in config.xml
126260                     f = {};
126261                     utils.forEach(objFeatures, function (o) {
126262                         if (widgetFeatures && !!widgetFeatures[o]) {
126263                             f[widgetFeatures[o].id] = widgetFeatures[o];
126264                         }
126265                     });
126266                     rst.handleSubFeatures(f);
126267                     delete rst.handleSubFeatures;
126268                 }
126269             }
126270             result = rst;
126271         }
126272 //        }
126273
126274         if (obj.children) {
126275             _objectFactory(result, obj.children/*, allowed*/);
126276         }
126277
126278         context.__defineGetter__(key, function () {
126279             return result;
126280         });
126281         // inject into the context if it is allowed or it has children that were allowed
126282 //        if (allowed(obj) || utils.count(result)) {
126283 //        context[key] = result;
126284 //        }
126285 //        else {
126286 //            if (context.hasOwnProperty(key))
126287 //                console.log("delete " + key);
126288 //            delete context[key];
126289 //        }
126290     });
126291 }
126292
126293 module.exports = {
126294     build: function (objects) {
126295         return {
126296             into: function (sandbox) {
126297 /*                var features = utils.copy(app.getInfo().features);
126298                     allowed = function (obj) {
126299                         var contains = function (requirements) {
126300                             return requirements.split('|').some(function (feature) {
126301                                 return !!features[feature];
126302                             });
126303                         };
126304                         //object is allowed if:
126305                         // 1. it has no feature requirement
126306                         // 2. the config file doesn't exist (features collection is null)
126307                         // 3. the feature exists in the defined features
126308                         return !obj.feature || !features || (features && contains(obj.feature));
126309                     };
126310 */
126311
126312                 _objectFactory(sandbox, objects/*, allowed*/);
126313             }
126314         };
126315     }
126316 };
126317
126318 });
126319 define('ripple/platform/w3c/1.0/Rotation', function (require, exports, module) {
126320 module.exports = function (alpha, beta, gamma) {
126321     return {
126322         alpha: alpha || 0,    //Rotation about the 'z' axis expressed in degrees [0, 360].    (Number)
126323         beta: beta || 0,      //Rotation about the 'x' axis expressed in degrees [-180, 180]. (Number)
126324         gamma: gamma || 0     //Rotation about the 'y' axis expressed in degrees [-90, 90].   (Number)
126325     };
126326 };
126327
126328 });
126329 define('ripple/platform/w3c/1.0/navigator', function (require, exports, module) {
126330 /*
126331  *  Copyright 2011 Research In Motion Limited.
126332  *
126333  * Licensed under the Apache License, Version 2.0 (the "License");
126334  * you may not use this file except in compliance with the License.
126335  * You may obtain a copy of the License at
126336  *
126337  * http://www.apache.org/licenses/LICENSE-2.0
126338  *
126339  * Unless required by applicable law or agreed to in writing, software
126340  * distributed under the License is distributed on an "AS IS" BASIS,
126341  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126342  * See the License for the specific language governing permissions and
126343  * limitations under the License.
126344  */
126345 var _original = window.navigator,
126346     utils = require('ripple/utils'),
126347     devices = require('ripple/devices'),
126348     constants = require('ripple/constants'),
126349     _self = {};
126350
126351 (function () {
126352     var key,
126353         nav = window.navigator;
126354
126355     function _handle(obj, key) {
126356         return typeof obj[key] !== "function" ? obj[key] : function () {
126357             return obj[key].apply(obj, Array.prototype.slice.call(arguments));
126358         };
126359     }
126360
126361     for (key in nav) {
126362         _self[key] = _handle(nav, key);
126363     }
126364 }());
126365
126366 _self.__defineGetter__('userAgent', function () {
126367     var currentUserAgent = devices.getCurrentDevice().userAgent;
126368
126369     return currentUserAgent === constants.COMMON.USER_AGENT_DEFAULT ?
126370         _original.userAgent : currentUserAgent;
126371 });
126372
126373 module.exports = _self;
126374
126375 });
126376 define('ripple/platform/w3c/1.0/SensorConnection', function (require, exports, module) {
126377 /*
126378  *  Copyright 2012 Intel Corporation.
126379  *
126380  * Licensed under the Apache License, Version 2.0 (the "License");
126381  * you may not use this file except in compliance with the License.
126382  * You may obtain a copy of the License at
126383  *
126384  * http://www.apache.org/licenses/LICENSE-2.0
126385  *
126386  * Unless required by applicable law or agreed to in writing, software
126387  * distributed under the License is distributed on an "AS IS" BASIS,
126388  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126389  * See the License for the specific language governing permissions and
126390  * limitations under the License.
126391  */
126392
126393 var utils = require('ripple/utils'),
126394     platform = require('ripple/platform'),
126395     event = require('ripple/event'),
126396     sensorSettings = require('ripple/sensorSettings'),
126397     accelerometer = require('ripple/accelerometer'),
126398     exception = require('ripple/exception'),
126399
126400     _permission = true,
126401     _self;
126402
126403 function ErrorMsg() {
126404     this.__defineGetter__("UNKNOWN_ERROR", function () {
126405         return "An unknown error has occurred.";
126406     });
126407
126408     this.__defineGetter__("TYPE_MISMATCH_ERROR", function () {
126409         return "The object type is incompatible with the expected type.";
126410     });
126411
126412     this.__defineGetter__("INVALID_VALUES_ERROR", function () {
126413         return "The content of an object does not contain valid values.";
126414     });
126415
126416     this.__defineGetter__("ILLEGAL_STATE", function () {
126417         return "The status of connection is illegal.";
126418     });
126419 }
126420
126421 // TODO: Should be replaced by a global object in tizen 1.0
126422 function ErrorCode() {
126423     this.__defineGetter__("UNKNOWN_ERR", function () {
126424         return 0;
126425     });
126426
126427     this.__defineGetter__("INVALID_VALUES_ERROR", function () {
126428         return 1;
126429     });
126430
126431     this.__defineGetter__("TYPE_MISMATCH_ERROR", function () {
126432         return 2;
126433     });
126434
126435     this.__defineGetter__("ILLEGAL_STATE", function () {
126436         return 3;
126437     });
126438 }
126439
126440 function SensorError(code, msg) {
126441     this.__defineGetter__("message", function () {
126442         return msg;
126443     });
126444     this.__defineGetter__("code", function () {
126445         return code;
126446     });
126447
126448     this.PERMISSION_DENIED = -100;
126449 }
126450
126451 function Event() {
126452     var _self = {
126453         CAPTURING_PHASE: 1,
126454         AT_TARGET:  2,
126455         BUBBLING_PHASE: 3,
126456
126457         type: '',
126458         target: null, //new EventTarget(),
126459         currentTarget: null, //new EventTarget(),
126460         eventPhase: 0,
126461         bubbles: false,
126462         cancelable: false,
126463         timeStamp: 0
126464     };
126465         
126466     this.__defineGetter__("type", function () {
126467         return _self.type;
126468     });
126469
126470     this.__defineGetter__("target", function () {
126471         return _self.target;
126472     });
126473
126474     this.__defineGetter__("currentTarget", function () {
126475         return _self.currentTarget;
126476     });
126477
126478     this.__defineGetter__("eventPhase", function () {
126479         return _self.eventPhase;
126480     });    
126481
126482     this.__defineGetter__("bubbles", function () {
126483         return _self.bubbles;
126484     });
126485
126486     this.__defineGetter__("cancelable", function () {
126487         return _self.cancelable;
126488     });
126489     
126490     this.__defineGetter__("timeStamp", function () {
126491         return _self.timeStamp;
126492     });
126493
126494     this.stopPropagation = function () {};
126495
126496     this.preventDefault = function () {};
126497
126498     this.initEvent = function (eventTypeArg, canBubbleArg, cancelableArg) {
126499         _self.type = eventTypeArg;
126500         _self.bubbles = canBubbleArg;
126501         _self.cancelable = cancelableArg;
126502     };
126503
126504     return _self;
126505 }
126506
126507 function SensorDataEvent() {
126508     var _self = {
126509         data: 0,
126510         accuracy: 0,
126511         timestamp: 0,
126512         reason: ''
126513     };
126514
126515     // This type of event inherit from Event
126516     Event.call(this);
126517
126518     this.__defineGetter__("data", function () {
126519         return _self.data;
126520     });
126521
126522     this.__defineGetter__("accuracy", function () {
126523         return _self.accuracy;
126524     });
126525
126526     this.__defineGetter__("timestamp", function () {
126527         return _self.timestamp;
126528     });
126529
126530     this.__defineGetter__("reason", function () {
126531         return _self.reason;
126532     });
126533
126534     this.initSensorDataEvent = function (type, bubbles, cancelable, reason, timestamp, accuracy, data) {
126535         this.initEvent(type, bubbles, cancelable);
126536
126537         _self.reason = reason;
126538         _self.timestamp = timestamp;
126539         _self.accuracy = accuracy;
126540         
126541         // If the data has only one part, just return the value, not the data object    
126542         if (utils.count(data) === 1) {
126543             utils.forEach(data, function (section, key) {
126544                 _self.data = data[key];
126545             });
126546         }
126547         else {
126548             _self.data = utils.copy(data);
126549         }
126550     };
126551 }
126552
126553 // As only one sensor will be used during the simulation with a SensorConnection object,
126554 // we can get that sensor object first and then the following read or write operations will be simplified
126555 function _getSensorObj(type, name) {
126556     var settings = platform.current().sensor, _sensor;
126557
126558     utils.forEach(settings, function (settingSection, settingType) {
126559         if (settingSection.type === type) {
126560
126561             if (settingSection.name && settingSection.name !== name) {
126562                 return;
126563             }
126564
126565             _sensor = utils.copy(settingSection);
126566         }
126567     });
126568
126569     return _sensor;
126570 }
126571
126572 function _getAccelerometerData(dataType) {
126573     var accelerometerData, data = {};
126574
126575     switch (dataType) {
126576     case "Accelerometer":
126577         accelerometerData = accelerometer.getInfo();
126578         data = {
126579             x: accelerometerData.acceleration.x,
126580             y: accelerometerData.acceleration.y,
126581             z: accelerometerData.acceleration.z
126582         };
126583         break;
126584     case "Rotation":
126585         accelerometerData = accelerometer.getInfo();
126586         data = {
126587             x: accelerometerData.orientation.alpha,
126588             y: accelerometerData.orientation.beta,
126589             z: accelerometerData.orientation.gamma
126590         };
126591         break;
126592     case "Orientation":
126593         accelerometerData = accelerometer.getInfo();
126594         data = {
126595             alpha: accelerometerData.orientation.alpha,
126596             beta: accelerometerData.orientation.beta,
126597             gamma: accelerometerData.orientation.gamma
126598         };
126599         break;
126600     default:
126601         break;
126602     }
126603
126604     return data;
126605 }
126606
126607 // The parameter of event callback is an object that contains the latest value, not the value itself,
126608 // so we need a function to create such object.
126609 function _getSensorData(sensorType, sensor, onerror) {
126610     var data = {}, value;
126611
126612     if (sensorType === "Accelerometer" || sensorType === "Rotation" || sensorType === "Orientation") {
126613         return _getAccelerometerData(sensorType);
126614     }
126615
126616     utils.forEach(sensor, function (sensorSection, key) {
126617         try {
126618             value = sensorSettings.retrieve(sensorType + "." + key);
126619         }
126620         catch (e) {
126621             if (onerror) {
126622                 onerror(e);
126623             }
126624         }
126625         
126626         if (value) {
126627             data[key] = value;
126628         }                    
126629     });
126630     
126631     return data;
126632 }
126633
126634 // As the event type in sensor.js file are named in this way, so we can get it with this function.
126635 function _getSensorEventTypes(type, sensor) {
126636     var types = [];
126637
126638     if (type === "Accelerometer" || type === "Rotation" || type === "Orientation") {
126639         return ["AccelerometerInfoChangedEvent"];
126640     }
126641
126642     utils.forEach(sensor, function (sensorSection, sensorType) {
126643         if (typeof sensorSection === "object") {
126644             types.push(type + "-" + sensorType + "Changed");
126645         }
126646     });
126647
126648     return types;
126649 }
126650
126651 function _onEventCallback(type, options, currentSensor, length, eventCallback, onerror) {
126652     return function (values) {
126653         var sensorEvent = new SensorDataEvent();
126654
126655         // Only the sensor that has one attribute could be compared with the threshold
126656         if (options && options.threshold && length === 1 && values[0] < options.threshold) {
126657             return;
126658         }
126659
126660         if (eventCallback) {
126661             sensorEvent.initSensorDataEvent(type, false, false, "read", (new Date()).getTime(), 
126662                                             currentSensor.resolution, _getSensorData(type, currentSensor, onerror));
126663
126664             eventCallback(sensorEvent);
126665         }
126666     };
126667 }
126668
126669 function _bind(name, obj) {
126670     var callback = null;
126671
126672     obj.__defineGetter__(name, function () {
126673         return callback;
126674     });
126675
126676     obj.__defineSetter__(name, function (cb) {
126677         callback = cb;
126678     });
126679
126680     return {
126681         get: function () {
126682             return callback;
126683         },
126684         set: function (value) {
126685             callback = value;
126686         },
126687         exec: function (arg) {
126688             return callback && callback(arg);
126689         },
126690         unbind: function (cb) {
126691             callback = cb === callback ? null : callback;
126692         }
126693     };
126694 }
126695
126696 function SensorConnection(type, name) {
126697     var _self,
126698         currentSensor = _getSensorObj(type, name),
126699         sensorEvent = new SensorDataEvent(),
126700         sensorEventTypes = _getSensorEventTypes(type, currentSensor),
126701         watches = [],
126702         _errorCode = new ErrorCode(),
126703         _errorMsg = new ErrorMsg(),
126704         sensorListener;
126705
126706     if (currentSensor) {
126707         _self = {
126708             sensor: {
126709                 resolution: currentSensor.resolution,
126710                 minDelay: currentSensor.minDelay,
126711                 range: currentSensor.range,
126712                 name: currentSensor.name,
126713                 type: currentSensor.type
126714             },
126715             status: "open",
126716             error: null,
126717             read: function () {
126718
126719                 if (_self.status !== "open" && _self.status !== "watching") {
126720                     exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
126721                     return;
126722                 }                
126723
126724                 setTimeout(function () {
126725                     if (sensorListener.get()) {
126726                         sensorEvent.initSensorDataEvent(type, false, false, "read", (new Date()).getTime(), 
126727                                                         currentSensor.resolution, _getSensorData(type, currentSensor, _self.onerror));
126728
126729                         sensorListener.exec(sensorEvent);
126730                     }
126731                 }, 1);  
126732
126733                 return;
126734             },
126735
126736             startWatch: function (options) {
126737                 var index, watchId, watchObj = {};
126738
126739                 if (_self.status !== "open") {
126740                     exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
126741                     return;
126742                 }
126743                     
126744                 if (typeof options !== "object") {
126745                     if (_self.onerror) {
126746                         _self.onerror(new SensorError(_errorCode.TYPE_MISMATCH_ERROR, _errorMsg.TYPE_MISMATCH_ERROR));
126747                     }
126748                 }
126749
126750                 setTimeout(function () {
126751                     watchId = (new Date()).getTime();   
126752
126753                     // As there will be many attributes for some sensor, each of them is needed to be watched.
126754                     for (index = 0; index < sensorEventTypes.length; index++) {
126755                         watchObj = {
126756                             eventType: sensorEventTypes[index],
126757                             onEvent: _onEventCallback(type, options, currentSensor, sensorEventTypes.length, sensorListener.get(), _self.onerror),
126758                         };
126759
126760                         watches.push(watchObj);
126761                         if (watchObj.eventType) {
126762                             event.on(watchObj.eventType, watchObj.onEvent);                                               
126763                         }
126764                     }
126765
126766                     
126767                     if (options && options.interval) {
126768                         watchObj.intervalId = setInterval(_onEventCallback(type, options, currentSensor, sensorEventTypes.length, sensorListener.get(), _self.onerror), 
126769                                                           options.interval);
126770                     }
126771
126772                     _self.status = "watching";
126773                     if (_self.onstatuschange) {
126774                         _self.onstatuschange();
126775                     }
126776                                                                                                         
126777                 }, 1);  
126778
126779                 return;
126780             },
126781
126782             endWatch: function () {
126783                 var index, watchObj;
126784
126785                 if (_self.status !== "watching") {
126786                     exception.raise(exception.types.Argument, "illegal state", new SensorError(_errorCode.ILLEGAL_STATE, _errorMsg.ILLEGAL_STATE));
126787                     return;
126788                 }
126789
126790                 for (index = 0; index < watches.length; index++) {
126791                     watchObj = watches[index];
126792
126793                     try {
126794                         event.deleteEventHandler(watchObj.eventType, watchObj.onEvent);  
126795                     }
126796                     catch (e) {
126797                         if (_self.onerror) {
126798                             _self.onerror(e);
126799                         }
126800                     }
126801
126802                     if (watchObj.intervalId) {
126803                         clearInterval(watchObj.intervalId);
126804                     }                
126805                 }
126806
126807                 watches = [];
126808
126809                 _self.status = "open";
126810                 if (_self.onstatuschange) {
126811                     _self.onstatuschange();
126812                 }
126813             },
126814
126815             // These functions are inherited from the EventTarget object
126816             addEventListener: function (eventType, callback, useCapture) {
126817                 var sensorEvent;
126818                 
126819                 if (eventType === "sensordata") {
126820                     sensorListener.set(callback);  
126821
126822                     event.on("sensordata", function (data) {
126823                         sensorEvent = new SensorDataEvent();        
126824                         sensorEvent.initSensorDataEvent("sensordata", false, false, "read", (new Date()).getTime(), 
126825                                                         currentSensor.resolution, _getSensorData(type, currentSensor, _self.onerror));           
126826
126827                         sensorListener.exec(sensorEvent);
126828                     });             
126829                 }               
126830             },
126831
126832             removeEventListener: function (eventType, callback) {
126833                 event.clear(eventType, callback);
126834                 sensorListener.unbind(callback);                                
126835             },
126836
126837             dispatchEvent: function (evt) {
126838                 event.trigger("sensordata", evt);
126839             }
126840         };
126841
126842         sensorListener = _bind("onsensordata", _self);
126843     }    
126844
126845     return _self;
126846 }
126847
126848 module.exports = function (option) {
126849  
126850     var connectionObj,
126851         _errorCode = new ErrorCode(),
126852         _errorMsg = new ErrorMsg();
126853
126854     if (option === null || option === undefined) {
126855         return null;
126856     }
126857
126858     // There are two ways to construct an object
126859     if (typeof option === "object") {
126860         if ((option.type === null || option.type === undefined) &&
126861             (option.name === null || option.name === undefined)) {
126862             // Spec: If none of the dictionary members are defined then raise an instantiation exception    
126863             exception.raise(exception.types.Argument, "type illegal", new SensorError(_errorCode.ILLEGAL_TYPE, _errorMsg.ILLEGAL_TYPE));             
126864         }
126865
126866         connectionObj = new SensorConnection(option.type, option.name);
126867     }
126868     else if (typeof option === "string") {
126869         connectionObj = new SensorConnection(option, option);
126870     }
126871
126872     return connectionObj;
126873 };
126874
126875 });
126876 define('ripple/platform/w3c/1.0/geolocation', function (require, exports, module) {
126877 /*
126878  *  Copyright 2011 Research In Motion Limited.
126879  *
126880  * Licensed under the Apache License, Version 2.0 (the "License");
126881  * you may not use this file except in compliance with the License.
126882  * You may obtain a copy of the License at
126883  *
126884  * http://www.apache.org/licenses/LICENSE-2.0
126885  *
126886  * Unless required by applicable law or agreed to in writing, software
126887  * distributed under the License is distributed on an "AS IS" BASIS,
126888  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126889  * See the License for the specific language governing permissions and
126890  * limitations under the License.
126891  */
126892 var geo = require('ripple/geo'),
126893     Position = require('ripple/platform/w3c/1.0/Position'),
126894     PositionError = require('ripple/platform/w3c/1.0/PositionError'),
126895     _watches = {},
126896     _self;
126897
126898 function createPosition() {
126899     var position = new Position(),
126900         positionInfo = geo.getPositionInfo();
126901
126902     position.coords.latitude = positionInfo.latitude;
126903     position.coords.longitude = positionInfo.longitude;
126904     position.coords.altitude = positionInfo.altitude;
126905     position.coords.altitudeAccuracy = positionInfo.altitudeAccuracy;
126906     position.coords.accuracy = positionInfo.accuracy;
126907     position.coords.heading = positionInfo.heading;
126908     position.coords.speed = positionInfo.speed;
126909     position.timestamp = positionInfo.timeStamp.getTime();
126910
126911     return position;
126912 }
126913
126914 _self = {
126915     getCurrentPosition: function (onSuccess, onError) {
126916         var delay = ((geo.delay || 0) * 1000) || 1,
126917             timeout = geo.timeout;
126918
126919         window.setTimeout(function () {
126920             if (timeout) {
126921                 var error = new PositionError();
126922                 error.code = PositionError.TIMEOUT;
126923                 error.message = "postion timed out";
126924
126925                 onError(error);
126926             }
126927             else {
126928                 // TODO: build facility to trigger onError() from emulator
126929                 // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
126930                 _self.lastPosition = createPosition();
126931                 onSuccess(_self.lastPosition);
126932             }
126933         }, delay);
126934     },
126935
126936     watchPosition: function (geolocationSuccess, geolocationError, geolocationOptions) {
126937         var watchId = (new Date()).getTime().toString(),
126938             watchObj = {},
126939             timeout;
126940
126941         if (geolocationOptions) {
126942             timeout = geolocationOptions.timeout || 10000;
126943
126944             watchObj = {
126945                 onSuccess: geolocationSuccess,
126946                 onError: geolocationError,
126947                 interval: timeout
126948             };
126949
126950             _watches[watchId] = watchObj;
126951
126952             _watches[watchId].intervalId = window.setInterval(function () {
126953                 _self.getCurrentPosition(_watches[watchId].onSuccess, _watches[watchId].onError);
126954             }, timeout);
126955
126956         }
126957         else {
126958             if (typeof geolocationError === "function") {
126959                 window.setTimeout(function () {
126960                     geolocationError();
126961                 }, 1);
126962             }
126963         }
126964
126965         return watchId;
126966     },
126967
126968     lastPosition: null,
126969
126970     clearWatch: function (watchId) {
126971         window.clearInterval(_watches[watchId].intervalId);
126972         delete _watches[watchId];
126973     }
126974 };
126975
126976 module.exports = _self;
126977
126978 });
126979 define('ripple/platform/w3c/1.0/Coordinates', function (require, exports, module) {
126980 /*
126981  *  Copyright 2011 Research In Motion Limited.
126982  *
126983  * Licensed under the Apache License, Version 2.0 (the "License");
126984  * you may not use this file except in compliance with the License.
126985  * You may obtain a copy of the License at
126986  *
126987  * http://www.apache.org/licenses/LICENSE-2.0
126988  *
126989  * Unless required by applicable law or agreed to in writing, software
126990  * distributed under the License is distributed on an "AS IS" BASIS,
126991  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126992  * See the License for the specific language governing permissions and
126993  * limitations under the License.
126994  */
126995 module.exports = function (latitude, longitude, altitude, accuracy, altitudeAccuracy, heading, speed) {
126996     return {
126997         latitude: latitude || 0,                    //Latitude in decimal degrees. (Number)
126998         longitude: longitude || 0,                  //Longitude in decimal degrees. (Number)
126999         altitude: altitude || 0,                    //Height of the position in meters above the ellipsoid. (Number)
127000         accuracy: accuracy || 0,                    //Accuracy level of the latitude and longitude coordinates in meters. (Number)
127001         altitudeAccuracy: altitudeAccuracy || 0,    //Accuracy level of the altitude coordinate in meters. (Number)
127002         heading: heading || 0,                      //Direction of travel, specified in degrees counting clockwise relative to the true north. (Number)
127003         speed: speed || 0                           //Current ground speed of the device, specified in meters per second. (Number)
127004     };
127005 };
127006
127007 });
127008 define('ripple/platform/w3c/1.0/Position', function (require, exports, module) {
127009 /*
127010  *  Copyright 2011 Research In Motion Limited.
127011  *
127012  * Licensed under the Apache License, Version 2.0 (the "License");
127013  * you may not use this file except in compliance with the License.
127014  * You may obtain a copy of the License at
127015  *
127016  * http://www.apache.org/licenses/LICENSE-2.0
127017  *
127018  * Unless required by applicable law or agreed to in writing, software
127019  * distributed under the License is distributed on an "AS IS" BASIS,
127020  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127021  * See the License for the specific language governing permissions and
127022  * limitations under the License.
127023  */
127024 var Coordinates = require('ripple/platform/w3c/1.0/Coordinates');
127025
127026 module.exports = function () {
127027     return {
127028         coords: new Coordinates(),
127029         timestamp: new Date().getTime()
127030     };
127031 };
127032
127033 });
127034 define('ripple/platform/w3c/1.0/Acceleration', function (require, exports, module) {
127035 module.exports = function (x, y, z) {
127036     return {
127037         x: x || 0,    //Acceleration in the 'x' expressed in m/s^2. (Number)
127038         y: y || 0,    //Acceleration in the 'y' expressed in m/s^2. (Number)
127039         z: z || 0     //Acceleration in the 'z' expressed in m/s^2. (Number)
127040     };
127041 };
127042
127043 });
127044 define('ripple/platform/w3c/1.0/PositionError', function (require, exports, module) {
127045 /*
127046  *  Copyright 2011 Research In Motion Limited.
127047  *
127048  * Licensed under the Apache License, Version 2.0 (the "License");
127049  * you may not use this file except in compliance with the License.
127050  * You may obtain a copy of the License at
127051  *
127052  * http://www.apache.org/licenses/LICENSE-2.0
127053  *
127054  * Unless required by applicable law or agreed to in writing, software
127055  * distributed under the License is distributed on an "AS IS" BASIS,
127056  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127057  * See the License for the specific language governing permissions and
127058  * limitations under the License.
127059  */
127060 var _self = function () {
127061     return {
127062         code: undefined,
127063         message: undefined
127064     };
127065 };
127066
127067 _self.PERMISSION_DENIED = "PERMISSION_DENIED";
127068 _self.POSITION_UNAVAILABLE = "POSITION_UNAVAILABLE";
127069 _self.TIMEOUT = "TIMEOUT";
127070
127071 module.exports = _self;
127072
127073 });
127074 define('ripple/platform/webworks.tablet/2.0.0/XMLHttpRequest', function (require, exports, module) {
127075 /*
127076  *  Copyright 2011 Research In Motion Limited.
127077  *
127078  * Licensed under the Apache License, Version 2.0 (the "License");
127079  * you may not use this file except in compliance with the License.
127080  * You may obtain a copy of the License at
127081  *
127082  * http://www.apache.org/licenses/LICENSE-2.0
127083  *
127084  * Unless required by applicable law or agreed to in writing, software
127085  * distributed under the License is distributed on an "AS IS" BASIS,
127086  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127087  * See the License for the specific language governing permissions and
127088  * limitations under the License.
127089  */
127090
127091 var xhr = require("ripple/platform/webworks.core/2.0.0/XMLHttpRequest");
127092 module.exports = xhr.create("ripple/platform/webworks.tablet/2.0.0/server");
127093
127094 });
127095 define('ripple/platform/webworks.tablet/2.0.0/spec', function (require, exports, module) {
127096 /*
127097  *  Copyright 2011 Research In Motion Limited.
127098  *
127099  * Licensed under the Apache License, Version 2.0 (the "License");
127100  * you may not use this file except in compliance with the License.
127101  * You may obtain a copy of the License at
127102  *
127103  * http://www.apache.org/licenses/LICENSE-2.0
127104  *
127105  * Unless required by applicable law or agreed to in writing, software
127106  * distributed under the License is distributed on an "AS IS" BASIS,
127107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127108  * See the License for the specific language governing permissions and
127109  * limitations under the License.
127110  */
127111 module.exports = {
127112
127113     id: "webworks.tablet",
127114     version: "2.0.0",
127115     name: "WebWorks-TabletOS",
127116
127117     persistencePrefix: "rim-tablet-",
127118
127119     ui: require('ripple/platform/webworks.tablet/2.0.0/spec/ui'),
127120     device: require('ripple/platform/webworks.tablet/2.0.0/spec/device'),
127121     config: require('ripple/platform/webworks.core/2.0.0/spec/config'),
127122     events: require('ripple/platform/webworks.tablet/2.0.0/spec/events'),
127123
127124     initialize: function () {},
127125
127126     objects: {
127127         XMLHttpRequest: {
127128             path: "webworks.tablet/2.0.0/XMLHttpRequest"
127129         },
127130         Coordinates: {
127131             path: "w3c/1.0/Coordinates"
127132         },
127133         Position: {
127134             path: "w3c/1.0/Position"
127135         },
127136         PositionError: {
127137             path: "w3c/1.0/PositionError"
127138         },
127139         navigator: {
127140             path: "w3c/1.0/navigator",
127141             children: {
127142                 geolocation: {
127143                     path: "w3c/1.0/geolocation"
127144                 }
127145             }
127146         },
127147         blackberry: {
127148             children: {
127149                 transport: {
127150                     path: "webworks.core/2.0.0/client/transport"
127151                 },
127152                 events: {
127153                     path: "webworks.core/2.0.0/client/events"
127154                 },
127155                 app: {
127156                     path: "webworks.tablet/2.0.0/client/app",
127157                     feature: "blackberry.app",
127158                     children: {
127159                         event: {
127160                             path: "webworks.tablet/2.0.0/client/appEvent",
127161                             feature: "blackberry.app.event"
127162                         }
127163                     }
127164                 },
127165                 invoke: {
127166                     path: "webworks.tablet/2.0.0/client/invoke",
127167                     feature: "blackberry.invoke",
127168                     children: {
127169                         BrowserArguments: {
127170                             path: "webworks.tablet/2.0.0/client/BrowserArguments",
127171                             feature: "blackberry.invoke.BrowserArguments"
127172                         },
127173                         CameraArguments: {
127174                             path: "webworks.tablet/2.0.0/client/CameraArguments",
127175                             feature: "blackberry.invoke.CameraArguments"
127176                         }
127177                     }
127178                 },
127179                 identity: {
127180                     path: "webworks.tablet/2.0.0/client/identity",
127181                     feature: "blackberry.identity"
127182                 },
127183                 system: {
127184                     path: "webworks.tablet/2.0.0/client/system",
127185                     children: {
127186                         event: {
127187                             path: "webworks.tablet/2.0.0/client/systemEvent"
127188                         }
127189                     }
127190                 },
127191                 ui: {
127192                     children: {
127193                         dialog: {
127194                             path: "webworks.core/2.0.0/client/dialog",
127195                             feature: "blackberry.ui.dialog"
127196                         }
127197                     }
127198                 },
127199                 utils: {
127200                     path: "webworks.core/2.0.0/client/utils",
127201                     feature: "blackberry.utils"
127202                 },
127203                 io: {
127204                     children: {
127205                         dir: {
127206                             path: "webworks.tablet/2.0.0/client/io/dir",
127207                             feature: "blackberry.io.dir"
127208                         },
127209                         file: {
127210                             path: "webworks.core/2.0.0/client/io/file",
127211                             feature: "blackberry.io.file"
127212                         }
127213                     }
127214                 }
127215             }
127216         }
127217     }
127218 };
127219
127220 });
127221 define('ripple/platform/webworks.tablet/2.0.0/client/CameraArguments', function (require, exports, module) {
127222 /*
127223  *  Copyright 2011 Research In Motion Limited.
127224  *
127225  * Licensed under the Apache License, Version 2.0 (the "License");
127226  * you may not use this file except in compliance with the License.
127227  * You may obtain a copy of the License at
127228  *
127229  * http://www.apache.org/licenses/LICENSE-2.0
127230  *
127231  * Unless required by applicable law or agreed to in writing, software
127232  * distributed under the License is distributed on an "AS IS" BASIS,
127233  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127234  * See the License for the specific language governing permissions and
127235  * limitations under the License.
127236  */
127237 //blackberry.invoke.CameraArguments ( )
127238 var _self = function () {
127239     return {
127240         //readwrite  property  Number   view
127241         view: 0
127242     };
127243 };
127244
127245 //const Number  VIEW_CAMERA  = 0
127246 _self.__defineGetter__("VIEW_CAMERA", function () {
127247     return 0;
127248 });
127249 //const Number  VIEW_RECORDER  = 1
127250 _self.__defineGetter__("VIEW_RECORDER", function () {
127251     return 1;
127252 });
127253
127254 module.exports = _self;
127255
127256 });
127257 define('ripple/platform/webworks.tablet/2.0.0/client/io/dir', function (require, exports, module) {
127258 /*
127259  * Copyright 2011 Research In Motion Limited.
127260  *
127261  * Licensed under the Apache License, Version 2.0 (the "License");
127262  * you may not use this file except in compliance with the License.
127263  * You may obtain a copy of the License at
127264  *
127265  *     http://www.apache.org/licenses/LICENSE-2.0
127266  *
127267  * Unless required by applicable law or agreed to in writing, software
127268  * distributed under the License is distributed on an "AS IS" BASIS,
127269  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127270  * See the License for the specific language governing permissions and
127271  * limitations under the License.
127272  */
127273 var dir = require('ripple/platform/webworks.core/2.0.0/client/io/dir'),
127274     utils = require('ripple/utils'),
127275     _self = {};
127276
127277 utils.mixin({
127278     appDirs: {
127279         "app": {
127280             "storage" : {
127281                 "path" : "file:///accounts/1000/appdata/emulatedapp/data"
127282             }
127283         },
127284         "shared": {
127285             "bookmarks": {
127286                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/bookmarks"
127287             },
127288             "books": {
127289                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/books"
127290             },
127291             "camera": {
127292                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/camera"
127293             },
127294             "documents": {
127295                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/documents"
127296             },
127297             "downloads": {
127298                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/downloads"
127299             },
127300             "misc": {
127301                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/misc"
127302             },
127303             "music": {
127304                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/music"
127305             },
127306             "photos": {
127307                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/photos"
127308             },
127309             "print": {
127310                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/print"
127311             },
127312             "videos": {
127313                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/videos"
127314             },
127315             "voice": {
127316                 "path" : "file:///accounts/1000/appdata/emulatedapp/shared/voice"
127317             }
127318         }
127319     }
127320 }, _self);
127321
127322 utils.mixin(dir, _self);
127323
127324 module.exports = _self;
127325
127326 });
127327 define('ripple/platform/webworks.tablet/2.0.0/client/BrowserArguments', function (require, exports, module) {
127328 /*
127329  *  Copyright 2011 Research In Motion Limited.
127330  *
127331  * Licensed under the Apache License, Version 2.0 (the "License");
127332  * you may not use this file except in compliance with the License.
127333  * You may obtain a copy of the License at
127334  *
127335  * http://www.apache.org/licenses/LICENSE-2.0
127336  *
127337  * Unless required by applicable law or agreed to in writing, software
127338  * distributed under the License is distributed on an "AS IS" BASIS,
127339  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127340  * See the License for the specific language governing permissions and
127341  * limitations under the License.
127342  */
127343 //blackberry.invoke.BrowserArguments ( url : String ,  [transport : blackberry.identity.Transport ] )
127344 module.exports = function (url, transport) {
127345     return {
127346         url: url
127347     };
127348 };
127349
127350 });
127351 define('ripple/platform/webworks.tablet/2.0.0/client/identity', function (require, exports, module) {
127352 /*
127353  *  Copyright 2011 Research In Motion Limited.
127354  *
127355  * Licensed under the Apache License, Version 2.0 (the "License");
127356  * you may not use this file except in compliance with the License.
127357  * You may obtain a copy of the License at
127358  *
127359  * http://www.apache.org/licenses/LICENSE-2.0
127360  *
127361  * Unless required by applicable law or agreed to in writing, software
127362  * distributed under the License is distributed on an "AS IS" BASIS,
127363  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127364  * See the License for the specific language governing permissions and
127365  * limitations under the License.
127366  */
127367 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
127368     _uri = "blackberry/identity/",
127369     _self = {};
127370
127371 _self.__defineGetter__("PIN", function () {
127372     return transport.call(_uri + "PIN");
127373 });
127374
127375 module.exports = _self;
127376
127377 });
127378 define('ripple/platform/webworks.tablet/2.0.0/client/system', function (require, exports, module) {
127379 /*
127380  *  Copyright 2011 Research In Motion Limited.
127381  *
127382  * Licensed under the Apache License, Version 2.0 (the "License");
127383  * you may not use this file except in compliance with the License.
127384  * You may obtain a copy of the License at
127385  *
127386  * http://www.apache.org/licenses/LICENSE-2.0
127387  *
127388  * Unless required by applicable law or agreed to in writing, software
127389  * distributed under the License is distributed on an "AS IS" BASIS,
127390  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127391  * See the License for the specific language governing permissions and
127392  * limitations under the License.
127393  */
127394 var utils = require('ripple/utils'),
127395     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
127396     system = require('ripple/platform/webworks.core/2.0.0/client/system'),
127397     _uri = "blackberry/system/";
127398
127399 system.__defineGetter__("scriptApiVersion", function () {
127400     return transport.call(_uri + "softwareVersion");
127401 });
127402
127403
127404 module.exports = system;
127405
127406 });
127407 define('ripple/platform/webworks.tablet/2.0.0/client/app', function (require, exports, module) {
127408 /*
127409  *  Copyright 2011 Research In Motion Limited.
127410  *
127411  * Licensed under the Apache License, Version 2.0 (the "License");
127412  * you may not use this file except in compliance with the License.
127413  * You may obtain a copy of the License at
127414  *
127415  * http://www.apache.org/licenses/LICENSE-2.0
127416  *
127417  * Unless required by applicable law or agreed to in writing, software
127418  * distributed under the License is distributed on an "AS IS" BASIS,
127419  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127420  * See the License for the specific language governing permissions and
127421  * limitations under the License.
127422  */
127423 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
127424     _uri = "blackberry/app/",
127425     _self;
127426
127427 _self = {
127428     exit: function () {
127429         transport.call(_uri + "exit", {async: true});
127430     }
127431 };
127432
127433 _self.__defineGetter__("author", function () {
127434     return transport.call(_uri + "author");
127435 });
127436
127437 _self.__defineGetter__("authorEmail", function () {
127438     return transport.call(_uri + "authorEmail");
127439 });
127440
127441 _self.__defineGetter__("authorURL", function () {
127442     return transport.call(_uri + "authorURL");
127443 });
127444
127445 _self.__defineGetter__("copyright", function () {
127446     return transport.call(_uri + "copyright");
127447 });
127448
127449 _self.__defineGetter__("description", function () {
127450     return transport.call(_uri + "description");
127451 });
127452
127453 _self.__defineGetter__("id", function () {
127454     return transport.call(_uri + "id");
127455 });
127456
127457 _self.__defineGetter__("license", function () {
127458     return transport.call(_uri + "license");
127459 });
127460
127461 _self.__defineGetter__("licenseURL", function () {
127462     return transport.call(_uri + "licenseURL");
127463 });
127464
127465 _self.__defineGetter__("name", function () {
127466     return transport.call(_uri + "name");
127467 });
127468
127469 _self.__defineGetter__("version", function () {
127470     return transport.call(_uri + "version");
127471 });
127472
127473 module.exports = _self;
127474
127475 });
127476 define('ripple/platform/webworks.tablet/2.0.0/client/invoke', function (require, exports, module) {
127477 /*\r
127478  *  Copyright 2011 Research In Motion Limited.\r
127479  *\r
127480  * Licensed under the Apache License, Version 2.0 (the "License");\r
127481  * you may not use this file except in compliance with the License.\r
127482  * You may obtain a copy of the License at\r
127483  *\r
127484  * http://www.apache.org/licenses/LICENSE-2.0\r
127485  *\r
127486  * Unless required by applicable law or agreed to in writing, software\r
127487  * distributed under the License is distributed on an "AS IS" BASIS,\r
127488  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
127489  * See the License for the specific language governing permissions and\r
127490  * limitations under the License.\r
127491  */\r
127492 var _uri = "blackberry/invoke/invoke",\r
127493     APP_TYPE = "appType",\r
127494     APP_URL_CAMERA = "camera://",\r
127495     APP_URL_CAMERA_VIDEO = "camera://video",\r
127496     APP_URL_MAP = "map://",\r
127497     APP_URL_MUSIC = "music://",\r
127498     APP_URL_PHOTOS = "photos://",\r
127499     APP_URL_VIDEOS = "videos://",\r
127500     APP_URL_APPWORLD = "appworld://",\r
127501     APP_URL_UPDATE = "update://",\r
127502     APP_TYPE_ERROR = "appType not supported",\r
127503     APP_BROWSER_ERROR = "Protocol specified in the url is not supported.",\r
127504     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
127505     _self;\r
127506 \r
127507 _self = {\r
127508     invoke: function (appType, args) {\r
127509         var get = {};\r
127510 \r
127511         switch (appType) {\r
127512 \r
127513         //Camera\r
127514         case 4:\r
127515             if (!args || args.view === 1) {\r
127516                 get.appType = APP_URL_CAMERA_VIDEO;\r
127517             } else {\r
127518                 get.appType = APP_URL_CAMERA;\r
127519             }\r
127520             break;\r
127521 \r
127522         //Maps\r
127523         case 5:\r
127524             get.appType = APP_URL_MAP;\r
127525             break;\r
127526 \r
127527         //Browser\r
127528         case 11:\r
127529 \r
127530             if (!args) {\r
127531                 get.appType = "http://";\r
127532             }\r
127533             else {\r
127534                 get.appType = args.url.split("://");\r
127535 \r
127536                 if (get.appType.length === 1) {\r
127537                     get.appType = "http://" + get.appType[0];\r
127538                 }\r
127539                 else if (get.appType.length === 2) {\r
127540                     if (get.appType[0].indexOf("http") !== 0) {\r
127541                         throw APP_BROWSER_ERROR;\r
127542                     }\r
127543                     else {\r
127544                         get.appType = args.url;\r
127545                     }\r
127546                 }\r
127547             }\r
127548             break;\r
127549 \r
127550         //Music\r
127551         case 13:\r
127552             get.appType = APP_URL_MUSIC;\r
127553             break;\r
127554 \r
127555         //Photos\r
127556         case 14:\r
127557             get.appType = APP_URL_PHOTOS;\r
127558             break;\r
127559 \r
127560         //Videos\r
127561         case 15:\r
127562             get.appType = APP_URL_VIDEOS;\r
127563             break;\r
127564 \r
127565         //AppWorld\r
127566         case 16:\r
127567             get.appType = APP_URL_APPWORLD;\r
127568             break;\r
127569 \r
127570         //Update\r
127571         case 17:\r
127572             get.appType = APP_URL_UPDATE;\r
127573             break;\r
127574 \r
127575         default:\r
127576             throw APP_TYPE_ERROR;\r
127577         }\r
127578 \r
127579         transport.call(_uri, {\r
127580             get: get,\r
127581             async: true\r
127582         });\r
127583     }\r
127584 };\r
127585 \r
127586 _self.__defineGetter__("APP_CAMERA", function () {\r
127587     return 4;\r
127588 });\r
127589 _self.__defineGetter__("APP_MAPS", function () {\r
127590     return 5;\r
127591 });\r
127592 _self.__defineGetter__("APP_BROWSER", function () {\r
127593     return 11;\r
127594 });\r
127595 _self.__defineGetter__("APP_MUSIC", function () {\r
127596     return 13;\r
127597 });\r
127598 _self.__defineGetter__("APP_PHOTOS", function () {\r
127599     return 14;\r
127600 });\r
127601 _self.__defineGetter__("APP_VIDEOS", function () {\r
127602     return 15;\r
127603 });\r
127604 _self.__defineGetter__("APP_APPWORLD", function () {\r
127605     return 16;\r
127606 });\r
127607 \r
127608 module.exports = _self;\r
127609
127610 });
127611 define('ripple/platform/webworks.tablet/2.0.0/client/systemEvent', function (require, exports, module) {
127612 /*
127613  *  Copyright 2011 Research In Motion Limited.
127614  *
127615  * Licensed under the Apache License, Version 2.0 (the "License");
127616  * you may not use this file except in compliance with the License.
127617  * You may obtain a copy of the License at
127618  *
127619  * http://www.apache.org/licenses/LICENSE-2.0
127620  *
127621  * Unless required by applicable law or agreed to in writing, software
127622  * distributed under the License is distributed on an "AS IS" BASIS,
127623  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127624  * See the License for the specific language governing permissions and
127625  * limitations under the License.
127626  */
127627 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
127628     api = "blackberry/system/event/";
127629
127630 function _poll(evt, handler) {
127631     transport.poll(api + evt, {}, function (data, response) {
127632         if (handler) {
127633             handler(data);
127634         }
127635         return !!handler;
127636     });
127637 }
127638
127639 module.exports = {
127640     deviceBatteryLevelChange: function (handler) {
127641         _poll("deviceBatteryLevelChange", handler);
127642     },
127643     deviceBatteryStateChange: function (handler) {
127644         _poll("deviceBatteryStateChange", handler);
127645     }
127646 };
127647
127648 });
127649 define('ripple/platform/webworks.tablet/2.0.0/client/appEvent', function (require, exports, module) {
127650 /*
127651  *  Copyright 2011 Research In Motion Limited.
127652  *
127653  * Licensed under the Apache License, Version 2.0 (the "License");
127654  * you may not use this file except in compliance with the License.
127655  * You may obtain a copy of the License at
127656  *
127657  * http://www.apache.org/licenses/LICENSE-2.0
127658  *
127659  * Unless required by applicable law or agreed to in writing, software
127660  * distributed under the License is distributed on an "AS IS" BASIS,
127661  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127662  * See the License for the specific language governing permissions and
127663  * limitations under the License.
127664  */
127665 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
127666     _callbacks = {},
127667     _self;
127668
127669 function _poll(evt, handler) {
127670     _callbacks[evt] = handler;
127671
127672     transport.poll("blackberry/app/event/" + evt, {}, function () {
127673         var func = _callbacks[evt];
127674
127675         if (func) {
127676             func();
127677         }
127678
127679         return !!func;
127680     });
127681 }
127682
127683 _self = {
127684     onBackground: function (handler) {
127685         _poll("onBackground", handler);
127686     },
127687
127688     onForeground: function (handler) {
127689         _poll("onForeground", handler);
127690     },
127691
127692     onSwipeDown: function (handler) {
127693         _poll("onSwipeDown", handler);
127694     },
127695
127696     onSwipeStart: function (handler) {
127697         _poll("onSwipeStart", handler);
127698     }
127699 };
127700
127701 module.exports = _self;
127702
127703 });
127704 define('ripple/platform/webworks.tablet/2.0.0/spec/device', function (require, exports, module) {
127705 /*
127706  *  Copyright 2011 Research In Motion Limited.
127707  *
127708  * Licensed under the Apache License, Version 2.0 (the "License");
127709  * you may not use this file except in compliance with the License.
127710  * You may obtain a copy of the License at
127711  *
127712  * http://www.apache.org/licenses/LICENSE-2.0
127713  *
127714  * Unless required by applicable law or agreed to in writing, software
127715  * distributed under the License is distributed on an "AS IS" BASIS,
127716  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127717  * See the License for the specific language governing permissions and
127718  * limitations under the License.
127719  */
127720 var event = require('ripple/event');
127721
127722 module.exports = {
127723     "transports": {
127724         "TCPCellular": {
127725             "name": "Cellular TCP",
127726             "control": {
127727                 "type": "checkbox",
127728                 "value": true
127729             }
127730         },
127731         "WAP": {
127732             "name": "WAP",
127733             "control": {
127734                 "type": "checkbox",
127735                 "value": false
127736             }
127737         },
127738         "WAP2": {
127739             "name": "WAP 2.0",
127740             "control": {
127741                 "type": "checkbox",
127742                 "value": false
127743             }
127744         },
127745         "MDS": {
127746             "name": "MDS",
127747             "control": {
127748                 "type": "checkbox",
127749                 "value": true
127750             }
127751         },
127752         "BISB": {
127753             "name": "BIS B",
127754             "control": {
127755                 "type": "checkbox",
127756                 "value": true
127757             }
127758         },
127759         "Unite": {
127760             "name": "Unite!",
127761             "control": {
127762                 "type": "checkbox",
127763                 "value": false
127764             }
127765         },
127766         "TCPWifi": {
127767             "name": "Wifi TCP",
127768             "control": {
127769                 "type": "checkbox",
127770                 "value": true
127771             }
127772         }
127773     },
127774     "identity": {
127775         "PIN": {
127776             "name": "PIN",
127777             "control": {
127778                 "type": "text",
127779                 "value": "43A8C489"
127780             }
127781         }
127782     },
127783     "battery": {
127784         "state": {
127785             "name": "Handset is Charging",
127786             "control": {
127787                 "type": "checkbox",
127788                 "value": true
127789             },
127790             "callback": function (setting) {
127791                 event.trigger("DeviceBatteryStateChanged", [setting]);
127792             }
127793         },
127794         "level":  {
127795             "name": "Charge Level (% remaining)",
127796             "control": {
127797                 "type": "select",
127798                 "value": 100
127799             },
127800             "options": (function () {
127801                 var i,
127802                     optionList = {};
127803
127804                 for (i = 0; i <= 100; i++) {
127805                     optionList[i] = i;
127806                 }
127807
127808                 return optionList;
127809             }()),
127810             "callback": function (setting) {
127811                 event.trigger("DeviceBatteryLevelChanged", [setting]);
127812             }
127813         }
127814     },
127815     "system": {
127816         "isMassStorageActive": {
127817             "name": "Mass Storage Is Connected",
127818             "control": {
127819                 "type": "checkbox",
127820                 "value": true
127821             }
127822         },
127823         "hasDataCoverage": {
127824             "name": "Has Data Coverage",
127825             "control": {
127826                 "type": "checkbox",
127827                 "value": true
127828             },
127829             "callback": function (setting) {
127830                 event.trigger("CoverageChange");
127831                 require('ripple/bus').send("network", setting);
127832             }
127833         },
127834         "lag": {
127835             "name": "Lag the network",
127836             "control": {
127837                 type: "checkbox",
127838                 value: false
127839             },
127840             "callback": function (setting) {
127841                 require('ripple/bus').send("lag", setting);
127842             }
127843         },
127844         "network": {
127845             "name": "Data Network",
127846             "control": {
127847                 "type": "select",
127848                 "value": "3GPP"
127849             },
127850             "options": {
127851                 "3GPP" : "3GPP",
127852                 "CDMA": "CDMA",
127853                 "iDEN": "iDEN",
127854                 "Wi-Fi": "Wi-Fi"
127855             },
127856             "callback": function (setting) {
127857                 event.trigger("CoverageChange");
127858             }
127859         }
127860     }
127861 };
127862
127863 });
127864 define('ripple/platform/webworks.tablet/2.0.0/spec/events', function (require, exports, module) {
127865 /*
127866  *  Copyright 2011 Research In Motion Limited.
127867  *
127868  * Licensed under the Apache License, Version 2.0 (the "License");
127869  * you may not use this file except in compliance with the License.
127870  * You may obtain a copy of the License at
127871  *
127872  * http://www.apache.org/licenses/LICENSE-2.0
127873  *
127874  * Unless required by applicable law or agreed to in writing, software
127875  * distributed under the License is distributed on an "AS IS" BASIS,
127876  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127877  * See the License for the specific language governing permissions and
127878  * limitations under the License.
127879  */
127880 var _self,
127881     utils = require('ripple/utils'),
127882     event = require('ripple/event'),
127883     events = require('ripple/platform/webworks.core/2.0.0/spec/events');
127884
127885 _self = {
127886     "app.event.onSwipeDown": {
127887         callback: function () {
127888             event.trigger("AppSwipeDown");
127889         }
127890     },
127891     "app.event.onSwipeStart": {
127892         callback: function () {
127893             event.trigger("AppSwipeStart");
127894         }
127895     }
127896 };
127897
127898 utils.mixin(events, _self);
127899
127900 module.exports = _self;
127901
127902 });
127903 define('ripple/platform/webworks.tablet/2.0.0/spec/ui', function (require, exports, module) {
127904 /*
127905  *  Copyright 2011 Research In Motion Limited.
127906  *
127907  * Licensed under the Apache License, Version 2.0 (the "License");
127908  * you may not use this file except in compliance with the License.
127909  * You may obtain a copy of the License at
127910  *
127911  * http://www.apache.org/licenses/LICENSE-2.0
127912  *
127913  * Unless required by applicable law or agreed to in writing, software
127914  * distributed under the License is distributed on an "AS IS" BASIS,
127915  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127916  * See the License for the specific language governing permissions and
127917  * limitations under the License.
127918  */
127919 module.exports = {
127920     plugins: [
127921         "accelerometer",
127922         "deviceSettings",
127923         "geoView",
127924         "platformEvents",
127925         "widgetConfig",
127926         "build"
127927     ]
127928 };
127929
127930 });
127931 define('ripple/platform/webworks.tablet/2.0.0/server', function (require, exports, module) {
127932 /*
127933  *  Copyright 2011 Research In Motion Limited.
127934  *
127935  * Licensed under the Apache License, Version 2.0 (the "License");
127936  * you may not use this file except in compliance with the License.
127937  * You may obtain a copy of the License at
127938  *
127939  * http://www.apache.org/licenses/LICENSE-2.0
127940  *
127941  * Unless required by applicable law or agreed to in writing, software
127942  * distributed under the License is distributed on an "AS IS" BASIS,
127943  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127944  * See the License for the specific language governing permissions and
127945  * limitations under the License.
127946  */
127947 var utils = require('ripple/utils'),
127948     platform = "ripple/platform/webworks.tablet/2.0.0/server/",
127949     core = "ripple/platform/webworks.core/2.0.0/server/",
127950     systemEvent = require(platform + 'systemEvent'),
127951     system = {};
127952
127953 // ugh, thanks to the spec...
127954 system.event = systemEvent;
127955 utils.mixin(require(core + "system"), system);
127956
127957 module.exports = {
127958     blackberry: {
127959         identity: require(platform + "identity"),
127960         app: require(platform + "app"),
127961         invoke: require(platform + "invoke"),
127962         system: system,
127963         ui: {
127964             dialog: require(core + "dialog")
127965         },
127966         io: {
127967             dir: require(core + "io/dir"),
127968             file: require(core + "io/file")
127969         }
127970     }
127971 };
127972
127973 });
127974 define('ripple/platform/webworks.tablet/2.0.0/server/identity', function (require, exports, module) {
127975 /*
127976  *  Copyright 2011 Research In Motion Limited.
127977  *
127978  * Licensed under the Apache License, Version 2.0 (the "License");
127979  * you may not use this file except in compliance with the License.
127980  * You may obtain a copy of the License at
127981  *
127982  * http://www.apache.org/licenses/LICENSE-2.0
127983  *
127984  * Unless required by applicable law or agreed to in writing, software
127985  * distributed under the License is distributed on an "AS IS" BASIS,
127986  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
127987  * See the License for the specific language governing permissions and
127988  * limitations under the License.
127989  */
127990 var deviceSettings = require('ripple/deviceSettings');
127991
127992 module.exports = {
127993     PIN: function () {
127994         return {code: 1, data: deviceSettings.retrieve("identity.PIN")};
127995     }
127996 };
127997
127998 });
127999 define('ripple/platform/webworks.tablet/2.0.0/server/app', function (require, exports, module) {
128000 /*
128001  *  Copyright 2011 Research In Motion Limited.
128002  *
128003  * Licensed under the Apache License, Version 2.0 (the "License");
128004  * you may not use this file except in compliance with the License.
128005  * You may obtain a copy of the License at
128006  *
128007  * http://www.apache.org/licenses/LICENSE-2.0
128008  *
128009  * Unless required by applicable law or agreed to in writing, software
128010  * distributed under the License is distributed on an "AS IS" BASIS,
128011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128012  * See the License for the specific language governing permissions and
128013  * limitations under the License.
128014  */
128015 var event = require('ripple/event'),
128016     app = require('ripple/app'),
128017     _self;
128018
128019 _self = {
128020     event: require('ripple/platform/webworks.tablet/2.0.0/server/appEvent'),
128021
128022     exit: function () {
128023         event.trigger("AppExit");
128024         return {code: 1};
128025     },
128026
128027     author: function () {
128028         return {code: 1, data: app.getInfo().author};
128029     },
128030
128031     authorEmail: function () {
128032         return {code: 1, data: app.getInfo().authorEmail};
128033     },
128034
128035     authorURL: function () {
128036         return {code: 1, data: app.getInfo().authorURL};
128037     },
128038
128039     copyright: function () {
128040         return {code: 1, data: app.getInfo().copyright};
128041     },
128042
128043     description: function () {
128044         return {code: 1, data: app.getInfo().description};
128045     },
128046
128047     id: function () {
128048         return {code: 1, data: app.getInfo().id};
128049     },
128050
128051     license: function () {
128052         return {code: 1, data: app.getInfo().license};
128053     },
128054
128055     licenseURL: function () {
128056         return {code: 1, data: app.getInfo().licenseURL};
128057     },
128058
128059     name: function () {
128060         return {code: 1, data: app.getInfo().name};
128061     },
128062
128063     version: function () {
128064         return {code: 1, data: app.getInfo().version};
128065     }
128066 };
128067
128068 module.exports = _self;
128069
128070 });
128071 define('ripple/platform/webworks.tablet/2.0.0/server/invoke', function (require, exports, module) {
128072 /*
128073  *  Copyright 2011 Research In Motion Limited.
128074  *
128075  * Licensed under the Apache License, Version 2.0 (the "License");
128076  * you may not use this file except in compliance with the License.
128077  * You may obtain a copy of the License at
128078  *
128079  * http://www.apache.org/licenses/LICENSE-2.0
128080  *
128081  * Unless required by applicable law or agreed to in writing, software
128082  * distributed under the License is distributed on an "AS IS" BASIS,
128083  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128084  * See the License for the specific language governing permissions and
128085  * limitations under the License.
128086  */
128087 var notifications = require('ripple/notifications'),
128088     constants = require('ripple/constants'),
128089     type = "normal",
128090     name = {
128091         "camera://": "Camera",
128092         "camera://video": "Video Camera",
128093         "map://": "Maps",
128094         "http://": "Browser",
128095         "music://": "Music",
128096         "photos://": "Photos",
128097         "videos://": "Videos",
128098         "appworld://": "App World",
128099         "update://": "Update"
128100     };
128101
128102 module.exports = {
128103     invoke: function (opts) {
128104         var app = name[opts.appType];
128105         if (app === undefined && opts.appType && opts.appType.match(/^http/i)) {
128106             app = "Browser";
128107         }
128108
128109         notifications.openNotification(type,
128110            "Requested to launch: " + app + " application.");
128111         return {code: 1};
128112     }
128113 };
128114
128115 });
128116 define('ripple/platform/webworks.tablet/2.0.0/server/systemEvent', function (require, exports, module) {
128117 /*
128118  *  Copyright 2011 Research In Motion Limited.
128119  *
128120  * Licensed under the Apache License, Version 2.0 (the "License");
128121  * you may not use this file except in compliance with the License.
128122  * You may obtain a copy of the License at
128123  *
128124  * http://www.apache.org/licenses/LICENSE-2.0
128125  *
128126  * Unless required by applicable law or agreed to in writing, software
128127  * distributed under the License is distributed on an "AS IS" BASIS,
128128  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128129  * See the License for the specific language governing permissions and
128130  * limitations under the License.
128131  */
128132 var event = require('ripple/event'),
128133     _onBatteryStateChange,
128134     _onBatteryLevelChange,
128135     _states = {
128136         UNKNOWN: 0,
128137         FULL: 1,
128138         CHARGING: 2,
128139         UNPLUGGED: 3
128140     },
128141     _battery = {
128142         state: _states.UNKNOWN,
128143         charging: null,
128144         level: null
128145     };
128146
128147 function _getState() {
128148     return _battery.level === 100 ? _states.FULL :
128149            _battery.charging ? _states.CHARGING : _states.UNPLUGGED;
128150 }
128151
128152 function _pass(baton, data) {
128153     if (baton) {
128154         baton.pass({code: 1, data: data});
128155     }
128156 }
128157
128158 event.on("DeviceBatteryStateChanged", function (charging) {
128159     _battery.charging = charging;
128160     _battery.state = _getState();
128161     _pass(_onBatteryStateChange, _battery.state);
128162 });
128163
128164 event.on("DeviceBatteryLevelChanged", function (level) {
128165     level = parseInt(level, 10);
128166
128167     _battery.level = level;
128168     _pass(_onBatteryLevelChange, level);
128169
128170     if (level === 100) {
128171         _battery.state = _getState();
128172         _pass(_onBatteryStateChange, _battery.state);
128173     }
128174 });
128175
128176 module.exports = {
128177     deviceBatteryLevelChange: function (get, post, baton) {
128178         baton.take();
128179         _onBatteryLevelChange = baton;
128180     },
128181     deviceBatteryStateChange: function (get, post, baton) {
128182         baton.take();
128183         _onBatteryStateChange = baton;
128184     }
128185 };
128186
128187 });
128188 define('ripple/platform/webworks.tablet/2.0.0/server/appEvent', function (require, exports, module) {
128189 /*
128190  *  Copyright 2011 Research In Motion Limited.
128191  *
128192  * Licensed under the Apache License, Version 2.0 (the "License");
128193  * you may not use this file except in compliance with the License.
128194  * You may obtain a copy of the License at
128195  *
128196  * http://www.apache.org/licenses/LICENSE-2.0
128197  *
128198  * Unless required by applicable law or agreed to in writing, software
128199  * distributed under the License is distributed on an "AS IS" BASIS,
128200  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128201  * See the License for the specific language governing permissions and
128202  * limitations under the License.
128203  */
128204 var event = require('ripple/event'),
128205     notifications = require('ripple/notifications'),
128206     _bg,
128207     _fg,
128208     _swipeDown,
128209     _swipeStart,
128210     _exit;
128211
128212 event.on("AppExit", function () {
128213     var baton = _exit;
128214     _exit = null;
128215     notifications.openNotification("normal", "blackberry.app.exit() as called, in the real world your app will exit, here... you get this notification");
128216     return baton && baton.pass({code: 1});
128217 });
128218
128219 event.on("AppRequestBackground", function () {
128220     var baton = _bg;
128221     _bg = null;
128222     return baton && baton.pass({code: 1});
128223 });
128224
128225 event.on("AppRequestForeground", function () {
128226     var baton = _fg;
128227     _fg = null;
128228     return baton && baton.pass({code: 1});
128229 });
128230
128231 event.on("AppSwipeDown", function () {
128232     var baton = _swipeDown;
128233     _swipeDown = null;
128234     return baton && baton.pass({code: 1});
128235 });
128236
128237 event.on("AppSwipeStart", function () {
128238     var baton = _swipeStart;
128239     _swipeStart = null;
128240     return baton && baton.pass({code: 1});
128241 });
128242
128243 module.exports = {
128244     onBackground: function (get, post, baton) {
128245         baton.take();
128246         _bg = baton;
128247         return {code: 1};
128248     },
128249
128250     onForeground: function (get, post, baton) {
128251         baton.take();
128252         _fg = baton;
128253         return {code: 1};
128254     },
128255
128256     onSwipeDown: function (get, post, baton) {
128257         baton.take();
128258         _swipeDown = baton;
128259         return {code: 1};
128260     },
128261
128262     onSwipeStart: function (get, post, baton) {
128263         baton.take();
128264         _swipeStart = baton;
128265         return {code: 1};
128266     }
128267 };
128268
128269 });
128270 define('ripple/platform/webworks.handset/2.0.0/XMLHttpRequest', function (require, exports, module) {
128271 /*
128272  *  Copyright 2011 Research In Motion Limited.
128273  *
128274  * Licensed under the Apache License, Version 2.0 (the "License");
128275  * you may not use this file except in compliance with the License.
128276  * You may obtain a copy of the License at
128277  *
128278  * http://www.apache.org/licenses/LICENSE-2.0
128279  *
128280  * Unless required by applicable law or agreed to in writing, software
128281  * distributed under the License is distributed on an "AS IS" BASIS,
128282  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128283  * See the License for the specific language governing permissions and
128284  * limitations under the License.
128285  */
128286
128287 var xhr = require("ripple/platform/webworks.core/2.0.0/XMLHttpRequest");
128288 module.exports = xhr.create("ripple/platform/webworks.handset/2.0.0/server");
128289
128290 });
128291 define('ripple/platform/webworks.handset/2.0.0/spec', function (require, exports, module) {
128292 /*
128293  *  Copyright 2011 Research In Motion Limited.
128294  *
128295  * Licensed under the Apache License, Version 2.0 (the "License");
128296  * you may not use this file except in compliance with the License.
128297  * You may obtain a copy of the License at
128298  *
128299  * http://www.apache.org/licenses/LICENSE-2.0
128300  *
128301  * Unless required by applicable law or agreed to in writing, software
128302  * distributed under the License is distributed on an "AS IS" BASIS,
128303  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128304  * See the License for the specific language governing permissions and
128305  * limitations under the License.
128306  */
128307 module.exports = {
128308
128309     id: "webworks.handset",
128310     version: "2.0.0",
128311     name: "WebWorks",
128312
128313     persistencePrefix: "rim-handset-",
128314
128315     ui: require('ripple/platform/webworks.handset/2.0.0/spec/ui'),
128316     device: require('ripple/platform/webworks.handset/2.0.0/spec/device'),
128317     config: require('ripple/platform/webworks.core/2.0.0/spec/config'),
128318     events: require('ripple/platform/webworks.handset/2.0.0/spec/events'),
128319
128320     initialize: function () {},
128321
128322     objects: {
128323         XMLHttpRequest: {
128324             path: "webworks.handset/2.0.0/XMLHttpRequest"
128325         },
128326         Coordinates: {
128327             path: "w3c/1.0/Coordinates"
128328         },
128329         Position: {
128330             path: "w3c/1.0/Position"
128331         },
128332         PositionError: {
128333             path: "w3c/1.0/PositionError"
128334         },
128335         navigator: {
128336             path: "w3c/1.0/navigator",
128337             children: {
128338                 geolocation: {
128339                     path: "w3c/1.0/geolocation"
128340                 }
128341             }
128342         },
128343         blackberry: {
128344             path: "webworks.handset/2.0.0/client/blackberry",
128345             children: {
128346                 pim: {
128347                     path: "webworks.handset/2.0.0/client/pim",
128348                     feature: "blackberry.pim.category|blackberry.pim.Task|blackberry.pim.Recurrence|blackberry.pim.Reminder|blackberry.pim.Appointment|blackberry.pim.Address|blackberry.pim.Attendee|blackberry.pim.Memo|blackberry.pim.Contact",
128349                     children: {
128350                         category: {
128351                             path: "webworks.handset/2.0.0/client/category",
128352                             feature: "blackberry.pim.category"
128353                         },
128354                         Task: {
128355                             path: "webworks.handset/2.0.0/client/Task",
128356                             feature: "blackberry.pim.Task"
128357                         },
128358                         Recurrence: {
128359                             path: "webworks.handset/2.0.0/client/Recurrence",
128360                             feature: "blackberry.pim.Recurrence"
128361                         },
128362                         Reminder: {
128363                             path: "webworks.handset/2.0.0/client/Reminder",
128364                             feature: "blackberry.pim.Reminder"
128365                         },
128366                         Appointment: {
128367                             path: "webworks.handset/2.0.0/client/Appointment",
128368                             feature: "blackberry.pim.Appointment"
128369                         },
128370                         Address: {
128371                             path: "webworks.handset/2.0.0/client/Address",
128372                             feature: "blackberry.pim.Address"
128373                         },
128374                         Attendee: {
128375                             path: "webworks.handset/2.0.0/client/Attendee",
128376                             feature: "blackberry.pim.Attendee"
128377                         },
128378                         Memo: {
128379                             path: "webworks.handset/2.0.0/client/Memo",
128380                             feature: "blackberry.pim.Memo"
128381                         },
128382                         Contact: {
128383                             path: "webworks.handset/2.0.0/client/Contact",
128384                             feature: "blackberry.pim.Contact"
128385                         }
128386                     }
128387                 },
128388                 phone: {
128389                     children: {
128390                         Phone: {
128391                             path: "webworks.handset/2.0.0/client/Phone",
128392                             feature: "blackberry.phone.Phone"
128393                         },
128394                         PhoneLogs: {
128395                             path: "webworks.handset/2.0.0/client/PhoneLogs",
128396                             feature: "blackberry.phone.PhoneLogs|blackberry.phone.Find",
128397                             children: {
128398                                 CallLog: {
128399                                     path: "webworks.handset/2.0.0/client/CallLog"
128400                                 }
128401                             }
128402                         },
128403                         Find: {
128404                             children: {
128405                                 FilterExpression: {
128406                                     path: "webworks.handset/2.0.0/client/FilterExpression",
128407                                     feature: "blackberry.phone.Find"
128408                                 }
128409                             }
128410                         }
128411                     }
128412                 },
128413                 message: {
128414                     path: "webworks.handset/2.0.0/client/messaging",
128415                     feature: "blackberry.message.sms|blackberry.message",
128416                     children: {
128417                         sms: {
128418                             path: "webworks.handset/2.0.0/client/sms",
128419                             feature: "blackberry.message.sms"
128420                         },
128421                         Message: {
128422                             path: "webworks.handset/2.0.0/client/Message",
128423                             feature: "blackberry.message"
128424                         }
128425                     }
128426                 },
128427                 transport: {
128428                     path: "webworks.core/2.0.0/client/transport"
128429                 },
128430                 events: {
128431                     path: "webworks.core/2.0.0/client/events"
128432                 },
128433                 app: {
128434                     path: "webworks.handset/2.0.0/client/app",
128435                     feature: "blackberry.app",
128436                     children: {
128437                         event: {
128438                             path: "webworks.handset/2.0.0/client/appEvent",
128439                             feature: "blackberry.app.event"
128440                         }
128441                     }
128442                 },
128443                 invoke: {
128444                     path: "webworks.handset/2.0.0/client/invoke",
128445                     feature: "blackberry.invoke",
128446                     children: {
128447                         AddressBookArguments: {
128448                             path: "webworks.handset/2.0.0/client/AddressBookArguments",
128449                             feature: "blackberry.invoke.AddressBookArguments"
128450                         },
128451                         BrowserArguments: {
128452                             path: "webworks.handset/2.0.0/client/BrowserArguments",
128453                             feature: "blackberry.invoke.BrowserArguments"
128454                         },
128455                         CameraArguments: {
128456                             path: "webworks.handset/2.0.0/client/CameraArguments",
128457                             feature: "blackberry.invoke.CameraArguments"
128458                         },
128459                         CalendarArguments: {
128460                             path: "webworks.handset/2.0.0/client/CalendarArguments",
128461                             feature: "blackberry.invoke.CalendarArguments"
128462                         },
128463                         JavaArguments: {
128464                             path: "webworks.handset/2.0.0/client/JavaArguments",
128465                             feature: "blackberry.invoke.JavaArguments"
128466                         },
128467                         MapsArguments: {
128468                             path: "webworks.handset/2.0.0/client/MapsArguments",
128469                             feature: "blackberry.invoke.MapsArguments"
128470                         },
128471                         MemoArguments: {
128472                             path: "webworks.handset/2.0.0/client/MemoArguments",
128473                             feature: "blackberry.invoke.MemoArguments"
128474                         },
128475                         MessageArguments: {
128476                             path: "webworks.handset/2.0.0/client/MessageArguments",
128477                             feature: "blackberry.invoke.MessageArguments"
128478                         },
128479                         PhoneArguments: {
128480                             path: "webworks.handset/2.0.0/client/PhoneArguments",
128481                             feature: "blackberry.invoke.PhoneArguments"
128482                         },
128483                         SearchArguments: {
128484                             path: "webworks.handset/2.0.0/client/SearchArguments",
128485                             feature: "blackberry.invoke.SearchArguments"
128486                         },
128487                         TaskArguments: {
128488                             path: "webworks.handset/2.0.0/client/TaskArguments",
128489                             feature: "blackberry.invoke.TaskArguments"
128490                         }
128491                     }
128492                 },
128493                 identity: {
128494                     path: "webworks.handset/2.0.0/client/identity",
128495                     feature: "blackberry.identity",
128496                     children: {
128497                         Transport: {
128498                             path: "webworks.handset/2.0.0/client/identity/Transport",
128499                             feature: "blackberry.identity"
128500                         },
128501                         Service: {
128502                             path: "webworks.handset/2.0.0/client/identity/Service",
128503                             feature: "blackberry.identity"
128504                         },
128505                         phone: {
128506                             path: "webworks.handset/2.0.0/client/identity/phone",
128507                             feature: "blackberry.identity.phone"
128508                         }
128509                     }
128510                 },
128511                 system: {
128512                     path: "webworks.handset/2.0.0/client/system",
128513                     feature: "blackberry.system",
128514                     children: {
128515                         event: {
128516                             path: "webworks.handset/2.0.0/client/systemEvent",
128517                             feature: "blackberry.system.event"
128518                         }
128519                     }
128520                 },
128521                 ui: {
128522                     children: {
128523                         dialog: {
128524                             path: "webworks.core/2.0.0/client/dialog",
128525                             feature: "blackberry.ui.dialog"
128526                         },
128527                         menu: {
128528                             path: "webworks.handset/2.0.0/client/menu",
128529                             children: {
128530                                 MenuItem: {
128531                                     path: "webworks.handset/2.0.0/client/MenuItem"
128532                                 }
128533                             }
128534                         }
128535                     }
128536                 },
128537                 utils: {
128538                     path: "webworks.core/2.0.0/client/utils",
128539                     feature: "blackberry.utils"
128540                 },
128541                 find: {
128542                     feature: "blackberry.find",
128543                     children: {
128544                         FilterExpression: {
128545                             path: "webworks.handset/2.0.0/client/FilterExpression",
128546                             feature: "blackberry.find"
128547                         }
128548                     }
128549                 },
128550                 push: {
128551                     path: "webworks.handset/2.0.0/client/push",
128552                     feature: "blackberry.push"
128553                 },
128554                 audio: {
128555                     path: "webworks.handset/2.0.0/client/audio",
128556                     feature: "blackberry.audio",
128557                     children: {
128558                         Player: {
128559                             path: "webworks.handset/2.0.0/client/AudioPlayer",
128560                             feature: "blackberry.audio.Player"
128561                         }
128562                     }
128563                 },
128564                 io: {
128565                     children: {
128566                         dir: {
128567                             path: "webworks.handset/2.0.0/client/io/dir",
128568                             feature: "blackberry.io.dir"
128569                         },
128570                         file: {
128571                             path: "webworks.core/2.0.0/client/io/file",
128572                             feature: "blackberry.io.file"
128573                         }
128574                     }
128575                 }
128576             }
128577         }
128578     }
128579 };
128580
128581 });
128582 define('ripple/platform/webworks.handset/2.0.0/client/CalendarArguments', function (require, exports, module) {
128583 /*
128584  *  Copyright 2011 Research In Motion Limited.
128585  *
128586  * Licensed under the Apache License, Version 2.0 (the "License");
128587  * you may not use this file except in compliance with the License.
128588  * You may obtain a copy of the License at
128589  *
128590  * http://www.apache.org/licenses/LICENSE-2.0
128591  *
128592  * Unless required by applicable law or agreed to in writing, software
128593  * distributed under the License is distributed on an "AS IS" BASIS,
128594  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128595  * See the License for the specific language governing permissions and
128596  * limitations under the License.
128597  */
128598 //blackberry.invoke.CalendarArguments ( )
128599 //blackberry.invoke.CalendarArguments ( date : Date )
128600 //blackberry.invoke.CalendarArguments ( appointment : blackberry.pim.Appointment )
128601 var _self = function () {
128602     //readonly  property  Appointment   appointment
128603     //readonly  property  Date   date
128604     //readwrite  property  Number   view
128605     return {
128606         appointment: undefined,
128607         date: undefined,
128608         view: 0
128609     };
128610 };
128611
128612 //const Number  VIEW_NEW  = 0
128613 _self.__defineGetter__("VIEW_NEW", function () {
128614     return 0;
128615 });
128616 //const Number  VIEW_VIEW  = 1
128617 _self.__defineGetter__("VIEW_VIEW", function () {
128618     return 1;
128619 });
128620 //const Number  VIEW_AGENDA  = 2
128621 _self.__defineGetter__("VIEW_AGENDA", function () {
128622     return 2;
128623 });
128624 //const Number  VIEW_DAY  = 3
128625 _self.__defineGetter__("VIEW_DAY", function () {
128626     return 3;
128627 });
128628 //const Number  VIEW_DEFAULT  = 4
128629 _self.__defineGetter__("VIEW_DEFAULT", function () {
128630     return 4;
128631 });
128632 //const Number  VIEW_MONTH  = 5
128633 _self.__defineGetter__("VIEW_MONTH", function () {
128634     return 5;
128635 });
128636 //const Number  VIEW_WEEK  = 6
128637 _self.__defineGetter__("VIEW_WEEK", function () {
128638     return 6;
128639 });
128640
128641 module.exports = _self;
128642
128643 });
128644 define('ripple/platform/webworks.handset/2.0.0/client/Appointment', function (require, exports, module) {
128645 /*
128646  *  Copyright 2011 Research In Motion Limited.
128647  *
128648  * Licensed under the Apache License, Version 2.0 (the "License");
128649  * you may not use this file except in compliance with the License.
128650  * You may obtain a copy of the License at
128651  *
128652  * http://www.apache.org/licenses/LICENSE-2.0
128653  *
128654  * Unless required by applicable law or agreed to in writing, software
128655  * distributed under the License is distributed on an "AS IS" BASIS,
128656  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128657  * See the License for the specific language governing permissions and
128658  * limitations under the License.
128659  */
128660 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
128661     utils = require('ripple/utils'),
128662     _uri = "blackberry/pim/appointment/";
128663
128664 function Appointment(service) {
128665     var _self = {
128666         allDay: false,
128667         attendees: [],
128668         end: null,
128669         freeBusy: null,
128670         location: null,
128671         note: null,
128672         recurrence: null,
128673         reminder: null,
128674         start: null,
128675         summary: null,
128676         uid: null,
128677         remove: function () {
128678             transport.call(_uri + "remove", {get: {uid: _self.uid}});
128679         },
128680         save: function () {
128681             if (_self.uid === null) {
128682                 _self.uid  = Number(Math.uuid(8, 10));
128683             }
128684             transport.call(_uri + "save", {post: {appointment: _self}});
128685         }
128686     };
128687
128688     return _self;
128689 }
128690
128691 function _massage(property, name) {
128692     if (name === "recurrence" && property) {
128693         if (property.end) {
128694             property.end = new Date(property.end);
128695         }
128696     }
128697     if (name === "reminder" && property) {
128698         if (property.date) {
128699             property.date = new Date(property.date);
128700         }
128701     }
128702     if ((name === "end" || name === "start") && property) {
128703         property = new Date(property);
128704     }
128705     return property;
128706 }
128707
128708 Appointment.find = function (filter, orderBy, maxReturn, service, isAscending) {
128709     var opts = {
128710         post: {
128711             filter: filter,
128712             orderBy: orderBy,
128713             maxReturn: maxReturn,
128714             service: service,
128715             isAscending: isAscending
128716         }
128717     };
128718
128719     return transport.call(_uri + "find", opts).map(function (obj) {
128720         var appt = new Appointment();
128721         appt.allDay = obj.allDay;
128722         appt.attendees = obj.attendees;
128723         appt.end = _massage(obj.end, "end");
128724         appt.freeBusy = obj.freeBusy;
128725         appt.location = obj.location;
128726         appt.note = obj.note;
128727         appt.recurrence = _massage(obj.recurrence, "recurrence");
128728         appt.reminder = _massage(obj.reminder, "reminder");
128729         appt.start = _massage(obj.start, "start");
128730         appt.summary = obj.summary;
128731         appt.uid = obj.uid;
128732         return appt;
128733     });
128734 };
128735
128736 Appointment.__defineGetter__("FREE", function () {
128737     return 0;
128738 });
128739 Appointment.__defineGetter__("TENTATIVE", function () {
128740     return 1;
128741 });
128742 Appointment.__defineGetter__("BUSY", function () {
128743     return 2;
128744 });
128745 Appointment.__defineGetter__("OUT_OF_OFFICE", function () {
128746     return 3;
128747 });
128748
128749 module.exports = Appointment;
128750
128751 });
128752 define('ripple/platform/webworks.handset/2.0.0/client/messaging', function (require, exports, module) {
128753 /*
128754  *  Copyright 2011 Research In Motion Limited.
128755  *
128756  * Licensed under the Apache License, Version 2.0 (the "License");
128757  * you may not use this file except in compliance with the License.
128758  * You may obtain a copy of the License at
128759  *
128760  * http://www.apache.org/licenses/LICENSE-2.0
128761  *
128762  * Unless required by applicable law or agreed to in writing, software
128763  * distributed under the License is distributed on an "AS IS" BASIS,
128764  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128765  * See the License for the specific language governing permissions and
128766  * limitations under the License.
128767  */
128768 module.exports = {};
128769
128770 });
128771 define('ripple/platform/webworks.handset/2.0.0/client/CameraArguments', function (require, exports, module) {
128772 /*
128773  *  Copyright 2011 Research In Motion Limited.
128774  *
128775  * Licensed under the Apache License, Version 2.0 (the "License");
128776  * you may not use this file except in compliance with the License.
128777  * You may obtain a copy of the License at
128778  *
128779  * http://www.apache.org/licenses/LICENSE-2.0
128780  *
128781  * Unless required by applicable law or agreed to in writing, software
128782  * distributed under the License is distributed on an "AS IS" BASIS,
128783  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128784  * See the License for the specific language governing permissions and
128785  * limitations under the License.
128786  */
128787 //blackberry.invoke.CameraArguments ( )
128788 var _self = function () {
128789     return {
128790         //readwrite  property  Number   view
128791         view: 0
128792     };
128793 };
128794
128795 //const Number  VIEW_CAMERA  = 0
128796 _self.__defineGetter__("VIEW_CAMERA", function () {
128797     return 0;
128798 });
128799 //const Number  VIEW_RECORDER  = 1
128800 _self.__defineGetter__("VIEW_RECORDER", function () {
128801     return 1;
128802 });
128803
128804 module.exports = _self;
128805
128806 });
128807 define('ripple/platform/webworks.handset/2.0.0/client/io/dir', function (require, exports, module) {
128808 /*
128809  * Copyright 2011 Research In Motion Limited.
128810  *
128811  * Licensed under the Apache License, Version 2.0 (the "License");
128812  * you may not use this file except in compliance with the License.
128813  * You may obtain a copy of the License at
128814  *
128815  *     http://www.apache.org/licenses/LICENSE-2.0
128816  *
128817  * Unless required by applicable law or agreed to in writing, software
128818  * distributed under the License is distributed on an "AS IS" BASIS,
128819  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128820  * See the License for the specific language governing permissions and
128821  * limitations under the License.
128822  */
128823 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
128824     dir = require('ripple/platform/webworks.core/2.0.0/client/io/dir'),
128825     utils = require('ripple/utils'),
128826     _uri = "blackberry/io/dir/",
128827     FILE = "file://",
128828     _self = {};
128829
128830 function _prunePrefix(path) {
128831     return path.replace(new RegExp("^" + FILE), '');
128832 }
128833
128834 utils.mixin({
128835     getFreeSpaceForRoot: function (path) {
128836         return transport.call(_uri + "getFreeSpaceForRoot", {
128837             post: {path: _prunePrefix(path)}
128838         });
128839     },
128840     getRootDirs: function () {
128841         return transport.call(_uri + "getRootDirs", {}).map(function (dir) {
128842             return FILE + dir;
128843         });
128844     }
128845 }, _self);
128846
128847 utils.mixin(dir, _self);
128848
128849 module.exports = _self;
128850
128851 });
128852 define('ripple/platform/webworks.handset/2.0.0/client/TaskArguments', function (require, exports, module) {
128853 /*
128854  *  Copyright 2011 Research In Motion Limited.
128855  *
128856  * Licensed under the Apache License, Version 2.0 (the "License");
128857  * you may not use this file except in compliance with the License.
128858  * You may obtain a copy of the License at
128859  *
128860  * http://www.apache.org/licenses/LICENSE-2.0
128861  *
128862  * Unless required by applicable law or agreed to in writing, software
128863  * distributed under the License is distributed on an "AS IS" BASIS,
128864  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128865  * See the License for the specific language governing permissions and
128866  * limitations under the License.
128867  */
128868 //blackberry.invoke.TaskArguments ( [task : blackberry.pim.Task ] )
128869 var _self = function (task) {
128870     return {
128871         view: 0,
128872         task: task
128873     };
128874 };
128875
128876 //const Number  VIEW_NEW  = 0
128877 _self.__defineGetter__("VIEW_NEW", function () {
128878     return 0;
128879 });
128880 //const Number  VIEW_EDIT  = 1
128881 _self.__defineGetter__("VIEW_EDIT", function () {
128882     return 1;
128883 });
128884
128885 module.exports = _self;
128886
128887 });
128888 define('ripple/platform/webworks.handset/2.0.0/client/identity/Service', function (require, exports, module) {
128889 /*
128890  *  Copyright 2011 Research In Motion Limited.
128891  *
128892  * Licensed under the Apache License, Version 2.0 (the "License");
128893  * you may not use this file except in compliance with the License.
128894  * You may obtain a copy of the License at
128895  *
128896  * http://www.apache.org/licenses/LICENSE-2.0
128897  *
128898  * Unless required by applicable law or agreed to in writing, software
128899  * distributed under the License is distributed on an "AS IS" BASIS,
128900  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128901  * See the License for the specific language governing permissions and
128902  * limitations under the License.
128903  */
128904 function Service() {
128905     return {
128906         emailAddress: null,
128907         isDefault: null,
128908         name: null,
128909         type: null
128910     };
128911 }
128912
128913 Service.__defineGetter__("TYPE_EMAIL", function () {
128914     return 0;
128915 });
128916
128917 Service.__defineGetter__("TYPE_CALENDAR", function () {
128918     return 1;
128919 });
128920
128921 Service.__defineGetter__("TYPE_CONTACT", function () {
128922     return 2;
128923 });
128924
128925 module.exports = Service;
128926
128927 });
128928 define('ripple/platform/webworks.handset/2.0.0/client/identity/Transport', function (require, exports, module) {
128929 /*
128930  *  Copyright 2011 Research In Motion Limited.
128931  *
128932  * Licensed under the Apache License, Version 2.0 (the "License");
128933  * you may not use this file except in compliance with the License.
128934  * You may obtain a copy of the License at
128935  *
128936  * http://www.apache.org/licenses/LICENSE-2.0
128937  *
128938  * Unless required by applicable law or agreed to in writing, software
128939  * distributed under the License is distributed on an "AS IS" BASIS,
128940  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128941  * See the License for the specific language governing permissions and
128942  * limitations under the License.
128943  */
128944 function Transport(name, type) {
128945     this.__defineGetter__("name", function () {
128946         return name || "";
128947     });
128948     this.__defineGetter__("type", function () {
128949         return type || "";
128950     });
128951 }
128952
128953 module.exports = Transport;
128954
128955 });
128956 define('ripple/platform/webworks.handset/2.0.0/client/identity/phone', function (require, exports, module) {
128957 /*
128958  *  Copyright 2011 Research In Motion Limited.
128959  *
128960  * Licensed under the Apache License, Version 2.0 (the "License");
128961  * you may not use this file except in compliance with the License.
128962  * You may obtain a copy of the License at
128963  *
128964  * http://www.apache.org/licenses/LICENSE-2.0
128965  *
128966  * Unless required by applicable law or agreed to in writing, software
128967  * distributed under the License is distributed on an "AS IS" BASIS,
128968  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
128969  * See the License for the specific language governing permissions and
128970  * limitations under the License.
128971  */
128972 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
128973     _uri = "blackberry/identity/phone/",
128974     _self;
128975
128976 _self = {
128977     getLineIds: function () {
128978         return transport.call(_uri + "getLineIds");
128979     },
128980     getLineLabel: function (id) {
128981         return transport.call(_uri + "getLineLabel", {get: {id: id}});
128982     },
128983     getLineNumber: function (id) {
128984         return transport.call(_uri + "getLineNumber", {get: {id: id}});
128985     },
128986     getLineType: function (id) {
128987         return transport.call(_uri + "getLineType", {get: {id: id}});
128988     }
128989 };
128990
128991 module.exports = _self;
128992
128993 });
128994 define('ripple/platform/webworks.handset/2.0.0/client/PhoneArguments', function (require, exports, module) {
128995 /*
128996  *  Copyright 2011 Research In Motion Limited.
128997  *
128998  * Licensed under the Apache License, Version 2.0 (the "License");
128999  * you may not use this file except in compliance with the License.
129000  * You may obtain a copy of the License at
129001  *
129002  * http://www.apache.org/licenses/LICENSE-2.0
129003  *
129004  * Unless required by applicable law or agreed to in writing, software
129005  * distributed under the License is distributed on an "AS IS" BASIS,
129006  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129007  * See the License for the specific language governing permissions and
129008  * limitations under the License.
129009  */
129010 //blackberry.invoke.PhoneArguments ( [dialString : String ] ,  [smartDialing : Boolean ] ,  [lineId : Number ] )
129011 var _self = function (dialString, smartDialing, lineId) {
129012     return {
129013         dialString: dialString,
129014         smartDialing: smartDialing,
129015         lineId: (lineId ? lineId : -1),
129016         view: 0
129017     };
129018 };
129019
129020 //const Number  VIEW_NEW  = 0
129021 _self.__defineGetter__("VIEW_CALL", function () {
129022     return 0;
129023 });
129024 //const Number  VIEW_DEFAULT  = 1
129025 _self.__defineGetter__("VIEW_VOICEMAIL", function () {
129026     return 1;
129027 });
129028
129029 module.exports = _self;
129030
129031 });
129032 define('ripple/platform/webworks.handset/2.0.0/client/BrowserArguments', function (require, exports, module) {
129033 /*
129034  *  Copyright 2011 Research In Motion Limited.
129035  *
129036  * Licensed under the Apache License, Version 2.0 (the "License");
129037  * you may not use this file except in compliance with the License.
129038  * You may obtain a copy of the License at
129039  *
129040  * http://www.apache.org/licenses/LICENSE-2.0
129041  *
129042  * Unless required by applicable law or agreed to in writing, software
129043  * distributed under the License is distributed on an "AS IS" BASIS,
129044  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129045  * See the License for the specific language governing permissions and
129046  * limitations under the License.
129047  */
129048 //blackberry.invoke.BrowserArguments ( url : String ,  [transport : blackberry.identity.Transport ] )
129049 module.exports = function (url, transport) {
129050     return {
129051         url: url
129052     };
129053 };
129054
129055 });
129056 define('ripple/platform/webworks.handset/2.0.0/client/AudioPlayer', function (require, exports, module) {
129057 /*
129058  *  Copyright 2011 Research In Motion Limited.
129059  *
129060  * Licensed under the Apache License, Version 2.0 (the "License");
129061  * you may not use this file except in compliance with the License.
129062  * You may obtain a copy of the License at
129063  *
129064  * http://www.apache.org/licenses/LICENSE-2.0
129065  *
129066  * Unless required by applicable law or agreed to in writing, software
129067  * distributed under the License is distributed on an "AS IS" BASIS,
129068  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129069  * See the License for the specific language governing permissions and
129070  * limitations under the License.
129071  */
129072 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
129073     _uri = "blackberry/audio/player/";
129074
129075 function Player(locator, type, async) {
129076     //we can't use the async prop since we need the ID before we can do anything else.
129077     var _id = transport.call(_uri + "create", {
129078             get: {locator: locator, type: type},
129079             async: false
129080         }),
129081         _listener,
129082         _closed,
129083         _self,
129084         _poll = function (path) {
129085             transport.poll(_uri + path, {
129086                 get: {id: _id}
129087             }, function (response) {
129088                 if (_listener) {
129089                     _listener(_self, response.event, response.eventData);
129090                 }
129091
129092                 return !!_listener;
129093             });
129094         };
129095
129096     _self = {
129097         addPlayerListener: function (callback) {
129098             if (!_closed && callback) {
129099                 _listener = callback;
129100                 _poll("onStart");
129101                 _poll("onStopped");
129102                 _poll("onBufferingStarted");
129103                 _poll("onBufferingStopped");
129104                 _poll("onDurationUpdated");
129105                 _poll("onEnd");
129106                 _poll("onError");
129107                 _poll("onVolumeChange");
129108                 _poll("onClose");
129109             }
129110             else {
129111                 _listener = null;
129112             }
129113
129114             return !_closed;
129115         },
129116
129117         close: function () {
129118             _listener = null;
129119             _closed = true;
129120             return transport.call(_uri + "close", {get: {id: _id}});
129121         },
129122
129123         pause: function () {
129124             return transport.call(_uri + "pause", {get: {id: _id}});
129125         },
129126
129127         play: function () {
129128             return transport.call(_uri + "play", {get: {id: _id}});
129129         }
129130     };
129131
129132     _self.__defineGetter__("duration", function () {
129133         return transport.call(_uri + "getDuration", {get: {id: _id}});
129134     });
129135
129136     _self.__defineGetter__("mediaTime", function () {
129137         return transport.call(_uri + "getMediaTime", {get: {id: _id}});
129138     });
129139
129140     _self.__defineSetter__("mediaTime", function (val) {
129141         transport.call(_uri + "setMediaTime", {get: {id: _id, value: val}});
129142     });
129143
129144     _self.__defineGetter__("state", function () {
129145         return transport.call(_uri + "getState", {get: {id: _id}});
129146     });
129147
129148     _self.__defineGetter__("volumeLevel", function () {
129149         return transport.call(_uri + "getVolumeLevel", {get: {id: _id}});
129150     });
129151
129152     _self.__defineSetter__("volumeLevel", function (val) {
129153         transport.call(_uri + "setVolumeLevel", {get: {id: _id, value: val}});
129154     });
129155
129156     _self.__defineGetter__("EVENT_BUFFERING_STARTED", function () {
129157         return "EVENT_BUFFERING_STARTED";
129158     });
129159     _self.__defineGetter__("EVENT_BUFFERING_STOPPED", function () {
129160         return "EVENT_BUFFERING_STOPPED";
129161     });
129162     _self.__defineGetter__("EVENT_CLOSED", function () {
129163         return "EVENT_CLOSED";
129164     });
129165     _self.__defineGetter__("EVENT_DEVICE_AVAILABLE", function () {
129166         return "EVENT_DEVICE_AVAILABLE";
129167     });
129168     _self.__defineGetter__("EVENT_DEVICE_UNAVAILABLE", function () {
129169         return "EVENT_DEVICE_UNAVAILABLE";
129170     });
129171     _self.__defineGetter__("EVENT_DURATION_UPDATED", function () {
129172         return "EVENT_DURATION_UPDATED";
129173     });
129174     _self.__defineGetter__("EVENT_END_OF_MEDIA", function () {
129175         return "EVENT_END_OF_MEDIA";
129176     });
129177     _self.__defineGetter__("EVENT_ERROR", function () {
129178         return "EVENT_ERROR";
129179     });
129180     _self.__defineGetter__("EVENT_RECORD_ERROR", function () {
129181         return "EVENT_ERROR";
129182     });
129183     _self.__defineGetter__("EVENT_RECORD_STARTED", function () {
129184         return "EVENT_RECORD_STARTED";
129185     });
129186     _self.__defineGetter__("EVENT_RECORD_STOPPED", function () {
129187         return "EVENT_RECORD_STOPPED";
129188     });
129189     _self.__defineGetter__("EVENT_SIZE_CHANGED", function () {
129190         return "EVENT_SIZE_CHANGED";
129191     });
129192     _self.__defineGetter__("EVENT_STARTED", function () {
129193         return "EVENT_STARTED";
129194     });
129195     _self.__defineGetter__("EVENT_STOPPED", function () {
129196         return "EVENT_STOPPED";
129197     });
129198     _self.__defineGetter__("EVENT_STOPPED_AT_TIME", function () {
129199         return "EVENT_STOPPED_AT_TIME";
129200     });
129201     _self.__defineGetter__("EVENT_VOLUME_CHANGED", function () {
129202         return "EVENT_VOLUME_CHANGED";
129203     });
129204
129205     return _self;
129206 }
129207
129208 Player.__defineGetter__("TIME_UNKNOWN", function () {
129209     return -1;
129210 });
129211 Player.__defineGetter__("CLOSED", function () {
129212     return 0;
129213 });
129214 Player.__defineGetter__("UNREALIZED", function () {
129215     return 100;
129216 });
129217 Player.__defineGetter__("REALIZED", function () {
129218     return 200;
129219 });
129220 Player.__defineGetter__("PREFETCHED", function () {
129221     return 300;
129222 });
129223 Player.__defineGetter__("STARTED", function () {
129224     return 400;
129225 });
129226
129227 module.exports = Player;
129228
129229 });
129230 define('ripple/platform/webworks.handset/2.0.0/client/category', function (require, exports, module) {
129231 /*
129232  *  Copyright 2011 Research In Motion Limited.
129233  *
129234  * Licensed under the Apache License, Version 2.0 (the "License");
129235  * you may not use this file except in compliance with the License.
129236  * You may obtain a copy of the License at
129237  *
129238  * http://www.apache.org/licenses/LICENSE-2.0
129239  *
129240  * Unless required by applicable law or agreed to in writing, software
129241  * distributed under the License is distributed on an "AS IS" BASIS,
129242  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129243  * See the License for the specific language governing permissions and
129244  * limitations under the License.
129245  */
129246 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
129247     _uri = "blackberry/pim/category/",
129248     _self;
129249
129250 _self = {
129251     addCategory: function (categoryName) {
129252         transport.call(_uri + "addCategory", {
129253             get: {categoryName: categoryName}
129254         });
129255     },
129256     deleteCategory: function (categoryName) {
129257         transport.call(_uri + "deleteCategory", {
129258             get: {categoryName: categoryName}
129259         });
129260     },
129261     getCategories: function () {
129262         return transport.call(_uri + "getCategories");
129263     }
129264 };
129265
129266 module.exports = _self;
129267
129268 });
129269 define('ripple/platform/webworks.handset/2.0.0/client/PushData', function (require, exports, module) {
129270 /*
129271  *  Copyright 2011 Research In Motion Limited.
129272  *
129273  * Licensed under the Apache License, Version 2.0 (the "License");
129274  * you may not use this file except in compliance with the License.
129275  * You may obtain a copy of the License at
129276  *
129277  * http://www.apache.org/licenses/LICENSE-2.0
129278  *
129279  * Unless required by applicable law or agreed to in writing, software
129280  * distributed under the License is distributed on an "AS IS" BASIS,
129281  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129282  * See the License for the specific language governing permissions and
129283  * limitations under the License.
129284  */
129285 function PushData(data, port) {
129286     this.port = port;
129287     this.data = data;
129288
129289     this.getHeaderField = function (field) {
129290         if (field === undefined || field === null) {
129291             throw "no field specified";
129292         }
129293         else if (!(typeof field === 'number' && field >= 0) && typeof field !== 'string') {
129294             throw "field is not valid";
129295         }
129296
129297         return data.headerField[field];
129298     };
129299
129300     this.getRequestURI =  function () {
129301         return data.requestURI;
129302     };
129303
129304     this.getSource = function () {
129305         return data.source;
129306     };
129307
129308     this.isChannelEncrypted = data.isChannelEncrypted;
129309
129310     this.payload = data.payload;
129311
129312     this.__defineGetter__("ACCEPT", function () {
129313         return 0;
129314     });
129315     this.__defineGetter__("DECLINE_USERDCR", function () {
129316         return 1;
129317     });
129318     this.__defineGetter__("DECLINE_USERDCU", function () {
129319         return 2;
129320     });
129321     this.__defineGetter__("DECLINE_USERPND", function () {
129322         return 3;
129323     });
129324     this.__defineGetter__("DECLINE_USERREQ", function () {
129325         return 4;
129326     });
129327     this.__defineGetter__("DECLINE_USERRFS", function () {
129328         return 5;
129329     });
129330 }
129331
129332 module.exports = PushData;
129333
129334 });
129335 define('ripple/platform/webworks.handset/2.0.0/client/identity', function (require, exports, module) {
129336 /*
129337  *  Copyright 2011 Research In Motion Limited.
129338  *
129339  * Licensed under the Apache License, Version 2.0 (the "License");
129340  * you may not use this file except in compliance with the License.
129341  * You may obtain a copy of the License at
129342  *
129343  * http://www.apache.org/licenses/LICENSE-2.0
129344  *
129345  * Unless required by applicable law or agreed to in writing, software
129346  * distributed under the License is distributed on an "AS IS" BASIS,
129347  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129348  * See the License for the specific language governing permissions and
129349  * limitations under the License.
129350  */
129351 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
129352     _uri = "blackberry/identity/",
129353     _self;
129354
129355 _self = {
129356     getDefaultService: function () {
129357         return transport.call(_uri + "getDefaultService");
129358     },
129359     getServiceList: function () {
129360         return transport.call(_uri + "getServiceList");
129361     },
129362     getTransportList: function () {
129363         return transport.call(_uri + "getTransportList");
129364     }
129365 };
129366
129367 _self.__defineGetter__("IMEI", function () {
129368     return transport.call(_uri + "IMEI");
129369 });
129370
129371 _self.__defineGetter__("IMSI", function () {
129372     return transport.call(_uri + "IMSI");
129373 });
129374
129375 _self.__defineGetter__("PIN", function () {
129376     return transport.call(_uri + "PIN");
129377 });
129378
129379 module.exports = _self;
129380
129381 });
129382 define('ripple/platform/webworks.handset/2.0.0/client/JavaArguments', function (require, exports, module) {
129383 /*
129384  *  Copyright 2011 Research In Motion Limited.
129385  *
129386  * Licensed under the Apache License, Version 2.0 (the "License");
129387  * you may not use this file except in compliance with the License.
129388  * You may obtain a copy of the License at
129389  *
129390  * http://www.apache.org/licenses/LICENSE-2.0
129391  *
129392  * Unless required by applicable law or agreed to in writing, software
129393  * distributed under the License is distributed on an "AS IS" BASIS,
129394  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129395  * See the License for the specific language governing permissions and
129396  * limitations under the License.
129397  */
129398 //blackberry.invoke.JavaArguments ( uri : String ,  [params : String [ ] ] )
129399 var _self = function (uri, params) {
129400     return {
129401         uri: uri,
129402         params: params,
129403         args: arguments
129404     };
129405 };
129406
129407 module.exports = _self;
129408
129409 });
129410 define('ripple/platform/webworks.handset/2.0.0/client/FilterExpression', function (require, exports, module) {
129411 /*
129412  *  Copyright 2011 Research In Motion Limited.
129413  *
129414  * Licensed under the Apache License, Version 2.0 (the "License");
129415  * you may not use this file except in compliance with the License.
129416  * You may obtain a copy of the License at
129417  *
129418  * http://www.apache.org/licenses/LICENSE-2.0
129419  *
129420  * Unless required by applicable law or agreed to in writing, software
129421  * distributed under the License is distributed on an "AS IS" BASIS,
129422  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129423  * See the License for the specific language governing permissions and
129424  * limitations under the License.
129425  */
129426 //blackberry.find.FilterExpression ( leftField  : object ,  operator  : object ,  rightField : object ,  [negate : Boolean ] )
129427 var FilterExpression = function (leftField, operator, rightField, negate) {
129428     this.__defineGetter__("leftField", function () {
129429         return leftField;
129430     });
129431
129432     this.__defineGetter__("operator", function () {
129433         return operator;
129434     });
129435
129436     this.__defineGetter__("rightField", function () {
129437         return rightField;
129438     });
129439
129440     this.__defineGetter__("negate", function () {
129441         return negate ? true : false;
129442     });
129443 };
129444
129445 module.exports = FilterExpression;
129446
129447 });
129448 define('ripple/platform/webworks.handset/2.0.0/client/system', function (require, exports, module) {
129449 /*
129450  *  Copyright 2011 Research In Motion Limited.
129451  *
129452  * Licensed under the Apache License, Version 2.0 (the "License");
129453  * you may not use this file except in compliance with the License.
129454  * You may obtain a copy of the License at
129455  *
129456  * http://www.apache.org/licenses/LICENSE-2.0
129457  *
129458  * Unless required by applicable law or agreed to in writing, software
129459  * distributed under the License is distributed on an "AS IS" BASIS,
129460  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129461  * See the License for the specific language governing permissions and
129462  * limitations under the License.
129463  */
129464 var utils = require('ripple/utils'),
129465     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
129466     system = require('ripple/platform/webworks.core/2.0.0/client/system'),
129467     _uri = "blackberry/system/",
129468     _self;
129469
129470 _self = {
129471     setHomeScreenBackground: function (filePath) {
129472         transport.call(_uri + "setHomeScreenBackground", {
129473             get: {filePath: filePath},
129474             async: true
129475         });
129476     },
129477 };
129478
129479 (function () {
129480     // HACK: can't type check if system[key] is a function, sets off getters
129481     // also can't use utils.mixin or forEach for the same reason
129482     function get(i) {
129483         return function () {
129484             return system[i];
129485         };
129486     }
129487
129488     for (var key in system) {
129489         if (system.hasOwnProperty(key)) {
129490             _self.__defineGetter__(key, get(key));
129491         }
129492     }
129493 }());
129494
129495 module.exports = _self;
129496
129497 });
129498 define('ripple/platform/webworks.handset/2.0.0/client/Recurrence', function (require, exports, module) {
129499 /*
129500  *  Copyright 2011 Research In Motion Limited.
129501  *
129502  * Licensed under the Apache License, Version 2.0 (the "License");
129503  * you may not use this file except in compliance with the License.
129504  * You may obtain a copy of the License at
129505  *
129506  * http://www.apache.org/licenses/LICENSE-2.0
129507  *
129508  * Unless required by applicable law or agreed to in writing, software
129509  * distributed under the License is distributed on an "AS IS" BASIS,
129510  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129511  * See the License for the specific language governing permissions and
129512  * limitations under the License.
129513  */
129514 function Recurrence() {
129515     return {
129516         //readwrite  property  Number   count
129517         //readwrite  property  Number   dayInMonth
129518         //readwrite  property  Number   dayInWeek
129519         //readwrite  property  Number   dayInYear
129520         //readwrite  property  Date   end
129521         //readwrite  property  Number   frequency
129522         //readwrite  property  Number   interval
129523         //readwrite  property  Number   monthInYear
129524         //readwrite  property  Number   weekInMonth
129525
129526         count: null,
129527         dayInMonth: null,
129528         dayInWeek: null,
129529         dayInYear: null,
129530         end: null,
129531         frequency: null,
129532         interval: null,
129533         monthInYear: null,
129534         weekInMonth: null
129535     };
129536 }
129537
129538 Recurrence.__defineGetter__("NO_REPEAT", function () {
129539     return 0;
129540 });
129541 Recurrence.__defineGetter__("DAILY", function () {
129542     return 1;
129543 });
129544 Recurrence.__defineGetter__("WEEKLY", function () {
129545     return 2;
129546 });
129547 Recurrence.__defineGetter__("MONTHLY", function () {
129548     return 3;
129549 });
129550 Recurrence.__defineGetter__("YEARLY", function () {
129551     return 4;
129552 });
129553 Recurrence.__defineGetter__("JANUARY", function () {
129554     return 0x20000;
129555 });
129556 Recurrence.__defineGetter__("FEBRUARY", function () {
129557     return 0x40000;
129558 });
129559 Recurrence.__defineGetter__("MARCH", function () {
129560     return 0x80000;
129561 });
129562 Recurrence.__defineGetter__("APRIL", function () {
129563     return 0x100000;
129564 });
129565 Recurrence.__defineGetter__("MAY", function () {
129566     return 0x200000;
129567 });
129568 Recurrence.__defineGetter__("JUNE", function () {
129569     return 0x400000;
129570 });
129571 Recurrence.__defineGetter__("JULY", function () {
129572     return 0x800000;
129573 });
129574 Recurrence.__defineGetter__("AUGUST", function () {
129575     return 0x1000000;
129576 });
129577 Recurrence.__defineGetter__("SEPTEMBER", function () {
129578     return 0x2000000;
129579 });
129580 Recurrence.__defineGetter__("OCTOBER", function () {
129581     return 0x4000000;
129582 });
129583 Recurrence.__defineGetter__("NOVEMBER", function () {
129584     return 0x8000000;
129585 });
129586 Recurrence.__defineGetter__("DECEMBER", function () {
129587     return 0x10000000;
129588 });
129589 Recurrence.__defineGetter__("FIRST", function () {
129590     return 0x1;
129591 });
129592 Recurrence.__defineGetter__("SECOND", function () {
129593     return 0x2;
129594 });
129595 Recurrence.__defineGetter__("THIRD", function () {
129596     return 0x4;
129597 });
129598 Recurrence.__defineGetter__("FOURTH", function () {
129599     return 0x8;
129600 });
129601 Recurrence.__defineGetter__("FIFTH", function () {
129602     return 0x10;
129603 });
129604 Recurrence.__defineGetter__("LAST", function () {
129605     return 0x20;
129606 });
129607 Recurrence.__defineGetter__("SECONDLAST", function () {
129608     return 0x40;
129609 });
129610 Recurrence.__defineGetter__("THIRDLAST", function () {
129611     return 0x80;
129612 });
129613 Recurrence.__defineGetter__("FOURTHLAST", function () {
129614     return 0x100;
129615 });
129616 Recurrence.__defineGetter__("FIFTHLAST", function () {
129617     return 0x200;
129618 });
129619 Recurrence.__defineGetter__("SUNDAY", function () {
129620     return 0x10000;
129621 });
129622 Recurrence.__defineGetter__("MONDAY", function () {
129623     return 0x8000;
129624 });
129625 Recurrence.__defineGetter__("TUESDAY", function () {
129626     return 0x4000;
129627 });
129628 Recurrence.__defineGetter__("WEDNESDAY", function () {
129629     return 0x2000;
129630 });
129631 Recurrence.__defineGetter__("THURSDAY", function () {
129632     return 0x1000;
129633 });
129634 Recurrence.__defineGetter__("FRIDAY", function () {
129635     return 0x800;
129636 });
129637 Recurrence.__defineGetter__("SATURDAY", function () {
129638     return 0x400;
129639 });
129640
129641 module.exports = Recurrence;
129642
129643 });
129644 define('ripple/platform/webworks.handset/2.0.0/client/Message', function (require, exports, module) {
129645 /*
129646  *  Copyright 2011 Research In Motion Limited.
129647  *
129648  * Licensed under the Apache License, Version 2.0 (the "License");
129649  * you may not use this file except in compliance with the License.
129650  * You may obtain a copy of the License at
129651  *
129652  * http://www.apache.org/licenses/LICENSE-2.0
129653  *
129654  * Unless required by applicable law or agreed to in writing, software
129655  * distributed under the License is distributed on an "AS IS" BASIS,
129656  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129657  * See the License for the specific language governing permissions and
129658  * limitations under the License.
129659  */
129660 var utils = require('ripple/platform/webworks.core/2.0.0/client/utils'),
129661     identity = require('ripple/platform/webworks.handset/2.0.0/client/identity'),
129662     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
129663     Service = require('ripple/platform/webworks.handset/2.0.0/client/identity/Service'),
129664     select = require('ripple/platform/webworks.core/2.0.0/select'),
129665     _uri = "blackberry/message/message/";
129666
129667 function Message(service) {
129668     var _service = service,
129669         _msg = {
129670             uid: 0,
129671             status: Message.STATUS_DRAFT,
129672             from: "",
129673             folder: Message.FOLDER_DRAFT,
129674             replyTo: "",
129675             bccRecipients: "",
129676             body: "",
129677             ccRecipients: "",
129678             priority: Message.PRIORITY_MEDIUM, //default to med priority
129679             subject: "",
129680             toRecipients: "",
129681
129682             remove: function () {
129683                 _msg.folder = Message.FOLDER_DELETED;
129684                 transport.call(_uri + "remove", {
129685                     get: {uid: _msg.uid}
129686                 });
129687             },
129688
129689             save: function () {
129690                 if (_msg.uid === 0) {
129691                     _msg.uid = Number(Math.uuid(8, 10));
129692                 }
129693
129694                 _msg.replyTo  = _msg.from = _service.emailAddress;
129695                 _msg.status =  Message.STATUS_SAVED;
129696                 transport.call(_uri + "save", {
129697                     post: {message: _msg}
129698                 });
129699             },
129700
129701             send: function () {
129702                 if (_msg.toRecipients) {
129703                     if (_msg.uid === 0) {
129704                         _msg.uid = Number(Math.uuid(8, 10));
129705                     }
129706
129707                     _msg.folder = Message.FOLDER_DRAFT;
129708                     _msg.status = Message.STATUS_UNKNOWN;
129709                     transport.call(_uri + "send", {
129710                         get: {message: _msg}
129711                     });
129712                 } else {
129713                     throw "message has no recipients";
129714                 }
129715             }
129716         };
129717
129718     if (!_service) {
129719         _service = identity.getDefaultService().reduce(function (email, service) {
129720             return service.type === Service.TYPE_EMAIL ? service : email;
129721         }, null);
129722     }
129723
129724     return _msg;
129725 }
129726
129727 Message.find = function (filter, maxReturn, service) {
129728     var opts = {
129729         post: {
129730             filter: filter,
129731             maxReturn: maxReturn,
129732             service: service
129733         }
129734     };
129735
129736     return transport.call(_uri + "find", opts).map(function (obj) {
129737         var msg = new Message();
129738
129739         msg.uid = obj.uid;
129740         msg.status = obj.status;
129741         msg.from = obj.from;
129742         msg.folder = obj.folder;
129743         msg.replyTo = obj.replyTo;
129744         msg.bccRecipients = obj.bccRecipients;
129745         msg.body = obj.body;
129746         msg.ccRecipients = obj.ccRecipients;
129747         msg.priority = obj.priority;
129748         msg.subject = obj.subject;
129749         msg.toRecipients = obj.toRecipients;
129750
129751         return msg;
129752     });
129753 };
129754
129755
129756 Message.__defineGetter__("STATUS_UNKNOWN", function () {
129757     return -1;
129758 });
129759 Message.__defineGetter__("STATUS_SAVED", function () {
129760     return 0;
129761 });
129762 Message.__defineGetter__("STATUS_DRAFT", function () {
129763     return 1;
129764 });
129765 Message.__defineGetter__("STATUS_SENT", function () {
129766     return 2;
129767 });
129768 Message.__defineGetter__("STATUS_ERROR_OCCURED", function () {
129769     return 3;
129770 });
129771 Message.__defineGetter__("PRIORITY_HIGH", function () {
129772     return 0;
129773 });
129774 Message.__defineGetter__("PRIORITY_MEDIUM", function () {
129775     return 1;
129776 });
129777 Message.__defineGetter__("PRIORITY_LOW", function () {
129778     return 2;
129779 });
129780 Message.__defineGetter__("FOLDER_INBOX", function () {
129781     return 0;
129782 });
129783 Message.__defineGetter__("FOLDER_SENT", function () {
129784     return 1;
129785 });
129786 Message.__defineGetter__("FOLDER_DRAFT", function () {
129787     return 2;
129788 });
129789 Message.__defineGetter__("FOLDER_OUTBOX", function () {
129790     return 3;
129791 });
129792 Message.__defineGetter__("FOLDER_DELETED", function () {
129793     return 4;
129794 });
129795 Message.__defineGetter__("FOLDER_OTHER", function () {
129796     return 5;
129797 });
129798
129799 module.exports = Message;
129800
129801 });
129802 define('ripple/platform/webworks.handset/2.0.0/client/menu', function (require, exports, module) {
129803 /*
129804  *  Copyright 2011 Research In Motion Limited.
129805  *
129806  * Licensed under the Apache License, Version 2.0 (the "License");
129807  * you may not use this file except in compliance with the License.
129808  * You may obtain a copy of the License at
129809  *
129810  * http://www.apache.org/licenses/LICENSE-2.0
129811  *
129812  * Unless required by applicable law or agreed to in writing, software
129813  * distributed under the License is distributed on an "AS IS" BASIS,
129814  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129815  * See the License for the specific language governing permissions and
129816  * limitations under the License.
129817  */
129818 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
129819     MenuItem = require('ripple/platform/webworks.handset/2.0.0/client/MenuItem'),
129820     utils = require('ripple/utils'),
129821     onSelect,
129822     _items = {},
129823     _uri = "blackberry/ui/menu/",
129824     _self;
129825
129826 _self = {
129827     addMenuItem: function (menuItem) {
129828         _items[menuItem.id] = menuItem;
129829
129830         transport.call(_uri + "addMenuItem", {
129831             get: {"item": menuItem}
129832         });
129833
129834         if (utils.count(_items) === 1) {
129835             transport.poll(_uri + "onSelect", {}, function (response) {
129836                 var item = _items[response];
129837
129838                 if (item && item.callback) {
129839                     item.callback();
129840                 }
129841
129842                 return !!utils.count(_items);
129843             });
129844         }
129845     },
129846
129847     clearMenuItems: function () {
129848         _items = {};
129849         transport.call(_uri + "clearMenuItems");
129850     },
129851
129852     getMenuItems: function () {
129853         return utils.map(_items, function (item) {
129854             var menuItem = new MenuItem(item.isSeparator, item.ordinal, item.caption, item.callback);
129855             menuItem.id = item.id;
129856             menuItem.isDefault = item.isDefault;
129857             return menuItem;
129858         });
129859     },
129860
129861     hasMenuItem: function (menuItem) {
129862         return !!_items[menuItem.id];
129863     },
129864
129865     open: function () {
129866         transport.call(_uri + "open", {async: true});
129867     },
129868
129869     removeMenuItem: function (menuItem) {
129870         delete _items[menuItem.id];
129871         transport.call(_uri + "removeMenuItem", {
129872             get: {item: menuItem}
129873         });
129874     },
129875
129876     setDefaultMenuItem: function (menuItem) {
129877         utils.forEach(_items, function (item) {
129878             item.isDefault = false;
129879         });
129880
129881         _items[menuItem.id].isDefault = true;
129882
129883         transport.call(_uri + "setDefaultMenuItem", {
129884             get: {id: menuItem.id}
129885         });
129886     }
129887 };
129888
129889 module.exports = _self;
129890
129891 });
129892 define('ripple/platform/webworks.handset/2.0.0/client/MessageArguments', function (require, exports, module) {
129893 /*
129894  *  Copyright 2011 Research In Motion Limited.
129895  *
129896  * Licensed under the Apache License, Version 2.0 (the "License");
129897  * you may not use this file except in compliance with the License.
129898  * You may obtain a copy of the License at
129899  *
129900  * http://www.apache.org/licenses/LICENSE-2.0
129901  *
129902  * Unless required by applicable law or agreed to in writing, software
129903  * distributed under the License is distributed on an "AS IS" BASIS,
129904  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
129905  * See the License for the specific language governing permissions and
129906  * limitations under the License.
129907  */
129908 //blackberry.invoke.MessageArguments ( )
129909 //blackberry.invoke.MessageArguments ( message : blackberry.message.Message )
129910 //blackberry.invoke.MessageArguments ( to : String ,  subject : String ,  body : String )
129911 var _self = function () {
129912     return {
129913         view: 1
129914     };
129915 };
129916
129917 //const Number  VIEW_NEW  = 0
129918 _self.__defineGetter__("VIEW_NEW", function () {
129919     return 0;
129920 });
129921 //const Number  VIEW_DEFAULT  = 1
129922 _self.__defineGetter__("VIEW_DEFAULT", function () {
129923     return 1;
129924 });
129925 //const Number  VIEW_SAVED  = 2
129926 _self.__defineGetter__("VIEW_SAVED", function () {
129927     return 2;
129928 });
129929 //const Number  VIEW_SEARCH  = 3
129930 _self.__defineGetter__("VIEW_SEARCH", function () {
129931     return 3;
129932 });
129933
129934 module.exports = _self;
129935
129936 });
129937 define('ripple/platform/webworks.handset/2.0.0/client/app', function (require, exports, module) {
129938 /*\r
129939  *  Copyright 2011 Research In Motion Limited.\r
129940  *\r
129941  * Licensed under the Apache License, Version 2.0 (the "License");\r
129942  * you may not use this file except in compliance with the License.\r
129943  * You may obtain a copy of the License at\r
129944  *\r
129945  * http://www.apache.org/licenses/LICENSE-2.0\r
129946  *\r
129947  * Unless required by applicable law or agreed to in writing, software\r
129948  * distributed under the License is distributed on an "AS IS" BASIS,\r
129949  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
129950  * See the License for the specific language governing permissions and\r
129951  * limitations under the License.\r
129952  */\r
129953 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
129954     _uri = "blackberry/app/",\r
129955     _self;\r
129956 \r
129957 _self = {\r
129958     exit: function () {\r
129959         transport.call(_uri + "exit", {async: true});\r
129960     },\r
129961 \r
129962     setHomeScreenIcon: function (uri, hover) {\r
129963         transport.call(_uri + "setHomeScreenIcon", {\r
129964             get: {\r
129965                 uri: uri,\r
129966                 hover: hover\r
129967             },\r
129968             async: true\r
129969         });\r
129970 \r
129971         return true;\r
129972     },\r
129973 \r
129974     setHomeScreenName: function (text) {\r
129975         transport.call(_uri + "setHomeScreenName", {\r
129976             get: {text: text},\r
129977             async: true\r
129978         });\r
129979 \r
129980         return true;\r
129981     },\r
129982 \r
129983     requestForeground: function () {\r
129984         transport.call(_uri + "requestForeground", {async: true});\r
129985     },\r
129986 \r
129987     requestBackground: function () {\r
129988         transport.call(_uri + "requestBackground", {async: true});\r
129989     },\r
129990 \r
129991     removeBannerIndicator: function () {\r
129992         transport.call(_uri + "removeBannerIndicator", {async: true});\r
129993     },\r
129994 \r
129995     showBannerIndicator: function (icon, count) {\r
129996         transport.call(_uri + "showBannerIndicator", {\r
129997             get: {\r
129998                 icon: icon,\r
129999                 count: count\r
130000             },\r
130001             async: true\r
130002         });\r
130003     },\r
130004 };\r
130005 \r
130006 _self.__defineGetter__("author", function () {\r
130007     return transport.call(_uri + "author");\r
130008 });\r
130009 \r
130010 _self.__defineGetter__("authorEmail", function () {\r
130011     return transport.call(_uri + "authorEmail");\r
130012 });\r
130013 \r
130014 _self.__defineGetter__("authorURL", function () {\r
130015     return transport.call(_uri + "authorURL");\r
130016 });\r
130017 \r
130018 _self.__defineGetter__("copyright", function () {\r
130019     return transport.call(_uri + "copyright");\r
130020 });\r
130021 \r
130022 _self.__defineGetter__("description", function () {\r
130023     return transport.call(_uri + "description");\r
130024 });\r
130025 \r
130026 _self.__defineGetter__("id", function () {\r
130027     return transport.call(_uri + "id");\r
130028 });\r
130029 \r
130030 _self.__defineGetter__("isForeground", function () {\r
130031     return transport.call(_uri + "isForeground");\r
130032 });\r
130033 \r
130034 _self.__defineGetter__("license", function () {\r
130035     return transport.call(_uri + "license");\r
130036 });\r
130037 \r
130038 _self.__defineGetter__("licenseURL", function () {\r
130039     return transport.call(_uri + "licenseURL");\r
130040 });\r
130041 \r
130042 _self.__defineGetter__("name", function () {\r
130043     return transport.call(_uri + "name");\r
130044 });\r
130045 \r
130046 _self.__defineGetter__("version", function () {\r
130047     return transport.call(_uri + "version");\r
130048 });\r
130049 \r
130050 module.exports = _self;\r
130051
130052 });
130053 define('ripple/platform/webworks.handset/2.0.0/client/Reminder', function (require, exports, module) {
130054 /*
130055  *  Copyright 2011 Research In Motion Limited.
130056  *
130057  * Licensed under the Apache License, Version 2.0 (the "License");
130058  * you may not use this file except in compliance with the License.
130059  * You may obtain a copy of the License at
130060  *
130061  * http://www.apache.org/licenses/LICENSE-2.0
130062  *
130063  * Unless required by applicable law or agreed to in writing, software
130064  * distributed under the License is distributed on an "AS IS" BASIS,
130065  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130066  * See the License for the specific language governing permissions and
130067  * limitations under the License.
130068  */
130069 var Reminder = function () {
130070
130071     return {
130072         //readwrite  property  Date   date
130073         //readwrite  property  Number   relativeHours
130074         //readwrite  property  Number   type
130075
130076         date: null,
130077         relativeHours: null,
130078         type: null
130079
130080     };
130081
130082 };
130083
130084 Reminder.__defineGetter__("DATE", function () {
130085     return 0;
130086 });
130087
130088 Reminder.__defineGetter__("RELATIVE", function () {
130089     return 1;
130090 });
130091
130092 module.exports = Reminder;
130093
130094 });
130095 define('ripple/platform/webworks.handset/2.0.0/client/invoke', function (require, exports, module) {
130096 /*\r
130097  *  Copyright 2011 Research In Motion Limited.\r
130098  *\r
130099  * Licensed under the Apache License, Version 2.0 (the "License");\r
130100  * you may not use this file except in compliance with the License.\r
130101  * You may obtain a copy of the License at\r
130102  *\r
130103  * http://www.apache.org/licenses/LICENSE-2.0\r
130104  *\r
130105  * Unless required by applicable law or agreed to in writing, software\r
130106  * distributed under the License is distributed on an "AS IS" BASIS,\r
130107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
130108  * See the License for the specific language governing permissions and\r
130109  * limitations under the License.\r
130110  */\r
130111 var _uri = "blackberry/invoke/invoke",\r
130112     APP_URL_CAMERA = "camera://",\r
130113     APP_URL_CAMERA_VIDEO = "camera://video",\r
130114     APP_URL_MAP = "map://",\r
130115     APP_URL_MUSIC = "music://",\r
130116     APP_URL_PHOTOS = "photos://",\r
130117     APP_URL_VIDEOS = "videos://",\r
130118     APP_URL_APPWORLD = "appworld://",\r
130119     APP_URL_UPDATE = "update://",\r
130120     APP_BROWSER_ERROR = "Protocol specified in the url is not supported.",\r
130121     APP_ADDRESSBOOK_ERROR = "Invalid arguments specified",\r
130122     transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
130123     _self;\r
130124 \r
130125 _self = {\r
130126     invoke: function (appType, args) {\r
130127         var get = {};\r
130128 \r
130129         switch (appType) {\r
130130 \r
130131         //AddressBook\r
130132         case 0:\r
130133             if (args) {\r
130134                 if (args.view === 1 && args.contact) {\r
130135                     throw APP_ADDRESSBOOK_ERROR; //contact cannot be used with this view\r
130136                 }\r
130137                 else if (args.view === 2 && !args.contact) {\r
130138                     throw APP_ADDRESSBOOK_ERROR; //need contact for this view\r
130139                 }\r
130140             }\r
130141 \r
130142             get.appType = appType;\r
130143             break;\r
130144 \r
130145         //Bluetooth Config\r
130146         case 1:\r
130147             get.appType = appType;\r
130148             break;\r
130149 \r
130150         //Calculator\r
130151         case 2:\r
130152             get.appType = appType;\r
130153             break;\r
130154 \r
130155         //Calendar\r
130156         case 3:\r
130157             get.appType = appType;\r
130158             break;\r
130159 \r
130160         //Camera\r
130161         case 4:\r
130162             if (!args || args.view === 1) {\r
130163                 get.appType = APP_URL_CAMERA_VIDEO;\r
130164             } else {\r
130165                 get.appType = APP_URL_CAMERA;\r
130166             }\r
130167             break;\r
130168 \r
130169         //Maps\r
130170         case 5:\r
130171             get.appType = APP_URL_MAP;\r
130172             break;\r
130173 \r
130174         //Memopad\r
130175         case 6:\r
130176             get.appType = appType;\r
130177             break;\r
130178 \r
130179         //Messages\r
130180         case 7:\r
130181             get.appType = appType;\r
130182             break;\r
130183 \r
130184         //Phone\r
130185         case 8:\r
130186             get.appType = appType;\r
130187             break;\r
130188 \r
130189         //Search\r
130190         case 9:\r
130191             get.appType = appType;\r
130192             break;\r
130193 \r
130194         //Tasks\r
130195         case 10:\r
130196             get.appType = appType;\r
130197             break;\r
130198 \r
130199         //Browser\r
130200         case 11:\r
130201 \r
130202             if (!args) {\r
130203                 get.appType = "http://";\r
130204             } else {\r
130205                 if (args.url && !args.url.match(/^https?:\/\//)) {\r
130206                     throw APP_BROWSER_ERROR;\r
130207                 }\r
130208                 get.appType = args.url;\r
130209             }\r
130210 \r
130211             break;\r
130212 \r
130213         //Java\r
130214         case 12:\r
130215             get.appType = appType;\r
130216             break;\r
130217 \r
130218         default:\r
130219             throw "appType not supported";\r
130220         }\r
130221 \r
130222         transport.call(_uri, {\r
130223             get: get,\r
130224             async: true\r
130225         });\r
130226     }\r
130227 };\r
130228 \r
130229 _self.__defineGetter__("APP_ADDRESSBOOK", function () {\r
130230     return 0;\r
130231 });\r
130232 _self.__defineGetter__("APP_BLUETOOTH_CONFIG", function () {\r
130233     return 1;\r
130234 });\r
130235 _self.__defineGetter__("APP_CALCULATOR", function () {\r
130236     return 2;\r
130237 });\r
130238 _self.__defineGetter__("APP_CALENDAR", function () {\r
130239     return 3;\r
130240 });\r
130241 _self.__defineGetter__("APP_CAMERA", function () {\r
130242     return 4;\r
130243 });\r
130244 _self.__defineGetter__("APP_MAPS", function () {\r
130245     return 5;\r
130246 });\r
130247 _self.__defineGetter__("APP_MEMOPAD", function () {\r
130248     return 6;\r
130249 });\r
130250 _self.__defineGetter__("APP_MESSAGES", function () {\r
130251     return 7;\r
130252 });\r
130253 _self.__defineGetter__("APP_PHONE", function () {\r
130254     return 8;\r
130255 });\r
130256 _self.__defineGetter__("APP_SEARCH", function () {\r
130257     return 9;\r
130258 });\r
130259 _self.__defineGetter__("APP_TASKS", function () {\r
130260     return 10;\r
130261 });\r
130262 _self.__defineGetter__("APP_BROWSER", function () {\r
130263     return 11;\r
130264 });\r
130265 _self.__defineGetter__("APP_JAVA", function () {\r
130266     return 12;\r
130267 });\r
130268 \r
130269 module.exports = _self;\r
130270
130271 });
130272 define('ripple/platform/webworks.handset/2.0.0/client/AddressBookArguments', function (require, exports, module) {
130273 /*
130274  *  Copyright 2011 Research In Motion Limited.
130275  *
130276  * Licensed under the Apache License, Version 2.0 (the "License");
130277  * you may not use this file except in compliance with the License.
130278  * You may obtain a copy of the License at
130279  *
130280  * http://www.apache.org/licenses/LICENSE-2.0
130281  *
130282  * Unless required by applicable law or agreed to in writing, software
130283  * distributed under the License is distributed on an "AS IS" BASIS,
130284  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130285  * See the License for the specific language governing permissions and
130286  * limitations under the License.
130287  */
130288 //blackberry.invoke.AddressBookArguments ( [contact : blackberry.pim.Contact ] )
130289 var _self = function (contact) {
130290     return {
130291         contact: contact,
130292         //readwrite  property  Number   view
130293         view: 0
130294     };
130295 };
130296
130297 //const Number  VIEW_NEW  = 0
130298 _self.__defineGetter__("VIEW_NEW", function () {
130299     return 0;
130300 });
130301 //const Number  VIEW_COMPOSE  = 1
130302 _self.__defineGetter__("VIEW_COMPOSE", function () {
130303     return 1;
130304 });
130305 //const Number  VIEW_DISPLAY  = 2
130306 _self.__defineGetter__("VIEW_DISPLAY", function () {
130307     return 2;
130308 });
130309
130310 module.exports = _self;
130311
130312 });
130313 define('ripple/platform/webworks.handset/2.0.0/client/Phone', function (require, exports, module) {
130314 /*
130315  *  Copyright 2011 Research In Motion Limited.
130316  *
130317  * Licensed under the Apache License, Version 2.0 (the "License");
130318  * you may not use this file except in compliance with the License.
130319  * You may obtain a copy of the License at
130320  *
130321  * http://www.apache.org/licenses/LICENSE-2.0
130322  *
130323  * Unless required by applicable law or agreed to in writing, software
130324  * distributed under the License is distributed on an "AS IS" BASIS,
130325  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130326  * See the License for the specific language governing permissions and
130327  * limitations under the License.
130328  */
130329 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
130330     _uri = "blackberry/phone/",
130331     _listeners = {},
130332     _self;
130333
130334 _self = {
130335     activeCalls: function () {
130336         return transport.call(_uri + "activeCalls");
130337     },
130338
130339     addPhoneListener: function (callback, eventType) {
130340         var assigned = false;
130341
130342         if (callback && typeof eventType === "number") {
130343             _listeners[eventType] = callback;
130344             assigned = true;
130345         } else if (eventType && callback === null) {
130346             delete _listeners[eventType];
130347         } else {
130348             _listeners = {};
130349         }
130350
130351         transport.poll(_uri + "onPhoneEvent", {
130352             get: {eventType: eventType}
130353         }, function (response) {
130354             var func = _listeners[eventType];
130355
130356             if (func) {
130357                 func(response.callId, response.error);
130358             }
130359
130360             return !!func;
130361         });
130362
130363         // hackish (return true that event was assigned, this is a disconnect between transport poll api and server)
130364         return assigned;
130365     },
130366
130367     inActiveCall: function () {
130368         return transport.call(_uri + "inActiveCall");
130369     }
130370 };
130371
130372 _self.__defineGetter__("CB_CALL_INITIATED", function () {
130373     return 0;
130374 });
130375 _self.__defineGetter__("CB_CALL_WAITING", function () {
130376     return 1;
130377 });
130378 _self.__defineGetter__("CB_CALL_INCOMING", function () {
130379     return 2;
130380 });
130381 _self.__defineGetter__("CB_CALL_ANSWERED", function () {
130382     return 3;
130383 });
130384 _self.__defineGetter__("CB_CALL_CONNECTED", function () {
130385     return 4;
130386 });
130387 _self.__defineGetter__("CB_CALL_CONFERENCECALL_ESTABLISHED", function () {
130388     return 5;
130389 });
130390 _self.__defineGetter__("CB_CONFERENCECALL_DISCONNECTED", function () {
130391     return 6;
130392 });
130393 _self.__defineGetter__("CB_CALL_DISCONNECTED", function () {
130394     return 7;
130395 });
130396 _self.__defineGetter__("CB_CALL_DIRECTCONNECT_CONNECTED", function () {
130397     return 8;
130398 });
130399 _self.__defineGetter__("CB_CALL_DIRECTCONNECT_DISCONNECTED", function () {
130400     return 9;
130401 });
130402 _self.__defineGetter__("CB_CALL_ENDED_BYUSER", function () {
130403     return 10;
130404 });
130405 _self.__defineGetter__("CB_CALL_FAILED", function () {
130406     return 11;
130407 });
130408 _self.__defineGetter__("CB_CALL_RESUMED", function () {
130409     return 12;
130410 });
130411 _self.__defineGetter__("CB_CALL_HELD", function () {
130412     return 13;
130413 });
130414 _self.__defineGetter__("CB_CALL_ADDED", function () {
130415     return 14;
130416 });
130417 _self.__defineGetter__("CB_CALL_REMOVED", function () {
130418     return 15;
130419 });
130420 _self.__defineGetter__("CALL_ERROR_SUBSCRIBER_BUSY", function () {
130421     return 1;
130422 });
130423 _self.__defineGetter__("CALL_ERROR_CONGESTION", function () {
130424     return 2;
130425 });
130426 _self.__defineGetter__("CALL_ERROR_RADIO_PATH_UNAVAILABLE", function () {
130427     return 3;
130428 });
130429 _self.__defineGetter__("CALL_ERROR_NUMBER_UNOBTAINABLE", function () {
130430     return 4;
130431 });
130432 _self.__defineGetter__("CALL_ERROR_AUTHORIZATION_FAILURE", function () {
130433     return 5;
130434 });
130435 _self.__defineGetter__("CALL_ERROR_EMERGENCY_CALLS_ONLY", function () {
130436     return 6;
130437 });
130438 _self.__defineGetter__("CALL_ERROR_HOLD_ERROR", function () {
130439     return 7;
130440 });
130441 _self.__defineGetter__("CALL_ERROR_OUTGOING_CALLS_BARRED", function () {
130442     return 8;
130443 });
130444 _self.__defineGetter__("CALL_ERROR_GENERAL", function () {
130445     return 9;
130446 });
130447 _self.__defineGetter__("CALL_ERROR_MAINTENANCE_REQUIRED", function () {
130448     return 10;
130449 });
130450 _self.__defineGetter__("CALL_ERROR_SERVICE_NOT_AVAILABLE", function () {
130451     return 11;
130452 });
130453 _self.__defineGetter__("CALL_ERROR_DUE_TO_FADING", function () {
130454     return 12;
130455 });
130456 _self.__defineGetter__("CALL_ERROR_LOST_DUE_TO_FADING", function () {
130457     return 13;
130458 });
130459 _self.__defineGetter__("CALL_ERROR_TRY_AGAIN", function () {
130460     return 14;
130461 });
130462 _self.__defineGetter__("CALL_ERROR_FDN_MISMATCH", function () {
130463     return 15;
130464 });
130465 _self.__defineGetter__("CALL_ERROR_CONNECTION_DENIED_BY_NETWORK", function () {
130466     return 16;
130467 });
130468 _self.__defineGetter__("CALL_ERROR_NUMBER_NOT_IN_SERVICE", function () {
130469     return 17;
130470 });
130471 _self.__defineGetter__("CALL_ERROR_PLEASE_TRY_LATER", function () {
130472     return 18;
130473 });
130474 _self.__defineGetter__("CALL_ERROR_SERVICE_CONFLICT", function () {
130475     return 19;
130476 });
130477 _self.__defineGetter__("CALL_ERROR_SYSTEM_BUSY_TRY_LATER", function () {
130478     return 20;
130479 });
130480 _self.__defineGetter__("CALL_ERROR_USER_BUSY_IN_PRIVATE", function () {
130481     return 21;
130482 });
130483 _self.__defineGetter__("CALL_ERROR_USER_BUSY_IN_DATA", function () {
130484     return 22;
130485 });
130486 _self.__defineGetter__("CALL_ERROR_USER_NOT_AUTHORIZED", function () {
130487     return 23;
130488 });
130489 _self.__defineGetter__("CALL_ERROR_USER_NOT_AVAILABLE", function () {
130490     return 24;
130491 });
130492 _self.__defineGetter__("CALL_ERROR_USER_UNKNOWN", function () {
130493     return 25;
130494 });
130495 _self.__defineGetter__("CALL_ERROR_USER_NOT_REACHABLE", function () {
130496     return 26;
130497 });
130498 _self.__defineGetter__("CALL_ERROR_INCOMING_CALL_BARRED", function () {
130499     return 27;
130500 });
130501 _self.__defineGetter__("CALL_ERROR_CALL_REPLACED_BY_STK", function () {
130502     return 28;
130503 });
130504 _self.__defineGetter__("CALL_ERROR_STK_CALL_NOT_ALLOWED", function () {
130505     return 29;
130506 });
130507
130508 module.exports = _self;
130509
130510 });
130511 define('ripple/platform/webworks.handset/2.0.0/client/audio', function (require, exports, module) {
130512 /*
130513  *  Copyright 2011 Research In Motion Limited.
130514  *
130515  * Licensed under the Apache License, Version 2.0 (the "License");
130516  * you may not use this file except in compliance with the License.
130517  * You may obtain a copy of the License at
130518  *
130519  * http://www.apache.org/licenses/LICENSE-2.0
130520  *
130521  * Unless required by applicable law or agreed to in writing, software
130522  * distributed under the License is distributed on an "AS IS" BASIS,
130523  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130524  * See the License for the specific language governing permissions and
130525  * limitations under the License.
130526  */
130527 module.exports = {
130528     supportedContentTypes: function (protocol) {
130529         return protocol === 'rtsp' ?
130530             ['audio/amr', 'audio/mp4', 'audio/aac'] :
130531             ['audio/midi', 'mpeg', 'x-wav', 'amr', 'basic', 'x-gsm', 'mp4', 'aac', 'x-ms-wma', 'flac', 'ogg'];
130532     },
130533     supportedProtocols: function (contentType) {
130534         return ['http', 'file', 'rtsp'];
130535     }
130536 };
130537
130538 });
130539 define('ripple/platform/webworks.handset/2.0.0/client/MapsArguments', function (require, exports, module) {
130540 /*
130541  *  Copyright 2011 Research In Motion Limited.
130542  *
130543  * Licensed under the Apache License, Version 2.0 (the "License");
130544  * you may not use this file except in compliance with the License.
130545  * You may obtain a copy of the License at
130546  *
130547  * http://www.apache.org/licenses/LICENSE-2.0
130548  *
130549  * Unless required by applicable law or agreed to in writing, software
130550  * distributed under the License is distributed on an "AS IS" BASIS,
130551  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130552  * See the License for the specific language governing permissions and
130553  * limitations under the License.
130554  */
130555 //blackberry.invoke.MapsArguments ( )
130556 //blackberry.invoke.MapsArguments ( latitude : Number ,  longitude : Number )
130557 //blackberry.invoke.MapsArguments ( locationDocument : Document ) - Supported in 5.0.0 only
130558 //blackberry.invoke.MapsArguments ( locationDocument : String ) - Supported in 6.0.0 only
130559 //blackberry.invoke.MapsArguments ( address : blackberry.pim.Address )
130560 var _self = function () {
130561     return {};
130562 };
130563
130564 module.exports = _self;
130565
130566 });
130567 define('ripple/platform/webworks.handset/2.0.0/client/Address', function (require, exports, module) {
130568 /*
130569  *  Copyright 2011 Research In Motion Limited.
130570  *
130571  * Licensed under the Apache License, Version 2.0 (the "License");
130572  * you may not use this file except in compliance with the License.
130573  * You may obtain a copy of the License at
130574  *
130575  * http://www.apache.org/licenses/LICENSE-2.0
130576  *
130577  * Unless required by applicable law or agreed to in writing, software
130578  * distributed under the License is distributed on an "AS IS" BASIS,
130579  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130580  * See the License for the specific language governing permissions and
130581  * limitations under the License.
130582  */
130583 function Address() {
130584     return {
130585         //readwrite  property  String   address1
130586         //readwrite  property  String   address2
130587         //readwrite  property  String   city
130588         //readwrite  property  String   country
130589         //readwrite  property  String   stateProvince
130590         //readwrite  property  String   zipPostal
130591
130592         address1: null,
130593         address2: null,
130594         city: null,
130595         country: null,
130596         stateProvince: null,
130597         zipPostal: null
130598     };
130599 }
130600
130601 module.exports = Address;
130602
130603 });
130604 define('ripple/platform/webworks.handset/2.0.0/client/PhoneLogs', function (require, exports, module) {
130605 /*
130606  *  Copyright 2011 Research In Motion Limited.
130607  *
130608  * Licensed under the Apache License, Version 2.0 (the "License");
130609  * you may not use this file except in compliance with the License.
130610  * You may obtain a copy of the License at
130611  *
130612  * http://www.apache.org/licenses/LICENSE-2.0
130613  *
130614  * Unless required by applicable law or agreed to in writing, software
130615  * distributed under the License is distributed on an "AS IS" BASIS,
130616  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130617  * See the License for the specific language governing permissions and
130618  * limitations under the License.
130619  */
130620 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
130621     CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
130622     utils = require('ripple/utils'),
130623     _onCallLog = {
130624         Added: null,
130625         Removed: null,
130626         Updated: null,
130627         Reset: null,
130628     },
130629     _uri = "blackberry/phone/logs/",
130630     _self;
130631
130632 function _massage(property, name) {
130633     if (name === "date" && property) {
130634         return new Date(property);
130635     }
130636     return property;
130637 }
130638
130639 function _toCallLog(log) {
130640     var callLog = new CallLog(),
130641         prop;
130642     for (prop in log) {
130643         if (log.hasOwnProperty(prop)) {
130644             callLog[prop] = _massage(log[prop], prop);
130645         }
130646     }
130647     return callLog;
130648 }
130649
130650 function handle(evt) {
130651     return function (response) {
130652         var func = _onCallLog[evt], args;
130653
130654         if (func) {
130655             args = utils.map(response, function (value) {
130656                 return _toCallLog(value);
130657             });
130658             func.apply(null, args);
130659         }
130660
130661         return !!func;
130662     };
130663 }
130664
130665 function poll(path) {
130666     transport.poll(_uri + path, {}, handle(path.replace("onCallLog", "")));
130667 }
130668
130669 _self = {
130670     addPhoneLogListener: function (onCallLogAdded, onCallLogRemoved, onCallLogUpdated, onCallLogReset) {
130671         _onCallLog.Added = onCallLogAdded;
130672         _onCallLog.Removed = onCallLogRemoved;
130673         _onCallLog.Updated = onCallLogUpdated;
130674         _onCallLog.Reset = onCallLogReset;
130675
130676         if (onCallLogAdded) {
130677             poll("onCallLogAdded");
130678         }
130679
130680         if (onCallLogRemoved) {
130681             poll("onCallLogRemoved");
130682         }
130683
130684         if (onCallLogUpdated) {
130685             poll("onCallLogUpdated");
130686         }
130687
130688         if (onCallLogReset) {
130689             poll("onCallLogReset");
130690         }
130691
130692         return !!(onCallLogAdded || onCallLogRemoved ||
130693                   onCallLogUpdated || onCallLogRemoved);
130694     },
130695
130696     callAt: function (index, folderID) {
130697         var log = transport.call(_uri + "callAt", {
130698             get: {
130699                 index: index,
130700                 folderID: folderID
130701             }
130702         });
130703
130704         if (log && log.date) {
130705             log.date = new Date(log.date);
130706         }
130707
130708         return log;
130709     },
130710
130711     deleteCallAt: function (index, folderID) {
130712         return transport.call(_uri + "deleteCallAt", {
130713             get: {
130714                 index: index,
130715                 folderID: folderID
130716             }
130717         });
130718     },
130719
130720     find: function (filter, folderID, orderBy, maxReturn, isAscending) {
130721         return transport.call(_uri + "find", {
130722             post: {
130723                 filter: filter,
130724                 folderID: folderID,
130725                 orderBy: orderBy,
130726                 maxReturn: maxReturn,
130727                 isAscending: isAscending
130728             }
130729         }).map(_toCallLog);
130730     },
130731
130732     numberOfCalls: function (folderID) {
130733         return transport.call(_uri + "numberOfCalls", {
130734             get: {
130735                 folderID: folderID
130736             }
130737         });
130738     }
130739 };
130740
130741 _self.__defineGetter__("FOLDER_MISSED_CALLS", function () {
130742     return 0;
130743 });
130744
130745 _self.__defineGetter__("FOLDER_NORMAL_CALLS", function () {
130746     return 1;
130747 });
130748
130749 module.exports = _self;
130750
130751 });
130752 define('ripple/platform/webworks.handset/2.0.0/client/systemEvent', function (require, exports, module) {
130753 /*
130754  *  Copyright 2011 Research In Motion Limited.
130755  *
130756  * Licensed under the Apache License, Version 2.0 (the "License");
130757  * you may not use this file except in compliance with the License.
130758  * You may obtain a copy of the License at
130759  *
130760  * http://www.apache.org/licenses/LICENSE-2.0
130761  *
130762  * Unless required by applicable law or agreed to in writing, software
130763  * distributed under the License is distributed on an "AS IS" BASIS,
130764  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130765  * See the License for the specific language governing permissions and
130766  * limitations under the License.
130767  */
130768 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
130769     utils = require('ripple/utils'),
130770     _self,
130771         _callbacks = {};
130772
130773 function _poll(evt, args, callback) {
130774     _callbacks[evt + args.key] = callback;
130775
130776     transport.poll("blackberry/system/event/" + evt, {get: args}, function () {
130777         var func = _callbacks[evt + args.key];
130778
130779         if (func) {
130780             func();
130781         }
130782
130783         return !!func;
130784     });
130785 }
130786
130787 _self = {
130788     onCoverageChange: function (callback) {
130789         _poll("onCoverageChange", {}, callback);
130790     },
130791
130792     onHardwareKey: function (key, callback) {
130793         _poll("onHardwareKey", {key: key}, callback);
130794     }
130795 };
130796
130797 _self.__defineGetter__("KEY_BACK", function () {
130798     return 0;
130799 });
130800 _self.__defineGetter__("KEY_MENU", function () {
130801     return 1;
130802 });
130803 _self.__defineGetter__("KEY_CONVENIENCE_1", function () {
130804     return 2;
130805 });
130806 _self.__defineGetter__("KEY_CONVENIENCE_2", function () {
130807     return 3;
130808 });
130809 _self.__defineGetter__("KEY_STARTCALL", function () {
130810     return 4;
130811 });
130812 _self.__defineGetter__("KEY_ENDCALL", function () {
130813     return 5;
130814 });
130815 _self.__defineGetter__("KEY_VOLUMEDOWN", function () {
130816     return 6;
130817 });
130818 _self.__defineGetter__("KEY_VOLUMEUP", function () {
130819     return 7;
130820 });
130821
130822 module.exports = _self;
130823
130824 });
130825 define('ripple/platform/webworks.handset/2.0.0/client/SearchArguments', function (require, exports, module) {
130826 /*
130827  *  Copyright 2011 Research In Motion Limited.
130828  *
130829  * Licensed under the Apache License, Version 2.0 (the "License");
130830  * you may not use this file except in compliance with the License.
130831  * You may obtain a copy of the License at
130832  *
130833  * http://www.apache.org/licenses/LICENSE-2.0
130834  *
130835  * Unless required by applicable law or agreed to in writing, software
130836  * distributed under the License is distributed on an "AS IS" BASIS,
130837  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130838  * See the License for the specific language governing permissions and
130839  * limitations under the License.
130840  */
130841 //blackberry.invoke.SearchArguments ( )
130842 //blackberry.invoke.SearchArguments ( text : String ,  name : String )
130843 var _self = function (text, name) {
130844
130845     return {
130846         text: text,
130847         name: name
130848     };
130849
130850 };
130851
130852 module.exports = _self;
130853
130854 });
130855 define('ripple/platform/webworks.handset/2.0.0/client/Memo', function (require, exports, module) {
130856 /*
130857  *  Copyright 2011 Research In Motion Limited.
130858  *
130859  * Licensed under the Apache License, Version 2.0 (the "License");
130860  * you may not use this file except in compliance with the License.
130861  * You may obtain a copy of the License at
130862  *
130863  * http://www.apache.org/licenses/LICENSE-2.0
130864  *
130865  * Unless required by applicable law or agreed to in writing, software
130866  * distributed under the License is distributed on an "AS IS" BASIS,
130867  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130868  * See the License for the specific language governing permissions and
130869  * limitations under the License.
130870  */
130871 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
130872     _uri = "blackberry/pim/memo/";
130873
130874 function Memo() {
130875     var _self = {
130876         categories: [],
130877         note: null,
130878         title: null,
130879         uid: null,
130880         remove: function () {
130881             transport.call(_uri + "remove", {
130882                 get: {uid: _self.uid}
130883             });
130884         },
130885         save: function () {
130886             if (_self.uid  === null) {
130887                 _self.uid  = Number(Math.uuid(8, 10));
130888             }
130889             transport.call(_uri + "save", {
130890                 post: {memo: _self}
130891             });
130892         }
130893     };
130894
130895     return _self;
130896 }
130897
130898 Memo.find = function (filter, orderBy, maxReturn, service, isAscending) {
130899     var opts = {
130900         post: {
130901             filter: filter,
130902             orderBy: orderBy,
130903             maxReturn: maxReturn,
130904             isAscending: isAscending,
130905             service: service
130906         }
130907     };
130908
130909     return transport.call(_uri + "find", opts).map(function (obj) {
130910         var memo = new Memo();
130911         memo.uid = obj.uid;
130912         memo.categories = obj.categories || [];
130913         memo.note = obj.note;
130914         memo.title = obj.title;
130915         return memo;
130916     });
130917 };
130918
130919 module.exports = Memo;
130920
130921 });
130922 define('ripple/platform/webworks.handset/2.0.0/client/push', function (require, exports, module) {
130923 /*
130924  *  Copyright 2011 Research In Motion Limited.
130925  *
130926  * Licensed under the Apache License, Version 2.0 (the "License");
130927  * you may not use this file except in compliance with the License.
130928  * You may obtain a copy of the License at
130929  *
130930  * http://www.apache.org/licenses/LICENSE-2.0
130931  *
130932  * Unless required by applicable law or agreed to in writing, software
130933  * distributed under the License is distributed on an "AS IS" BASIS,
130934  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130935  * See the License for the specific language governing permissions and
130936  * limitations under the License.
130937  */
130938 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
130939     _self,
130940     _uri = "blackberry/push/onPush",
130941     callbacks = {},
130942     PushData = require('ripple/platform/webworks.handset/2.0.0/client/PushData');
130943
130944 _self = {
130945     openPushListener: function (callback, port, bbTransport, maxQueueCap) {
130946         callbacks["onPush" + port] = callback;
130947
130948         transport.poll(_uri, {
130949             get: {
130950                 port: port,
130951                 bbTransport: bbTransport,
130952                 maxQueueCap: maxQueueCap
130953             }
130954         }, function (response) {
130955             var func = callbacks["onPush" + port];
130956
130957             if (func) {
130958                 func(new PushData(response, port));
130959             }
130960
130961             return !!func;
130962         });
130963     },
130964
130965     closePushListener: function (port) {
130966         delete callbacks["onPush" + port];
130967     }
130968 };
130969
130970 module.exports = _self;
130971
130972 });
130973 define('ripple/platform/webworks.handset/2.0.0/client/pim', function (require, exports, module) {
130974 /*
130975  *  Copyright 2011 Research In Motion Limited.
130976  *
130977  * Licensed under the Apache License, Version 2.0 (the "License");
130978  * you may not use this file except in compliance with the License.
130979  * You may obtain a copy of the License at
130980  *
130981  * http://www.apache.org/licenses/LICENSE-2.0
130982  *
130983  * Unless required by applicable law or agreed to in writing, software
130984  * distributed under the License is distributed on an "AS IS" BASIS,
130985  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130986  * See the License for the specific language governing permissions and
130987  * limitations under the License.
130988  */
130989 module.exports = {};
130990
130991 });
130992 define('ripple/platform/webworks.handset/2.0.0/client/MemoArguments', function (require, exports, module) {
130993 /*
130994  *  Copyright 2011 Research In Motion Limited.
130995  *
130996  * Licensed under the Apache License, Version 2.0 (the "License");
130997  * you may not use this file except in compliance with the License.
130998  * You may obtain a copy of the License at
130999  *
131000  * http://www.apache.org/licenses/LICENSE-2.0
131001  *
131002  * Unless required by applicable law or agreed to in writing, software
131003  * distributed under the License is distributed on an "AS IS" BASIS,
131004  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131005  * See the License for the specific language governing permissions and
131006  * limitations under the License.
131007  */
131008 //blackberry.invoke.MemoArguments ( [memo : blackberry.pim.Memo ] )
131009 var _self = function (memo) {
131010     return {
131011         memo: memo,
131012         view: 0
131013     };
131014 };
131015
131016 //const Number  VIEW_NEW  = 0
131017 _self.__defineGetter__("VIEW_NEW", function () {
131018     return 0;
131019 });
131020 //const Number  VIEW_EDIT  = 1
131021 _self.__defineGetter__("VIEW_EDIT", function () {
131022     return 1;
131023 });
131024
131025 module.exports = _self;
131026
131027 });
131028 define('ripple/platform/webworks.handset/2.0.0/client/Attendee', function (require, exports, module) {
131029 /*
131030  *  Copyright 2011 Research In Motion Limited.
131031  *
131032  * Licensed under the Apache License, Version 2.0 (the "License");
131033  * you may not use this file except in compliance with the License.
131034  * You may obtain a copy of the License at
131035  *
131036  * http://www.apache.org/licenses/LICENSE-2.0
131037  *
131038  * Unless required by applicable law or agreed to in writing, software
131039  * distributed under the License is distributed on an "AS IS" BASIS,
131040  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131041  * See the License for the specific language governing permissions and
131042  * limitations under the License.
131043  */
131044 function Attendee() {
131045     return {
131046         //readwrite  property  String   address
131047         //readwrite  property  Number   type
131048
131049         address: null,
131050         type: null
131051     };
131052 }
131053
131054 Attendee.__defineGetter__("ORGANIZER", function () {
131055     return 0;
131056 });
131057
131058 Attendee.__defineGetter__("INVITED", function () {
131059     return 1;
131060 });
131061
131062 Attendee.__defineGetter__("ACCEPTED", function () {
131063     return 2;
131064 });
131065
131066 Attendee.__defineGetter__("DECLINED", function () {
131067     return 3;
131068 });
131069
131070 Attendee.__defineGetter__("TENTATIVE", function () {
131071     return 4;
131072 });
131073
131074 module.exports =  Attendee;
131075
131076 });
131077 define('ripple/platform/webworks.handset/2.0.0/client/appEvent', function (require, exports, module) {
131078 /*
131079  *  Copyright 2011 Research In Motion Limited.
131080  *
131081  * Licensed under the Apache License, Version 2.0 (the "License");
131082  * you may not use this file except in compliance with the License.
131083  * You may obtain a copy of the License at
131084  *
131085  * http://www.apache.org/licenses/LICENSE-2.0
131086  *
131087  * Unless required by applicable law or agreed to in writing, software
131088  * distributed under the License is distributed on an "AS IS" BASIS,
131089  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131090  * See the License for the specific language governing permissions and
131091  * limitations under the License.
131092  */
131093 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
131094     _callbacks = {},
131095     _self;
131096
131097 function _poll(evt, handler) {
131098     _callbacks[evt] = handler;
131099
131100     transport.poll("blackberry/app/event/" + evt, {}, function () {
131101         var func = _callbacks[evt];
131102
131103         if (func) {
131104             func();
131105         }
131106
131107         return !!func;
131108     });
131109 }
131110
131111 _self = {
131112     onBackground: function (handler) {
131113         _poll("onBackground", handler);
131114     },
131115
131116     onForeground: function (handler) {
131117         _poll("onForeground", handler);
131118     },
131119
131120     onExit: function (handler) {
131121         _poll("onExit", handler);
131122     }
131123 };
131124
131125 module.exports = _self;
131126
131127 });
131128 define('ripple/platform/webworks.handset/2.0.0/client/blackberry', function (require, exports, module) {
131129 /*
131130  * Copyright 2011 Research In Motion Limited.
131131  *
131132  * Licensed under the Apache License, Version 2.0 (the "License");
131133  * you may not use this file except in compliance with the License.
131134  * You may obtain a copy of the License at
131135  *
131136  *     http://www.apache.org/licenses/LICENSE-2.0
131137  *
131138  * Unless required by applicable law or agreed to in writing, software
131139  * distributed under the License is distributed on an "AS IS" BASIS,
131140  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131141  * See the License for the specific language governing permissions and
131142  * limitations under the License.
131143  */
131144 var blackberry = {},
131145     transport = require('ripple/platform/webworks.core/2.0.0/client/transport');
131146
131147 blackberry.__defineGetter__("network", function () {
131148     return transport.call("blackberry/system/network");
131149 });
131150
131151 module.exports = blackberry;
131152
131153 });
131154 define('ripple/platform/webworks.handset/2.0.0/client/CallLog', function (require, exports, module) {
131155 /*
131156  *  Copyright 2011 Research In Motion Limited.
131157  *
131158  * Licensed under the Apache License, Version 2.0 (the "License");
131159  * you may not use this file except in compliance with the License.
131160  * You may obtain a copy of the License at
131161  *
131162  * http://www.apache.org/licenses/LICENSE-2.0
131163  *
131164  * Unless required by applicable law or agreed to in writing, software
131165  * distributed under the License is distributed on an "AS IS" BASIS,
131166  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131167  * See the License for the specific language governing permissions and
131168  * limitations under the License.
131169  */
131170 function CallLog() {
131171     // readwrite  property  String   addressBookNumber
131172     // readwrite  property  String   addressBookType
131173     // readwrite  property  Date   date
131174     // readwrite  property  Number   duration
131175     // readwrite  property  String   name
131176     // readwrite  property  String   notes
131177     // readwrite  property  String   number
131178     // readwrite  property  Number   status
131179     // readwrite  property  Number   type
131180     this.addressBookNumber = null;
131181     this.addressBookType = null;
131182     this.date = null;
131183     this.duration = null;
131184     this.name = null;
131185     this.notes = null;
131186     this.number = null;
131187     this.status = null;
131188     this.type = null;
131189 }
131190
131191 function _get(val) {
131192     return function () {
131193         return val;
131194     };
131195 }
131196
131197 CallLog.__defineGetter__("STATUS_NORMAL", _get(0));
131198 CallLog.__defineGetter__("STATUS_BUSY", _get(1));
131199 CallLog.__defineGetter__("STATUS_CONGESTION", _get(2));
131200 CallLog.__defineGetter__("STATUS_PATH_UNAVAILABLE", _get(3));
131201 CallLog.__defineGetter__("STATUS_NUMBER_UNOBTAINABLE", _get(4));
131202 CallLog.__defineGetter__("STATUS_AUTHENTICATION_FAILURE", _get(5));
131203 CallLog.__defineGetter__("STATUS_EMERGENCY_CALLS_ONLY", _get(6));
131204 CallLog.__defineGetter__("STATUS_HOLD_ERROR", _get(7));
131205 CallLog.__defineGetter__("STATUS_OUTGOING_CALLS_BARRED", _get(8));
131206 CallLog.__defineGetter__("STATUS_GENERAL_ERROR", _get(9));
131207 CallLog.__defineGetter__("STATUS_MAINTENANCE_REQUIRED", _get(10));
131208 CallLog.__defineGetter__("STATUS_SERVICE_NOT_AVAILABLE", _get(11));
131209 CallLog.__defineGetter__("STATUS_CALL_FAIL_DUE_TO_FADING", _get(12));
131210 CallLog.__defineGetter__("STATUS_CALL_LOST_DUE_TO_FADING", _get(13));
131211 CallLog.__defineGetter__("STATUS_CALL_FAILED_TRY_AGAIN", _get(14));
131212 CallLog.__defineGetter__("STATUS_FDN_MISMATCH", _get(15));
131213 CallLog.__defineGetter__("STATUS_CONNECTION_DENIED", _get(16));
131214 CallLog.__defineGetter__("STATUS_INCOMING_CALL_BARRED", _get(17));
131215 CallLog.__defineGetter__("TYPE_RECEIVED_CALL", _get(0));
131216 CallLog.__defineGetter__("TYPE_PLACED_CALL", _get(1));
131217 CallLog.__defineGetter__("TYPE_MISSED_CALL_UNOPENED", _get(2));
131218 CallLog.__defineGetter__("TYPE_MISSED_CALL_OPENED", _get(3));
131219
131220 module.exports = CallLog;
131221
131222 });
131223 define('ripple/platform/webworks.handset/2.0.0/client/sms', function (require, exports, module) {
131224 /*
131225  *  Copyright 2011 Research In Motion Limited.
131226  *
131227  * Licensed under the Apache License, Version 2.0 (the "License");
131228  * you may not use this file except in compliance with the License.
131229  * You may obtain a copy of the License at
131230  *
131231  * http://www.apache.org/licenses/LICENSE-2.0
131232  *
131233  * Unless required by applicable law or agreed to in writing, software
131234  * distributed under the License is distributed on an "AS IS" BASIS,
131235  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131236  * See the License for the specific language governing permissions and
131237  * limitations under the License.
131238  */
131239 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
131240     _uri = "blackberry/message/sms/",
131241     onReceive,
131242     _self;
131243
131244 _self = {
131245     addReceiveListener: function (callback) {
131246         onReceive = callback;
131247         transport.poll(_uri + "onReceive", {}, function (response) {
131248             if (onReceive) {
131249                 onReceive(response.body, response.from, response.time);
131250             }
131251             return !!onReceive;
131252         });
131253     },
131254
131255     removeReceiveListener: function () {
131256         if (onReceive) {
131257             onReceive = null;
131258             return true;
131259         }
131260
131261         return false;
131262     },
131263
131264     send: function (message, address) {
131265         transport.call(_uri + "send", {
131266             get: {
131267                 message: message,
131268                 address: address
131269             },
131270             async: true
131271         });
131272     }
131273 };
131274
131275 _self.__defineGetter__("isListeningForMessage", function () {
131276     return transport.call(_uri + "isListeningForMessage", {async: false});
131277 });
131278
131279 _self.__defineSetter__("isListeningForMessage", function (value) {
131280     transport.call(_uri + "isListeningForMessage", {
131281         async: false,
131282         get: {isListeningForMessage: value}
131283     });
131284 });
131285
131286 module.exports = _self;
131287
131288 });
131289 define('ripple/platform/webworks.handset/2.0.0/client/MenuItem', function (require, exports, module) {
131290 /*
131291  *  Copyright 2011 Research In Motion Limited.
131292  *
131293  * Licensed under the Apache License, Version 2.0 (the "License");
131294  * you may not use this file except in compliance with the License.
131295  * You may obtain a copy of the License at
131296  *
131297  * http://www.apache.org/licenses/LICENSE-2.0
131298  *
131299  * Unless required by applicable law or agreed to in writing, software
131300  * distributed under the License is distributed on an "AS IS" BASIS,
131301  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131302  * See the License for the specific language governing permissions and
131303  * limitations under the License.
131304  */
131305 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
131306     event = require('ripple/event');
131307
131308 function MenuItem(isSeparator, ordinal, caption, callback) {
131309     var _isDefault = false,
131310         id = Math.uuid();
131311
131312     if (ordinal < 0) {
131313         throw "Ordinal cannot be less than 0";
131314     } else if (isSeparator) {
131315         if (caption !== undefined) {
131316             throw "caption must not be supplied";
131317         } else if (callback !== undefined) {
131318             throw "callback must not be supplied";
131319         }
131320     } else if (!isSeparator) {
131321         if (caption === undefined) {
131322             throw "caption must be supplied";
131323         }
131324     }
131325
131326     this.callback = callback;
131327
131328     this.__defineSetter__("id", function (i) {
131329         id = i;
131330     });
131331
131332     this.__defineGetter__("id", function () {
131333         return id;
131334     });
131335
131336     this.__defineSetter__("caption", function (c) {
131337         caption = c;
131338         event.trigger("MenuItemChanged", [this]);
131339     });
131340
131341     this.__defineGetter__("caption", function () {
131342         return caption;
131343     });
131344
131345     this.__defineSetter__("ordinal", function (o) {
131346         ordinal = o;
131347         event.trigger("MenuItemChanged", [this]);
131348     });
131349
131350     this.__defineGetter__("ordinal", function () {
131351         return ordinal;
131352     });
131353
131354     this.__defineGetter__("isSeparator", function () {
131355         return isSeparator;
131356     });
131357
131358     this.__defineSetter__("isDefault", function (d) {
131359         _isDefault = d;
131360         event.trigger("MenuItemChanged", [this]);
131361     });
131362
131363     this.__defineGetter__("isDefault", function () {
131364         return _isDefault;
131365     });
131366
131367     this.__defineGetter__("id", function () {
131368         return id;
131369     });
131370 }
131371
131372 module.exports = MenuItem;
131373
131374 });
131375 define('ripple/platform/webworks.handset/2.0.0/client/Contact', function (require, exports, module) {
131376 /*
131377  *  Copyright 2011 Research In Motion Limited.
131378  *
131379  * Licensed under the Apache License, Version 2.0 (the "License");
131380  * you may not use this file except in compliance with the License.
131381  * You may obtain a copy of the License at
131382  *
131383  * http://www.apache.org/licenses/LICENSE-2.0
131384  *
131385  * Unless required by applicable law or agreed to in writing, software
131386  * distributed under the License is distributed on an "AS IS" BASIS,
131387  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131388  * See the License for the specific language governing permissions and
131389  * limitations under the License.
131390  */
131391 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
131392     _uri = "blackberry/pim/contact/";
131393
131394 function Contact(service) {
131395     var _self = {
131396         anniversary: null,
131397         birthday: null,
131398         categories: [],
131399         company: null,
131400         email1: "",
131401         email2: "",
131402         email3: "",
131403         faxPhone: null,
131404         firstName: null,
131405         homeAddress: null,
131406         homePhone: null,
131407         homePhone2: null,
131408         jobTitle: null,
131409         lastName: null,
131410         mobilePhone: null,
131411         note: null,
131412         otherPhone: null,
131413         pagerPhone: null,
131414         picture: null,
131415         pin: null,
131416         title: null,
131417         uid: null,
131418         user1: null,
131419         user2: null,
131420         user3: null,
131421         user4: null,
131422         webpage: null,
131423         workAddress: null,
131424         workPhone: null,
131425         workPhone2: null,
131426         remove: function () {
131427             if (!_self.uid) {
131428                 throw "task has not yet been saved (has no uid)";
131429             }
131430             transport.call(_uri + "remove", {
131431                 get: { id: _self.uid }
131432             });
131433         },
131434         save: function () {
131435             if (!_self.uid) {
131436                 _self.uid = Math.uuid(null, 16);
131437             }
131438             transport.call(_uri + "save", {
131439                 post: { contact: _self }
131440             });
131441         },
131442         setPicture: function (picture) {
131443             throw "not implemented";
131444         }
131445     };
131446
131447     return _self;
131448 }
131449
131450 function _massage(property, name) {
131451     if ((name === "anniversary" || name === "birthday") && property) {
131452         return new Date(property);
131453     }
131454     return property;
131455 }
131456
131457 Contact.find = function (fieldFilter, orderBy, maxReturn, service, isAscending) {
131458     return transport.call(_uri + "find", {
131459         post: {
131460             fieldFilter: fieldFilter,
131461             orderBy: orderBy,
131462             maxReturn: maxReturn,
131463             service: service,
131464             isAscending: isAscending
131465         }
131466     }).map(function (properties) {
131467         var contact = new Contact(),
131468             key;
131469         for (key in properties) {
131470             if (contact.hasOwnProperty(key)) {
131471                 contact[key] = _massage(properties[key], key);
131472             }
131473         }
131474         return contact;
131475     });
131476 };
131477
131478 module.exports = Contact;
131479
131480 });
131481 define('ripple/platform/webworks.handset/2.0.0/client/PhoneCall', function (require, exports, module) {
131482 /*
131483  *  Copyright 2011 Research In Motion Limited.
131484  *
131485  * Licensed under the Apache License, Version 2.0 (the "License");
131486  * you may not use this file except in compliance with the License.
131487  * You may obtain a copy of the License at
131488  *
131489  * http://www.apache.org/licenses/LICENSE-2.0
131490  *
131491  * Unless required by applicable law or agreed to in writing, software
131492  * distributed under the License is distributed on an "AS IS" BASIS,
131493  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131494  * See the License for the specific language governing permissions and
131495  * limitations under the License.
131496  */
131497 function PhoneCall(onhold) {
131498     return {
131499         //Boolean   isOnHold ( )
131500         //readonly  property  Boolean   outgoing
131501         //readonly  property  String   recipientName
131502         //readonly  property  String   recipientNumber
131503
131504         outgoing: false,
131505         recipientName: null,
131506         recipientNumber: null,
131507
131508         isOnHold: function () {
131509             return onhold;
131510         }
131511     };
131512 }
131513
131514 module.exports = PhoneCall;
131515
131516 });
131517 define('ripple/platform/webworks.handset/2.0.0/client/Task', function (require, exports, module) {
131518 /*
131519  *  Copyright 2011 Research In Motion Limited.
131520  *
131521  * Licensed under the Apache License, Version 2.0 (the "License");
131522  * you may not use this file except in compliance with the License.
131523  * You may obtain a copy of the License at
131524  *
131525  * http://www.apache.org/licenses/LICENSE-2.0
131526  *
131527  * Unless required by applicable law or agreed to in writing, software
131528  * distributed under the License is distributed on an "AS IS" BASIS,
131529  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131530  * See the License for the specific language governing permissions and
131531  * limitations under the License.
131532  */
131533 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
131534     _uri = "blackberry/pim/Task/";
131535
131536 function Task() {
131537     var _self = {
131538         save: function () {
131539             if (!_self.uid) {
131540                 _self.uid = Math.uuid(null, 16);
131541             }
131542             transport.call(_uri + "save",  {
131543                 post: {
131544                     task: _self
131545                 }
131546             });
131547         },
131548         remove: function () {
131549             if (!_self.uid) {
131550                 throw "task has not yet been saved (has no uid)";
131551             }
131552             transport.call(_uri + "remove", {
131553                 get: {
131554                     id: _self.uid
131555                 }
131556             });
131557         },
131558         uid: null,
131559         categories: [],
131560         due: null,
131561         note: "",
131562         priority: Task.PRIORITY_NORMAL,
131563         recurrence: null,
131564         reminder: null,
131565         status: Task.NOT_STARTED,
131566         summary: ""
131567     };
131568
131569     return _self;
131570 }
131571
131572 function _massage(property, name) {
131573     if (name === "recurrence" && property) {
131574         if (property.end) {
131575             property.end = new Date(property.end);
131576         }
131577     }
131578     if (name === "reminder" && property) {
131579         if (property.date) {
131580             property.date = new Date(property.date);
131581         }
131582     }
131583     if (name === "due" && property) {
131584         property = new Date(property);
131585     }
131586     return property;
131587 }
131588
131589 Task.find = function (filter, orderBy, maxReturn, isAscending) {
131590     return transport.call(_uri + "find", {
131591         post: {
131592             filter: filter,
131593             orderBy: orderBy,
131594             maxReturn: maxReturn,
131595             isAscending: isAscending
131596         }
131597     }).map(function (properties) {
131598         var task = new Task(),
131599             key;
131600         for (key in properties) {
131601             if (task.hasOwnProperty(key)) {
131602                 task[key] = _massage(properties[key], key);
131603             }
131604         }
131605         return task;
131606     });
131607 };
131608
131609 Task.__defineGetter__("NOT_STARTED", function () {
131610     return 0;
131611 });
131612
131613 Task.__defineGetter__("IN_PROGRESS", function () {
131614     return 1;
131615 });
131616
131617 Task.__defineGetter__("COMPLETED", function () {
131618     return 2;
131619 });
131620
131621 Task.__defineGetter__("WAITING", function () {
131622     return 3;
131623 });
131624
131625 Task.__defineGetter__("DEFERRED", function () {
131626     return 4;
131627 });
131628
131629 Task.__defineGetter__("PRIORITY_HIGH", function () {
131630     return 0;
131631 });
131632
131633 Task.__defineGetter__("PRIORITY_NORMAL", function () {
131634     return 1;
131635 });
131636
131637 Task.__defineGetter__("PRIORITY_LOW", function () {
131638     return 2;
131639 });
131640
131641 module.exports = Task;
131642
131643 });
131644 define('ripple/platform/webworks.handset/2.0.0/spec/device', function (require, exports, module) {
131645 /*
131646  *  Copyright 2011 Research In Motion Limited.
131647  *
131648  * Licensed under the Apache License, Version 2.0 (the "License");
131649  * you may not use this file except in compliance with the License.
131650  * You may obtain a copy of the License at
131651  *
131652  * http://www.apache.org/licenses/LICENSE-2.0
131653  *
131654  * Unless required by applicable law or agreed to in writing, software
131655  * distributed under the License is distributed on an "AS IS" BASIS,
131656  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131657  * See the License for the specific language governing permissions and
131658  * limitations under the License.
131659  */
131660 var event = require('ripple/event');
131661
131662 module.exports = {
131663     "transports": {
131664         "TCP Cellular": {
131665             "name": "Cellular TCP",
131666             "control": {
131667                 "type": "checkbox",
131668                 "value": true
131669             }
131670         },
131671         "Wap": {
131672             "name": "WAP",
131673             "control": {
131674                 "type": "checkbox",
131675                 "value": false
131676             }
131677         },
131678         "Wap 2.0": {
131679             "name": "WAP 2.0",
131680             "control": {
131681                 "type": "checkbox",
131682                 "value": false
131683             }
131684         },
131685         "MDS": {
131686             "name": "MDS",
131687             "control": {
131688                 "type": "checkbox",
131689                 "value": true
131690             }
131691         },
131692         "Bis B": {
131693             "name": "BIS B",
131694             "control": {
131695                 "type": "checkbox",
131696                 "value": true
131697             }
131698         },
131699         "Unite!": {
131700             "name": "Unite",
131701             "control": {
131702                 "type": "checkbox",
131703                 "value": false
131704             }
131705         },
131706         "TCP Wifi": {
131707             "name": "Wifi TCP",
131708             "control": {
131709                 "type": "checkbox",
131710                 "value": true
131711             }
131712         }
131713     },
131714     "identity": {
131715         "IMEI": {
131716             "name": "IMEI",
131717             "control": {
131718                 "type": "text",
131719                 "value": "123456786543210"
131720             }
131721         },
131722         "IMSI": {
131723             "name": "IMSI",
131724             "control": {
131725                 "type": "text",
131726                 "value": "310150123456789"
131727             }
131728         },
131729         "PIN": {
131730             "name": "PIN",
131731             "control": {
131732                 "type": "text",
131733                 "value": "43A8C489"
131734             }
131735         }
131736     },
131737     "system": {
131738         "isMassStorageActive": {
131739             "name": "Mass Storage Is Connected",
131740             "control": {
131741                 "type": "checkbox",
131742                 "value": true
131743             }
131744         },
131745         "hasDataCoverage": {
131746             "name": "Has Data Coverage",
131747             "control": {
131748                 "type": "checkbox",
131749                 "value": true
131750             },
131751             "callback": function (setting) {
131752                 event.trigger("CoverageChange");
131753                 require('ripple/bus').send("network", setting);
131754             }
131755         },
131756         "lag": {
131757             "name": "Lag the network",
131758             "control": {
131759                 type: "checkbox",
131760                 value: false
131761             },
131762             "callback": function (setting) {
131763                 require('ripple/bus').send("lag", setting);
131764             }
131765         },
131766         "network": {
131767             "name": "Data Network",
131768             "control": {
131769                 "type": "select",
131770                 "value": "3GPP"
131771             },
131772             "options": {
131773                 "3GPP" : "3GPP",
131774                 "CDMA": "CDMA",
131775                 "iDEN": "iDEN",
131776                 "Wi-Fi": "Wi-Fi"
131777             },
131778             "callback": function (setting) {
131779                 event.trigger("CoverageChange");
131780             }
131781         }
131782     }
131783 };
131784
131785 });
131786 define('ripple/platform/webworks.handset/2.0.0/spec/events', function (require, exports, module) {
131787 /*
131788  *  Copyright 2011 Research In Motion Limited.
131789  *
131790  * Licensed under the Apache License, Version 2.0 (the "License");
131791  * you may not use this file except in compliance with the License.
131792  * You may obtain a copy of the License at
131793  *
131794  * http://www.apache.org/licenses/LICENSE-2.0
131795  *
131796  * Unless required by applicable law or agreed to in writing, software
131797  * distributed under the License is distributed on an "AS IS" BASIS,
131798  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131799  * See the License for the specific language governing permissions and
131800  * limitations under the License.
131801  */
131802 var _self,
131803     utils = require('ripple/utils'),
131804     event = require('ripple/event'),
131805     events = require('ripple/platform/webworks.core/2.0.0/spec/events');
131806
131807 _self = {
131808     "system.event.onExit": {
131809         callback: function () {
131810             event.trigger("AppExit");
131811         }
131812     },
131813     "system.event.onCoverageChange": {
131814         callback: function () {
131815             event.trigger("CoverageChange");
131816         }
131817     },
131818     "system.event.onHardwareKey": {
131819         args: [
131820             "Back",
131821             "Menu",
131822             "Convenience 1",
131823             "Convenience 2",
131824             "Start Call",
131825             "End Call",
131826             "Volume Down",
131827             "Volume Up"
131828         ],
131829         callback: function (key) {
131830             event.trigger("HardwareKey", [key]);
131831         }
131832     }
131833 };
131834
131835 utils.mixin(events, _self);
131836
131837 module.exports = _self;
131838
131839 });
131840 define('ripple/platform/webworks.handset/2.0.0/spec/ui', function (require, exports, module) {
131841 /*
131842  *  Copyright 2011 Research In Motion Limited.
131843  *
131844  * Licensed under the Apache License, Version 2.0 (the "License");
131845  * you may not use this file except in compliance with the License.
131846  * You may obtain a copy of the License at
131847  *
131848  * http://www.apache.org/licenses/LICENSE-2.0
131849  *
131850  * Unless required by applicable law or agreed to in writing, software
131851  * distributed under the License is distributed on an "AS IS" BASIS,
131852  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131853  * See the License for the specific language governing permissions and
131854  * limitations under the License.
131855  */
131856 module.exports = {
131857     plugins: [
131858         "accelerometer",
131859         "deviceSettings",
131860         "geoView",
131861         "platformEvents",
131862         "widgetConfig",
131863         "messaging",
131864         "push",
131865         "phone",
131866         "build"
131867     ]
131868 };
131869
131870 });
131871 define('ripple/platform/webworks.handset/2.0.0/server', function (require, exports, module) {
131872 /*
131873  *  Copyright 2011 Research In Motion Limited.
131874  *
131875  * Licensed under the Apache License, Version 2.0 (the "License");
131876  * you may not use this file except in compliance with the License.
131877  * You may obtain a copy of the License at
131878  *
131879  * http://www.apache.org/licenses/LICENSE-2.0
131880  *
131881  * Unless required by applicable law or agreed to in writing, software
131882  * distributed under the License is distributed on an "AS IS" BASIS,
131883  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131884  * See the License for the specific language governing permissions and
131885  * limitations under the License.
131886  */
131887 var utils = require('ripple/utils'),
131888     platform = "ripple/platform/webworks.handset/2.0.0/server/",
131889     core = "ripple/platform/webworks.core/2.0.0/server/",
131890     systemEvent = require(platform + 'systemEvent'),
131891     system = {};
131892
131893 // ugh, thanks to the spec...
131894 system.event = systemEvent;
131895 utils.mixin(require(core + "system"), system);
131896
131897 module.exports = {
131898     blackberry: {
131899         invoke: require(platform + "invoke"),
131900         system: system,
131901         app: require(platform + "app"),
131902         identity: require(platform + "identity"),
131903         message: {
131904             sms: require(platform + "sms"),
131905             message: require(platform + "message")
131906         },
131907         push: require(platform + "push"),
131908         pim: {
131909             Task: require(platform + "Task"),
131910             category: require(platform + "category"),
131911             memo: require(platform + "memo"),
131912             appointment: require(platform + "appointment"),
131913             contact: require(platform + "contact")
131914         },
131915         audio: {
131916             player: require(platform + "audioPlayer")
131917         },
131918         ui: {
131919             menu: require(platform + "menu"),
131920             dialog: require(core + "dialog")
131921         },
131922         phone: require(platform + "phone"),
131923         io: {
131924             dir: require(platform + "io/dir"),
131925             file: require(core + "io/file")
131926         }
131927     }
131928 };
131929
131930 });
131931 define('ripple/platform/webworks.handset/2.0.0/server/audioPlayer', function (require, exports, module) {
131932 /*
131933  *  Copyright 2011 Research In Motion Limited.
131934  *
131935  * Licensed under the Apache License, Version 2.0 (the "License");
131936  * you may not use this file except in compliance with the License.
131937  * You may obtain a copy of the License at
131938  *
131939  * http://www.apache.org/licenses/LICENSE-2.0
131940  *
131941  * Unless required by applicable law or agreed to in writing, software
131942  * distributed under the License is distributed on an "AS IS" BASIS,
131943  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131944  * See the License for the specific language governing permissions and
131945  * limitations under the License.
131946  */
131947 //create my dom collection node in UI
131948
131949 var utils = require('ripple/utils'),
131950     constants = require('ripple/constants'),
131951     notifications = require('ripple/notifications'),
131952     Player = require('ripple/platform/webworks.handset/2.0.0/client/AudioPlayer'),
131953     _handlers = {
131954         loadstart: {},
131955         canplaythrough: {},
131956         durationchange: {},
131957         ended: {},
131958         error: {},
131959         play: {},
131960         pause: {},
131961         volumechange: {},
131962         close: {}
131963     },
131964     extract = {
131965         time: function (audio) {
131966             return audio.currentTime;
131967         },
131968         duration: function (audio) {
131969             return audio.duration;
131970         },
131971         error: function (audio) {
131972             return audio.error;
131973         },
131974         nothing: function (audio) {
131975             return null;
131976         }
131977     },
131978     container;
131979
131980 container = utils.createElement("section", {
131981     id: "webworks-audio-players"
131982 });
131983
131984 document.getElementById("ui").appendChild(container);
131985
131986 function _errClosed(method) {
131987     notifications.openNotification("error",
131988        "attempted to call " + method + " on a player that is already closed. This is a very bad thing to do :)");
131989     return false;
131990 }
131991
131992 function _removeHandler(type, id) {
131993     var audio = document.getElementById(id);
131994
131995     if (audio && _handlers[type][id]) {
131996         audio.removeEventListener(type, _handlers[type][id]);
131997         delete _handlers[type][id];
131998     }
131999 }
132000
132001 function _addHandler(type, id, callback) {
132002     var audio = document.getElementById(id);
132003
132004     if (audio) {
132005         _removeHandler(type, id);
132006         audio.addEventListener(type, callback);
132007         _handlers[type][id] = callback;
132008     }
132009 }
132010
132011 function proxyEvent(from, map) {
132012     var audio = document.getElementById(map.id);
132013
132014     if (audio) {
132015         map.baton.take();
132016         _addHandler(from, map.id, function () {
132017             _removeHandler(from, map.id);
132018             map.baton.pass({code: 1, data: {
132019                 event: map.target,
132020                 eventData: map.data(this)
132021             }});
132022         });
132023     }
132024     else {
132025         return {code: -1, data: {event: "EVENT_ERROR", eventData: 5}};
132026     }
132027 }
132028
132029 module.exports = {
132030
132031     create: function (args) {
132032         var id = Math.uuid(),
132033             audio = utils.createElement("audio", {
132034                 id: id
132035             });
132036
132037         audio.setAttribute("src", args.locator);
132038
132039         if (args.type) {
132040             audio.setAttribute("type", args.type);
132041         }
132042
132043         container.appendChild(audio);
132044         audio.load();
132045
132046         if (audio.error) {
132047             throw "there was a problem opening the audio file";
132048         }
132049
132050         return {code: 1, data: id};
132051     },
132052
132053     play: function (args) {
132054         var audio = document.getElementById(args.id),
132055             playing;
132056
132057         if (audio) {
132058             audio.play();
132059             audio.rimState = Player.STARTED;
132060             playing = !!!audio.error;
132061         }
132062         else {
132063             playing = _errClosed("play");
132064         }
132065
132066         return {code: 1, data: playing};
132067     },
132068
132069     pause: function (args) {
132070         var audio = document.getElementById(args.id),
132071             paused;
132072
132073         if (audio) {
132074             audio.pause();
132075             paused = !!!audio.error;
132076         } else {
132077             paused = _errClosed("pause");
132078         }
132079
132080         return {code: 1, data: paused};
132081     },
132082
132083     close: function (args) {
132084         var audio = document.getElementById(args.id),
132085             callback = _handlers["close"][args.id],
132086             closed = true;
132087
132088         if (audio) {
132089             if (callback) {
132090                 callback();
132091             }
132092             container.removeChild(audio);
132093         }
132094         else {
132095             closed = _errClosed("close");
132096         }
132097
132098         return {code: 1, data: closed};
132099     },
132100
132101     onStart: function (args, post, baton) {
132102         return proxyEvent("play", {
132103             id: args.id,
132104             baton: baton,
132105             target: "EVENT_START",
132106             data: extract.time
132107         });
132108     },
132109
132110     onStopped: function (args, post, baton) {
132111         return proxyEvent("pause", {
132112             id: args.id,
132113             baton: baton,
132114             target: "EVENT_STOPPED",
132115             data: extract.time
132116         });
132117     },
132118
132119     onBufferingStarted: function (args, post, baton) {
132120         return proxyEvent("loadstart", {
132121             id: args.id,
132122             baton: baton,
132123             target: "EVENT_BUFFERING_STARTED",
132124             data: extract.time
132125         });
132126     },
132127
132128     onBufferingStopped: function (args, post, baton) {
132129         return proxyEvent("canplaythrough", {
132130             id: args.id,
132131             baton: baton,
132132             target: "EVENT_BUFFERING_STOPPED",
132133             data: extract.time
132134         });
132135     },
132136
132137     onDurationUpdated: function (args, post, baton) {
132138         return proxyEvent("durationchange", {
132139             id: args.id,
132140             baton: baton,
132141             target: "EVENT_DURATION_UPDATED",
132142             data: extract.duration
132143         });
132144     },
132145
132146     onEnd: function (args, post, baton) {
132147         return proxyEvent("ended", {
132148             id: args.id,
132149             baton: baton,
132150             target: "EVENT_END_OF_MEDIA",
132151             data: extract.duration
132152         });
132153     },
132154
132155     onError: function (args, post, baton) {
132156         return proxyEvent("error", {
132157             id: args.id,
132158             baton: baton,
132159             target: "EVENT_ERROR",
132160             data: extract.error
132161         });
132162     },
132163
132164     onVolumeChange: function (args, post, baton) {
132165         return proxyEvent("volumechange", {
132166             id: args.id,
132167             baton: baton,
132168             target: "EVENT_VOLUME_CHANGED",
132169             data: extract.nothing
132170         });
132171     },
132172
132173     onClose: function (args, post, baton) {
132174         return proxyEvent("close", {
132175             id: args.id,
132176             baton: baton,
132177             target: "EVENT_CLOSED",
132178             data: extract.nothing
132179         });
132180     },
132181
132182     getDuration: function (args) {
132183         var audio = document.getElementById(args.id),
132184             duration;
132185
132186         if (audio) {
132187             duration = audio.duration;
132188         }
132189         else {
132190             _errClosed("getDuration");
132191             duration = -1;
132192         }
132193
132194         return {code: 1, data: duration};
132195     },
132196
132197     getMediaTime: function (args) {
132198         var audio = document.getElementById(args.id),
132199             time;
132200
132201         if (audio) {
132202             time = audio.currentTime;
132203         }
132204         else {
132205             _errClosed("getMediaTime");
132206             time = -1;
132207         }
132208
132209         return {code: 1, data: time};
132210     },
132211
132212     setMediaTime: function (args) {
132213         var audio = document.getElementById(args.id);
132214
132215         if (audio) {
132216             audio.currentTime = args.value;
132217         }
132218         else {
132219             _errClosed("setMediaTime");
132220         }
132221
132222         return {code: 1};
132223     },
132224
132225     getVolumeLevel: function (args) {
132226         var audio = document.getElementById(args.id),
132227             level;
132228
132229         if (audio) {
132230             level = audio.volume * 100;
132231         }
132232         else {
132233             _errClosed("getVolumeLevel");
132234             level = -1;
132235         }
132236
132237         return {code: 1, data: level};
132238     },
132239
132240     setVolumeLevel: function (args) {
132241         var audio = document.getElementById(args.id);
132242
132243         if (audio) {
132244             audio.volume = args.value / 100;
132245         }
132246         else {
132247             _errClosed("setVolumeLevel");
132248         }
132249
132250         return {code: 1};
132251     },
132252
132253     getState: function (args) {
132254         var audio = document.getElementById(args.id),
132255             state = audio ? audio.rimState || Player.PREFETCHED : Player.CLOSED;
132256         return {code: 1, data: state};
132257     }
132258 };
132259
132260 });
132261 define('ripple/platform/webworks.handset/2.0.0/server/io/dir', function (require, exports, module) {
132262 /*
132263  * Copyright 2011 Research In Motion Limited.
132264  *
132265  * Licensed under the Apache License, Version 2.0 (the "License");
132266  * you may not use this file except in compliance with the License.
132267  * You may obtain a copy of the License at
132268  *
132269  *     http://www.apache.org/licenses/LICENSE-2.0
132270  *
132271  * Unless required by applicable law or agreed to in writing, software
132272  * distributed under the License is distributed on an "AS IS" BASIS,
132273  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132274  * See the License for the specific language governing permissions and
132275  * limitations under the License.
132276  */
132277 var cache = require('ripple/platform/webworks.core/2.0.0/fsCache'),
132278     dir = require('ripple/platform/webworks.core/2.0.0/server/io/dir'),
132279     utils = require('ripple/utils'),
132280     _self = {};
132281
132282 function _packet(data) {
132283     return {
132284         code: 1,
132285         data: data
132286     };
132287 }
132288
132289 utils.mixin({
132290     getFreeSpaceForRoot: function (get, post, baton) {
132291         return _packet(cache.dir.getFreeSpaceForRoot(post.path));
132292     },
132293     getRootDirs: function (get, post, baton) {
132294         return _packet(cache.dir.getRootDirs());
132295     }
132296 }, _self);
132297
132298 utils.mixin(dir, _self);
132299
132300 module.exports = _self;
132301
132302 });
132303 define('ripple/platform/webworks.handset/2.0.0/server/identity/phone', function (require, exports, module) {
132304 /*
132305  *  Copyright 2011 Research In Motion Limited.
132306  *
132307  * Licensed under the Apache License, Version 2.0 (the "License");
132308  * you may not use this file except in compliance with the License.
132309  * You may obtain a copy of the License at
132310  *
132311  * http://www.apache.org/licenses/LICENSE-2.0
132312  *
132313  * Unless required by applicable law or agreed to in writing, software
132314  * distributed under the License is distributed on an "AS IS" BASIS,
132315  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132316  * See the License for the specific language governing permissions and
132317  * limitations under the License.
132318  */
132319 var _lines = [
132320         {id: 1, number: 12345678910, label: "rogers", type: 1},
132321         {id: 2, number: 10987654321, label: "mystery", type: 0}
132322     ],
132323     _self;
132324
132325 function _filterLines(args) {
132326
132327     var result = _lines;
132328
132329     if (args && typeof args.id === "number") {
132330         result = _lines.filter(function (line) {
132331             return line.id === args.id;
132332         });
132333
132334         if (result.length === 0) {
132335             throw "invalid line id: " + args.id;
132336         }
132337     }
132338
132339     return result;
132340 }
132341
132342 _self = {
132343     getLineIds: function () {
132344         var lines = _lines.map(function (line) {
132345             return line.id;
132346         });
132347         return {
132348             code: 1,
132349             data: lines
132350         };
132351     },
132352     getLineLabel: function (args) {
132353         return {
132354             code: 1,
132355             data: _filterLines(args)[0].label
132356         };
132357     },
132358     getLineNumber: function (args) {
132359         return {
132360             code: 1,
132361             data: _filterLines(args)[0].number
132362         };
132363     },
132364     getLineType: function (args) {
132365         return {
132366             code: 1,
132367             data: _filterLines(args)[0].type
132368         };
132369     }
132370 };
132371
132372 module.exports = _self;
132373
132374 });
132375 define('ripple/platform/webworks.handset/2.0.0/server/category', function (require, exports, module) {
132376 /*
132377  *  Copyright 2011 Research In Motion Limited.
132378  *
132379  * Licensed under the Apache License, Version 2.0 (the "License");
132380  * you may not use this file except in compliance with the License.
132381  * You may obtain a copy of the License at
132382  *
132383  * http://www.apache.org/licenses/LICENSE-2.0
132384  *
132385  * Unless required by applicable law or agreed to in writing, software
132386  * distributed under the License is distributed on an "AS IS" BASIS,
132387  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132388  * See the License for the specific language governing permissions and
132389  * limitations under the License.
132390  */
132391 var db = require('ripple/db'),
132392     _KEY = "blackberry-pim-category",
132393     _self;
132394
132395 function _get() {
132396     return db.retrieveObject(_KEY) || [];
132397 }
132398
132399 function _save(category) {
132400     var categories = _get();
132401     if (!categories.some(function (item) {
132402         return item === category;
132403     })) {
132404         categories.push(category);
132405         db.saveObject(_KEY, categories);
132406     }
132407 }
132408
132409 function _remove(category) {
132410     var categories = _get(),
132411         index = categories.indexOf(category);
132412
132413     if (index >= 0) {
132414         categories.splice(index, 1);
132415         db.saveObject(_KEY, categories);
132416     }
132417 }
132418
132419 _self = {
132420     addCategory: function (args) {
132421         _save(args.categoryName);
132422         return {code: 1};
132423     },
132424     deleteCategory: function (args) {
132425         _remove(args.categoryName);
132426         return {code: 1};
132427     },
132428     getCategories: function () {
132429         return {code: 1, data: _get()};
132430     }
132431 };
132432
132433 module.exports = _self;
132434
132435 });
132436 define('ripple/platform/webworks.handset/2.0.0/server/identity', function (require, exports, module) {
132437 /*
132438  *  Copyright 2011 Research In Motion Limited.
132439  *
132440  * Licensed under the Apache License, Version 2.0 (the "License");
132441  * you may not use this file except in compliance with the License.
132442  * You may obtain a copy of the License at
132443  *
132444  * http://www.apache.org/licenses/LICENSE-2.0
132445  *
132446  * Unless required by applicable law or agreed to in writing, software
132447  * distributed under the License is distributed on an "AS IS" BASIS,
132448  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132449  * See the License for the specific language governing permissions and
132450  * limitations under the License.
132451  */
132452 var _self,
132453     Service = require('ripple/platform/webworks.handset/2.0.0/client/identity/Service'),
132454     Transport = require('ripple/platform/webworks.handset/2.0.0/client/identity/Transport'),
132455     utils = require('ripple/utils'),
132456     platform = require('ripple/platform'),
132457     deviceSettings = require('ripple/deviceSettings'),
132458     _transportTypes = [
132459         {name: "TCP Cellular", type: "TCP Cellular"},
132460         {name: "Wap", type: "Wap"},
132461         {name: "Wap 2.0", type: "Wap 2.0"},
132462         {name: "MDS", type: "MDS"},
132463         {name: "BIS B", type: "Bis B"},
132464         {name: "Unite!", type: "Unite!"},
132465         {name: "TCP Wifi", type: "TCP Wifi"},
132466     ],
132467     _services = [
132468         new Service(),
132469         new Service()
132470     ];
132471
132472 function _isTransportAvailable(transport) {
132473     return deviceSettings.retrieveAsBoolean("transports." + transport.type);
132474 }
132475
132476 utils.mixin({
132477     name: "Super Dave Osborne",
132478     emailAddress: "dave@stunt.com",
132479     isDefault: true,
132480     type: Service.TYPE_EMAIL
132481 }, _services[0]);
132482
132483 utils.mixin({
132484     name: "Fred Penner",
132485     emailAddress: "fred@fredpenner.com",
132486     isDefault: false,
132487     type: Service.TYPE_CONTACT
132488 }, _services[1]);
132489
132490 _self = {
132491     getDefaultService: function () {
132492         var serices = _services.filter(function (service) {
132493             return service.isDefault === true;
132494         });
132495         return {code: 1, data: serices};
132496     },
132497     getServiceList: function () {
132498         return {code: 1, data: _services};
132499     },
132500     getTransportList: function () {
132501         var transports = _transportTypes.filter(function (transport) {
132502             return _isTransportAvailable(transport);
132503         }).map(function (transport) {
132504             return new Transport(transport.name, transport.type);
132505         });
132506         return {code: 1, data: transports};
132507     },
132508     IMEI: function () {
132509         return {code: 1, data: deviceSettings.retrieve("identity.IMEI")};
132510     },
132511     IMSI: function () {
132512         return {code: 1, data: deviceSettings.retrieve("identity.IMSI")};
132513     },
132514     PIN: function () {
132515         return {code: 1, data: deviceSettings.retrieve("identity.PIN")};
132516     },
132517     phone: require('ripple/platform/webworks.handset/2.0.0/server/identity/phone')
132518 };
132519
132520 module.exports = _self;
132521
132522 });
132523 define('ripple/platform/webworks.handset/2.0.0/server/menu', function (require, exports, module) {
132524 /*
132525  *  Copyright 2011 Research In Motion Limited.
132526  *
132527  * Licensed under the Apache License, Version 2.0 (the "License");
132528  * you may not use this file except in compliance with the License.
132529  * You may obtain a copy of the License at
132530  *
132531  * http://www.apache.org/licenses/LICENSE-2.0
132532  *
132533  * Unless required by applicable law or agreed to in writing, software
132534  * distributed under the License is distributed on an "AS IS" BASIS,
132535  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132536  * See the License for the specific language governing permissions and
132537  * limitations under the License.
132538  */
132539 var _menuItems = {},
132540     event = require('ripple/event'),
132541     events = require('ripple/platform/webworks.core/2.0.0/client/events'),
132542     ui = require('ripple/ui'),
132543     devices = require('ripple/devices'),
132544     utils = require('ripple/utils'),
132545     tooltip = require('ripple/ui/plugins/tooltip'),
132546     _self,
132547     isMenuOpen = false,
132548     _baton,
132549     menuWindow = document ? document.getElementById("menu-window") : undefined;
132550
132551 if (menuWindow) {
132552     menuWindow.addEventListener("click", function () {
132553         _self.close();
132554     });
132555 }
132556
132557 event.on("LayoutChanged", function () {
132558     if (isMenuOpen) {
132559         _self.close();
132560         //Used to resize menu on orientation change
132561         _self.open();
132562     }
132563 });
132564
132565 event.on("HardwareKeyDefault", function (key) {
132566     if (key === 1 || key === "1") { //menu button key
132567         if (isMenuOpen) {
132568             _self.close();
132569         }
132570         else {
132571             _self.open();
132572         }
132573     }
132574 });
132575
132576 event.on("MenuItemSelected", function (menuItem) {
132577     var baton = _baton;
132578     _baton = null;
132579     return baton && baton.pass({code: 1, data: menuItem});
132580 });
132581
132582 event.on("MenuItemChanged", function (menuItem) {
132583     _menuItems[menuItem.id] = menuItem;
132584 });
132585
132586 _self = {
132587
132588     onSelect : function (args, post, baton) {
132589         baton.take();
132590         _baton = baton;
132591     },
132592
132593     addMenuItem: function (args) {
132594         if (!args) {
132595             throw "item not found";
132596         }
132597         _menuItems[args.item.id] = args.item;
132598         event.trigger("MenuChanged", [_menuItems]);
132599         return {code: 1};
132600     },
132601
132602     clearMenuItems: function () {
132603         _menuItems = {};
132604         event.trigger("MenuChanged", [utils.copy(_menuItems)]);
132605         return {code: 1};
132606     },
132607
132608     open: function () {
132609         function _return() {
132610             return {code: 1};
132611         }
132612
132613         if (utils.count(_menuItems) === 0) {
132614             _return();
132615         }
132616
132617         ui.showOverlay("menu-window", function (menu) {
132618             var container = document.getElementById("viewport-container"),
132619                 height = window.getComputedStyle(container, null).getPropertyValue("height"),
132620                 width = window.getComputedStyle(container, null).getPropertyValue("width"),
132621                 menuButtons = document.getElementById("menu-buttons"),
132622                 sorted,
132623                 menuItem;
132624
132625             if (!menuButtons) {
132626                 _return();
132627             }
132628
132629             menu.setAttribute("style", "display:block;height:" + height + "; width:" + width + ";");
132630             isMenuOpen = true;
132631
132632             sorted = utils.map(_menuItems, function (item) {
132633                 return item;
132634             }).sort(function (a, b) {
132635                 return a.ordinal - b.ordinal;
132636             });
132637
132638             menuButtons.innerHTML = "";
132639             sorted.forEach(function (item) {
132640                 if (!item.isSeparator) {
132641                     if (item.isDefault) {
132642                         menuItem = utils.createElement("div", {
132643                             "class": "overlay-menu-item-default",
132644                             "id": "default-menu-item"
132645                         });
132646                     }
132647                     else {
132648                         menuItem = utils.createElement("div", {
132649                             "class": "overlay-menu-item"
132650                         });
132651                     }
132652                     menuItem.innerHTML = item.caption;
132653
132654                     menuItem.addEventListener("click", function () {
132655                         _baton.pass({code: 1, data: item.id});
132656                     });
132657                 }
132658                 else {
132659                     menuItem = utils.createElement("hr", {});
132660                 }
132661                 menuButtons.appendChild(menuItem);
132662                 tooltip.create("#default-menu-item", "Default Item");
132663             });
132664         }, true);
132665
132666         event.trigger("MenuOpened", []);
132667
132668         _return();
132669     },
132670
132671     close: function () {
132672         ui.hideOverlay("menu-window", function (menu) {
132673             var menuButtons = document.getElementById("menu-buttons");
132674             menuButtons.innerHTML = "";
132675             isMenuOpen = false;
132676             menu.setAttribute("style", "display:none;");
132677
132678         });
132679         return {code: 1};
132680     },
132681
132682     removeMenuItem: function (args) {
132683         delete _menuItems[args.item.id];
132684         event.trigger("MenuChanged", [_menuItems]);
132685         return {code: 1};
132686     },
132687
132688     setDefaultMenuItem: function (args) {
132689
132690         utils.forEach(_menuItems, function (item) {
132691             item.isDefault = false;
132692         });
132693
132694         _menuItems[args.id].isDefault = true;
132695
132696         event.trigger("DefaultItemChanged", [_menuItems[args.id]]);
132697         return {code: 1};
132698     }
132699 };
132700
132701 module.exports = _self;
132702
132703 });
132704 define('ripple/platform/webworks.handset/2.0.0/server/app', function (require, exports, module) {
132705 /*
132706  *  Copyright 2011 Research In Motion Limited.
132707  *
132708  * Licensed under the Apache License, Version 2.0 (the "License");
132709  * you may not use this file except in compliance with the License.
132710  * You may obtain a copy of the License at
132711  *
132712  * http://www.apache.org/licenses/LICENSE-2.0
132713  *
132714  * Unless required by applicable law or agreed to in writing, software
132715  * distributed under the License is distributed on an "AS IS" BASIS,
132716  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132717  * See the License for the specific language governing permissions and
132718  * limitations under the License.
132719  */
132720 var event = require('ripple/event'),
132721     app = require('ripple/app'),
132722     notifications = require('ripple/notifications'),
132723     constants = require('ripple/constants'),
132724     ui = require('ripple/ui'),
132725     _isForeground = true,
132726     _self;
132727
132728 _self = {
132729     event: require('ripple/platform/webworks.handset/2.0.0/server/appEvent'),
132730
132731     exit: function () {
132732         event.trigger("AppExit");
132733         return {code: 1};
132734     },
132735
132736     author: function () {
132737         return {code: 1, data: app.getInfo().author};
132738     },
132739
132740     authorEmail: function () {
132741         return {code: 1, data: app.getInfo().authorEmail};
132742     },
132743
132744     authorURL: function () {
132745         return {code: 1, data: app.getInfo().authorURL};
132746     },
132747
132748     copyright: function () {
132749         return {code: 1, data: app.getInfo().copyright};
132750     },
132751
132752     description: function () {
132753         return {code: 1, data: app.getInfo().description};
132754     },
132755
132756     isForeground: function () {
132757         return {code: 1, data: _isForeground};
132758     },
132759
132760     id: function () {
132761         return {code: 1, data: app.getInfo().id};
132762     },
132763
132764     license: function () {
132765         return {code: 1, data: app.getInfo().license};
132766     },
132767
132768     licenseURL: function () {
132769         return {code: 1, data: app.getInfo().licenseURL};
132770     },
132771
132772     name: function () {
132773         return {code: 1, data: app.getInfo().name};
132774     },
132775
132776     version: function () {
132777         return {code: 1, data: app.getInfo().version};
132778     },
132779
132780     requestBackground: function () {
132781         ui.showOverlay("background-window", function (background) {
132782             var button = background.children["background-return"];
132783
132784             if (button) {
132785                 button.addEventListener("click", _self.requestForeground);
132786             }
132787             _isForeground = false;
132788             event.trigger("AppRequestBackground");
132789         });
132790
132791         return {code: 1};
132792     },
132793
132794     requestForeground: function () {
132795         ui.hideOverlay("background-window", function (background) {
132796             var button = background.children["background-return"];
132797
132798             if (button) {
132799                 button.removeEventListener("click", _self.requestForeground);
132800             }
132801             _isForeground = true;
132802             event.trigger("AppRequestForeground");
132803         });
132804
132805         return {code: 1};
132806     },
132807
132808     setHomeScreenIcon: function (args) {
132809         if (args.uri) {
132810             var msg = "The application set the home screen" +
132811                (args.hover ? " hover " : " ") +
132812                "icon to " + args.uri;
132813
132814             notifications.openNotification("normal", msg);
132815             return {code: 1};
132816         }
132817         else {
132818             return {code: 0};
132819         }
132820     },
132821
132822     setHomeScreenName: function (args) {
132823         if (args.text) {
132824             var msg = "The application set the home screen name to " + args.text;
132825             notifications.openNotification("normal", msg);
132826             return {code: 1};
132827         }
132828         else {
132829             return {code: 1};
132830         }
132831     },
132832
132833     removeBannerIndicator: function () {
132834         event.trigger("BannerUpdated", ["", 0]);
132835         return {code: 1};
132836     },
132837
132838     showBannerIndicator: function (args) {
132839         event.trigger("BannerUpdated", [args.icon, args.count]);
132840         return {code: 1};
132841     },
132842
132843 };
132844
132845 module.exports = _self;
132846
132847 });
132848 define('ripple/platform/webworks.handset/2.0.0/server/invoke', function (require, exports, module) {
132849 /*
132850  *  Copyright 2011 Research In Motion Limited.
132851  *
132852  * Licensed under the Apache License, Version 2.0 (the "License");
132853  * you may not use this file except in compliance with the License.
132854  * You may obtain a copy of the License at
132855  *
132856  * http://www.apache.org/licenses/LICENSE-2.0
132857  *
132858  * Unless required by applicable law or agreed to in writing, software
132859  * distributed under the License is distributed on an "AS IS" BASIS,
132860  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132861  * See the License for the specific language governing permissions and
132862  * limitations under the License.
132863  */
132864 var notifications = require('ripple/notifications'),
132865     constants = require('ripple/constants'),
132866     type = "normal",
132867     name = {
132868         "0": "Address Book",
132869         "1": "Bluetooth Config",
132870         "2": "Calculator",
132871         "3": "Calendar",
132872         "camera://": "Camera",
132873         "camera://video": "Video Camera",
132874         "map://": "Maps",
132875         "6": "Memopad",
132876         "7": "Messages",
132877         "8": "Phone",
132878         "9": "Search",
132879         "10": "Tasks",
132880         "11": "Browser",
132881         "http://": "Browser",
132882         "12": "Java",
132883     };
132884
132885 module.exports = {
132886     invoke: function (opts) {
132887         var app = name[opts.appType];
132888         if (app === undefined && opts.appType && opts.appType.match(/^http/i)) {
132889             app = "Browser";
132890         }
132891
132892         notifications.openNotification(type,
132893            "Requested to launch: " + app + " application.");
132894         return {code: 1};
132895     }
132896 };
132897
132898 });
132899 define('ripple/platform/webworks.handset/2.0.0/server/contact', function (require, exports, module) {
132900 /*
132901  *  Copyright 2011 Research In Motion Limited.
132902  *
132903  * Licensed under the Apache License, Version 2.0 (the "License");
132904  * you may not use this file except in compliance with the License.
132905  * You may obtain a copy of the License at
132906  *
132907  * http://www.apache.org/licenses/LICENSE-2.0
132908  *
132909  * Unless required by applicable law or agreed to in writing, software
132910  * distributed under the License is distributed on an "AS IS" BASIS,
132911  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132912  * See the License for the specific language governing permissions and
132913  * limitations under the License.
132914  */
132915 var select = require('ripple/platform/webworks.core/2.0.0/select'),
132916     db = require('ripple/db'),
132917     utils = require('ripple/utils'),
132918     _KEY = "blackberry-pim-contacts",
132919     _self;
132920
132921 function _defaultContacts() {
132922     var id1 = Math.uuid(null, 16),
132923         id2 = Math.uuid(null, 16),
132924         id3 = Math.uuid(null, 16),
132925         id4 = Math.uuid(null, 16),
132926         contacts = {};
132927
132928     contacts[id1] = {
132929         uuid: id1,
132930         firstName: "Leonardo",
132931         homePhone: "4567892345",
132932         email1: "leo@underground.com"
132933     };
132934     contacts[id2] = {
132935         uuid: id2,
132936         firstName: "Raphael",
132937         homePhone: "4563457890",
132938         email1: "raph@underground.com"
132939     };
132940     contacts[id3] = {
132941         uuid: id3,
132942         firstName: "Michelangelo",
132943         homePhone: "4563453425",
132944         email1: "mike@underground.com"
132945     };
132946     contacts[id4] = {
132947         uuid: id4,
132948         firstName: "Donatello",
132949         homePhone: "4563453425",
132950         email1: "don@undergound.com"
132951     };
132952
132953     return contacts;
132954 }
132955
132956 function _get() {
132957     return db.retrieveObject(_KEY) || _defaultContacts();
132958 }
132959
132960 function _save(contacts) {
132961     db.saveObject(_KEY, contacts);
132962 }
132963
132964 _self = {
132965     save: function (get, post) {
132966         var contacts = _get();
132967
132968         contacts[post.contact.uid] = post.contact;
132969         _save(contacts);
132970         return {code: 1};
132971     },
132972     remove: function (get, post) {
132973         var contacts = _get(),
132974             id = get.id;
132975
132976         delete contacts[id];
132977         _save(contacts);
132978         return {code: 1};
132979     },
132980     find: function (get, post) {
132981         var contacts = _get(),
132982             match = select.from(contacts);
132983
132984         if (post.orderBy) {
132985             match.orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc");
132986         }
132987
132988         if (post.maxReturn) {
132989             match.max(post.maxReturn);
132990         }
132991
132992         return {code: 1, data: match.where(post.fieldFilter)};
132993     }
132994 };
132995
132996 module.exports = _self;
132997
132998 });
132999 define('ripple/platform/webworks.handset/2.0.0/server/systemEvent', function (require, exports, module) {
133000 /*
133001  *  Copyright 2011 Research In Motion Limited.
133002  *
133003  * Licensed under the Apache License, Version 2.0 (the "License");
133004  * you may not use this file except in compliance with the License.
133005  * You may obtain a copy of the License at
133006  *
133007  * http://www.apache.org/licenses/LICENSE-2.0
133008  *
133009  * Unless required by applicable law or agreed to in writing, software
133010  * distributed under the License is distributed on an "AS IS" BASIS,
133011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133012  * See the License for the specific language governing permissions and
133013  * limitations under the License.
133014  */
133015 var event = require('ripple/event'),
133016     _onCoverageChange,
133017     _onHardwareKey = {};
133018
133019 event.on("CoverageChange", function () {
133020     var baton = _onCoverageChange;
133021     _onCoverageChange = null;
133022     return baton && baton.pass({code: 1});
133023 });
133024
133025 event.on("HardwareKey", function (key) {
133026     var baton = _onHardwareKey["key_" + key];
133027     delete _onHardwareKey["key_" + key];
133028
133029     if (baton) {
133030         baton.pass({code: 1});
133031     }
133032     else {
133033         event.trigger("HardwareKeyDefault", [key]);
133034     }
133035 });
133036
133037 module.exports = {
133038     onCoverageChange: function (args, post, baton) {
133039         baton.take();
133040         _onCoverageChange = baton;
133041     },
133042
133043     onHardwareKey: function (args, post, baton) {
133044         baton.take();
133045         _onHardwareKey["key_" + args.key] = baton;
133046     }
133047 };
133048
133049 });
133050 define('ripple/platform/webworks.handset/2.0.0/server/push', function (require, exports, module) {
133051 /*
133052  *  Copyright 2011 Research In Motion Limited.
133053  *
133054  * Licensed under the Apache License, Version 2.0 (the "License");
133055  * you may not use this file except in compliance with the License.
133056  * You may obtain a copy of the License at
133057  *
133058  * http://www.apache.org/licenses/LICENSE-2.0
133059  *
133060  * Unless required by applicable law or agreed to in writing, software
133061  * distributed under the License is distributed on an "AS IS" BASIS,
133062  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133063  * See the License for the specific language governing permissions and
133064  * limitations under the License.
133065  */
133066 var event = require('ripple/event'),
133067     utils = require('ripple/utils'),
133068     _handlers = {},
133069     _self;
133070
133071 function listenersChanged() {
133072     var ports = utils.map(_handlers, function (handler) {
133073         return handler.port;
133074     });
133075     event.trigger("PushListenersChanged", [ports]);
133076 }
133077
133078 event.on("Push", function (data, port) {
133079     var handler = _handlers["port_" + port];
133080     delete _handlers["port_" + port];
133081     window.setTimeout(function () {
133082         if (!_handlers["port_" + port]) {
133083             //doesn't look like they are coming back ;)
133084             listenersChanged();
133085         }
133086     }, 100);
133087     return handler && handler.baton.pass({code: 1, data: data});
133088 });
133089
133090 _self = {
133091
133092     onPush: function (args, post, baton) {
133093         if (!args.port) {
133094             throw "no port specified";
133095         }
133096         else if (typeof args.port !== 'number') {
133097             throw "port is not a number";
133098         }
133099         baton.take();
133100         _handlers["port_" + args.port] = {
133101             port: args.port,
133102             baton: baton
133103         };
133104         listenersChanged();
133105     }
133106 };
133107
133108 module.exports = _self;
133109
133110 });
133111 define('ripple/platform/webworks.handset/2.0.0/server/memo', function (require, exports, module) {
133112 /*
133113  *  Copyright 2011 Research In Motion Limited.
133114  *
133115  * Licensed under the Apache License, Version 2.0 (the "License");
133116  * you may not use this file except in compliance with the License.
133117  * You may obtain a copy of the License at
133118  *
133119  * http://www.apache.org/licenses/LICENSE-2.0
133120  *
133121  * Unless required by applicable law or agreed to in writing, software
133122  * distributed under the License is distributed on an "AS IS" BASIS,
133123  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133124  * See the License for the specific language governing permissions and
133125  * limitations under the License.
133126  */
133127 var db = require('ripple/db'),
133128     select = require('ripple/platform/webworks.core/2.0.0/select'),
133129     _self;
133130
133131 function _get() {
133132     return db.retrieveObject("webworks-pim-memo-list") || {};
133133 }
133134
133135 function _do(func) {
133136     var memos = _get();
133137     func(memos);
133138     db.saveObject("webworks-pim-memo-list", memos);
133139 }
133140
133141 _self = {
133142     find: function (get, post) {
133143         var memos = select.from(_get())
133144                     .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
133145                     .max(post.maxReturn)
133146                     .where(post.filter);
133147         return {code: 1, data: memos};
133148     },
133149     remove: function (get, post) {
133150         _do(function (memos) {
133151             if (!memos[get.uid]) {
133152                 throw "attempting to delete a non existant memo with uid: " + get.uid;
133153             }
133154             delete memos[get.uid];
133155         });
133156         return {code: 1};
133157     },
133158     save: function (get, post) {
133159         _do(function (memos) {
133160             memos[post.memo.uid] = post.memo;
133161         });
133162         return {code: 1};
133163     }
133164 };
133165
133166 module.exports = _self;
133167
133168 });
133169 define('ripple/platform/webworks.handset/2.0.0/server/appEvent', function (require, exports, module) {
133170 /*
133171  *  Copyright 2011 Research In Motion Limited.
133172  *
133173  * Licensed under the Apache License, Version 2.0 (the "License");
133174  * you may not use this file except in compliance with the License.
133175  * You may obtain a copy of the License at
133176  *
133177  * http://www.apache.org/licenses/LICENSE-2.0
133178  *
133179  * Unless required by applicable law or agreed to in writing, software
133180  * distributed under the License is distributed on an "AS IS" BASIS,
133181  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133182  * See the License for the specific language governing permissions and
133183  * limitations under the License.
133184  */
133185 var event = require('ripple/event'),
133186     notifications = require('ripple/notifications'),
133187     _bg,
133188     _fg,
133189     _exit;
133190
133191 event.on("AppRequestBackground", function () {
133192     var baton = _bg;
133193     _bg = null;
133194     return baton && baton.pass({code: 1});
133195 });
133196
133197 event.on("AppRequestForeground", function () {
133198     var baton = _fg;
133199     _fg = null;
133200     return baton && baton.pass({code: 1});
133201 });
133202
133203 event.on("AppExit", function () {
133204     var baton = _exit;
133205     _exit = null;
133206     notifications.openNotification("normal", "blackberry.app.exit() as called, in the real world your app will exit, here... you get this notification");
133207     return baton && baton.pass({code: 1});
133208 });
133209
133210 module.exports = {
133211     onBackground: function (get, post, baton) {
133212         baton.take();
133213         _bg = baton;
133214         return {code: 1};
133215     },
133216
133217     onForeground: function (get, post, baton) {
133218         baton.take();
133219         _fg = baton;
133220         return {code: 1};
133221     },
133222
133223     onExit: function (get, post, baton) {
133224         baton.take();
133225         _exit = baton;
133226         return {code: 1};
133227     }
133228 };
133229
133230 });
133231 define('ripple/platform/webworks.handset/2.0.0/server/appointment', function (require, exports, module) {
133232 /*
133233  *  Copyright 2011 Research In Motion Limited.
133234  *
133235  * Licensed under the Apache License, Version 2.0 (the "License");
133236  * you may not use this file except in compliance with the License.
133237  * You may obtain a copy of the License at
133238  *
133239  * http://www.apache.org/licenses/LICENSE-2.0
133240  *
133241  * Unless required by applicable law or agreed to in writing, software
133242  * distributed under the License is distributed on an "AS IS" BASIS,
133243  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133244  * See the License for the specific language governing permissions and
133245  * limitations under the License.
133246  */
133247 var db = require('ripple/db'),
133248     select = require('ripple/platform/webworks.core/2.0.0/select'),
133249     _self;
133250
133251 function _get() {
133252     return db.retrieveObject("webworks-pim-appointment-list") || {};
133253 }
133254
133255 function _do(func) {
133256     var appointments = _get();
133257     func(appointments);
133258     db.saveObject("webworks-pim-appointment-list", appointments);
133259 }
133260
133261 _self = {
133262     find: function (get, post) {
133263         var appointments = _get(),
133264             data = select.from(appointments)
133265                     .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
133266                     .max(post.maxReturn)
133267                     .where(post.filter);
133268
133269         return {code: 1, data: data};
133270     },
133271
133272     remove: function (get) {
133273         _do(function (appointments) {
133274             if (!appointments[get.uid]) {
133275                 throw "attempting to delete a non existant appointment with uid: " + get.uid;
133276             }
133277             delete appointments[get.uid];
133278         });
133279
133280         return {code: 1};
133281     },
133282
133283     save: function (get, post) {
133284         _do(function (appointments) {
133285             appointments[post.appointment.uid] = post.appointment;
133286         });
133287
133288         return {code: 1};
133289     }
133290 };
133291
133292 module.exports = _self;
133293
133294 });
133295 define('ripple/platform/webworks.handset/2.0.0/server/sms', function (require, exports, module) {
133296 /*
133297  *  Copyright 2011 Research In Motion Limited.
133298  *
133299  * Licensed under the Apache License, Version 2.0 (the "License");
133300  * you may not use this file except in compliance with the License.
133301  * You may obtain a copy of the License at
133302  *
133303  * http://www.apache.org/licenses/LICENSE-2.0
133304  *
133305  * Unless required by applicable law or agreed to in writing, software
133306  * distributed under the License is distributed on an "AS IS" BASIS,
133307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133308  * See the License for the specific language governing permissions and
133309  * limitations under the License.
133310  */
133311 var _listener,
133312     _isListening = false,
133313     notifications = require('ripple/notifications'),
133314     constants = require('ripple/constants'),
133315     event = require('ripple/event'),
133316     _console = require('ripple/console'),
133317     _onReceive,
133318     _self;
133319
133320 event.on("MessageReceived", function (message) {
133321     if (!_isListening || message.type !== 'sms') {
133322         return;
133323     }
133324
133325     var baton = _onReceive;
133326     _onReceive = null;
133327     _isListening = false;
133328     return baton && baton.pass({code: 1, data: message});
133329 });
133330
133331 _self = {
133332     onReceive: function (args, post, baton) {
133333         baton.take();
133334         _onReceive = baton;
133335         _isListening = !!_onReceive;
133336     },
133337
133338     send: function (args) {
133339         var msg = "To " + args.address + ": " + args.message;
133340         notifications.openNotification("normal", msg);
133341         _console.log(msg);
133342         return {code: 1};
133343     },
133344
133345     isListeningForMessage: function (get, post, baton) {
133346         if (get && typeof get.isListeningForMessage === "boolean") {
133347             _isListening = get.isListeningForMessage;
133348         }
133349
133350         return {code: 1, data: _isListening};
133351     }
133352 };
133353
133354 module.exports = _self;
133355
133356 });
133357 define('ripple/platform/webworks.handset/2.0.0/server/phone', function (require, exports, module) {
133358 /*
133359  *  Copyright 2011 Research In Motion Limited.
133360  *
133361  * Licensed under the Apache License, Version 2.0 (the "License");
133362  * you may not use this file except in compliance with the License.
133363  * You may obtain a copy of the License at
133364  *
133365  * http://www.apache.org/licenses/LICENSE-2.0
133366  *
133367  * Unless required by applicable law or agreed to in writing, software
133368  * distributed under the License is distributed on an "AS IS" BASIS,
133369  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133370  * See the License for the specific language governing permissions and
133371  * limitations under the License.
133372  */
133373 var PhoneCall = require('ripple/platform/webworks.handset/2.0.0/client/PhoneCall'),
133374     PhoneLogs = require('ripple/platform/webworks.handset/2.0.0/client/PhoneLogs'),
133375     CallLog = require('ripple/platform/webworks.handset/2.0.0/client/CallLog'),
133376     select = require('ripple/platform/webworks.core/2.0.0/select'),
133377     event = require('ripple/event'),
133378     utils = require('ripple/utils'),
133379     db = require('ripple/db'),
133380     _KEY = "blackberry-phone-logs",
133381     _onPhoneEventListeners = {},
133382     _activeCalls = {},
133383     _onCallLogAdded,
133384     _onCallLogRemoved,
133385     _onCallLogUpdated,
133386     _onCallLogReset,
133387     _self;
133388
133389 function _defaultLogs() {
133390     var n1 = new CallLog(),
133391         n2 = new CallLog(),
133392         m1 = new CallLog(),
133393         m2 = new CallLog();
133394
133395     n1.number = "12344567";
133396     n1.name = "larry";
133397     n1.type = CallLog.TYPE_PLACED_CALL;
133398     n1.status = CallLog.STATUS_NORMAL;
133399
133400     n2.number = "14567890";
133401     n2.name = "curly";
133402     n2.type = CallLog.TYPE_RECEIVED_CALL;
133403     n2.status = CallLog.STATUS_NORMAL;
133404
133405     m1.number = "17659800";
133406     m1.name = "moe";
133407     m1.type = CallLog.TYPE_MISSED_CALL_UNOPENED;
133408     m1.status = CallLog.STATUS_NORMAL;
133409
133410     m2.number = "14567896";
133411     m2.name = "snarf";
133412     m2.type = CallLog.TYPE_MISSED_CALL_OPENED;
133413     m2.status = CallLog.STATUS_NORMAL;
133414
133415     return {
133416         normal: [n1, n2],
133417         missed: [m1, m2]
133418     };
133419 }
133420
133421 function _getLogs(folderID) {
133422     var logs = db.retrieveObject(_KEY) || _defaultLogs();
133423     return folderID === undefined || folderID === null ?
133424         logs : logs[folderID !== PhoneLogs.FOLDER_NORMAL_CALLS ? "missed" : "normal"];
133425 }
133426
133427 function _saveLogs(logs) {
133428     db.saveObject(_KEY, logs);
133429 }
133430
133431 function _isMissedCall(log) {
133432     return (log.type === CallLog.TYPE_MISSED_CALL_UNOPENED ||
133433             log.type === CallLog.TYPE_MISSED_CALL_OPENED) ? true : false;
133434 }
133435
133436 function _isNormalCall(log) {
133437     return (log.type === CallLog.TYPE_RECEIVED_CALL ||
133438             log.type === CallLog.TYPE_PLACED_CALL) ? true : false;
133439 }
133440
133441 event.on("PhoneEvent", function (type, callId, error) {
133442     var baton = _onPhoneEventListeners[type];
133443     delete _onPhoneEventListeners[type];
133444
133445     return baton && baton.pass({code: 1, data: {callId: callId, error: error}});
133446 });
133447
133448 event.on("PhoneCallLogAdded", function (log) {
133449     var logs = _getLogs(),
133450         baton = _onCallLogAdded;
133451
133452     logs[_isMissedCall(log) ? "missed" : "normal"].push(log);
133453     _saveLogs(logs);
133454
133455     _onCallLogAdded = null;
133456     return baton && baton.pass({code: 1, data: {log: log}});
133457 });
133458
133459 event.on("PhoneCallLogRemoved", function (log) {
133460     // TODO: make this be the only one responsible for deletion (instead of triggering internally)
133461     var baton = _onCallLogRemoved;
133462     _onCallLogRemoved = null;
133463     return baton && baton.pass({code: 1, data: {log: log}});
133464 });
133465
133466 event.on("PhoneCallLogUpdated", function (newLog, oldLog) {
133467     // TODO: implement way to update with just this event
133468     var baton = _onCallLogUpdated;
133469     _onCallLogUpdated = null;
133470     return baton && baton.pass({code: 1, data: {
133471         newLog: newLog,
133472         oldLog: oldLog
133473     }});
133474 });
133475
133476 event.on("PhoneCallLogReset", function () {
133477     _saveLogs(_defaultLogs());
133478     var baton = _onCallLogReset;
133479     _onCallLogReset = null;
133480     return baton && baton.pass({code: 1});
133481 });
133482
133483 event.on("PhoneCallInitiated", function (call) {
133484     _activeCalls[call.id] = call;
133485 });
133486
133487 event.on("PhoneCallEnded", function (call) {
133488     delete _activeCalls[call.id];
133489 });
133490
133491 _self = {
133492     logs: {
133493         onCallLogAdded: function (get, post, baton) {
133494             baton.take();
133495             _onCallLogAdded = baton;
133496         },
133497
133498         onCallLogRemoved: function (get, post, baton) {
133499             baton.take();
133500             _onCallLogRemoved = baton;
133501         },
133502
133503         onCallLogUpdated: function (get, post, baton) {
133504             baton.take();
133505             _onCallLogUpdated = baton;
133506         },
133507
133508         onCallLogReset: function (get, post, baton) {
133509             baton.take();
133510             _onCallLogReset = baton;
133511         },
133512
133513         callAt: function (get) {
133514             var logs = _getLogs(get.folderID !== null && get.folderID !== undefined ?
133515                                         get.folderID : PhoneLogs.FOLDER_MISSED_CALLS);
133516             return {code: 1, data: logs.length > get.index ? logs[get.index] : null};
133517         },
133518
133519         deleteCallAt: function (get) {
133520             var logs = _getLogs(),
133521                 subLog = _getLogs(get.folderID),
133522                 deleted = false,
133523                 type, log;
133524
133525             if (subLog.length > get.index &&
133526                (type = _isNormalCall(subLog[get.index]) ? "normal" : "missed") &&
133527                (log = logs[type].splice(get.index, 1))) {
133528                 event.trigger("PhoneCallLogRemoved", [log]);
133529                 _saveLogs(logs);
133530                 deleted = true;
133531             }
133532
133533             return {code: 1, data: deleted};
133534         },
133535
133536         find: function (get, post) {
133537             var data = select.from(_getLogs(post.folderID !== null && post.folderID !== undefined ?
133538                                         post.folderID : PhoneLogs.FOLDER_MISSED_CALLS))
133539                     .orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc")
133540                     .max(post.maxReturn)
133541                     .where(post.filter, select.ops.phone);
133542             return {code: 1, data: data};
133543         },
133544
133545         numberOfCalls: function (get) {
133546             return {code: 1, data: _getLogs(get.folderID !== null && get.folderID !== undefined ?
133547                                         get.folderID : PhoneLogs.FOLDER_MISSED_CALLS).length};
133548         }
133549     },
133550
133551     onPhoneEvent: function (get, post, baton) {
133552         baton.take();
133553         _onPhoneEventListeners[get.eventType] = baton;
133554     },
133555
133556     activeCalls: function () {
133557         var data = utils.map(_activeCalls, function (callItem) {
133558             var call = new PhoneCall(callItem.onhold);
133559             call.outgoing = callItem.outgoing;
133560             call.recipientName = callItem.recipient.name;
133561             call.recipientNumber = callItem.recipient.number;
133562             return call;
133563         });
133564         return {code: 1, data: data};
133565     },
133566
133567     inActiveCall: function () {
133568         return {code: 1, data: utils.count(_activeCalls) > 0 ? true : false};
133569     }
133570 };
133571
133572 module.exports = _self;
133573
133574 });
133575 define('ripple/platform/webworks.handset/2.0.0/server/message', function (require, exports, module) {
133576 /*
133577  *  Copyright 2011 Research In Motion Limited.
133578  *
133579  * Licensed under the Apache License, Version 2.0 (the "License");
133580  * you may not use this file except in compliance with the License.
133581  * You may obtain a copy of the License at
133582  *
133583  * http://www.apache.org/licenses/LICENSE-2.0
133584  *
133585  * Unless required by applicable law or agreed to in writing, software
133586  * distributed under the License is distributed on an "AS IS" BASIS,
133587  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133588  * See the License for the specific language governing permissions and
133589  * limitations under the License.
133590  */
133591 var db = require('ripple/db'),
133592     utils = require('ripple/utils'),
133593     select = require('ripple/platform/webworks.core/2.0.0/select'),
133594     Message = require('ripple/platform/webworks.handset/2.0.0/client/Message'),
133595     _self;
133596
133597 function _get() {
133598     return db.retrieveObject("webworks-message-list") || {};
133599 }
133600
133601 function _do(func) {
133602     var messages = _get();
133603     func(messages);
133604     db.saveObject("webworks-message-list", messages);
133605 }
133606
133607 _self = {
133608     find: function (get, post) {
133609         var data = select
133610                 .from(_get())
133611                 .max(post.maxReturn)
133612                 .where(post.filter);
133613         return {code: 1, data: data};
133614     },
133615
133616     remove: function (get, post) {
133617         _do(function (messages) {
133618             if (!messages[get.uid]) {
133619                 throw "attempting to delete a non existant message with uid: " + get.uid;
133620             }
133621             delete messages[get.uid];
133622         });
133623         return {code: 1};
133624     },
133625
133626     save: function (get, post) {
133627         _do(function (messages) {
133628             var orig = messages[post.message.uid],
133629                 updated = utils.copy(post.message);
133630
133631             updated.folder = orig ? orig.folder : Message.FOLDER_DRAFT;
133632             updated.status = orig ? orig.status : Message.STATUS_DRAFT;
133633
133634             messages[post.message.uid] = updated;
133635         });
133636         return {code: 1};
133637     },
133638
133639     send: function (get, post) {
133640         _do(function (messages) {
133641             var updated = utils.copy(get.message);
133642
133643             updated.folder = Message.FOLDER_SENT;
133644             updated.status = Message.STATUS_SENT;
133645
133646             messages[updated.uid] = updated;
133647         });
133648         return {code: 1};
133649     }
133650 };
133651
133652 module.exports = _self;
133653
133654 });
133655 define('ripple/platform/webworks.handset/2.0.0/server/Task', function (require, exports, module) {
133656 /*
133657  *  Copyright 2011 Research In Motion Limited.
133658  *
133659  * Licensed under the Apache License, Version 2.0 (the "License");
133660  * you may not use this file except in compliance with the License.
133661  * You may obtain a copy of the License at
133662  *
133663  * http://www.apache.org/licenses/LICENSE-2.0
133664  *
133665  * Unless required by applicable law or agreed to in writing, software
133666  * distributed under the License is distributed on an "AS IS" BASIS,
133667  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133668  * See the License for the specific language governing permissions and
133669  * limitations under the License.
133670  */
133671 var select = require('ripple/platform/webworks.core/2.0.0/select'),
133672     db = require('ripple/db'),
133673     utils = require('ripple/utils'),
133674     _KEY = "blackberry-pim-task",
133675     _self;
133676
133677 function _get() {
133678     return db.retrieveObject(_KEY) || {};
133679 }
133680
133681 function _save(tasks) {
133682     db.saveObject(_KEY, tasks);
133683 }
133684
133685 _self = {
133686     save: function (get, post) {
133687         var tasks = _get(),
133688             properties = post.task,
133689             id = properties.uid;
133690
133691         if (tasks[id]) {
133692             utils.mixin(properties, tasks[id]);
133693         } else {
133694             tasks[id] = properties;
133695         }
133696
133697         _save(tasks);
133698
133699         return {code: 1};
133700     },
133701
133702     remove: function (get, post) {
133703         var tasks = _get(),
133704             id = get.id;
133705
133706         delete tasks[id];
133707
133708         _save(tasks);
133709
133710         return {code: 1};
133711     },
133712
133713     find: function (get, post) {
133714         var tasks = _get(),
133715             match = select.from(tasks);
133716
133717         if (post.orderBy) {
133718             match.orderBy(post.orderBy, post.isAscending === false ? "desc" : "asc");
133719         }
133720
133721         if (post.maxReturn) {
133722             match.max(post.maxReturn);
133723         }
133724
133725         return {code: 1, data: match.where(post.filter)};
133726     }
133727 };
133728
133729 module.exports = _self;
133730
133731 });
133732 define('ripple/platform/web/default/spec', function (require, exports, module) {
133733 /*
133734  *  Copyright 2011 Research In Motion Limited.
133735  *
133736  * Licensed under the Apache License, Version 2.0 (the "License");
133737  * you may not use this file except in compliance with the License.
133738  * You may obtain a copy of the License at
133739  *
133740  * http://www.apache.org/licenses/LICENSE-2.0
133741  *
133742  * Unless required by applicable law or agreed to in writing, software
133743  * distributed under the License is distributed on an "AS IS" BASIS,
133744  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133745  * See the License for the specific language governing permissions and
133746  * limitations under the License.
133747  */
133748
133749 module.exports = {
133750
133751     id: "web",
133752     version: "default",
133753     name: "Mobile Web",
133754
133755     ui: require('ripple/platform/web/default/spec/ui'),
133756     device: {},
133757
133758     persistencePrefix: "tinyhippos-",
133759
133760     initialize: function () {},
133761
133762     objects: {
133763         Coordinates: {
133764             path: "w3c/1.0/Coordinates"
133765         },
133766         Position: {
133767             path: "w3c/1.0/Position"
133768         },
133769         PositionError: {
133770             path: "w3c/1.0/PositionError"
133771         },
133772         navigator: {
133773             path: "w3c/1.0/navigator",
133774             children: {
133775                 geolocation: {
133776                     path: "w3c/1.0/geolocation"
133777                 }
133778             }
133779         },
133780         device: {
133781             path: "web/default/device"
133782         }
133783     },
133784 };
133785
133786 });
133787 define('ripple/platform/web/default/device', function (require, exports, module) {
133788 /*
133789  *  Copyright 2011 Research In Motion Limited.
133790  *
133791  * Licensed under the Apache License, Version 2.0 (the "License");
133792  * you may not use this file except in compliance with the License.
133793  * You may obtain a copy of the License at
133794  *
133795  * http://www.apache.org/licenses/LICENSE-2.0
133796  *
133797  * Unless required by applicable law or agreed to in writing, software
133798  * distributed under the License is distributed on an "AS IS" BASIS,
133799  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133800  * See the License for the specific language governing permissions and
133801  * limitations under the License.
133802  */
133803 window.addEventListener("load", function () {
133804     var event = require('ripple/event');
133805
133806     event.on("HardwareKey", function (key) {
133807         event.trigger("HardwareKeyDefault", [key]);
133808     });
133809
133810     //HACK: Remove this guy from namespace since we are just hacking this in as a bootstrapper
133811     delete window.device;
133812 });
133813
133814 });
133815 define('ripple/platform/web/default/spec/ui', function (require, exports, module) {
133816 module.exports = {
133817     plugins: [
133818         "accelerometer",
133819         "geoView"
133820     ]
133821 };
133822
133823 });
133824 define('ripple/platform/phonegap/1.0.0/CameraAttributes', function (require, exports, module) {
133825 /*
133826  *  Copyright 2011 Research In Motion Limited.
133827  *
133828  * Licensed under the Apache License, Version 2.0 (the "License");
133829  * you may not use this file except in compliance with the License.
133830  * You may obtain a copy of the License at
133831  *
133832  * http://www.apache.org/licenses/LICENSE-2.0
133833  *
133834  * Unless required by applicable law or agreed to in writing, software
133835  * distributed under the License is distributed on an "AS IS" BASIS,
133836  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133837  * See the License for the specific language governing permissions and
133838  * limitations under the License.
133839  */
133840 module.exports = function (supportsVideo, hasFlash, sensorPixels, maxZoomFactor) {
133841     return {
133842         supportsVideo: supportsVideo,
133843         hasFlash: hasFlash,
133844         sensorPixels: sensorPixels,
133845         maxZoomFactor: maxZoomFactor
133846     };
133847
133848 };
133849
133850 });
133851 define('ripple/platform/phonegap/1.0.0/map', function (require, exports, module) {
133852 /*
133853  *  Copyright 2011 Research In Motion Limited.
133854  *
133855  * Licensed under the Apache License, Version 2.0 (the "License");
133856  * you may not use this file except in compliance with the License.
133857  * You may obtain a copy of the License at
133858  *
133859  * http://www.apache.org/licenses/LICENSE-2.0
133860  *
133861  * Unless required by applicable law or agreed to in writing, software
133862  * distributed under the License is distributed on an "AS IS" BASIS,
133863  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133864  * See the License for the specific language governing permissions and
133865  * limitations under the License.
133866  */
133867 module.exports = {
133868     show: function () {
133869         throw "not implemented";
133870     }
133871 };
133872
133873 });
133874 define('ripple/platform/phonegap/1.0.0/NetworkAttributes', function (require, exports, module) {
133875 /*
133876  *  Copyright 2011 Research In Motion Limited.
133877  *
133878  * Licensed under the Apache License, Version 2.0 (the "License");
133879  * you may not use this file except in compliance with the License.
133880  * You may obtain a copy of the License at
133881  *
133882  * http://www.apache.org/licenses/LICENSE-2.0
133883  *
133884  * Unless required by applicable law or agreed to in writing, software
133885  * distributed under the License is distributed on an "AS IS" BASIS,
133886  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133887  * See the License for the specific language governing permissions and
133888  * limitations under the License.
133889  */
133890 module.exports = function (info, id, activeConnections) {
133891     return {
133892         info: info,
133893         id: id,
133894         activeConnections: activeConnections || []
133895     };
133896 };
133897
133898 });
133899 define('ripple/platform/phonegap/1.0.0/AVCodecsAttributes', function (require, exports, module) {
133900 /*
133901  *  Copyright 2011 Research In Motion Limited.
133902  *
133903  * Licensed under the Apache License, Version 2.0 (the "License");
133904  * you may not use this file except in compliance with the License.
133905  * You may obtain a copy of the License at
133906  *
133907  * http://www.apache.org/licenses/LICENSE-2.0
133908  *
133909  * Unless required by applicable law or agreed to in writing, software
133910  * distributed under the License is distributed on an "AS IS" BASIS,
133911  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133912  * See the License for the specific language governing permissions and
133913  * limitations under the License.
133914  */
133915 module.exports = function (info, id, audioCodecs, videoCodecs) {
133916     return {
133917         info: info,
133918         id: id,
133919         audioCodecs: audioCodecs,
133920         videoCodecs: videoCodecs
133921     };
133922 };
133923
133924 });
133925 define('ripple/platform/phonegap/1.0.0/ContactField', function (require, exports, module) {
133926 /*
133927  *  Copyright 2011 Research In Motion Limited.
133928  *
133929  * Licensed under the Apache License, Version 2.0 (the "License");
133930  * you may not use this file except in compliance with the License.
133931  * You may obtain a copy of the License at
133932  *
133933  * http://www.apache.org/licenses/LICENSE-2.0
133934  *
133935  * Unless required by applicable law or agreed to in writing, software
133936  * distributed under the License is distributed on an "AS IS" BASIS,
133937  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133938  * See the License for the specific language governing permissions and
133939  * limitations under the License.
133940  */
133941 module.exports = function (type, value, pref) {
133942     return {
133943         type: type,
133944         value: value,
133945         pref: pref || false
133946     };
133947 };
133948
133949 });
133950 define('ripple/platform/phonegap/1.0.0/ContactAccount', function (require, exports, module) {
133951 /*
133952  *  Copyright 2011 Research In Motion Limited.
133953  *
133954  * Licensed under the Apache License, Version 2.0 (the "License");
133955  * you may not use this file except in compliance with the License.
133956  * You may obtain a copy of the License at
133957  *
133958  * http://www.apache.org/licenses/LICENSE-2.0
133959  *
133960  * Unless required by applicable law or agreed to in writing, software
133961  * distributed under the License is distributed on an "AS IS" BASIS,
133962  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133963  * See the License for the specific language governing permissions and
133964  * limitations under the License.
133965  */
133966 module.exports = function (domain, username, userid) {
133967     return {
133968         domain: domain,
133969         username: username,
133970         userid: userid
133971     };
133972 };
133973
133974 });
133975 define('ripple/platform/phonegap/1.0.0/NetworkStatus', function (require, exports, module) {
133976 /*
133977  *  Copyright 2011 Research In Motion Limited.
133978  *
133979  * Licensed under the Apache License, Version 2.0 (the "License");
133980  * you may not use this file except in compliance with the License.
133981  * You may obtain a copy of the License at
133982  *
133983  * http://www.apache.org/licenses/LICENSE-2.0
133984  *
133985  * Unless required by applicable law or agreed to in writing, software
133986  * distributed under the License is distributed on an "AS IS" BASIS,
133987  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133988  * See the License for the specific language governing permissions and
133989  * limitations under the License.
133990  */
133991 module.exports = {
133992     NOT_REACHABLE: 0,
133993     REACHABLE_VIA_CARRIER_DATA_NETWORK: 1,
133994     REACHABLE_VIA_WIFI_NETWORK: 2
133995 };
133996
133997 });
133998 define('ripple/platform/phonegap/1.0.0/spec', function (require, exports, module) {
133999 module.exports = {
134000     id: "phonegap",
134001     version: "1.0.0",
134002     name: "PhoneGap",
134003     type: "platform",
134004
134005     persistencePrefix: "phonegap-",
134006
134007     config: require('ripple/platform/phonegap/1.0.0/spec/config'),
134008     device: require('ripple/platform/phonegap/1.0.0/spec/device'),
134009     ui: require('ripple/platform/phonegap/1.0.0/spec/ui'),
134010     events: require('ripple/platform/phonegap/1.0.0/spec/events'),
134011
134012     initialize: function () { },
134013
134014     objects: {
134015         PhoneGap: {
134016             path: "phonegap/1.0.0/PhoneGap"
134017         },
134018         Coordinates: {
134019             path: "w3c/1.0/Coordinates"
134020         },
134021         Position: {
134022             path: "w3c/1.0/Position"
134023         },
134024         PositionError: {
134025             path: "w3c/1.0/PositionError"
134026         },
134027         Acceleration: {
134028             path: "phonegap/1.0.0/Acceleration"
134029         },
134030         navigator: {
134031             path: "phonegap/1.0.0/navigator",
134032             children: {
134033                 accelerometer: {
134034                     path: "phonegap/1.0.0/accelerometer"
134035                 },
134036                 geolocation: {
134037                     path: "w3c/1.0/geolocation"
134038                 },
134039                 notification: {
134040                     path: "phonegap/1.0.0/notification"
134041                 },
134042                 contacts: {
134043                     path: "phonegap/1.0.0/contacts"
134044                 },
134045                 network: {
134046                     path: "phonegap/1.0.0/network"
134047                 },
134048                 camera: {
134049                     path: "phonegap/1.0.0/camera"
134050                 },
134051                 sms: {
134052                     path: "phonegap/1.0.0/sms"
134053                 },
134054                 telephony: {
134055                     path: "phonegap/1.0.0/telephony"
134056                 },
134057                 map: {
134058                     path: "phonegap/1.0.0/map"
134059                 },
134060                 orientation: {
134061                     path: "phonegap/1.0.0/orientation"
134062                 },
134063                 system: {
134064                     path: "phonegap/1.0.0/system"
134065                 },
134066                 compass: {
134067                     path: "phonegap/1.0.0/compass"
134068                 }
134069             }
134070         },
134071         ContactError: {
134072             path: "phonegap/1.0.0/ContactError"
134073         },
134074         Contact: {
134075             path: "phonegap/1.0.0/Contact"
134076         },
134077         ContactName: {
134078             path: "phonegap/1.0.0/ContactName"
134079         },
134080         ContactAccount: {
134081             path: "phonegap/1.0.0/ContactAccount"
134082         },
134083         ContactAddress: {
134084             path: "phonegap/1.0.0/ContactAddress"
134085         },
134086         ContactOrganization: {
134087             path: "phonegap/1.0.0/ContactOrganization"
134088         },
134089         ContactFindOptions: {
134090             path: "phonegap/1.0.0/ContactFindOptions"
134091         },
134092         ContactField: {
134093             path: "phonegap/1.0.0/ContactField"
134094         },
134095         NetworkStatus: {
134096             path: "phonegap/1.0.0/NetworkStatus"
134097         },
134098         device: {
134099             path: "phonegap/1.0.0/device"
134100         },
134101         SystemInfoOptions: {
134102             path: "phonegap/1.0.0/SystemInfoOptions"
134103         },
134104         PowerAttributes: {
134105             path: "phonegap/1.0.0/PowerAttributes"
134106         },
134107         CPUAttributes: {
134108             path: "phonegap/1.0.0/CPUAttributes"
134109         },
134110         ThermalAttributes: {
134111             path: "phonegap/1.0.0/ThermalAttributes"
134112         },
134113         NetworkAttributes: {
134114             path: "phonegap/1.0.0/NetworkAttributes"
134115         },
134116         Connection: {
134117             path: "phonegap/1.0.0/Connection"
134118         },
134119         ConnectionAttributes: {
134120             path: "phonegap/1.0.0/ConnectionAttributes"
134121         },
134122         SensorAttributes: {
134123             path: "phonegap/1.0.0/SensorAttributes"
134124         },
134125         AVCodecsAttributes: {
134126             path: "phonegap/1.0.0/AVCodecsAttributes"
134127         },
134128         AudioCodecAttributes: {
134129             path: "phonegap/1.0.0/AudioCodecAttributes"
134130         },
134131         VideoCodecAttributes: {
134132             path: "phonegap/1.0.0/VideoCodecAttributes"
134133         },
134134         StorageUnitAttributes: {
134135             path: "phonegap/1.0.0/StorageUnitAttributes"
134136         },
134137         InputDevicesAttributes: {
134138             path: "phonegap/1.0.0/InputDevicesAttributes"
134139         },
134140         OutputDevicesAttributes: {
134141             path: "phonegap/1.0.0/OutputDevicesAttributes"
134142         },
134143         DisplayDeviceAttributes: {
134144             path: "phonegap/1.0.0/DisplayDeviceAttributes"
134145         },
134146         AudioDeviceAttributes: {
134147             path: "phonegap/1.0.0/AudioDeviceAttributes"
134148         },
134149         PrintingDeviceAttributes: {
134150             path: "phonegap/1.0.0/PrintingDeviceAttributes"
134151         },
134152         BrailleDeviceAttributes: {
134153             path: "phonegap/1.0.0/BrailleDeviceAttributes"
134154         },
134155         PointerAttributes: {
134156             path: "phonegap/1.0.0/PointerAttributes"
134157         },
134158         KeyboardAttributes: {
134159             path: "phonegap/1.0.0/KeyboardAttributes"
134160         },
134161         CameraAttributes: {
134162             path: "phonegap/1.0.0/CameraAttributes"
134163         },
134164         MicrophoneAttributes: {
134165             path: "phonegap/1.0.0/MicrophoneAttributes"
134166         }
134167     }
134168
134169 };
134170
134171 });
134172 define('ripple/platform/phonegap/1.0.0/ContactFindOptions', function (require, exports, module) {
134173 /*
134174  *  Copyright 2011 Research In Motion Limited.
134175  *
134176  * Licensed under the Apache License, Version 2.0 (the "License");
134177  * you may not use this file except in compliance with the License.
134178  * You may obtain a copy of the License at
134179  *
134180  * http://www.apache.org/licenses/LICENSE-2.0
134181  *
134182  * Unless required by applicable law or agreed to in writing, software
134183  * distributed under the License is distributed on an "AS IS" BASIS,
134184  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134185  * See the License for the specific language governing permissions and
134186  * limitations under the License.
134187  */
134188 module.exports = function (filter, multiple, updatedSince) {
134189     return {
134190         filter: filter || "",
134191         multiple: multiple || false,
134192         updatedSince: updatedSince || ""
134193     };
134194 };
134195
134196 });
134197 define('ripple/platform/phonegap/1.0.0/SensorAttributes', function (require, exports, module) {
134198 /*
134199  *  Copyright 2011 Research In Motion Limited.
134200  *
134201  * Licensed under the Apache License, Version 2.0 (the "License");
134202  * you may not use this file except in compliance with the License.
134203  * You may obtain a copy of the License at
134204  *
134205  * http://www.apache.org/licenses/LICENSE-2.0
134206  *
134207  * Unless required by applicable law or agreed to in writing, software
134208  * distributed under the License is distributed on an "AS IS" BASIS,
134209  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134210  * See the License for the specific language governing permissions and
134211  * limitations under the License.
134212  */
134213 module.exports = function (value, min, max, normalizedValue) {
134214     return {
134215         value: value,
134216         min: min,
134217         max: max,
134218         normalizedValue: normalizedValue
134219     };
134220 };
134221
134222 });
134223 define('ripple/platform/phonegap/1.0.0/PhoneGap', function (require, exports, module) {
134224 /*
134225  *  Copyright 2011 Research In Motion Limited.
134226  *
134227  * Licensed under the Apache License, Version 2.0 (the "License");
134228  * you may not use this file except in compliance with the License.
134229  * You may obtain a copy of the License at
134230  *
134231  * http://www.apache.org/licenses/LICENSE-2.0
134232  *
134233  * Unless required by applicable law or agreed to in writing, software
134234  * distributed under the License is distributed on an "AS IS" BASIS,
134235  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134236  * See the License for the specific language governing permissions and
134237  * limitations under the License.
134238  */
134239 module.exports = {
134240     available: true
134241 };
134242
134243 });
134244 define('ripple/platform/phonegap/1.0.0/SystemInfoOptions', function (require, exports, module) {
134245 /*
134246  *  Copyright 2011 Research In Motion Limited.
134247  *
134248  * Licensed under the Apache License, Version 2.0 (the "License");
134249  * you may not use this file except in compliance with the License.
134250  * You may obtain a copy of the License at
134251  *
134252  * http://www.apache.org/licenses/LICENSE-2.0
134253  *
134254  * Unless required by applicable law or agreed to in writing, software
134255  * distributed under the License is distributed on an "AS IS" BASIS,
134256  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134257  * See the License for the specific language governing permissions and
134258  * limitations under the License.
134259  */
134260 module.exports = function (highThreshold, lowThreshold, thresholdTarget, timeout, id) {
134261     return {
134262         highThreshold: highThreshold,
134263         lowThreshold: lowThreshold,
134264         thresholdTarget: thresholdTarget,
134265         timeout: timeout,
134266         id: id
134267     };
134268 };
134269
134270 });
134271 define('ripple/platform/phonegap/1.0.0/navigator', function (require, exports, module) {
134272 /*
134273  *  Copyright 2011 Research In Motion Limited.
134274  *
134275  * Licensed under the Apache License, Version 2.0 (the "License");
134276  * you may not use this file except in compliance with the License.
134277  * You may obtain a copy of the License at
134278  *
134279  * http://www.apache.org/licenses/LICENSE-2.0
134280  *
134281  * Unless required by applicable law or agreed to in writing, software
134282  * distributed under the License is distributed on an "AS IS" BASIS,
134283  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134284  * See the License for the specific language governing permissions and
134285  * limitations under the License.
134286  */
134287 var nav = require('ripple/platform/w3c/1.0/navigator'),
134288     event = require('ripple/event'),
134289     _console = require('ripple/console'),
134290     utils = require('ripple/utils'),
134291     emulatorBridge = require('ripple/emulatorBridge'),
134292     _self = {};
134293
134294 event.on("TinyHipposLoaded", function () {
134295     var doc = emulatorBridge.document(),
134296         evt = doc.createEvent("Events");
134297     evt.initEvent("deviceready", true, true);
134298     doc.dispatchEvent(evt);
134299     _console.log("fired deviceready event!");
134300 });
134301
134302 utils.mixin(nav, _self);
134303
134304 module.exports = _self;
134305
134306 });
134307 define('ripple/platform/phonegap/1.0.0/device', function (require, exports, module) {
134308 /*
134309  *  Copyright 2011 Research In Motion Limited.
134310  *
134311  * Licensed under the Apache License, Version 2.0 (the "License");
134312  * you may not use this file except in compliance with the License.
134313  * You may obtain a copy of the License at
134314  *
134315  * http://www.apache.org/licenses/LICENSE-2.0
134316  *
134317  * Unless required by applicable law or agreed to in writing, software
134318  * distributed under the License is distributed on an "AS IS" BASIS,
134319  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134320  * See the License for the specific language governing permissions and
134321  * limitations under the License.
134322  */
134323 var _self = {},
134324     event = require('ripple/event'),
134325     devices = require('ripple/devices');
134326
134327
134328 event.on("HardwareKey", function (key) {
134329     event.trigger("HardwareKeyDefault", [key]);
134330 });
134331
134332 _self.__defineGetter__("name", function () {
134333     return devices.getCurrentDevice().name;
134334 });
134335
134336 _self.__defineGetter__("platform", function () {
134337     return devices.getCurrentDevice().osName;
134338 });
134339
134340 _self.__defineGetter__("uuid", function () {
134341     return devices.getCurrentDevice().uuid;
134342 });
134343
134344 _self.__defineGetter__("version", function () {
134345     return devices.getCurrentDevice().osVersion;
134346 });
134347
134348 _self.phonegap = "placeholder string";
134349
134350 module.exports = _self;
134351
134352 });
134353 define('ripple/platform/phonegap/1.0.0/AudioCodecAttributes', function (require, exports, module) {
134354 /*
134355  *  Copyright 2011 Research In Motion Limited.
134356  *
134357  * Licensed under the Apache License, Version 2.0 (the "License");
134358  * you may not use this file except in compliance with the License.
134359  * You may obtain a copy of the License at
134360  *
134361  * http://www.apache.org/licenses/LICENSE-2.0
134362  *
134363  * Unless required by applicable law or agreed to in writing, software
134364  * distributed under the License is distributed on an "AS IS" BASIS,
134365  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134366  * See the License for the specific language governing permissions and
134367  * limitations under the License.
134368  */
134369 module.exports = function (info, id, compFormats, encode, decode) {
134370     return {
134371         info: info,
134372         id: id,
134373         compFormats: compFormats,
134374         encode: encode,
134375         decode: decode
134376     };
134377 };
134378
134379 });
134380 define('ripple/platform/phonegap/1.0.0/spec/config', function (require, exports, module) {
134381 /*
134382  *  Copyright 2011 Research In Motion Limited.
134383  *
134384  * Licensed under the Apache License, Version 2.0 (the "License");
134385  * you may not use this file except in compliance with the License.
134386  * You may obtain a copy of the License at
134387  *
134388  * http://www.apache.org/licenses/LICENSE-2.0
134389  *
134390  * Unless required by applicable law or agreed to in writing, software
134391  * distributed under the License is distributed on an "AS IS" BASIS,
134392  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134393  * See the License for the specific language governing permissions and
134394  * limitations under the License.
134395  */
134396 var constants = require('ripple/constants');
134397
134398 module.exports = {
134399     fileName: "config.xml",
134400     validateVersion: function (configValidationObject) {
134401         var valid = true;
134402         valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) ||
134403             (!configValidationObject.widget.validationResult[0].attributes["xmlns:gap"].valid));
134404
134405         return valid;
134406     },
134407     extractInfo: function (configValidationObject) {
134408         if (!configValidationObject) {
134409             return null;
134410         }
134411
134412         var widgetInfo = {};
134413
134414         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
134415         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
134416         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
134417         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
134418
134419         return widgetInfo;
134420     },
134421     schema: {
134422         rootElement: "widget",
134423         widget: {
134424             nodeName: "widget",
134425             required: true,
134426             occurrence: 1,
134427             attributes: {
134428                 xmlns: {
134429                     attributeName: "xmlns",
134430                     required: true,
134431                     type: "list",
134432                     listValues: ["http://www.w3.org/ns/widgets"]
134433                 },
134434                 "xmlns:gap": {
134435                     attributeName: "xmlns:gap",
134436                     required: true,
134437                     type: "list",
134438                     listValues: ["http://phonegap.com/ns/1.0"]
134439                 },
134440                 "xml:lang": {
134441                     attributeName: "xml:lang",
134442                     required: false,
134443                     type: "iso-language"
134444                 },
134445                 dir: {
134446                     attributeName: "dir",
134447                     required: false,
134448                     type: "list",
134449                     listValues: ["ltr", "rtl", "lro", "rlo"]
134450                 },
134451                 id: {
134452                     attributeName: "id",
134453                     required: false,
134454                     type: "string"
134455                 },
134456                 version: {
134457                     attributeName: "version",
134458                     required: false,
134459                     type: "string"
134460                 },
134461                 height: {
134462                     attributeName: "height",
134463                     required: false,
134464                     type: "integer"
134465                 },
134466                 width: {
134467                     attributeName: "width",
134468                     required: false,
134469                     type: "integer"
134470                 },
134471                 viewmodes: {
134472                     attributeName: "viewmodes",
134473                     required: false,
134474                     type: "list",
134475                     listValues: ["floating", "fullscreen"]
134476                 }
134477             },
134478             children: {
134479                 name: {
134480                     nodeName: "name",
134481                     required: false,
134482                     occurrence: 0,
134483                     type: "string",
134484                     attributes: {
134485                         "short": {
134486                             attributeName: "short",
134487                             type: "string",
134488                             required: false
134489                         },
134490                         "xml:lang": {
134491                             attributeName: "xml:lang",
134492                             type: "string",
134493                             required: false,
134494                             unique: true
134495                         }
134496                     }
134497                 },
134498                 description: {
134499                     nodeName: "description",
134500                     required: false,
134501                     occurrence: 0,
134502                     type: "string",
134503                     attributes: {
134504                         "xml:lang": {
134505                             attributeName: "xml:lang",
134506                             type: "string",
134507                             required: false,
134508                             unique: true
134509                         }
134510                     }
134511                 },
134512                 author: {
134513                     nodeName: "author",
134514                     required: false,
134515                     occurrence: 1,
134516                     type: "string",
134517                     attributes: {
134518                         email: {
134519                             attributeName: "email",
134520                             type: "regex",
134521                             required: false,
134522                             regex: constants.REGEX.EMAIL
134523                         },
134524                         href: {
134525                             attributeName: "href",
134526                             type: "regex",
134527                             required: false,
134528                             regex: constants.REGEX.URL
134529                         }
134530                     }
134531                 },
134532                 license: {
134533                     nodeName: "license",
134534                     required: false,
134535                     occurrence: 1,
134536                     type: "string",
134537                     attributes: {
134538                         href: {
134539                             attributeName: "href",
134540                             type: "regex",
134541                             required: false,
134542                             regex: constants.REGEX.URL
134543                         },
134544                         "xml:lang": {
134545                             attributeName: "xml:lang",
134546                             type: "string",
134547                             required: false,
134548                             unique: true
134549                         }
134550                     }
134551                 },
134552                 icon: {
134553                     nodeName: "icon",
134554                     required: false,
134555                     occurrence: 0,
134556                     attributes: {
134557                         src: {
134558                             attributeName: "src",
134559                             type: "string",
134560                             required: true
134561                         },
134562                         height: {
134563                             attributeName: "height",
134564                             required: false,
134565                             type: "integer"
134566                         },
134567                         width: {
134568                             attributeName: "width",
134569                             required: false,
134570                             type: "integer"
134571                         }
134572                     }
134573                 },
134574                 content: {
134575                     nodeName: "content",
134576                     required: false,
134577                     occurrence: 1,
134578                     attributes: {
134579                         src: {
134580                             attributeName: "src",
134581                             type: "string",
134582                             required: true
134583                         },
134584                         encoding: {
134585                             attributeName: "encoding",
134586                             type: "string",
134587                             required: false
134588                         },
134589                         type: {
134590                             attributeName: "type",
134591                             type: "string",
134592                             required: false
134593                         }
134594                     }
134595                 },
134596                 feature: {
134597                     nodeName: "feature",
134598                     required: false,
134599                     occurrence: 0,
134600                     attributes: {
134601                         name: {
134602                             attributeName: "name",
134603                             type: "list",
134604                             required: true,
134605                             listValues: ["http://api.phonegap.com/1.0/accelerometer", "http://api.phonegap.com/1.0/camera",
134606                                 "http://api.phonegap.com/1.0/compass", "http://api.phonegap.com/1.0/contacts", "http://api.phonegap.com/1.0/device",
134607                                 "http://api.phonegap.com/1.0/events", "http://api.phonegap.com/1.0/file", "http://api.phonegap.com/1.0/geolocation",
134608                                 "http://api.phonegap.com/1.0/media", "http://api.phonegap.com/1.0/network", "http://api.phonegap.com/1.0/notification",
134609                                 "http://api.phonegap.com/1.0/storage"]
134610                         },
134611                         required: {
134612                             attributeName: "required",
134613                             type: "boolean",
134614                             required: false
134615                         }
134616                     }
134617                 },
134618                 preference: {
134619                     nodeName: "preference",
134620                     required: false,
134621                     occurrence: 0,
134622                     attributes: {
134623                         name: {
134624                             attributeName: "name",
134625                             type: "string",
134626                             required: true
134627                         },
134628                         value: {
134629                             type: "string",
134630                             attributeName: "value",
134631                             required: false
134632                         },
134633                         readonly: {
134634                             attributeName: "readonly",
134635                             type: "boolean",
134636                             required: false
134637                         }
134638                     }
134639                 }
134640             }
134641         }
134642     }
134643 };
134644
134645 });
134646 define('ripple/platform/phonegap/1.0.0/spec/device', function (require, exports, module) {
134647 /*
134648  *  Copyright 2011 Research In Motion Limited.
134649  *
134650  * Licensed under the Apache License, Version 2.0 (the "License");
134651  * you may not use this file except in compliance with the License.
134652  * You may obtain a copy of the License at
134653  *
134654  * http://www.apache.org/licenses/LICENSE-2.0
134655  *
134656  * Unless required by applicable law or agreed to in writing, software
134657  * distributed under the License is distributed on an "AS IS" BASIS,
134658  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134659  * See the License for the specific language governing permissions and
134660  * limitations under the License.
134661  */
134662 var event = require('ripple/event');
134663
134664 module.exports = {
134665     "NetworkStatus": {
134666         "connectionType": {
134667             "name": "Connection Type",
134668             "control": {
134669                 "type": "select",
134670                 "value": "ethernet"
134671             },
134672             "options": {
134673                 "unknown": "UNKNOWN",
134674                 "ethernet": "ETHERNET",
134675                 "wifi": "WIFI",
134676                 "2g": "CELL_2G",
134677                 "3g": "CELL_3G",
134678                 "4g": "CELL_4G",
134679                 "none": "none"
134680             },
134681             "callback": function (setting) {
134682                 var connected = setting !== "none";
134683                 require('ripple/bus').send("network", connected);
134684             }
134685         },
134686         "lag": {
134687             "name": "Lag the network",
134688             "control": {
134689                 type: "checkbox",
134690                 value: false
134691             },
134692             "callback": function (setting) {
134693                 require('ripple/bus').send("lag", setting);
134694             }
134695         },
134696     }
134697 };
134698
134699 });
134700 define('ripple/platform/phonegap/1.0.0/spec/events', function (require, exports, module) {
134701 function _fires(name, data) {
134702     return function () {
134703         var doc = require("ripple/emulatorBridge").document(),
134704             evt = doc.createEvent("Events");
134705
134706         evt.initEvent(name, true, false);
134707         doc.dispatchEvent(evt);
134708     };
134709 }
134710
134711 module.exports = {
134712     "deviceready": {
134713         callback: _fires("deviceready")
134714     },
134715     "backbutton": {
134716         callback: _fires("backbutton")
134717     },
134718     "menubutton": {
134719         callback: _fires("menubutton")
134720     },
134721     "pause": {
134722         callback: _fires("pause")
134723     },
134724     "resume": {
134725         callback: _fires("resume")
134726     },
134727     "searchbutton": {
134728         callback: _fires("searchbutton")
134729     },
134730     "online": {
134731         callback: _fires("online")
134732     },
134733     "offline": {
134734         callback: _fires("offline")
134735     }
134736 };
134737
134738 });
134739 define('ripple/platform/phonegap/1.0.0/spec/ui', function (require, exports, module) {
134740 /*
134741  *  Copyright 2011 Research In Motion Limited.
134742  *
134743  * Licensed under the Apache License, Version 2.0 (the "License");
134744  * you may not use this file except in compliance with the License.
134745  * You may obtain a copy of the License at
134746  *
134747  * http://www.apache.org/licenses/LICENSE-2.0
134748  *
134749  * Unless required by applicable law or agreed to in writing, software
134750  * distributed under the License is distributed on an "AS IS" BASIS,
134751  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134752  * See the License for the specific language governing permissions and
134753  * limitations under the License.
134754  */
134755 module.exports = {
134756     plugins: [
134757         "accelerometer",
134758         "deviceSettings",
134759         "geoView",
134760         "widgetConfig",
134761         "platformEvents"
134762     ]
134763 };
134764
134765 });
134766 define('ripple/platform/phonegap/1.0.0/VideoCodecAttributes', function (require, exports, module) {
134767 /*
134768  *  Copyright 2011 Research In Motion Limited.
134769  *
134770  * Licensed under the Apache License, Version 2.0 (the "License");
134771  * you may not use this file except in compliance with the License.
134772  * You may obtain a copy of the License at
134773  *
134774  * http://www.apache.org/licenses/LICENSE-2.0
134775  *
134776  * Unless required by applicable law or agreed to in writing, software
134777  * distributed under the License is distributed on an "AS IS" BASIS,
134778  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134779  * See the License for the specific language governing permissions and
134780  * limitations under the License.
134781  */
134782 module.exports = function (info, id, compFormats, containerFormats, hwAccel, profiles, frameTypes, rateTypes) {
134783     return {
134784         info: info,
134785         id: id,
134786         compFormats: compFormats,
134787         containerFormats: containerFormats,
134788         hwAccel: hwAccel,
134789         profiles: profiles,
134790         frameTypes: frameTypes,
134791         rateTypes: rateTypes
134792     };
134793 };
134794
134795 });
134796 define('ripple/platform/phonegap/1.0.0/Connection', function (require, exports, module) {
134797 /*
134798  *  Copyright 2011 Research In Motion Limited.
134799  *
134800  * Licensed under the Apache License, Version 2.0 (the "License");
134801  * you may not use this file except in compliance with the License.
134802  * You may obtain a copy of the License at
134803  *
134804  * http://www.apache.org/licenses/LICENSE-2.0
134805  *
134806  * Unless required by applicable law or agreed to in writing, software
134807  * distributed under the License is distributed on an "AS IS" BASIS,
134808  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134809  * See the License for the specific language governing permissions and
134810  * limitations under the License.
134811  */
134812 module.exports = {
134813     UNKNOWN: "unknown",
134814     ETHERNET: "ethernet",
134815     WIFI: "wifi",
134816     CELL_2G: "2g",
134817     CELL_3G: "3g",
134818     CELL_4G: "4g",
134819     NONE: "none"
134820 };
134821
134822 });
134823 define('ripple/platform/phonegap/1.0.0/notification', function (require, exports, module) {
134824 /*
134825  *  Copyright 2011 Research In Motion Limited.
134826  *
134827  * Licensed under the Apache License, Version 2.0 (the "License");
134828  * you may not use this file except in compliance with the License.
134829  * You may obtain a copy of the License at
134830  *
134831  * http://www.apache.org/licenses/LICENSE-2.0
134832  *
134833  * Unless required by applicable law or agreed to in writing, software
134834  * distributed under the License is distributed on an "AS IS" BASIS,
134835  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134836  * See the License for the specific language governing permissions and
134837  * limitations under the License.
134838  */
134839 var notifications = require('ripple/notifications'),
134840     constants = require('ripple/constants'),
134841     _console = require('ripple/console'),
134842     ui = require('ripple/ui'),
134843     goodVibrations = require('ripple/ui/plugins/goodVibrations');
134844
134845 module.exports = {
134846     alert: function (message, title, buttonName) {
134847         notifications.openNotification("normal", message);
134848     },
134849
134850     beep: function (times) {
134851         for (var i = times; i > 0; i--) {
134852             _console.log("beep!");
134853         }
134854         notifications.openNotification("normal", "BEEP x " + times);
134855     },
134856
134857     vibrate: function (milliseconds) {
134858         milliseconds = milliseconds || 500;
134859         goodVibrations.vibrateDevice(milliseconds);
134860     }
134861 };
134862
134863 });
134864 define('ripple/platform/phonegap/1.0.0/telephony', function (require, exports, module) {
134865 /*
134866  *  Copyright 2011 Research In Motion Limited.
134867  *
134868  * Licensed under the Apache License, Version 2.0 (the "License");
134869  * you may not use this file except in compliance with the License.
134870  * You may obtain a copy of the License at
134871  *
134872  * http://www.apache.org/licenses/LICENSE-2.0
134873  *
134874  * Unless required by applicable law or agreed to in writing, software
134875  * distributed under the License is distributed on an "AS IS" BASIS,
134876  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134877  * See the License for the specific language governing permissions and
134878  * limitations under the License.
134879  */
134880 module.exports = {
134881     send: function () {
134882         throw "not implemented";
134883     }
134884 };
134885
134886 });
134887 define('ripple/platform/phonegap/1.0.0/system', function (require, exports, module) {
134888 module.exports = {
134889     get: function () {
134890         throw "not implemented";
134891     },
134892     has: function () {
134893         throw "not implemented";
134894     },
134895     monitor: function () {
134896         throw "not implemented";
134897     }
134898 };
134899
134900 });
134901 define('ripple/platform/phonegap/1.0.0/contacts', function (require, exports, module) {
134902 /*
134903  *  Copyright 2011 Research In Motion Limited.
134904  *
134905  * Licensed under the Apache License, Version 2.0 (the "License");
134906  * you may not use this file except in compliance with the License.
134907  * You may obtain a copy of the License at
134908  *
134909  * http://www.apache.org/licenses/LICENSE-2.0
134910  *
134911  * Unless required by applicable law or agreed to in writing, software
134912  * distributed under the License is distributed on an "AS IS" BASIS,
134913  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134914  * See the License for the specific language governing permissions and
134915  * limitations under the License.
134916  */
134917 var Contact = require('./Contact'),
134918     ContactName = require('./ContactName'),
134919     ContactError = require('./ContactError'),
134920     ContactField = require('./ContactField'),
134921     utils = require('ripple/utils'),
134922     db = require('ripple/db'),
134923     event = require('ripple/event'),
134924     _defaultContacts = 
134925     [{
134926         "id": Math.uuid(undefined, 16),
134927         "name": new ContactName("Brent Lintner"),
134928         "displayName": "Brent Lintner",
134929         "emails": [new ContactField("work", "brent@tinyhippos.com", false)]
134930     }, {
134931         "id": Math.uuid(undefined, 16),
134932         "name": new ContactName("PJ Lowe"),
134933         "displayName": "PJ Lowe",
134934         "emails": [new ContactField("work", "pj@tinyhippos.com", false)]
134935     }, {
134936         "id": Math.uuid(undefined, 16),
134937         "name": new ContactName("Dan Silivestru"),
134938         "displayName": "Dan Silivestru",
134939         "emails": [new ContactField("work", "dan@tinyhippos.com", false)]
134940     }, {
134941         "id": Math.uuid(undefined, 16),
134942         "name": new ContactName("Gord Tanner"),
134943         "displayName": "Gord Tanner",
134944         "emails": [new ContactField("work", "gord@tinyhippos.com", true)]
134945     }, {
134946         "id": Math.uuid(undefined, 16),
134947         "name": new ContactName("Mark McArdle"),
134948         "displayName": "Mark McArdle",
134949         "emails": [new ContactField("work", "mark@tinyhippos.com", false)]
134950     }],
134951     self;
134952
134953 function _error(callback, code, msg) {
134954     var e = new ContactError();
134955     e.code = code;
134956     e.message = msg;
134957     window.setTimeout(function () {
134958         callback(e);
134959     }, 1);
134960 }
134961
134962
134963 function _getContacts() {
134964     return db.retrieveObject("phonegap-contacts") || 
134965         _defaultContacts.map(function (person) {
134966             var contact = new Contact();
134967             contact.updated = new Date();
134968             utils.forEach(person, function (value, prop) {
134969                 contact[prop] = value;
134970             });
134971
134972             return contact;
134973         });
134974 }
134975
134976 function _saveContacts(contacts) {
134977     db.saveObject("phonegap-contacts", contacts);
134978 }
134979
134980 function _filtered(compare, options) {
134981     // this could be done a lot better..
134982     var found = false;
134983     if (!options.filter || options.filter === "") {
134984         found = true;
134985     } else if (typeof compare === "string" &&
134986               compare.match(new RegExp(".*" + options.filter + ".*", "i"))) {
134987         found = true;
134988     } else if (typeof compare === "object" || compare instanceof Array) {
134989         utils.forEach(compare, function (value) {
134990             if (!found) {
134991                 found = _filtered(value, options);
134992             }
134993         });
134994     }
134995     return found;
134996 }
134997
134998 event.on("phonegap-contact-save", function (contactProperties, success, error) {
134999     var contacts = _getContacts(),
135000         existsIndex = contacts.reduce(function (result, value, index) {
135001             return value.id === contactProperties.id ? index : result;
135002         }, -1),
135003         contact = existsIndex >= 0 ? contacts[existsIndex] : new Contact();
135004
135005     utils.mixin(contactProperties, contact);
135006     if (existsIndex < 0) {
135007         contacts.push(contact);
135008     }
135009     _saveContacts(contacts);
135010     success(contact);
135011 });
135012
135013 event.on("phonegap-contact-remove", function (id, success, error) {
135014     if (!id) {
135015         _error(error, ContactError.NOT_FOUND_ERROR, "id is falsy (" + id + ")");
135016     } else {
135017         var contacts = _getContacts(),
135018             toDelete = contacts.reduce(function (result, current, index) {
135019                 return current.id === id ? index : result;
135020             }, -1);
135021
135022         if (toDelete >= 0) {
135023             contacts.splice(toDelete, 1);
135024             _saveContacts(contacts);
135025             success();
135026         } else {
135027             _error(error, ContactError.NOT_FOUND_ERROR, "could not find contact with id (" + id + ")");
135028         }
135029     }
135030 });
135031
135032 self = module.exports = {
135033     create: function (properties) {
135034         var contact = new Contact();
135035         utils.forEach(properties, function (value, key) {
135036             contact[key] = value;
135037         });
135038         return contact;
135039     },
135040     find: function (fields, success, error, options) {
135041         var foundContacts = [],
135042             tempContact = self.create(),
135043             contacts = _getContacts(),
135044             errorFlag = false;
135045
135046         options = options || {};
135047
135048         // not a fan of error handling at the moment
135049         if (!fields || !("forEach" in fields)) {
135050             errorFlag = true;
135051             _error(error, ContactError.INVALID_ARGUMENT_ERROR, "missing contact fields array");
135052             return;
135053         }
135054
135055         // handle special case of ["*"] to return all fields
135056         if (fields.length === 1 && fields[0] === "*") {
135057             fields = utils.map(tempContact, function (v, k) {
135058                 return k;
135059             });
135060         }
135061
135062         fields.forEach(function (prop) {
135063             if (!(tempContact.hasOwnProperty(prop))) {
135064                 errorFlag = true;
135065                 _error(error, ContactError.INVALID_ARGUMENT_ERROR, "invalid contact field (" + prop + ")");
135066             }
135067         });
135068
135069         if (typeof success !== "function" && !errorFlag) {
135070             errorFlag = true;
135071             _error(error, ContactError.INVALID_ARGUMENT_ERROR, "missing success callback");
135072         }
135073
135074         if (errorFlag) {
135075             return;
135076         }
135077
135078         if (fields.length > 0) {
135079             contacts.forEach(function (contact, index) {
135080                 var newContact = utils.copy(contact);
135081
135082                 if (options && (!_filtered(contact, options) ||
135083                         options.updatedSince && contact.updated && contact.updated.getTime() < options.updatedSince.getTime())) {
135084                     return;
135085                 }
135086
135087                 utils.forEach(newContact, function (value, prop) {
135088                     if (typeof newContact[prop] !== "function" && prop !== "id" &&
135089                         !fields.some(function (field) {
135090                             return field === prop;
135091                         })) {
135092                         delete newContact[prop];
135093                     }
135094                 });
135095
135096                 foundContacts.push(newContact);
135097             });
135098         }
135099
135100         window.setTimeout(function () {
135101             // TODO: don't loop over entire db just to slice the array
135102             if (options.multiple === false) {
135103                 foundContacts = foundContacts.splice(0, 1);
135104             }
135105             success(foundContacts);
135106         }, 1);
135107     }
135108 };
135109
135110 });
135111 define('ripple/platform/phonegap/1.0.0/PointerAttributes', function (require, exports, module) {
135112 /*
135113  *  Copyright 2011 Research In Motion Limited.
135114  *
135115  * Licensed under the Apache License, Version 2.0 (the "License");
135116  * you may not use this file except in compliance with the License.
135117  * You may obtain a copy of the License at
135118  *
135119  * http://www.apache.org/licenses/LICENSE-2.0
135120  *
135121  * Unless required by applicable law or agreed to in writing, software
135122  * distributed under the License is distributed on an "AS IS" BASIS,
135123  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135124  * See the License for the specific language governing permissions and
135125  * limitations under the License.
135126  */
135127 module.exports = function (type, supportsMultiTouch, info) {
135128     return {
135129         type: type,
135130         supportsMultiTouch: supportsMultiTouch,
135131         info: info
135132     };
135133 };
135134
135135 });
135136 define('ripple/platform/phonegap/1.0.0/AudioDeviceAttributes', function (require, exports, module) {
135137 /*
135138  *  Copyright 2011 Research In Motion Limited.
135139  *
135140  * Licensed under the Apache License, Version 2.0 (the "License");
135141  * you may not use this file except in compliance with the License.
135142  * You may obtain a copy of the License at
135143  *
135144  * http://www.apache.org/licenses/LICENSE-2.0
135145  *
135146  * Unless required by applicable law or agreed to in writing, software
135147  * distributed under the License is distributed on an "AS IS" BASIS,
135148  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135149  * See the License for the specific language governing permissions and
135150  * limitations under the License.
135151  */
135152 module.exports = function (type, freqRangeLow, freqRangeHigh, volumeLevel, info) {
135153     return {
135154         type: type,
135155         freqRangeLow: freqRangeLow,
135156         freqRangeHigh: freqRangeHigh,
135157         volumeLevel: volumeLevel,
135158         info: info
135159     };
135160
135161 };
135162
135163 });
135164 define('ripple/platform/phonegap/1.0.0/DisplayDeviceAttributes', function (require, exports, module) {
135165 /*
135166  *  Copyright 2011 Research In Motion Limited.
135167  *
135168  * Licensed under the Apache License, Version 2.0 (the "License");
135169  * you may not use this file except in compliance with the License.
135170  * You may obtain a copy of the License at
135171  *
135172  * http://www.apache.org/licenses/LICENSE-2.0
135173  *
135174  * Unless required by applicable law or agreed to in writing, software
135175  * distributed under the License is distributed on an "AS IS" BASIS,
135176  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135177  * See the License for the specific language governing permissions and
135178  * limitations under the License.
135179  */
135180 module.exports = function (orientation, brightness, contrast, blanked, dotsPerInchW, dotsPerInchH, physicalWidth, physicalHeight, info) {
135181     return {
135182         orientation: orientation,
135183         brightness: brightness,
135184         contrast: contrast,
135185         blanked: blanked,
135186         dotsPerInchW: dotsPerInchW,
135187         dotsPerInchH: dotsPerInchH,
135188         physicalWidth: physicalWidth,
135189         physicalHeight: physicalHeight,
135190         info: info
135191     };
135192 };
135193
135194 });
135195 define('ripple/platform/phonegap/1.0.0/InputDevicesAttributes', function (require, exports, module) {
135196 /*
135197  *  Copyright 2011 Research In Motion Limited.
135198  *
135199  * Licensed under the Apache License, Version 2.0 (the "License");
135200  * you may not use this file except in compliance with the License.
135201  * You may obtain a copy of the License at
135202  *
135203  * http://www.apache.org/licenses/LICENSE-2.0
135204  *
135205  * Unless required by applicable law or agreed to in writing, software
135206  * distributed under the License is distributed on an "AS IS" BASIS,
135207  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135208  * See the License for the specific language governing permissions and
135209  * limitations under the License.
135210  */
135211 module.exports = function (info, id, pointingDevices, activePointingDevices, keyboards, activeKeyboards, cameras, activeCameras, microphones, activeMicrophones) {
135212     return {
135213         info: info,
135214         id: id,
135215         pointingDevices: pointingDevices,
135216         activePointingDevices: activePointingDevices,
135217         keyboards: keyboards,
135218         activeKeyboards: activeKeyboards,
135219         cameras: cameras,
135220         activeCameras: activeCameras,
135221         microphones: microphones,
135222         activeMicrophones: activeMicrophones
135223     };
135224
135225 };
135226
135227 });
135228 define('ripple/platform/phonegap/1.0.0/camera', function (require, exports, module) {
135229 /*
135230  *  Copyright 2011 Research In Motion Limited.
135231  *
135232  * Licensed under the Apache License, Version 2.0 (the "License");
135233  * you may not use this file except in compliance with the License.
135234  * You may obtain a copy of the License at
135235  *
135236  * http://www.apache.org/licenses/LICENSE-2.0
135237  *
135238  * Unless required by applicable law or agreed to in writing, software
135239  * distributed under the License is distributed on an "AS IS" BASIS,
135240  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135241  * See the License for the specific language governing permissions and
135242  * limitations under the License.
135243  */
135244 module.exports = {
135245     getPicture: function (cameraSuccess, cameraError, cameraOptions) {
135246         if (cameraError) {
135247             cameraError.apply(null, ["not implemented"]);
135248         }
135249         else {
135250             throw "not implemented";
135251         }
135252     }
135253 };
135254
135255 });
135256 define('ripple/platform/phonegap/1.0.0/network', function (require, exports, module) {
135257 /*
135258  *  Copyright 2011 Research In Motion Limited.
135259  *
135260  * Licensed under the Apache License, Version 2.0 (the "License");
135261  * you may not use this file except in compliance with the License.
135262  * You may obtain a copy of the License at
135263  *
135264  * http://www.apache.org/licenses/LICENSE-2.0
135265  *
135266  * Unless required by applicable law or agreed to in writing, software
135267  * distributed under the License is distributed on an "AS IS" BASIS,
135268  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135269  * See the License for the specific language governing permissions and
135270  * limitations under the License.
135271  */
135272 var deviceSettings = require('ripple/deviceSettings'),
135273     _self = {
135274         connection: {
135275         }
135276     };
135277
135278 _self.connection.__defineGetter__("type", function () {
135279     return deviceSettings.retrieve("NetworkStatus.connectionType");
135280 });
135281
135282 module.exports = _self;
135283
135284 });
135285 define('ripple/platform/phonegap/1.0.0/KeyboardAttributes', function (require, exports, module) {
135286 /*
135287  *  Copyright 2011 Research In Motion Limited.
135288  *
135289  * Licensed under the Apache License, Version 2.0 (the "License");
135290  * you may not use this file except in compliance with the License.
135291  * You may obtain a copy of the License at
135292  *
135293  * http://www.apache.org/licenses/LICENSE-2.0
135294  *
135295  * Unless required by applicable law or agreed to in writing, software
135296  * distributed under the License is distributed on an "AS IS" BASIS,
135297  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135298  * See the License for the specific language governing permissions and
135299  * limitations under the License.
135300  */
135301 module.exports = function (type, isHardware, info) {
135302     return {
135303         type: type,
135304         isHardware: isHardware,
135305         info: info
135306     };
135307 };
135308
135309 });
135310 define('ripple/platform/phonegap/1.0.0/ContactAddress', function (require, exports, module) {
135311 /*
135312  *  Copyright 2011 Research In Motion Limited.
135313  *
135314  * Licensed under the Apache License, Version 2.0 (the "License");
135315  * you may not use this file except in compliance with the License.
135316  * You may obtain a copy of the License at
135317  *
135318  * http://www.apache.org/licenses/LICENSE-2.0
135319  *
135320  * Unless required by applicable law or agreed to in writing, software
135321  * distributed under the License is distributed on an "AS IS" BASIS,
135322  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135323  * See the License for the specific language governing permissions and
135324  * limitations under the License.
135325  */
135326 module.exports = function (pref, type, formatted, streetAddress, locality, region, postalCode, country, id) {
135327     return {
135328         pref: pref || null,
135329         type: type || null,
135330         formatted: formatted || null,
135331         streetAddress: streetAddress || null,
135332         locality: locality || null,
135333         region: region || null,
135334         postalCode: postalCode || null,
135335         country: country || null,
135336         id: id || null
135337     };
135338 };
135339
135340 });
135341 define('ripple/platform/phonegap/1.0.0/BrailleDeviceAttributes', function (require, exports, module) {
135342 /*
135343  *  Copyright 2011 Research In Motion Limited.
135344  *
135345  * Licensed under the Apache License, Version 2.0 (the "License");
135346  * you may not use this file except in compliance with the License.
135347  * You may obtain a copy of the License at
135348  *
135349  * http://www.apache.org/licenses/LICENSE-2.0
135350  *
135351  * Unless required by applicable law or agreed to in writing, software
135352  * distributed under the License is distributed on an "AS IS" BASIS,
135353  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135354  * See the License for the specific language governing permissions and
135355  * limitations under the License.
135356  */
135357 module.exports = function (nbCells, info) {
135358     return {
135359         nbCells: nbCells,
135360         info: info
135361     };
135362
135363 };
135364
135365 });
135366 define('ripple/platform/phonegap/1.0.0/CPUAttributes', function (require, exports, module) {
135367 /*
135368  *  Copyright 2011 Research In Motion Limited.
135369  *
135370  * Licensed under the Apache License, Version 2.0 (the "License");
135371  * you may not use this file except in compliance with the License.
135372  * You may obtain a copy of the License at
135373  *
135374  * http://www.apache.org/licenses/LICENSE-2.0
135375  *
135376  * Unless required by applicable law or agreed to in writing, software
135377  * distributed under the License is distributed on an "AS IS" BASIS,
135378  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135379  * See the License for the specific language governing permissions and
135380  * limitations under the License.
135381  */
135382 module.exports = function (info, id, usage) {
135383     return {
135384         info: info,
135385         id: id,
135386         usage: usage
135387     };
135388 };
135389
135390 });
135391 define('ripple/platform/phonegap/1.0.0/ThermalAttributes', function (require, exports, module) {
135392 /*
135393  *  Copyright 2011 Research In Motion Limited.
135394  *
135395  * Licensed under the Apache License, Version 2.0 (the "License");
135396  * you may not use this file except in compliance with the License.
135397  * You may obtain a copy of the License at
135398  *
135399  * http://www.apache.org/licenses/LICENSE-2.0
135400  *
135401  * Unless required by applicable law or agreed to in writing, software
135402  * distributed under the License is distributed on an "AS IS" BASIS,
135403  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135404  * See the License for the specific language governing permissions and
135405  * limitations under the License.
135406  */
135407 module.exports = function (info, id, state) {
135408     return {
135409         info: info,
135410         id: id,
135411         state: state
135412     };
135413 };
135414
135415 });
135416 define('ripple/platform/phonegap/1.0.0/ContactOrganization', function (require, exports, module) {
135417 /*
135418  *  Copyright 2011 Research In Motion Limited.
135419  *
135420  * Licensed under the Apache License, Version 2.0 (the "License");
135421  * you may not use this file except in compliance with the License.
135422  * You may obtain a copy of the License at
135423  *
135424  * http://www.apache.org/licenses/LICENSE-2.0
135425  *
135426  * Unless required by applicable law or agreed to in writing, software
135427  * distributed under the License is distributed on an "AS IS" BASIS,
135428  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135429  * See the License for the specific language governing permissions and
135430  * limitations under the License.
135431  */
135432 module.exports = function (pref, type, name, dept, title) {
135433     return {
135434         pref: pref || null,
135435         type: type || null,
135436         name: name || null,
135437         department: dept || null,
135438         title: title || null
135439     };
135440 };
135441
135442 });
135443 define('ripple/platform/phonegap/1.0.0/orientation', function (require, exports, module) {
135444 /*
135445  *  Copyright 2011 Research In Motion Limited.
135446  *
135447  * Licensed under the Apache License, Version 2.0 (the "License");
135448  * you may not use this file except in compliance with the License.
135449  * You may obtain a copy of the License at
135450  *
135451  * http://www.apache.org/licenses/LICENSE-2.0
135452  *
135453  * Unless required by applicable law or agreed to in writing, software
135454  * distributed under the License is distributed on an "AS IS" BASIS,
135455  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135456  * See the License for the specific language governing permissions and
135457  * limitations under the License.
135458  */
135459 module.exports = {
135460     currentOrientation: null,
135461     getCurrentOrientation: function (onSuccess, onFail) {
135462         throw "not implemented";
135463     },
135464     watchOrientation: function () {
135465         throw "not implemented";
135466     }
135467 };
135468
135469 });
135470 define('ripple/platform/phonegap/1.0.0/compass', function (require, exports, module) {
135471 /*
135472  *  Copyright 2011 Research In Motion Limited.
135473  *
135474  * Licensed under the Apache License, Version 2.0 (the "License");
135475  * you may not use this file except in compliance with the License.
135476  * You may obtain a copy of the License at
135477  *
135478  * http://www.apache.org/licenses/LICENSE-2.0
135479  *
135480  * Unless required by applicable law or agreed to in writing, software
135481  * distributed under the License is distributed on an "AS IS" BASIS,
135482  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135483  * See the License for the specific language governing permissions and
135484  * limitations under the License.
135485  */
135486 var geo = require('ripple/geo');
135487
135488 function _getHeading() {
135489     return geo.getPositionInfo().heading;
135490 }
135491
135492 module.exports = {
135493     getCurrentHeading: function (compassSuccess, compassError, compassOptions) {
135494         setTimeout(function () {
135495             compassSuccess(_getHeading());
135496         }, 1);
135497     },
135498     watchHeading: function (compassSuccess, compassError, compassOptions) {
135499         compassOptions = compassOptions || {};
135500         return setInterval(function () {
135501             compassSuccess(_getHeading());
135502         }, compassOptions.frequency || 100);
135503     },
135504     clearWatch: function (watchId) {
135505         clearInterval(watchId);
135506     }
135507 };
135508
135509 });
135510 define('ripple/platform/phonegap/1.0.0/ContactError', function (require, exports, module) {
135511 /*
135512  *  Copyright 2011 Research In Motion Limited.
135513  *
135514  * Licensed under the Apache License, Version 2.0 (the "License");
135515  * you may not use this file except in compliance with the License.
135516  * You may obtain a copy of the License at
135517  *
135518  * http://www.apache.org/licenses/LICENSE-2.0
135519  *
135520  * Unless required by applicable law or agreed to in writing, software
135521  * distributed under the License is distributed on an "AS IS" BASIS,
135522  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135523  * See the License for the specific language governing permissions and
135524  * limitations under the License.
135525  */
135526 function ContactError(code) {
135527     this.code = code || null;
135528 }
135529
135530 ContactError.UNKNOWN_ERROR = 0;
135531 ContactError.INVALID_ARGUMENT_ERROR = 1;
135532 ContactError.NOT_FOUND_ERROR = 2;
135533 ContactError.TIMEOUT_ERROR = 3;
135534 ContactError.PENDING_OPERATION_ERROR = 4;
135535 ContactError.IO_ERROR = 5;
135536 ContactError.NOT_SUPPORTED_ERROR = 6;
135537 ContactError.PERMISSION_DENIED_ERROR = 20;
135538
135539 module.exports = ContactError;
135540
135541 });
135542 define('ripple/platform/phonegap/1.0.0/OutputDevicesAttributes', function (require, exports, module) {
135543 /*
135544  *  Copyright 2011 Research In Motion Limited.
135545  *
135546  * Licensed under the Apache License, Version 2.0 (the "License");
135547  * you may not use this file except in compliance with the License.
135548  * You may obtain a copy of the License at
135549  *
135550  * http://www.apache.org/licenses/LICENSE-2.0
135551  *
135552  * Unless required by applicable law or agreed to in writing, software
135553  * distributed under the License is distributed on an "AS IS" BASIS,
135554  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135555  * See the License for the specific language governing permissions and
135556  * limitations under the License.
135557  */
135558 module.exports = function (info, id, displayDevices, activeDisplayDevices, printingDevices, activePrintingDevice, brailleDevices, activeBrailleDevice, audioDevices, activeAudioDevices) {
135559     return {
135560         info: info,
135561         id: id,
135562         displayDevices: displayDevices,
135563         activeDisplayDevices: activeDisplayDevices,
135564         printingDevices: printingDevices,
135565         activePrintingDevice: activePrintingDevice,
135566         brailleDevices: brailleDevices,
135567         activeBrailleDevice: activeBrailleDevice,
135568         audioDevices: audioDevices,
135569         activeAudioDevices: activeAudioDevices
135570     };
135571 };
135572
135573 });
135574 define('ripple/platform/phonegap/1.0.0/MicrophoneAttributes', function (require, exports, module) {
135575 /*
135576  *  Copyright 2011 Research In Motion Limited.
135577  *
135578  * Licensed under the Apache License, Version 2.0 (the "License");
135579  * you may not use this file except in compliance with the License.
135580  * You may obtain a copy of the License at
135581  *
135582  * http://www.apache.org/licenses/LICENSE-2.0
135583  *
135584  * Unless required by applicable law or agreed to in writing, software
135585  * distributed under the License is distributed on an "AS IS" BASIS,
135586  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135587  * See the License for the specific language governing permissions and
135588  * limitations under the License.
135589  */
135590 module.exports = function (type, freqRangeLow, freqRangeHigh, info, name, types) {
135591     return {
135592         type: type,
135593         freqRangeLow: freqRangeLow,
135594         freqRangeHigh: freqRangeHigh,
135595         info: info,
135596         name: name,
135597         types: types
135598     };
135599 };
135600
135601 });
135602 define('ripple/platform/phonegap/1.0.0/ContactName', function (require, exports, module) {
135603 /*
135604  *  Copyright 2011 Research In Motion Limited.
135605  *
135606  * Licensed under the Apache License, Version 2.0 (the "License");
135607  * you may not use this file except in compliance with the License.
135608  * You may obtain a copy of the License at
135609  *
135610  * http://www.apache.org/licenses/LICENSE-2.0
135611  *
135612  * Unless required by applicable law or agreed to in writing, software
135613  * distributed under the License is distributed on an "AS IS" BASIS,
135614  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135615  * See the License for the specific language governing permissions and
135616  * limitations under the License.
135617  */
135618 module.exports = function (formatted, familyName, givenName, middleName, honorificPrefix, honorificSuffix) {
135619     return {
135620         formatted: formatted,
135621         familyName: familyName,
135622         givenName: givenName,
135623         middleName: middleName,
135624         honorificPrefix: honorificPrefix,
135625         honorificSuffix: honorificSuffix
135626     };
135627 };
135628
135629 });
135630 define('ripple/platform/phonegap/1.0.0/StorageUnitAttributes', function (require, exports, module) {
135631 /*
135632  *  Copyright 2011 Research In Motion Limited.
135633  *
135634  * Licensed under the Apache License, Version 2.0 (the "License");
135635  * you may not use this file except in compliance with the License.
135636  * You may obtain a copy of the License at
135637  *
135638  * http://www.apache.org/licenses/LICENSE-2.0
135639  *
135640  * Unless required by applicable law or agreed to in writing, software
135641  * distributed under the License is distributed on an "AS IS" BASIS,
135642  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135643  * See the License for the specific language governing permissions and
135644  * limitations under the License.
135645  */
135646 module.exports = function (info, id, type, isWritable, capacity, availableCapacity, isRemoveable) {
135647     return {
135648         info: info,
135649         id: id,
135650         type: type,
135651         isWritable: isWritable,
135652         capacity: capacity,
135653         availableCapacity: availableCapacity,
135654         isRemoveable: isRemoveable
135655     };
135656 };
135657
135658 });
135659 define('ripple/platform/phonegap/1.0.0/Acceleration', function (require, exports, module) {
135660 /*
135661  *  Copyright 2011 Research In Motion Limited.
135662  *
135663  * Licensed under the Apache License, Version 2.0 (the "License");
135664  * you may not use this file except in compliance with the License.
135665  * You may obtain a copy of the License at
135666  *
135667  * http://www.apache.org/licenses/LICENSE-2.0
135668  *
135669  * Unless required by applicable law or agreed to in writing, software
135670  * distributed under the License is distributed on an "AS IS" BASIS,
135671  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135672  * See the License for the specific language governing permissions and
135673  * limitations under the License.
135674  */
135675 module.exports = function (x, y, z) {
135676     return {
135677         x: x || 0,
135678         y: y || 0,
135679         z: z || 0,
135680         timestamp: new Date().getTime()
135681     };
135682 };
135683
135684 });
135685 define('ripple/platform/phonegap/1.0.0/accelerometer', function (require, exports, module) {
135686 /*
135687  *  Copyright 2011 Research In Motion Limited.
135688  *
135689  * Licensed under the Apache License, Version 2.0 (the "License");
135690  * you may not use this file except in compliance with the License.
135691  * You may obtain a copy of the License at
135692  *
135693  * http://www.apache.org/licenses/LICENSE-2.0
135694  *
135695  * Unless required by applicable law or agreed to in writing, software
135696  * distributed under the License is distributed on an "AS IS" BASIS,
135697  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135698  * See the License for the specific language governing permissions and
135699  * limitations under the License.
135700  */
135701 var Acceleration = require('ripple/platform/phonegap/1.0.0/Acceleration'),
135702     utils = require('ripple/utils'),
135703     event = require('ripple/event'),
135704     _accelerometerInfo = new Acceleration(),
135705     _watches = {},
135706     self;
135707
135708 module.exports = self = {
135709     getCurrentAcceleration: function (onSuccess, onError) {
135710         // TODO: implement error call if accelerometer is not available, to be driven by behaviours?
135711
135712         if (typeof onSuccess === "function") {
135713             setTimeout(function () {
135714                 // TODO: build facility to trigger onError() from emulator
135715                 // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
135716                 onSuccess(utils.copy(_accelerometerInfo));
135717             }, 1);
135718         }
135719
135720     },
135721
135722     watchAcceleration: function (accelerometerSuccess, accelerometerError, accelerometerOptions) {
135723         var watchId = (new Date()).getTime().toString(),
135724             watchObj = {};
135725
135726
135727         if (accelerometerOptions &&
135728                 accelerometerOptions.frequency && typeof
135729                 accelerometerOptions.frequency === "number" &&
135730                 accelerometerOptions.frequency === Math.floor(accelerometerOptions.frequency)) {
135731
135732             watchObj = {
135733                 onSuccess: accelerometerSuccess,
135734                 onError: accelerometerError,
135735                 interval: accelerometerOptions.frequency
135736             };
135737
135738             _watches[watchId] = watchObj;
135739
135740             _watches[watchId].intervalId = setInterval(function () {
135741                 self.getCurrentAcceleration(_watches[watchId].onSuccess, _watches[watchId].onError);
135742             }, accelerometerOptions.frequency);
135743
135744         }
135745         else {
135746             if (typeof accelerometerError === "function") {
135747                 setTimeout(function () {
135748                     accelerometerError();
135749                 }, 1);
135750             }
135751         }
135752
135753         return watchId;
135754     },
135755
135756     clearWatch: function (watchId) {
135757         clearInterval(_watches[watchId].intervalId);
135758     }
135759 };
135760
135761 event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
135762     _accelerometerInfo.x = accelerometerInfo.accelerationIncludingGravity.x / 9.8;
135763     _accelerometerInfo.y = accelerometerInfo.accelerationIncludingGravity.y / 9.8;
135764     _accelerometerInfo.z = accelerometerInfo.accelerationIncludingGravity.z / 9.8;
135765     _accelerometerInfo.timestamp = (new Date()).getTime();
135766 });
135767
135768 });
135769 define('ripple/platform/phonegap/1.0.0/ConnectionAttributes', function (require, exports, module) {
135770 /*
135771  *  Copyright 2011 Research In Motion Limited.
135772  *
135773  * Licensed under the Apache License, Version 2.0 (the "License");
135774  * you may not use this file except in compliance with the License.
135775  * You may obtain a copy of the License at
135776  *
135777  * http://www.apache.org/licenses/LICENSE-2.0
135778  *
135779  * Unless required by applicable law or agreed to in writing, software
135780  * distributed under the License is distributed on an "AS IS" BASIS,
135781  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135782  * See the License for the specific language governing permissions and
135783  * limitations under the License.
135784  */
135785 module.exports = function (info, id, type, currentOrientation, currentUploadBandwidth, maxDownloadBandwidth, maxUploadBandwidth, currentSignalStrength, roaming) {
135786     return {
135787         info: info,
135788         id: id,
135789         type: type,
135790         currentDownloadBandwidth: currentOrientation,
135791         currentUploadBandwidth: currentUploadBandwidth,
135792         maxDownloadBandwidth: maxDownloadBandwidth,
135793         maxUploadBandwidth: maxUploadBandwidth,
135794         currentSignalStrength: currentSignalStrength,
135795         roaming: roaming
135796     };
135797 };
135798
135799 });
135800 define('ripple/platform/phonegap/1.0.0/PowerAttributes', function (require, exports, module) {
135801 /*
135802  *  Copyright 2011 Research In Motion Limited.
135803  *
135804  * Licensed under the Apache License, Version 2.0 (the "License");
135805  * you may not use this file except in compliance with the License.
135806  * You may obtain a copy of the License at
135807  *
135808  * http://www.apache.org/licenses/LICENSE-2.0
135809  *
135810  * Unless required by applicable law or agreed to in writing, software
135811  * distributed under the License is distributed on an "AS IS" BASIS,
135812  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135813  * See the License for the specific language governing permissions and
135814  * limitations under the License.
135815  */
135816 module.exports = function (info, id, level, timeRemaining, isBattery, isCharging) {
135817     return {
135818         info: info,
135819         id: id,
135820         level: level,
135821         timeRemaining: timeRemaining,
135822         isBattery: isBattery,
135823         isCharging: isCharging
135824     };
135825 };
135826
135827 });
135828 define('ripple/platform/phonegap/1.0.0/sms', function (require, exports, module) {
135829 /*
135830  *  Copyright 2011 Research In Motion Limited.
135831  *
135832  * Licensed under the Apache License, Version 2.0 (the "License");
135833  * you may not use this file except in compliance with the License.
135834  * You may obtain a copy of the License at
135835  *
135836  * http://www.apache.org/licenses/LICENSE-2.0
135837  *
135838  * Unless required by applicable law or agreed to in writing, software
135839  * distributed under the License is distributed on an "AS IS" BASIS,
135840  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135841  * See the License for the specific language governing permissions and
135842  * limitations under the License.
135843  */
135844 module.exports = {
135845     send: function () {
135846         throw "not implemented";
135847     }
135848 };
135849
135850 });
135851 define('ripple/platform/phonegap/1.0.0/service', function (require, exports, module) {
135852 /*
135853  *  Copyright 2011 Research In Motion Limited.
135854  *
135855  * Licensed under the Apache License, Version 2.0 (the "License");
135856  * you may not use this file except in compliance with the License.
135857  * You may obtain a copy of the License at
135858  *
135859  * http://www.apache.org/licenses/LICENSE-2.0
135860  *
135861  * Unless required by applicable law or agreed to in writing, software
135862  * distributed under the License is distributed on an "AS IS" BASIS,
135863  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135864  * See the License for the specific language governing permissions and
135865  * limitations under the License.
135866  */
135867 // for form, but could probably just delete
135868 module.exports = {};
135869
135870 });
135871 define('ripple/platform/phonegap/1.0.0/PrintingDeviceAttributes', function (require, exports, module) {
135872 /*
135873  *  Copyright 2011 Research In Motion Limited.
135874  *
135875  * Licensed under the Apache License, Version 2.0 (the "License");
135876  * you may not use this file except in compliance with the License.
135877  * You may obtain a copy of the License at
135878  *
135879  * http://www.apache.org/licenses/LICENSE-2.0
135880  *
135881  * Unless required by applicable law or agreed to in writing, software
135882  * distributed under the License is distributed on an "AS IS" BASIS,
135883  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135884  * See the License for the specific language governing permissions and
135885  * limitations under the License.
135886  */
135887 module.exports = function (type, resolution, color, info) {
135888     return {
135889         type: type,
135890         resolution: resolution,
135891         color: color,
135892         info: info
135893     };
135894 };
135895
135896 });
135897 define('ripple/platform/phonegap/1.0.0/Contact', function (require, exports, module) {
135898 /*
135899  *  Copyright 2011 Research In Motion Limited.
135900  *
135901  * Licensed under the Apache License, Version 2.0 (the "License");
135902  * you may not use this file except in compliance with the License.
135903  * You may obtain a copy of the License at
135904  *
135905  * http://www.apache.org/licenses/LICENSE-2.0
135906  *
135907  * Unless required by applicable law or agreed to in writing, software
135908  * distributed under the License is distributed on an "AS IS" BASIS,
135909  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135910  * See the License for the specific language governing permissions and
135911  * limitations under the License.
135912  */
135913 var utils = require('ripple/utils'),
135914     event = require('ripple/event');
135915
135916 function _properties(obj) {
135917     var prop, newObj = {};
135918     for (prop in obj) {
135919         if (Object.prototype.hasOwnProperty.call(obj, prop)) {
135920             if (typeof obj[prop] !== "function") {
135921                 newObj[prop] = utils.copy(obj[prop]);
135922             }
135923         }
135924     }
135925     return newObj;
135926 }
135927
135928 module.exports = function (
135929         id,
135930         displayName,
135931         name,
135932         nickname,
135933         phoneNumbers,
135934         emails,
135935         addresses,
135936         ims,
135937         organizations,
135938         birthday,
135939         note,
135940         photos,
135941         categories,
135942         urls
135943 ) {
135944
135945     return {
135946         id: id || Math.uuid(undefined, 16),
135947         displayName: displayName || null,
135948         name: name || null,
135949         nickname: nickname || null,
135950         phoneNumbers: phoneNumbers || null,
135951         emails: emails || null,
135952         addresses: addresses || null,
135953         ims: ims || null,
135954         organizations: organizations || null,
135955         birthday: birthday || null,
135956         note: note || null,
135957         photos: photos || null,
135958         categories: categories || null,
135959         urls: urls || null,
135960         save: function (success, error) {
135961             var _self = this,
135962                 lastUpdated = this.updated; // hackish
135963
135964             this.updated = new Date();
135965
135966             if (!this.id) {
135967                 this.id = Math.uuid(undefined, 16);
135968             }
135969
135970             event.trigger("phonegap-contact-save", [_properties(this), success, function (e) {
135971                 _self.updated = lastUpdated;
135972                 error(e);
135973             }]);
135974         },
135975         remove: function (success, error) {
135976             event.trigger("phonegap-contact-remove", [this.id, success, error]);
135977         },
135978         clone: function () {
135979             var copy = utils.copy(this);
135980             copy.id = null;
135981             return copy;
135982         }
135983     };
135984 };
135985
135986 });
135987 define('ripple/platform/webworks.bb10/1.0.0/spec', function (require, exports, module) {
135988 /*
135989  *  Copyright 2011 Research In Motion Limited.
135990  *
135991  * Licensed under the Apache License, Version 2.0 (the "License");
135992  * you may not use this file except in compliance with the License.
135993  * You may obtain a copy of the License at
135994  *
135995  * http://www.apache.org/licenses/LICENSE-2.0
135996  *
135997  * Unless required by applicable law or agreed to in writing, software
135998  * distributed under the License is distributed on an "AS IS" BASIS,
135999  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136000  * See the License for the specific language governing permissions and
136001  * limitations under the License.
136002  */
136003 module.exports = {
136004
136005     id: "webworks.bb10",
136006     version: "1.0.0",
136007     name: "BlackBerry 10 WebWorks",
136008
136009     persistencePrefix: "rim-bb10-",
136010
136011     ui: require('ripple/platform/webworks.bb10/1.0.0/spec/ui'),
136012     device: require('ripple/platform/webworks.bb10/1.0.0/spec/device'),
136013     config: require('ripple/platform/webworks.bb10/1.0.0/spec/config'),
136014     events: require('ripple/platform/webworks.bb10/1.0.0/spec/events'),
136015
136016     initialize: function () {
136017         var event = require('ripple/event'),
136018             _console = require('ripple/console'),
136019             emulatorBridge = require('ripple/emulatorBridge');
136020
136021         event.on("TinyHipposLoaded", function () {
136022             var doc = emulatorBridge.document(),
136023                 evt = doc.createEvent("Events");
136024             evt.initEvent("webworksready", true, true);
136025             doc.dispatchEvent(evt);
136026             _console.log("fired webworksready event!");
136027         });
136028     },
136029
136030     objects: {
136031         Coordinates: {
136032             path: "w3c/1.0/Coordinates"
136033         },
136034         Position: {
136035             path: "w3c/1.0/Position"
136036         },
136037         PositionError: {
136038             path: "w3c/1.0/PositionError"
136039         },
136040         navigator: {
136041             path: "webworks.bb10/1.0.0/navigator",
136042             children: {
136043                 geolocation: {
136044                     path: "w3c/1.0/geolocation"
136045                 }
136046             }
136047         },
136048         blackberry: {
136049             children: {
136050                 event: {
136051                     path: "webworks.bb10/1.0.0/event"
136052                 },
136053                 app: {
136054                     path: "webworks.bb10/1.0.0/app",
136055                     feature: "blackberry.app"
136056                 },
136057                 invoke: {
136058                     path: "webworks.bb10/1.0.0/invoke",
136059                     feature: "blackberry.invoke"
136060                 },
136061                 identity: {
136062                     path: "webworks.bb10/1.0.0/identity",
136063                     feature: "blackberry.identity"
136064                 },
136065                 system: {
136066                     path: "webworks.bb10/1.0.0/system"
136067                 },
136068                 connection: {
136069                     path: "webworks.bb10/1.0.0/connection"
136070                 },
136071                 ui: {
136072                     children: {
136073                         dialog: {
136074                             path: "webworks.bb10/1.0.0/dialog",
136075                             feature: "blackberry.ui.dialog"
136076                         }
136077                     }
136078                 },
136079             }
136080         }
136081     }
136082 };
136083
136084 });
136085 define('ripple/platform/webworks.bb10/1.0.0/connection', function (require, exports, module) {
136086 /*
136087  *  Copyright 2011 Research In Motion Limited.
136088  *
136089  * Licensed under the Apache License, Version 2.0 (the "License");
136090  * you may not use this file except in compliance with the License.
136091  * You may obtain a copy of the License at
136092  *
136093  * http://www.apache.org/licenses/LICENSE-2.0
136094  *
136095  * Unless required by applicable law or agreed to in writing, software
136096  * distributed under the License is distributed on an "AS IS" BASIS,
136097  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136098  * See the License for the specific language governing permissions and
136099  * limitations under the License.
136100  */
136101 var deviceSettings = require('ripple/deviceSettings'),
136102     _self = {};
136103
136104 _self.__defineGetter__("type", function () {
136105     return deviceSettings.retrieve("NetworkStatus.connectionType");
136106 });
136107
136108 _self.__defineGetter__("UNKNOWN", function () { return "unknown"; });
136109 _self.__defineGetter__("ETHERNET", function () { return "ethernet"; });
136110 _self.__defineGetter__("WIFI", function () { return "wifi"; });
136111 _self.__defineGetter__("BLUETOOTH_DUN", function () { return "bluetooth_dun"; });
136112 _self.__defineGetter__("USB", function () { return "usb"; });
136113 _self.__defineGetter__("VPN", function () { return "vpn"; });
136114 _self.__defineGetter__("BB", function () { return "rim-bb"; });
136115 _self.__defineGetter__("CELL_2G", function () { return "2g"; });
136116 _self.__defineGetter__("CELL_3G", function () { return "3g"; });
136117 _self.__defineGetter__("CELL_4G", function () { return "4g"; });
136118 _self.__defineGetter__("NONE", function () { return "none"; });
136119
136120 module.exports = _self;
136121
136122 });
136123 define('ripple/platform/webworks.bb10/1.0.0/event', function (require, exports, module) {
136124 /*
136125  *  Copyright 2011 Research In Motion Limited.
136126  *
136127  * Licensed under the Apache License, Version 2.0 (the "License");
136128  * you may not use this file except in compliance with the License.
136129  * You may obtain a copy of the License at
136130  *
136131  * http://www.apache.org/licenses/LICENSE-2.0
136132  *
136133  * Unless required by applicable law or agreed to in writing, software
136134  * distributed under the License is distributed on an "AS IS" BASIS,
136135  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136136  * See the License for the specific language governing permissions and
136137  * limitations under the License.
136138  */
136139
136140 var event = require('ripple/event'),
136141     settings = require('ripple/deviceSettings'),
136142     app = require('ripple/app'),
136143     cons = require('ripple/console'),
136144     utils = require('ripple/utils'),
136145     events = {
136146         batterystatus: {
136147             callbacks: [],
136148             feature: 'blackberry.system' 
136149         },
136150         batterylow: {
136151             callbacks: [],
136152             feature: 'blackberry.system'
136153         },
136154         batterycritical: {
136155             callbacks: [],
136156             feature: 'blackberry.system'
136157         },
136158         connectionchange: {
136159             callbacks: [],
136160             feature: 'blackberry.connection'
136161         },
136162         invoked: {
136163             callbacks: [],
136164             feature: 'blackberry.invoked'
136165         },
136166         swipedown: {
136167             callbacks: [],
136168             feature: 'blackberry.app'
136169         },
136170         resume: {
136171             callbacks: [],
136172             feature: 'blackberry.app'
136173         },
136174         pause: {
136175             callbacks: [],
136176             feature: 'blackberry.app'
136177         },
136178         languagechange: {
136179             callbacks: [],
136180             feature: "blackberry.system"
136181         },
136182         regionchange: {
136183             callbacks: [],
136184             feature: "blackberry.system"
136185         }
136186     };
136187
136188 function _apply(eventName, args) {
136189     events[eventName].callbacks.forEach(function (cb) {
136190         cb.apply(null, args);
136191     });
136192 }
136193
136194 event.on('DeviceBatteryStateChanged', function (charging) {
136195     var info = {
136196         isPlugged: charging,
136197         level: parseInt(settings.retrieve('battery.level'), 10)
136198     };
136199
136200     _apply('batterystatus', [info]);
136201 });
136202
136203 event.on('DeviceBatteryLevelChanged', function (level) {
136204     var info = {
136205         isPlugged: settings.retrieve('battery.state'),
136206         level: parseInt(level, 10)
136207     };
136208
136209     _apply('batterystatus', [info]);
136210     
136211     if (level === '14') {
136212         _apply('batterylow', [info]);
136213     }
136214
136215     if (level === '4') {
136216         _apply('batterycritical', [info]);
136217     }
136218 });
136219
136220 event.on('DeviceConnectionChanged', function (info) {
136221     _apply('connectionchange', [info]);
136222 });
136223
136224 event.on("LanguageChanged", function (lang) {
136225     _apply("languagechange", [lang]);
136226 });
136227
136228 event.on("RegionChanged", function (lang) {
136229     _apply("regionchange", [lang]);
136230 });
136231
136232 event.on("AppInvoke", function (invokeInfo) {
136233     var invokeTargets = app.getInfo().invokeTargets;
136234
136235     if (!invokeTargets) {
136236         cons.log("The application cannot be invoked, please add a rim:invoke-target node in config.xml");
136237         return;
136238     }
136239
136240     if (invokeTargets.some(function (target) {
136241         return target.filter.some(function (filter) {
136242             return (
136243                 (!filter.property ||
136244                 (filter.property && filter.property[0]["@attributes"].var === "exts" && filter.property[0]["@attributes"].value.split(",").some(function (value) {
136245                     return invokeInfo.extension.match(value);
136246                 })) ||
136247                 (filter.property && filter.property[0]["@attributes"].var === "uris" && filter.property[0]["@attributes"].value.split(",").some(function (value) {
136248                     return invokeInfo.uri.match(value);
136249                 }))) &&
136250                 filter.action.some(function (action) {
136251                     return invokeInfo.action.match(action["#text"][0].replace("*", ""));
136252                 }) &&
136253                 filter["mime-type"].some(function (type) {
136254                     return invokeInfo.type.match(type["#text"][0].replace("*", ""));
136255                 })
136256             );
136257         });
136258     })) {
136259         _apply('invoked', [invokeInfo]);
136260     }
136261     else {
136262         cons.log("Cannot invoke application, values enter to not match values in rim:invoke-target in config.xml");
136263     }
136264 });
136265
136266 event.on('AppSwipeDown', function () {
136267     _apply('swipedown');
136268 });
136269
136270 event.on('AppResume', function () {
136271     _apply('resume');
136272 });
136273
136274 event.on('AppPause', function () {
136275     _apply('pause');
136276 });
136277
136278 module.exports = {
136279     addEventListener: function (type, func) {
136280         this.removeEventListener(type, func);
136281
136282         if (!app.getInfo().features || app.getInfo().features[events[type].feature]) {
136283             events[type].callbacks.push(func);
136284         }
136285         else {
136286             throw ("Cannot register a hanlder for the " + type + " event. Please add the '" + 
136287                   events[type].feature + "' to your config.xml.");
136288         }
136289     },
136290
136291     removeEventListener: function (type, func) {
136292         var idx = events[type].callbacks.indexOf(func);
136293         if (idx >= 0) {
136294             delete events[type].callbacks[idx];
136295         }
136296     }
136297 };
136298
136299 });
136300 define('ripple/platform/webworks.bb10/1.0.0/navigator', function (require, exports, module) {
136301 /*
136302  *  Copyright 2011 Research In Motion Limited.
136303  *
136304  * Licensed under the Apache License, Version 2.0 (the "License");
136305  * you may not use this file except in compliance with the License.
136306  * You may obtain a copy of the License at
136307  *
136308  * http://www.apache.org/licenses/LICENSE-2.0
136309  *
136310  * Unless required by applicable law or agreed to in writing, software
136311  * distributed under the License is distributed on an "AS IS" BASIS,
136312  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136313  * See the License for the specific language governing permissions and
136314  * limitations under the License.
136315  */
136316 var nav = require('ripple/platform/w3c/1.0/navigator'),
136317     utils = require('ripple/utils'),
136318     deviceSettings = require('ripple/deviceSettings'),
136319     _self = {};
136320
136321 utils.mixin(nav, _self);
136322
136323 _self.__defineGetter__("language", function () {
136324     return deviceSettings.retrieve("system.language");
136325 });
136326
136327 module.exports = _self;
136328
136329 });
136330 define('ripple/platform/webworks.bb10/1.0.0/device', function (require, exports, module) {
136331 /*
136332  *  Copyright 2011 Research In Motion Limited.
136333  *
136334  * Licensed under the Apache License, Version 2.0 (the "License");
136335  * you may not use this file except in compliance with the License.
136336  * You may obtain a copy of the License at
136337  *
136338  * http://www.apache.org/licenses/LICENSE-2.0
136339  *
136340  * Unless required by applicable law or agreed to in writing, software
136341  * distributed under the License is distributed on an "AS IS" BASIS,
136342  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136343  * See the License for the specific language governing permissions and
136344  * limitations under the License.
136345  */
136346 var devices = require('ripple/devices'),
136347     _self = {};
136348
136349 _self.__defineGetter__("softwareVersion", function () {
136350     return devices.getCurrentDevice().osVersion;
136351 });
136352
136353 _self.__defineGetter__("hardwareId", function () {
136354     return devices.getCurrentDevice().hardwareId;
136355 });
136356 module.exports = _self;
136357
136358 });
136359 define('ripple/platform/webworks.bb10/1.0.0/spec/config', function (require, exports, module) {
136360 /*
136361  *  Copyright 2011 Research In Motion Limited.
136362  *
136363  * Licensed under the Apache License, Version 2.0 (the "License");
136364  * you may not use this file except in compliance with the License.
136365  * You may obtain a copy of the License at
136366  *
136367  * http://www.apache.org/licenses/LICENSE-2.0
136368  *
136369  * Unless required by applicable law or agreed to in writing, software
136370  * distributed under the License is distributed on an "AS IS" BASIS,
136371  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136372  * See the License for the specific language governing permissions and
136373  * limitations under the License.
136374  */
136375 var utils = require('ripple/utils');
136376
136377 module.exports = {
136378     fileName: "config.xml",
136379     validateVersion: function (config) {
136380         return true;
136381     },
136382     extractInfo: function (config) {
136383         if (!config) {
136384             return null;
136385         }
136386
136387         var widgetInfo = {},
136388             widgetFeatures = config.widget.children.feature.validationResult,
136389             accessUrls = config.widget.children.access.validationResult,
136390             invokeTargets = config.rawJSON.widget[0]["rim:invoke-target"],
136391             accessFeatures = config.widget.children.access.children.feature.validationResult,
136392             toFeature = function (validationResult) {
136393                 return {
136394                     id: validationResult.attributes.id.value,
136395                     required: !validationResult.attributes.required || validationResult.attributes.required.value,
136396                     URIs: []
136397                 };
136398             };
136399
136400         widgetInfo.id = config.widget.validationResult[0].attributes.id.value;
136401         widgetInfo.name = config.widget.children.name.validationResult[0].value;
136402         widgetInfo.icon = config.widget.children.icon.validationResult[0].attributes.src.value;
136403         widgetInfo.version = config.widget.validationResult[0].attributes.version.value;
136404         widgetInfo.author = config.widget.children.author.validationResult[0].value;
136405         widgetInfo.authorEmail = config.widget.children.author.validationResult[0].attributes.email.value;
136406         widgetInfo.authorURL = config.widget.children.author.validationResult[0].attributes.href.value;
136407         widgetInfo.copyright = config.widget.children.author.validationResult[0].attributes["rim:copyright"].value;
136408         widgetInfo.description = config.widget.children.description.validationResult[0].value;
136409         widgetInfo.invokeTargets = invokeTargets;
136410         if (config.widget.children.license.validationResult[0]) {
136411             widgetInfo.license = config.widget.children.license.validationResult[0].value;
136412             widgetInfo.licenseURL = config.widget.children.license.validationResult[0].attributes.href.value;
136413         }
136414
136415         widgetInfo.features = widgetFeatures.reduce(function (features, validationResult) {
136416             if (validationResult.valid) {
136417                 var feature = toFeature(validationResult);
136418                 feature.URIs.push({
136419                     value: utils.location().href,
136420                     subdomains: true
136421                 });
136422                 features = features || {};
136423                 features[feature.id] = feature;
136424             }
136425             return features;
136426         }, {});
136427
136428         widgetInfo.features = accessUrls.map(function (access) {
136429             return {
136430                 uri: access.attributes.uri.value,
136431                 subdomains: access.attributes.subdomains.value,
136432                 features: accessFeatures ? accessFeatures.filter(function (f) {
136433                     return f.node && f.node.parentNode && f.node.parentNode.attributes.uri.value === access.attributes.uri.value;
136434                 }) : null
136435             };
136436         }).reduce(function (result, access) {
136437             return access.features ? access.features.reduce(function (features, validationResult) {
136438                 var feature = features[validationResult.attributes.id.value] || toFeature(validationResult);
136439                 feature.URIs.push({
136440                     value: access.uri,
136441                     subdomains: access.subdomains
136442                 });
136443                 features[feature.id] = feature;
136444                 return features;
136445             }, result) : result;
136446         }, widgetInfo.features);
136447
136448         return widgetInfo;
136449     },
136450     schema: {
136451         rootElement: "widget",
136452         widget: {
136453             nodeName: "widget",
136454             required: true,
136455             occurrence: 1,
136456             attributes: {
136457                 xmlns: {
136458                     attributeName: "xmlns",
136459                     required: true,
136460                     type: "list",
136461                     listValues: ["http://www.w3.org/ns/widgets"]
136462                 },
136463                 "xmlns:rim": {
136464                     attributeName: "xmlns:rim",
136465                     required: true,
136466                     type: "list",
136467                     listValues: ["http://www.blackberry.com/ns/widgets"]
136468                 },
136469                 "xml:lang": {
136470                     attributeName: "xml:lang",
136471                     required: false,
136472                     type: "iso-language"
136473                 },
136474                 id: {
136475                     attributeName: "id",
136476                     required: false,
136477                     type: "string"
136478                 },
136479                 version: {
136480                     attributeName: "version",
136481                     required: false,
136482                     type: "string"
136483                 },
136484                 "rim:header": {
136485                     attributeName: "rim:header",
136486                     required: false,
136487                     type: "string"
136488                 },
136489                 "rim:backButton": {
136490                     attributeName: "rim:backButton",
136491                     required: false,
136492                     type: "string"
136493                 }
136494             },
136495             children: {
136496                 name: {
136497                     nodeName: "name",
136498                     required: true,
136499                     occurrence: 1,
136500                     attributes: {
136501                         "xml:lang": {
136502                             attributeName: "xml:lang",
136503                             required: false,
136504                             type: "iso-language"
136505                         },
136506                         "its:dir": {
136507                             attributeName: "its:dir",
136508                             required: false,
136509                             type: "list",
136510                             listValues: ["rtl", "ltr", "lro", "rlo"]
136511                         }
136512                     }
136513                 },
136514                 description: {
136515                     nodeName: "description",
136516                     required: false,
136517                     occurrence: 1,
136518                     attributes: {
136519                         "xml:lang": {
136520                             attributeName: "xml:lang",
136521                             required: false,
136522                             type: "iso-language"
136523                         },
136524                         "its:dir": {
136525                             attributeName: "its:dir",
136526                             required: false,
136527                             type: "list",
136528                             listValues: ["rtl", "ltr", "lro", "rlo"]
136529                         }
136530                     }
136531                 },
136532                 icon: {
136533                     nodeName: "icon",
136534                     required: false,
136535                     occurrence: 0,
136536                     attributes: {
136537                         src: {
136538                             attributeName: "src",
136539                             type: "string",
136540                             required: true
136541                         },
136542                         "rim:hover": {
136543                             attributeName: "rim:hover",
136544                             type: "boolean",
136545                             required: false
136546                         }
136547                     }
136548                 },
136549                 author: {
136550                     nodeName: "author",
136551                     required: false,
136552                     occurrence: 1,
136553                     attributes: {
136554                         href: {
136555                             attributeName: "href",
136556                             type: "string",
136557                             required: false
136558                         },
136559                         "rim:copyright": {
136560                             attributeName: "rim:copyright",
136561                             type: "string",
136562                             required: false
136563                         },
136564                         email: {
136565                             attributeName: "email",
136566                             type: "string",
136567                             required: false
136568                         },
136569                         "xml:lang": {
136570                             attributeName: "xml:lang",
136571                             required: false,
136572                             type: "iso-language"
136573                         },
136574                         "its:dir": {
136575                             attributeName: "its:dir",
136576                             required: false,
136577                             type: "list",
136578                             listValues: ["rtl", "ltr", "lro", "rlo"]
136579                         }
136580                     }
136581                 },
136582                 license: {
136583                     nodeName: "license",
136584                     required: false,
136585                     occurrence: 1,
136586                     attributes : {
136587                         href: {
136588                             attributeName: "href",
136589                             type: "string",
136590                             required: false
136591                         },
136592                         "xml:lang": {
136593                             attributeName: "xml:lang",
136594                             required: false,
136595                             type: "iso-language"
136596                         },
136597                         "its:dir": {
136598                             attributeName: "its:dir",
136599                             required: false,
136600                             type: "list",
136601                             listValues: ["rtl", "ltr", "lro", "rlo"]
136602                         }
136603                     }
136604                 },
136605                 "rim:cache": {
136606                     nodeName: "rim:cache",
136607                     required: false,
136608                     occurrence: 1,
136609                     attributes: {
136610                         disableAllCache: {
136611                             attributeName: "disableAllCache",
136612                             required: false,
136613                             type: "boolean"
136614                         },
136615                         aggressiveCacheAge: {
136616                             attributeName: "aggressiveCacheAge",
136617                             required: false,
136618                             type: "number"
136619                         },
136620                         maxCacheSizeTotal: {
136621                             attributeName: "maxCacheSizeTotal",
136622                             required: false,
136623                             type: "number"
136624                         },
136625                         maxCacheSizeItem: {
136626                             attributeName: "maxCacheSizeItem",
136627                             required: false,
136628                             type: "number"
136629                         }
136630                     }
136631                 },
136632                 access: {
136633                     nodeName: "access",
136634                     required: false,
136635                     occurrence: 0,
136636                     attributes: {
136637                         uri: {
136638                             attributeName: "uri",
136639                             required: true,
136640                             type: "string"
136641                         },
136642                         subdomains: {
136643                             attributeName: "subdomains",
136644                             required: false,
136645                             type: "boolean"
136646                         }
136647                     },
136648                     children: {
136649                         feature: {
136650                             nodeName: "feature",
136651                             required: false,
136652                             occurrence: 0,
136653                             attributes: {
136654                                 id: {
136655                                     attributeName: "id",
136656                                     required: true,
136657                                     //TODO: this should be a list
136658                                     type: "string"
136659                                 },
136660                                 required: {
136661                                     attributeName: "required",
136662                                     required: false,
136663                                     type: "boolean"
136664                                 },
136665                                 version: {
136666                                     attributeName: "version",
136667                                     required: false,
136668                                     type: "string"
136669                                 }
136670                             }
136671                         }
136672                     }
136673                 },
136674                 feature: {
136675                     nodeName: "feature",
136676                     required: false,
136677                     occurrence: 0,
136678                     attributes: {
136679                         id: {
136680                             attributeName: "id",
136681                             required: true,
136682                             //TODO: this should be a list
136683                             type: "string"
136684                         },
136685                         required: {
136686                             attributeName: "required",
136687                             required: false,
136688                             type: "boolean"
136689                         },
136690                         version: {
136691                             attributeName: "version",
136692                             required: false,
136693                             type: "string"
136694                         }
136695                     }
136696                 },
136697                 "rim:loadingScreen": {
136698                     nodeName: "rim:loadingScreen",
136699                     required: false,
136700                     occurrence: 1,
136701                     attributes: {
136702                         backgroundColor: {
136703                             attributeName: "backgroundColor",
136704                             required: false,
136705                             type: "string"
136706                         },
136707                         backgroundImage: {
136708                             attributeName: "backgroundImage",
136709                             required: false,
136710                             type: "string"
136711                         },
136712                         foregroundImage: {
136713                             attributeName: "foregroundImage",
136714                             required: false,
136715                             type: "string"
136716                         },
136717                         onRemotePageLoad: {
136718                             attributeName: "onRemotePageLoad",
136719                             required: false,
136720                             type: "boolean"
136721                         },
136722                         onLocalPageLoad: {
136723                             attributeName: "onLocalPageLoad",
136724                             required : false,
136725                             type: "boolean"
136726                         },
136727                         onFirstLaunch: {
136728                             attributeName: "onFirstLaunch",
136729                             required: false,
136730                             type: "boolean"
136731                         }
136732                     },
136733                     children: {
136734                         "rim:transitionEffect": {
136735                             nodeName: "rim:transitionEffect",
136736                             required: false,
136737                             occurrence: 1,
136738                             attributes: {
136739                                 "type": {
136740                                     attributeName: "type",
136741                                     required: true,
136742                                     type: "list",
136743                                     listValues: ["slidePush", "slideOver", "fadeIn", "fadeOut", "wipeIn", "wipeOut", "zoomIn", "zoomOut"]
136744                                 },
136745                                 duration: {
136746                                     attributeName: "duration",
136747                                     required: false,
136748                                     type: "number"
136749                                 },
136750                                 direction: {
136751                                     attributeName: "direction",
136752                                     required: false,
136753                                     type: "list",
136754                                     listValues: ["left", "right", "up", "down"]
136755                                 }
136756                             }
136757                         }
136758                     }
136759                 },
136760                 "rim:invoke-target": {
136761                     nodeName: "rim:invoke-target",
136762                     required: false,
136763                     occurrence: 0,
136764                     attributes: {
136765                         id: {
136766                             attributeName: "id",
136767                             required: true,
136768                             type: "string"
136769                         }
136770                     },
136771                     children: {
136772                         "type": {
136773                             nodeName: "type",
136774                             required: true,
136775                             occurrence: 1
136776                         },
136777                         "require-source-permissions": {
136778                             nodeName: "require-source-permissions",
136779                             required: false,
136780                             occurence: 0
136781                         },
136782                         "filter": {
136783                             nodeName: "filter",
136784                             required: false,
136785                             occurence: 0,
136786                             children: {
136787                                 "action": {
136788                                     nodeName: "action",
136789                                     required: true,
136790                                     occurence: 0
136791                                 },
136792                                 "mime-type": {
136793                                     nodeName: "mime-type",
136794                                     required: true,
136795                                     occurence: 0
136796                                 },
136797                                 "property": {
136798                                     nodeName: "property",
136799                                     required: false,
136800                                     occurenc: 0,
136801                                     attributes: {
136802                                         "var": {
136803                                             attributeName: "var",
136804                                             required: false,
136805                                             type: "string"
136806                                         },
136807                                         "value": {
136808                                             attributeName: "value",
136809                                             required: false,
136810                                             type: "string"
136811                                         }
136812                                     }
136813                                 }
136814                             },
136815                         }
136816                     }
136817                 },
136818                 "rim:connection": {
136819                     nodeName: "rim:connection",
136820                     required: false,
136821                     occurrence: 1,
136822                     attributes: {
136823                         timeout: {
136824                             attributeName: "timeout",
136825                             required: false,
136826                             type: "number"
136827                         }
136828                     },
136829                     children: {
136830                         id: {
136831                             nodeName: "id",
136832                             required: false,
136833                             occurrence: 0
136834                         }
136835                     }
136836                 },
136837                 "rim:navigation": {
136838                     nodeName: "rim:navigation",
136839                     required: false,
136840                     occurrence: 1,
136841                     attributes: {
136842                         mode: {
136843                             attributeName: "mode",
136844                             required: false,
136845                             type: "list",
136846                             listValues: ["focus"]
136847                         }
136848                     }
136849                 },
136850                 "content": {
136851                     nodeName: "content",
136852                     required: true,
136853                     occurrence: 1,
136854                     attributes: {
136855                         src: {
136856                             attributeName: "src",
136857                             required: true,
136858                             type: "string"
136859                         },
136860                         type: {
136861                             attributeName: "type",
136862                             required: false,
136863                             type: "string"
136864                         },
136865                         charset: {
136866                             attributeName: "charset",
136867                             required: false,
136868                             type: "string"
136869                         }
136870                     }
136871                 }
136872             }
136873         }
136874     }
136875 };
136876
136877 });
136878 define('ripple/platform/webworks.bb10/1.0.0/spec/device', function (require, exports, module) {
136879 /*
136880  *  Copyright 2011 Research In Motion Limited.
136881  *
136882  * Licensed under the Apache License, Version 2.0 (the "License");
136883  * you may not use this file except in compliance with the License.
136884  * You may obtain a copy of the License at
136885  *
136886  * http://www.apache.org/licenses/LICENSE-2.0
136887  *
136888  * Unless required by applicable law or agreed to in writing, software
136889  * distributed under the License is distributed on an "AS IS" BASIS,
136890  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136891  * See the License for the specific language governing permissions and
136892  * limitations under the License.
136893  */
136894 var event = require('ripple/event');
136895
136896 module.exports = {
136897     "NetworkStatus": {
136898         "connectionType": {
136899             "name": "Connection Type",
136900             "control": {
136901                 "type": "select",
136902                 "value": "ethernet"
136903             },
136904             "options": {
136905                 "unknown": "UNKNOWN",
136906                 "ethernet": "ETHERNET",
136907                 "wifi": "WIFI",
136908                 "bluetooth_dun": "BLUETOOTH_DUN",
136909                 "usb": "USB",
136910                 "vpn": "VPN",
136911                 "rim-bb": "BB",
136912                 "2g": "CELL_2G",
136913                 "3g": "CELL_3G",
136914                 "4g": "CELL_4G",
136915                 "none": "NONE"
136916             },
136917             "callback": function (setting, oldSetting) {
136918                 event.trigger("DeviceConnectionChanged", [{oldType: oldSetting, newType: setting}]);
136919             }
136920         }
136921     },
136922     "identity": {
136923         "uuid": {
136924             "name": "uuid",
136925             "control": {
136926                 "type": "text",
136927                 "value": "43A8C489"
136928             }
136929         }
136930     },
136931     "system": {
136932         "language": {
136933             "name": "language",
136934             "control": {
136935                 "type": "text",
136936                 "value": "en_US"
136937             },
136938             "callback": function (setting) {
136939                 event.trigger("LanguageChanged", [setting]);
136940             }
136941         },
136942         "region": {
136943             "name": "region",
136944             "control": {
136945                 "type": "text",
136946                 "value": "en_CA"
136947             },
136948             "callback": function (setting) {
136949                 event.trigger("RegionChanged", [setting]);
136950             }
136951         }
136952     },
136953     "battery": {
136954         "state": {
136955             "name": "Handset is Charging",
136956             "control": {
136957                 "type": "checkbox",
136958                 "value": true
136959             },
136960             "callback": function (setting) {
136961                 event.trigger("DeviceBatteryStateChanged", [setting]);
136962             }
136963         },
136964         "level":  {
136965             "name": "Charge Level (% remaining)",
136966             "control": {
136967                 "type": "select",
136968                 "value": 100
136969             },
136970             "options": (function () {
136971                 var i,
136972                     optionList = {};
136973
136974                 for (i = 0; i <= 100; i++) {
136975                     optionList[i] = i;
136976                 }
136977
136978                 return optionList;
136979             }()),
136980             "callback": function (setting) {
136981                 event.trigger("DeviceBatteryLevelChanged", [setting]);
136982             }
136983         }
136984     },
136985     "Perimeters": {
136986         "perimeter": {
136987             "name": "Perimeter",
136988             "control": {
136989                 "type": "select",
136990                 "value": "Consumer"
136991             },
136992             "options": {
136993                 "Enterprise": "Enterprise",
136994                 "Consumer": "Consumer"
136995             }
136996         }
136997     }
136998 };
136999
137000 });
137001 define('ripple/platform/webworks.bb10/1.0.0/spec/events', function (require, exports, module) {
137002 /*
137003  *  Copyright 2011 Research In Motion Limited.
137004  *
137005  * Licensed under the Apache License, Version 2.0 (the "License");
137006  * you may not use this file except in compliance with the License.
137007  * You may obtain a copy of the License at
137008  *
137009  * http://www.apache.org/licenses/LICENSE-2.0
137010  *
137011  * Unless required by applicable law or agreed to in writing, software
137012  * distributed under the License is distributed on an "AS IS" BASIS,
137013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137014  * See the License for the specific language governing permissions and
137015  * limitations under the License.
137016  */
137017 var _self,
137018     event = require('ripple/event');
137019
137020 module.exports = {
137021     "blackberry.event.swipedown": {
137022         callback: function () {
137023             event.trigger("AppSwipeDown");
137024         }
137025     },
137026     "blackberry.event.resume": {
137027         callback: function () {
137028             event.trigger("AppResume");
137029         }
137030     },
137031     "blackberry.event.pause": {
137032         callback: function () {
137033             event.trigger("AppPause");
137034         }
137035     }
137036 };
137037
137038 });
137039 define('ripple/platform/webworks.bb10/1.0.0/spec/ui', function (require, exports, module) {
137040 /*
137041  *  Copyright 2011 Research In Motion Limited.
137042  *
137043  * Licensed under the Apache License, Version 2.0 (the "License");
137044  * you may not use this file except in compliance with the License.
137045  * You may obtain a copy of the License at
137046  *
137047  * http://www.apache.org/licenses/LICENSE-2.0
137048  *
137049  * Unless required by applicable law or agreed to in writing, software
137050  * distributed under the License is distributed on an "AS IS" BASIS,
137051  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137052  * See the License for the specific language governing permissions and
137053  * limitations under the License.
137054  */
137055 module.exports = {
137056     plugins: [
137057         "accelerometer",
137058         "deviceSettings",
137059         "geoView",
137060         "platformEvents",
137061         "widgetConfig",
137062         "build",
137063         "invoke"
137064     ]
137065 };
137066
137067 });
137068 define('ripple/platform/webworks.bb10/1.0.0/identity', function (require, exports, module) {
137069 /*
137070  *  Copyright 2011 Research In Motion Limited.
137071  *
137072  * Licensed under the Apache License, Version 2.0 (the "License");
137073  * you may not use this file except in compliance with the License.
137074  * You may obtain a copy of the License at
137075  *
137076  * http://www.apache.org/licenses/LICENSE-2.0
137077  *
137078  * Unless required by applicable law or agreed to in writing, software
137079  * distributed under the License is distributed on an "AS IS" BASIS,
137080  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137081  * See the License for the specific language governing permissions and
137082  * limitations under the License.
137083  */
137084 var deviceSettings = require('ripple/deviceSettings'),
137085     _self = {};
137086
137087 _self.__defineGetter__("uuid", function () {
137088     return deviceSettings.retrieve("identity.uuid");
137089 });
137090
137091 module.exports = _self;
137092
137093 });
137094 define('ripple/platform/webworks.bb10/1.0.0/system', function (require, exports, module) {
137095 /*\r
137096  *  Copyright 2011 Research In Motion Limited.\r
137097  *\r
137098  * Licensed under the Apache License, Version 2.0 (the "License");\r
137099  * you may not use this file except in compliance with the License.\r
137100  * You may obtain a copy of the License at\r
137101  *\r
137102  * http://www.apache.org/licenses/LICENSE-2.0\r
137103  *\r
137104  * Unless required by applicable law or agreed to in writing, software\r
137105  * distributed under the License is distributed on an "AS IS" BASIS,\r
137106  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
137107  * See the License for the specific language governing permissions and\r
137108  * limitations under the License.\r
137109  */\r
137110 var deviceSettings = require('ripple/deviceSettings'),\r
137111     devices = require('ripple/devices'),\r
137112     app = require('ripple/app'),\r
137113     utils = require('ripple/utils'),\r
137114     _self;\r
137115 \r
137116 function _is(feature) {\r
137117     return {\r
137118         allowedFor: function (location) {\r
137119             return feature && feature.URIs.some(function (uri) {\r
137120                 return uri.value === location ||\r
137121                       (location.indexOf(uri.value) >= 0 && uri.subdomains);\r
137122             });\r
137123         }\r
137124     };\r
137125 }\r
137126 \r
137127 _self = {\r
137128     hasCapability: function (capability) {\r
137129         var capabilities = devices.getCurrentDevice().capabilities;\r
137130         return capabilities ? capabilities.some(function (type) {\r
137131                 return type === capability;\r
137132             }) : false;\r
137133     },\r
137134     hasPermission: function (desiredModule) {\r
137135         var info = app.getInfo(),\r
137136             feature = info.features ? info.features[desiredModule] : null;\r
137137 \r
137138         return feature === null || _is(feature).allowedFor(utils.location().href) ? _self.ALLOW : _self.DENY;\r
137139     }\r
137140 };\r
137141 \r
137142 _self.__defineGetter__("ALLOW", function () {\r
137143     return 0;\r
137144 });\r
137145 \r
137146 _self.__defineGetter__("DENY", function () {\r
137147     return 1;\r
137148 });\r
137149 \r
137150 _self.__defineGetter__("softwareVersion", function () {\r
137151     return devices.getCurrentDevice().osVersion;\r
137152 });\r
137153 \r
137154 _self.__defineGetter__("hardwareId", function () {\r
137155     return devices.getCurrentDevice().hardwareId;\r
137156 });\r
137157 \r
137158 _self.__defineGetter__("language", function () {\r
137159     return deviceSettings.retrieve("system.language");\r
137160 });\r
137161 \r
137162 _self.__defineGetter__("region", function () {\r
137163     return deviceSettings.retrieve("system.region");\r
137164 });\r
137165 \r
137166 module.exports = _self;\r
137167
137168 });
137169 define('ripple/platform/webworks.bb10/1.0.0/app', function (require, exports, module) {
137170 /*
137171  *  Copyright 2011 Research In Motion Limited.
137172  *
137173  * Licensed under the Apache License, Version 2.0 (the "License");
137174  * you may not use this file except in compliance with the License.
137175  * You may obtain a copy of the License at
137176  *
137177  * http://www.apache.org/licenses/LICENSE-2.0
137178  *
137179  * Unless required by applicable law or agreed to in writing, software
137180  * distributed under the License is distributed on an "AS IS" BASIS,
137181  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137182  * See the License for the specific language governing permissions and
137183  * limitations under the License.
137184  */
137185 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
137186     app = require('ripple/app'),
137187     notifications = require('ripple/notifications'),
137188     _uri = "blackberry/app/",
137189     _self;
137190
137191 _self = {
137192     exit: function () {
137193         notifications.openNotification("normal", "blackberry.app.exit() was called, in the real world your app will exit, here... you get this notification");
137194     }
137195 };
137196
137197 _self.__defineGetter__("author", function () {
137198     return app.getInfo().author;
137199 });
137200
137201 _self.__defineGetter__("authorEmail", function () {
137202     return app.getInfo().authorEmail;
137203 });
137204
137205 _self.__defineGetter__("authorURL", function () {
137206     return app.getInfo().authorURL;
137207 });
137208
137209 _self.__defineGetter__("copyright", function () {
137210     return app.getInfo().copyright;
137211 });
137212
137213 _self.__defineGetter__("description", function () {
137214     return app.getInfo().description;
137215 });
137216
137217 _self.__defineGetter__("id", function () {
137218     return app.getInfo().id;
137219 });
137220
137221 _self.__defineGetter__("license", function () {
137222     return app.getInfo().license;
137223 });
137224
137225 _self.__defineGetter__("licenseURL", function () {
137226     return app.getInfo().licenseURL;
137227 });
137228
137229 _self.__defineGetter__("name", function () {
137230     return app.getInfo().name;
137231 });
137232
137233 _self.__defineGetter__("version", function () {
137234     return app.getInfo().version;
137235 });
137236
137237 module.exports = _self;
137238
137239 });
137240 define('ripple/platform/webworks.bb10/1.0.0/invoke', function (require, exports, module) {
137241 /*\r
137242  *  Copyright 2011 Research In Motion Limited.\r
137243  *\r
137244  * Licensed under the Apache License, Version 2.0 (the "License");\r
137245  * you may not use this file except in compliance with the License.\r
137246  * You may obtain a copy of the License at\r
137247  *\r
137248  * http://www.apache.org/licenses/LICENSE-2.0\r
137249  *\r
137250  * Unless required by applicable law or agreed to in writing, software\r
137251  * distributed under the License is distributed on an "AS IS" BASIS,\r
137252  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
137253  * See the License for the specific language governing permissions and\r
137254  * limitations under the License.\r
137255  */\r
137256 \r
137257 var notifications = require('ripple/notifications'),\r
137258     utils = require('ripple/utils'),\r
137259     _self = {};\r
137260 \r
137261 function _fail(onError) {\r
137262     if (onError && typeof onError === "function") {\r
137263         onError("invalid invocation request");\r
137264     }\r
137265 }\r
137266 \r
137267 _self.invoke = function (request, onSuccess, onError) {\r
137268     var argsString = "";\r
137269 \r
137270     if (!request) { // is this check even needed?\r
137271         _fail(onError);\r
137272         return;\r
137273     } else {\r
137274         if (request) {\r
137275             utils.forEach(request, function (arg, key) {\r
137276                 argsString += key + " = " + arg + "</br>";\r
137277             });\r
137278 \r
137279             notifications.openNotification("normal", "Requested to invoke external application with the following arguments:</br> " +\r
137280                                            argsString + "</br>");\r
137281         }\r
137282         else {\r
137283             _fail(onError);\r
137284             return;\r
137285         }\r
137286     }\r
137287 };\r
137288 \r
137289 _self.__defineGetter__("ACTION_OPEN", function () {\r
137290     return "bb.action.OPEN";\r
137291 });\r
137292 _self.__defineGetter__("ACTION_VIEW", function () { \r
137293     return "bb.action.VIEW"; \r
137294 });\r
137295 _self.__defineGetter__("ACTION_SHARE", function () {\r
137296     return "bb.action.SHARE";\r
137297 });\r
137298 \r
137299 module.exports = _self;\r
137300
137301 });
137302 define('ripple/platform/webworks.bb10/1.0.0/dialog', function (require, exports, module) {
137303 /*
137304  *  Copyright 2011 Research In Motion Limited.
137305  *
137306  * Licensed under the Apache License, Version 2.0 (the "License");
137307  * you may not use this file except in compliance with the License.
137308  * You may obtain a copy of the License at
137309  *
137310  * http://www.apache.org/licenses/LICENSE-2.0
137311  *
137312  * Unless required by applicable law or agreed to in writing, software
137313  * distributed under the License is distributed on an "AS IS" BASIS,
137314  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137315  * See the License for the specific language governing permissions and
137316  * limitations under the License.
137317  */
137318 var _self,
137319     ui = require('ripple/ui'),
137320     event = require('ripple/event'),
137321     isDialogVisible = false,
137322     visibleDialogArgs,
137323     utils = require('ripple/utils');
137324
137325 function getButtonsForDialogType(dialogType) {
137326     switch (dialogType) {
137327     case _self.D_OK:
137328         return ["Ok"];
137329     case _self.D_SAVE:
137330         return ["Save", "Discard"];
137331     case _self.D_DELETE:
137332         return ["Delete", "Cancel"];
137333     case _self.D_YES_NO:
137334         return ["Yes", "No"];
137335     case _self.D_OK_CANCEL:
137336         return ["Ok", "Cancel"];
137337     default:
137338         throw new Error("Invalid dialog type: " + dialogType);
137339     }
137340 }
137341
137342 event.on("LayoutChanged", function () {
137343     if (isDialogVisible) {
137344         closeDialog();
137345         //Used to resize dialog on orientation change
137346         _self.ask(visibleDialogArgs);
137347     }
137348 });
137349
137350 function closeDialog() {
137351     var buttonsDiv = document.getElementById("dialog-buttons"),
137352         messageDiv = document.getElementById("dialog-message");
137353
137354     ui.hideOverlay("dialog-window", function (dialog) {
137355         buttonsDiv.innerHTML = "";
137356         messageDiv.innerHTML = "";
137357         isDialogVisible = false;
137358     });
137359 }
137360
137361 function ask(args, callback) {
137362     if (!args) {
137363         throw ("No arguments provided");
137364     } else if (!args.buttons || !args.message) {
137365         throw ("Invalid arguments");
137366     }
137367     visibleDialogArgs = args;
137368
137369     ui.showOverlay("dialog-window", function (dialog) {
137370         var container = document.getElementById("viewport-container"),
137371             height = window.getComputedStyle(container, null).getPropertyValue("height"),
137372             width = window.getComputedStyle(container, null).getPropertyValue("width"),
137373             sizeDiv = document.getElementById("dialog-wrapper"),
137374             positionDiv = document.getElementById("dialog-window"),
137375             titleDiv = document.getElementById("dialog-title"),
137376             buttonsDiv = document.getElementById("dialog-buttons"),
137377             messageDiv = document.getElementById("dialog-message"),
137378             position, size;
137379
137380         if (!messageDiv || !buttonsDiv) {
137381             return;
137382         }
137383
137384         dialog.setAttribute("style", "display:-webkit-box;height:" + height + "; width:" + width + ";");
137385
137386         position = "overlay-dialog";
137387         size = "overlay-dialog-wrapper";
137388
137389         if (args.settings && args.settings.position) {
137390             position += " overlay-dialog-" + args.settings.position;
137391         }
137392
137393         if (args.settings && args.settings.size) {
137394             size += " overlay-dialog-wrapper-" + args.settings.size;
137395         }
137396
137397         positionDiv.setAttribute("class", position);
137398         sizeDiv.setAttribute("class", size);
137399
137400         titleDiv.innerHTML = args.settings && args.settings.title ? args.settings.title : "";
137401         messageDiv.innerHTML = args.message;
137402         isDialogVisible = true;
137403
137404         args.buttons.forEach(function (button) {
137405             var buttonElement = utils.createElement("input", {
137406                 "type": "button",
137407                 "value": button
137408             });
137409             buttonElement.addEventListener("click", function () {
137410                 var buttonIndex = args.buttons.indexOf(button);
137411                 closeDialog();
137412                 callback(buttonIndex);
137413             });
137414             buttonsDiv.appendChild(buttonElement);
137415         });
137416     }, true);
137417 }
137418
137419 _self = {
137420     customAskAsync: function (message, choices, callback, settings) {
137421         ask({
137422             message: message,
137423             buttons: choices,
137424             settings: settings
137425         }, function (response) {
137426             if (callback) {
137427                 callback(response);
137428             }
137429         });
137430     },
137431
137432     standardAskAsync: function (message, type, callback, settings) {
137433         var choices = getButtonsForDialogType(type);
137434         ask({ 
137435             message: message, 
137436             buttons: choices, 
137437             settings: settings
137438         }, function (response) {
137439             if (callback) {
137440                 callback(response);
137441             }
137442         });
137443     }
137444 };
137445
137446 _self.__defineGetter__("D_OK", function () {
137447     return 0;
137448 });
137449
137450 _self.__defineGetter__("D_SAVE", function () {
137451     return 1;
137452 });
137453
137454 _self.__defineGetter__("D_DELETE", function () {
137455     return 2;
137456 });
137457
137458 _self.__defineGetter__("D_YES_NO", function () {
137459     return 3;
137460 });
137461
137462 _self.__defineGetter__("D_OK_CANCEL", function () {
137463     return 4;
137464 });
137465
137466 _self.__defineGetter__("BOTTOM", function () {
137467     return "bottomCenter";
137468 });
137469
137470 _self.__defineGetter__("CENTER", function () {
137471     return "middleCenter";
137472 });
137473
137474 _self.__defineGetter__("TOP", function () {
137475     return "topCenter";
137476 });
137477
137478 _self.__defineGetter__("SIZE_FULL", function () {
137479     return "full";
137480 });
137481
137482 _self.__defineGetter__("SIZE_LARGE", function () {
137483     return "large";
137484 });
137485
137486 _self.__defineGetter__("SIZE_MEDIUM", function () {
137487     return "medium";
137488 });
137489
137490 _self.__defineGetter__("SIZE_SMALL", function () {
137491     return "small";
137492 });
137493
137494 _self.__defineGetter__("SIZE_TALL", function () {
137495     return "tall";
137496 });
137497
137498 module.exports = _self;
137499
137500 });
137501 define('ripple/platform/webworks.core/2.0.0/fsCache', function (require, exports, module) {
137502 /*
137503  * Copyright 2011 Research In Motion Limited.
137504  *
137505  * Licensed under the Apache License, Version 2.0 (the "License");
137506  * you may not use this file except in compliance with the License.
137507  * You may obtain a copy of the License at
137508  *
137509  *     http://www.apache.org/licenses/LICENSE-2.0
137510  *
137511  * Unless required by applicable law or agreed to in writing, software
137512  * distributed under the License is distributed on an "AS IS" BASIS,
137513  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137514  * See the License for the specific language governing permissions and
137515  * limitations under the License.
137516  */
137517 var fs = require('ripple/dbfs'),
137518     utils = require('ripple/utils'),
137519     _console = require('ripple/console'),
137520     constants = require('ripple/constants'),
137521     event = require('ripple/event'),
137522     bbUtils = require('ripple/platform/webworks.core/2.0.0/client/utils'),
137523     FileProperties = require('ripple/platform/webworks.core/2.0.0/client/FileProperties'),
137524     _cache = {},
137525     _self;
137526
137527 function _createPath(path) {
137528     var parts = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
137529         workflow = jWorkflow.order();
137530
137531     parts.forEach(function (part, index) {
137532         var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/");
137533
137534         workflow.andThen(function (prev, baton) {
137535             baton.take();
137536             fs.mkdir(dir, baton.pass, baton.pass);
137537         });
137538     });
137539
137540     workflow.start(_self.refresh);
137541 }
137542 event.on("FileSystemInitialized", function () {
137543     _createPath("/SDCard");
137544     _createPath("/store/home/user/music");
137545     _createPath("/store/home/user/pictures");
137546     _createPath("/store/home/user/videos");
137547     _createPath("/store/home/user/videos");
137548     _createPath("/accounts/1000/appdata/emulatedapp/data");
137549     _createPath("/accounts/1000/appdata/emulatedapp/shared/bookmarks");
137550     _createPath("/accounts/1000/appdata/emulatedapp/shared/books");
137551     _createPath("/accounts/1000/appdata/emulatedapp/shared/camera");
137552     _createPath("/accounts/1000/appdata/emulatedapp/shared/documents");
137553     _createPath("/accounts/1000/appdata/emulatedapp/shared/downloads");
137554     _createPath("/accounts/1000/appdata/emulatedapp/shared/misc");
137555     _createPath("/accounts/1000/appdata/emulatedapp/shared/music");
137556     _createPath("/accounts/1000/appdata/emulatedapp/shared/photos");
137557     _createPath("/accounts/1000/appdata/emulatedapp/shared/print");
137558     _createPath("/accounts/1000/appdata/emulatedapp/shared/videos");
137559     _createPath("/accounts/1000/appdata/emulatedapp/shared/voice");
137560 });
137561
137562 function _fsError(e) {
137563     _self.refresh();
137564     if (e.code !== 1) { // suppress file not found error
137565         _console.error("FileSystem error (code " + e.code + ")");
137566     }
137567 }
137568
137569 function _walk(path, parent) {
137570     fs.ls(path, function (entries) {
137571         parent.children = parent.children || {};
137572
137573         entries.forEach(function (entry) {
137574             parent.children[entry.name] = entry;
137575             parent.children[entry.name].properties = {};
137576
137577             if (entry.isDirectory) {
137578                 _walk(entry.fullPath, entry);
137579             } else {
137580                 entry.file(function (file) {
137581                     utils.mixin(file, parent.children[entry.name].properties);
137582                 });
137583                 fs.read(entry.fullPath, function (data) {
137584                     parent.children[entry.name].data = data;
137585                 }, function (e) {
137586                     console.error(e);
137587                 });
137588             }
137589         });
137590     }, function (e) {
137591         console.error(e);
137592     });
137593 }
137594
137595 function _get(path) {
137596     return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
137597         return token === "" ? obj : (obj && obj.children ? obj.children[token] || null : null);
137598     }, _cache);
137599 }
137600
137601 function _getInfo(path) {
137602     var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
137603         name = parent.splice(parent.length - 1, 1).join(""),
137604         ext = name.split(".");
137605
137606     return {
137607         name: name,
137608         extension: ext.length > 1 ? ext[ext.length - 1] : "",
137609         hidden: (name.length > 0 && name[0] === ".") || false,
137610         parent: parent.join("/") || "/"
137611     };
137612 }
137613
137614 function _set(path, obj) {
137615     var parent = _cache,
137616         tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
137617         child = tokens.splice(tokens.length - 1, 1).join("");
137618
137619     tokens.forEach(function (token) {
137620         parent = parent.children[token];
137621     });
137622
137623     parent.children = parent.children || {};
137624     obj.properties = obj.properties || {};
137625     parent.children[child] = obj;
137626 }
137627
137628 function _delete(path) {
137629     var parent = _cache,
137630         tokens = path.replace(/^\//, '').replace(/\/$/, '').split("/"),
137631         child = tokens.splice(tokens.length - 1, 1).join("");
137632
137633     tokens.forEach(function (token) {
137634         parent = parent.children[token];
137635     });
137636
137637     delete parent.children[child];
137638 }
137639
137640 // TODO: handle exceptions so that any respective fs command can error out
137641 // TODO: dateCreated is always dateModified
137642
137643 _self = {
137644     refresh: function () {
137645         _cache = {};
137646         _walk("/", _cache);
137647     },
137648     file: {
137649         exists: function (path) {
137650             var entry = _get(path);
137651             return !!(entry && !entry.isDirectory);
137652         },
137653
137654         deleteFile: function (path) {
137655             _delete(path);
137656             fs.rm(path, function () {}, _fsError);
137657         },
137658
137659         copy: function (from, to) {
137660             var fromEntry = _get(from);
137661
137662             _set(to, {
137663                 fullPath: to,
137664                 properties: fromEntry.properties,
137665                 data: fromEntry.data
137666             });
137667
137668             fs.cp(from, to, function (entry) {
137669                 entry.file(function (file) {
137670                     entry.properties = entry.properties || {};
137671                     utils.mixin(file, entry.properties);
137672                     _set(to, entry);
137673                 });
137674             }, _fsError);
137675         },
137676
137677         getFileProperties: function (path) {
137678             var entry = _get(path),
137679                 info = _getInfo(path);
137680
137681             fs.stat(path, function () {}, _fsError);
137682
137683             return new FileProperties({
137684                 //HACK: not sure where these should come from so check both for now.
137685                 dateCreated: entry.properties.lastModifiedDate || entry.lastModifiedDate,
137686                 dateModified: entry.properties.lastModifiedDate || entry.lastModifiedDate,
137687                 directory: info.parent,
137688                 fileExtension: info.extension,
137689                 isHidden: info.hidden,
137690                 isReadonly: false,
137691                 mimeType: entry.properties.type,
137692                 size: entry.properties.size
137693             });
137694         },
137695
137696         rename: function (path, newName) {
137697             _self.dir.rename(path, newName);
137698         },
137699
137700         readFile: function (path, success, async) {
137701             var entry = _get(path);
137702
137703             async = async === false ? async : true;
137704
137705             if (!async) {
137706                 success(bbUtils.stringToBlob(entry.data));
137707             }
137708             else {
137709                 fs.read(path, function (data) {
137710                     var blob = bbUtils.stringToBlob(data);
137711                     if (async) {
137712                         success(blob);
137713                     }
137714                     entry.data = data;
137715                     _set(path, entry);
137716                 }, _fsError);
137717             }
137718         },
137719
137720         saveFile: function (path, blob) {
137721             var data = bbUtils.blobToString(blob);
137722
137723             _set(path, {
137724                 lastModifiedDate: new Date(),
137725                 fullPath: path,
137726                 isDirectory: false,
137727                 properties: {
137728                     type: "",
137729                     size: blob.size
137730                 },
137731                 data: data
137732             });
137733
137734             fs.write(path, data, function (entry) {
137735                 entry.data = data;
137736                 entry.file(function (file) {
137737                     entry.properties = entry.properties || {};
137738                     utils.mixin(file, entry.properties);
137739                     _set(path, entry);
137740                 });
137741             }, _fsError);
137742         }
137743     },
137744     dir: {
137745         createNewDir: function (path) {
137746             var entry = _get(path),
137747                 info = _getInfo(path);
137748
137749             if (!entry) {
137750                 _set(path, {
137751                     name: info.name,
137752                     isDirectory: true,
137753                     fullPath: path
137754                 });
137755             }
137756
137757             fs.mkdir(path, function (entry) {
137758                 _set(path, entry);
137759             }, _fsError);
137760         },
137761
137762         deleteDirectory: function (path, recursive) {
137763             _delete(path);
137764             if (recursive) {
137765                 fs.rm(path, function () {}, _fsError, {recursive: recursive});
137766             } else {
137767                 fs.rmdir(path, function () {}, _fsError);
137768             }
137769         },
137770
137771         exists: function (path) {
137772             var entry = _get(path);
137773             return !!(entry && entry.isDirectory);
137774         },
137775
137776         getFreeSpaceForRoot: function (path) {
137777             function _du(obj, size) {
137778                 utils.forEach(obj, function (child, key) {
137779                     if (child.isDirectory && child.children) {
137780                         size += _du(child.children, size);
137781                     } else if (child.properties && child.properties.size) {
137782                         size += child.properties.size;
137783                     }
137784                 });
137785                 return size;
137786             }
137787
137788             return constants.FS_SIZE - _du(_cache.children, 0);
137789         },
137790
137791         getParentDirectory: function (path) {
137792             path = "/" + path.replace(/^\//, '').replace(/\/$/, '');
137793
137794             var entry = _get(path),
137795                 array = path.split("/");
137796
137797             return entry ? array.splice(0, array.length - 1).join("/") || "/" : null;
137798         },
137799
137800         listDirectories: function (path) {
137801             var dir = _get(path),
137802                 directories = [];
137803
137804             utils.forEach(dir.children, function (item) {
137805                 if (item.isDirectory) {
137806                     directories.push(item.name);
137807                 }
137808             });
137809
137810             fs.ls(path, function () {}, _fsError);
137811
137812             return directories;
137813         },
137814
137815         listFiles: function (path) {
137816             var dir = _get(path),
137817                 files = [];
137818
137819             if (dir) {
137820                 utils.forEach(dir.children, function (item) {
137821                     if (!item.isDirectory) {
137822                         files.push(item.name);
137823                     }
137824                 });
137825             }
137826
137827             fs.ls(path, function () {}, _fsError);
137828
137829             return files;
137830         },
137831
137832         rename: function (path, newName) {
137833             var info = _getInfo(path),
137834                 parent = info.parent,
137835                 oldName = info.name,
137836                 from = (parent === "/" ? "" : parent) + "/" + oldName,
137837                 to =  (parent === "/" ? "" : parent) + "/" + newName;
137838
137839             _delete(from);
137840             _set(to, {
137841                 name: info.name,
137842                 fullPath: path
137843             });
137844
137845             fs.mv(from, to, function (entry) {
137846                 _set(to, entry);
137847             }, _fsError);
137848         },
137849
137850         getRootDirs: function () {
137851             return _self.dir.listDirectories("/");
137852         }
137853     }
137854 };
137855
137856 module.exports = _self;
137857
137858 });
137859 define('ripple/platform/webworks.core/2.0.0/XMLHttpRequest', function (require, exports, module) {
137860 /*
137861  *  Copyright 2011 Research In Motion Limited.
137862  *
137863  * Licensed under the Apache License, Version 2.0 (the "License");
137864  * you may not use this file except in compliance with the License.
137865  * You may obtain a copy of the License at
137866  *
137867  * http://www.apache.org/licenses/LICENSE-2.0
137868  *
137869  * Unless required by applicable law or agreed to in writing, software
137870  * distributed under the License is distributed on an "AS IS" BASIS,
137871  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137872  * See the License for the specific language governing permissions and
137873  * limitations under the License.
137874  */
137875 module.exports = {
137876     create: function (server) {
137877         var XHR = window.XMLHttpRequest,
137878             webworks = require(server);
137879
137880         return function () {
137881             var _url,
137882                 _async,
137883                 xhr = new XHR(),
137884                 origMethods = {
137885                     open: xhr.open,
137886                     send: xhr.send,
137887                     setRequestHeader: xhr.setRequestHeader
137888                 };
137889
137890             function onreadystatechange() {
137891                 if (typeof xhr.onreadystatechange === "function") {
137892                     xhr.onreadystatechange();
137893                 }
137894             }
137895
137896             function statemachine(getResult) {
137897                 var state = 0,
137898                     incState = function (prev, baton) {
137899                         state++;
137900                         if (_async) {
137901                             baton.take();
137902                             window.setTimeout(baton.pass, 1);
137903                         }
137904                     },
137905                     setResponse = function (result) {
137906                         xhr.__defineGetter__("status", function () {
137907                             return 200;
137908                         });
137909
137910                         xhr.__defineGetter__("responseText", function () {
137911                             return result !== null && result !== undefined ?
137912                                 JSON.stringify(result) : null;
137913                         });
137914                     };
137915
137916                 xhr.__defineGetter__("readyState", function () {
137917                     return state;
137918                 });
137919
137920                 jWorkflow.order(incState)
137921                          .andThen(onreadystatechange)
137922                          .andThen(incState)
137923                          .andThen(onreadystatechange)
137924                          .andThen(incState)
137925                          .andThen(onreadystatechange)
137926                          .andThen(getResult)
137927                          .andThen(setResponse)
137928                          .andThen(incState)
137929                          .andThen(onreadystatechange)
137930                          .start();
137931             }
137932
137933             xhr.setRequestHeader = function (header, value) {
137934                 if (!_url.match(/^webworks:\/\//)) {
137935                     origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
137936                 }
137937             };
137938
137939             xhr.open = function (method, url, async, user, password) {
137940                 _url = url;
137941                 _async = async;
137942
137943                 if (!_url.match(/^webworks:\/\//)) {
137944                     origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
137945                 }
137946             };
137947
137948             xhr.send = function (post) {
137949                 if (!_url.match(/^webworks:\/\//)) {
137950                     origMethods.send.apply(xhr, Array.prototype.slice.call(arguments));
137951                     return;
137952                 }
137953
137954                 var params = _url.match(/\?(.*)$/),
137955                     objPath = _url.match(/^webworks:\/\/([^\?]*)/)[1].split("/"),
137956                     apiMethod = objPath.reduce(function (obj, name) {
137957                         return obj[name];
137958                     }, webworks),
137959                     postParams = {},
137960                     get = {};
137961
137962                 if (params) {
137963                     params[1].split("&").forEach(function (param) {
137964                             var pair = param.split("="),
137965                                 key = decodeURIComponent(pair[0]),
137966                                 value = decodeURIComponent(pair[1]);
137967                             // parsing undefied with JSON throws exception
137968                             get[key] = value === "undefined" ? undefined : JSON.parse(value);
137969                         });
137970                 }
137971
137972                 if (post) {
137973                     post.split("&").forEach(function (param) {
137974                             var pair = param.split("="),
137975                                 value;
137976                             try {
137977                                 value = JSON.parse(decodeURIComponent(pair[1]));
137978                             } catch (e) {
137979                                 value = pair[1] === "undefined" ? undefined : pair[1];
137980                             }
137981
137982                             postParams[pair[0]] = value;
137983                         });
137984                 }
137985
137986                 statemachine(function (prev, baton) {
137987                     return apiMethod(get, postParams, baton);
137988                 });
137989             };
137990
137991             return xhr;
137992         };
137993     }
137994 };
137995
137996 });
137997 define('ripple/platform/webworks.core/2.0.0/client/io/file', function (require, exports, module) {
137998 /*
137999  * Copyright 2011 Research In Motion Limited.
138000  *
138001  * Licensed under the Apache License, Version 2.0 (the "License");
138002  * you may not use this file except in compliance with the License.
138003  * You may obtain a copy of the License at
138004  *
138005  *     http://www.apache.org/licenses/LICENSE-2.0
138006  *
138007  * Unless required by applicable law or agreed to in writing, software
138008  * distributed under the License is distributed on an "AS IS" BASIS,
138009  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138010  * See the License for the specific language governing permissions and
138011  * limitations under the License.
138012  */
138013 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
138014     _uri = "blackberry/io/file/",
138015     FILE = "file://",
138016     _onFileOpened;
138017
138018 function _prunePrefix(path) {
138019     return path.replace(new RegExp("^" + FILE), '');
138020 }
138021
138022 module.exports = {
138023     copy: function (from, to) {
138024         transport.call(_uri + "copy", {
138025             post: {from: _prunePrefix(from), to: _prunePrefix(to)}
138026         });
138027     },
138028     deleteFile: function (path) {
138029         transport.call(_uri + "deleteFile", {
138030             post: {path: _prunePrefix(path)}
138031         });
138032     },
138033     exists: function (path) {
138034         return transport.call(_uri + "exists", {
138035             post: {path: _prunePrefix(path)}
138036         });
138037     },
138038     getFileProperties: function (path) {
138039         var properties = transport.call(_uri + "getFileProperties", {
138040             post: {path: _prunePrefix(path)}
138041         });
138042         properties.directory = FILE + properties.directory;
138043         return properties;
138044     },
138045     open: function (path, newName) {
138046         transport.call(_uri + "open", {
138047             post: {path: _prunePrefix(path)}
138048         });
138049     },
138050     readFile: function (path, onFileOpened, async) {
138051         async = async === false ? false : true;
138052
138053         var uri = _uri + "readFile",
138054             args = {
138055                 post: {path: _prunePrefix(path), async: async}
138056             },
138057             callResult;
138058
138059         _onFileOpened = onFileOpened;
138060
138061         if (async) {
138062             transport.poll(uri, args, function (data, res) {
138063                 if (_onFileOpened) {
138064                     _onFileOpened(FILE + data.fullPath, data.blobData);
138065                 }
138066                 return false;
138067             });
138068         } else {
138069             callResult = transport.call(uri, args);
138070             _onFileOpened(FILE + callResult.fullPath, callResult.blobData);
138071         }
138072     },
138073     rename: function (path, newName) {
138074         transport.call(_uri + "rename", {
138075             post: {path: _prunePrefix(path), newName: newName}
138076         });
138077     },
138078     saveFile: function (path, blob) {
138079         transport.call(_uri + "saveFile", {
138080             post: {path: _prunePrefix(path), blob: blob}
138081         });
138082     }
138083 };
138084
138085 });
138086 define('ripple/platform/webworks.core/2.0.0/client/io/dir', function (require, exports, module) {
138087 /*
138088  * Copyright 2011 Research In Motion Limited.
138089  *
138090  * Licensed under the Apache License, Version 2.0 (the "License");
138091  * you may not use this file except in compliance with the License.
138092  * You may obtain a copy of the License at
138093  *
138094  *     http://www.apache.org/licenses/LICENSE-2.0
138095  *
138096  * Unless required by applicable law or agreed to in writing, software
138097  * distributed under the License is distributed on an "AS IS" BASIS,
138098  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138099  * See the License for the specific language governing permissions and
138100  * limitations under the License.
138101  */
138102 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),
138103     _uri = "blackberry/io/dir/",
138104     FILE = "file://";
138105
138106 function _prunePrefix(path) {
138107     return path.replace(new RegExp("^" + FILE), '');
138108 }
138109
138110 function _addPrefix(path) {
138111     return FILE + path;
138112 }
138113
138114 module.exports = {
138115     createNewDir: function (path) {
138116         transport.call(_uri + "createNewDir", {
138117             post: {path: _prunePrefix(path)}
138118         });
138119     },
138120     deleteDirectory: function (path, recursive) {
138121         transport.call(_uri + "deleteDirectory", {
138122             post: {path: _prunePrefix(path), recursive: recursive}
138123         });
138124     },
138125     exists: function (path) {
138126         return transport.call(_uri + "exists", {
138127             post: {path: _prunePrefix(path)}
138128         });
138129     },
138130     getParentDirectory: function (path) {
138131         return _addPrefix(transport.call(_uri + "getParentDirectory", {
138132             post: {path: _prunePrefix(path)}
138133         }));
138134     },
138135     listDirectories: function (path) {
138136         return transport.call(_uri + "listDirectories", {
138137             post: {path: _prunePrefix(path)}
138138         });
138139     },
138140     listFiles: function (path) {
138141         return transport.call(_uri + "listFiles", {
138142             post: {path: _prunePrefix(path)}
138143         });
138144     },
138145     rename: function (path, newName) {
138146         transport.call(_uri + "rename", {
138147             post: {path: _prunePrefix(path), newName: newName}
138148         });
138149     }
138150 };
138151
138152 });
138153 define('ripple/platform/webworks.core/2.0.0/client/transport', function (require, exports, module) {
138154 /*
138155  * Copyright 2011 Research In Motion Limited.
138156  *
138157  * Licensed under the Apache License, Version 2.0 (the "License");
138158  * you may not use this file except in compliance with the License.
138159  * You may obtain a copy of the License at
138160  *
138161  *     http://www.apache.org/licenses/LICENSE-2.0
138162  *
138163  * Unless required by applicable law or agreed to in writing, software
138164  * distributed under the License is distributed on an "AS IS" BASIS,
138165  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138166  * See the License for the specific language governing permissions and
138167  * limitations under the License.
138168  */
138169 var _self;
138170
138171 function RemoteFunctionCall(functionUri) {
138172     var params = {},
138173         postString = "",
138174         postParams = {};
138175
138176     function composeUri() {
138177         var uri = "webworks://" + functionUri,
138178             paramCount = 1,
138179             param;
138180
138181         for (param in params) {
138182             if (params.hasOwnProperty(param)) {
138183                 if (paramCount === 1) {
138184                     uri += "?";
138185                 } else {
138186                     uri += "&";
138187                 }
138188                 uri += param + "=" + params[param];
138189                 paramCount++;
138190             }
138191
138192             uri = uri.replace(/\&$/, "");
138193         }
138194
138195         return uri;
138196     }
138197
138198     function createXhrRequest(uri, isAsync) {
138199         var request = new XMLHttpRequest(),
138200             paramCount = 1,
138201             param;
138202
138203         for (param in postParams) {
138204             if (postParams.hasOwnProperty(param)) {
138205                 postString += param + "=" + postParams[param] + "&";
138206                 paramCount++;
138207             }
138208         }
138209
138210         postString = postString.replace(/\&$/, "");
138211
138212         // TODO: make get/post
138213         request.open("POST", uri, isAsync);
138214         request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
138215
138216         return request;
138217     }
138218
138219     this.addParam = function (name, value) {
138220         params[name] = encodeURIComponent(JSON.stringify(value));
138221     };
138222
138223     this.addPostParam = function (name, value) {
138224         postParams[name] = encodeURIComponent(JSON.stringify(value));
138225     };
138226
138227     this.makeSyncCall = function (success, error) {
138228         var requestUri = composeUri(),
138229             request = createXhrRequest(requestUri, false),
138230             response, errored, cb, data;
138231
138232         request.send(postString);
138233
138234         response = JSON.parse(request.responseText || "null");
138235         errored = response.code < 0;
138236         cb = errored ? error : success;
138237         data = errored ? response.msg : response.data;
138238
138239         if (cb) {
138240             cb(data, response);
138241         }
138242         else if (errored) {
138243             throw data;
138244         }
138245
138246         return data;
138247     };
138248
138249     this.makeAsyncCall = function (success, error) {
138250         var requestUri = composeUri(),
138251             request = createXhrRequest(requestUri, true);
138252
138253         request.onreadystatechange = function () {
138254             if (request.readyState === 4 && request.status === 200) {
138255                 var response = JSON.parse(request.responseText || "null"),
138256                     cb = response.code < 0 ? error : success,
138257                     data = response.code < 0 ? response.msg : response.data;
138258
138259                 return cb && cb(data, response);
138260             }
138261         };
138262
138263         request.send(postString);
138264     };
138265 }
138266
138267 _self = {
138268     call: function (url, opts, success, error) {
138269         var request = new RemoteFunctionCall(url),
138270             name;
138271
138272         opts = opts || {};
138273
138274         if (opts.get) {
138275             for (name in opts.get) {
138276                 if (Object.hasOwnProperty.call(opts.get, name)) {
138277                     request.addParam(name, opts.get[name]);
138278                 }
138279             }
138280         }
138281
138282         if (opts.post) {
138283             for (name in opts.post) {
138284                 if (Object.hasOwnProperty.call(opts.post, name)) {
138285                     request.addPostParam(name, opts.post[name]);
138286                 }
138287             }
138288         }
138289
138290         return opts.async ? request.makeAsyncCall(success, error) : request.makeSyncCall(success, error);
138291     },
138292
138293     poll: function (url, opts, callback) {
138294         opts = opts || {};
138295         opts.async = true;
138296
138297         _self.call(url, opts, function (data, response) {
138298             if (callback(data, response)) {
138299                 _self.poll(url, opts, callback);
138300             }
138301         });
138302     }
138303 };
138304
138305 module.exports = _self;
138306
138307 });
138308 define('ripple/platform/webworks.core/2.0.0/client/system', function (require, exports, module) {
138309 /*\r
138310  *  Copyright 2011 Research In Motion Limited.\r
138311  *\r
138312  * Licensed under the Apache License, Version 2.0 (the "License");\r
138313  * you may not use this file except in compliance with the License.\r
138314  * You may obtain a copy of the License at\r
138315  *\r
138316  * http://www.apache.org/licenses/LICENSE-2.0\r
138317  *\r
138318  * Unless required by applicable law or agreed to in writing, software\r
138319  * distributed under the License is distributed on an "AS IS" BASIS,\r
138320  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
138321  * See the License for the specific language governing permissions and\r
138322  * limitations under the License.\r
138323  */\r
138324 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
138325     _uri = "blackberry/system/",\r
138326     _self;\r
138327 \r
138328 _self = {\r
138329     hasCapability: function (capability) {\r
138330         return transport.call(_uri + "hasCapability", {\r
138331             get: {capability: capability}\r
138332         });\r
138333     },\r
138334 \r
138335     hasDataCoverage: function () {\r
138336         return transport.call(_uri + "hasDataCoverage");\r
138337     },\r
138338 \r
138339     hasPermission: function (desiredModule) {\r
138340         return transport.call(_uri + "hasPermission", {\r
138341             get: {desiredModule: desiredModule}\r
138342         });\r
138343     },\r
138344 \r
138345     isMassStorageActive: function () {\r
138346         return transport.call(_uri + "isMassStorageActive");\r
138347     }\r
138348 };\r
138349 \r
138350 _self.__defineGetter__("model", function () {\r
138351     return transport.call(_uri + "model");\r
138352 });\r
138353 _self.__defineGetter__("scriptApiVersion", function () {\r
138354     return transport.call(_uri + "scriptApiVersion");\r
138355 });\r
138356 _self.__defineGetter__("softwareVersion", function () {\r
138357     return transport.call(_uri + "softwareVersion");\r
138358 });\r
138359 \r
138360 _self.__defineGetter__("ALLOW", function () {\r
138361     return 0;\r
138362 });\r
138363 _self.__defineGetter__("DENY", function () {\r
138364     return 1;\r
138365 });\r
138366 _self.__defineGetter__("PROMPT", function () {\r
138367     return 2;\r
138368 });\r
138369 _self.__defineGetter__("NOT_SET", function () {\r
138370     return 3;\r
138371 });\r
138372 \r
138373 module.exports = _self;\r
138374
138375 });
138376 define('ripple/platform/webworks.core/2.0.0/client/dialog', function (require, exports, module) {
138377 /*\r
138378  *  Copyright 2011 Research In Motion Limited.\r
138379  *\r
138380  * Licensed under the Apache License, Version 2.0 (the "License");\r
138381  * you may not use this file except in compliance with the License.\r
138382  * You may obtain a copy of the License at\r
138383  *\r
138384  * http://www.apache.org/licenses/LICENSE-2.0\r
138385  *\r
138386  * Unless required by applicable law or agreed to in writing, software\r
138387  * distributed under the License is distributed on an "AS IS" BASIS,\r
138388  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
138389  * See the License for the specific language governing permissions and\r
138390  * limitations under the License.\r
138391  */\r
138392 var transport = require('ripple/platform/webworks.core/2.0.0/client/transport'),\r
138393     _uri = "blackberry/ui/dialog/",\r
138394     _self;\r
138395 \r
138396 function getButtonsForDialogType(dialogType) {\r
138397     switch (dialogType) {\r
138398     case _self.D_OK:\r
138399         return ["Ok"];\r
138400     case _self.D_SAVE:\r
138401         return ["Save", "Discard"];\r
138402     case _self.D_DELETE:\r
138403         return ["Delete", "Cancel"];\r
138404     case _self.D_YES_NO:\r
138405         return ["Yes", "No"];\r
138406     case _self.D_OK_CANCEL:\r
138407         return ["Ok", "Cancel"];\r
138408     default:\r
138409         throw new Error("Invalid dialog type: " + dialogType);\r
138410     }\r
138411 }\r
138412 \r
138413 _self = {\r
138414     customAskAsync: function (message, choices, callback, settings) {\r
138415         return transport.call(_uri + "ask", {\r
138416             async: true,\r
138417             get: {\r
138418                 message: message,\r
138419                 buttons: choices,\r
138420                 settings: settings\r
138421             }\r
138422         }, function (response) {\r
138423             if (callback) {\r
138424                 callback(response);\r
138425             }\r
138426         });\r
138427     },\r
138428 \r
138429     standardAskAsync: function (message, type, callback, settings) {\r
138430         var choices = getButtonsForDialogType(type);\r
138431         return transport.call(_uri + "ask", {\r
138432             async: true,\r
138433             get: {\r
138434                 message: message,\r
138435                 buttons: choices,\r
138436                 settings: settings\r
138437             }\r
138438         }, function (response) {\r
138439             if (callback) {\r
138440                 callback(response);\r
138441             }\r
138442         });\r
138443     }\r
138444 };\r
138445 \r
138446 _self.__defineGetter__("D_OK", function () {\r
138447     return 0;\r
138448 });\r
138449 \r
138450 _self.__defineGetter__("D_SAVE", function () {\r
138451     return 1;\r
138452 });\r
138453 \r
138454 _self.__defineGetter__("D_DELETE", function () {\r
138455     return 2;\r
138456 });\r
138457 \r
138458 _self.__defineGetter__("D_YES_NO", function () {\r
138459     return 3;\r
138460 });\r
138461 \r
138462 _self.__defineGetter__("D_OK_CANCEL", function () {\r
138463     return 4;\r
138464 });\r
138465 \r
138466 _self.__defineGetter__("BOTTOM", function () {\r
138467     return "bottomCenter";\r
138468 });\r
138469 \r
138470 _self.__defineGetter__("CENTER", function () {\r
138471     return "middleCenter";\r
138472 });\r
138473 \r
138474 _self.__defineGetter__("TOP", function () {\r
138475     return "topCenter";\r
138476 });\r
138477 \r
138478 _self.__defineGetter__("SIZE_FULL", function () {\r
138479     return "full";\r
138480 });\r
138481 \r
138482 _self.__defineGetter__("SIZE_LARGE", function () {\r
138483     return "large";\r
138484 });\r
138485 \r
138486 _self.__defineGetter__("SIZE_MEDIUM", function () {\r
138487     return "medium";\r
138488 });\r
138489 \r
138490 _self.__defineGetter__("SIZE_SMALL", function () {\r
138491     return "small";\r
138492 });\r
138493 \r
138494 _self.__defineGetter__("SIZE_TALL", function () {\r
138495     return "tall";\r
138496 });\r
138497 \r
138498 module.exports = _self;\r
138499
138500 });
138501 define('ripple/platform/webworks.core/2.0.0/client/events', function (require, exports, module) {
138502 /*
138503  * Copyright 2011 Research In Motion Limited.
138504  *
138505  * Licensed under the Apache License, Version 2.0 (the "License");
138506  * you may not use this file except in compliance with the License.
138507  * You may obtain a copy of the License at
138508  *
138509  *     http://www.apache.org/licenses/LICENSE-2.0
138510  *
138511  * Unless required by applicable law or agreed to in writing, software
138512  * distributed under the License is distributed on an "AS IS" BASIS,
138513  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138514  * See the License for the specific language governing permissions and
138515  * limitations under the License.
138516  */
138517 var _handlers = [],
138518     _self;
138519
138520 _self = {
138521     eventsMap: {
138522         getHandlerById: function (handlerId) {
138523             return _handlers[handlerId];
138524         },
138525         addHandler: function (handler) {
138526             _handlers.push(handler);
138527             return _handlers.length - 1;
138528         },
138529         removeHandler: function (handlerId) {
138530             if (handlerId > -1 && handlerId < _handlers.length) {
138531                 delete _handlers[handlerId]; //cannot splice because all published IDs would refer to the wrong handler
138532             }
138533         }
138534     },
138535
138536     registerEventHandler : function (eventName, eventCallback, eventParams) {
138537         return _self.eventsMap.addHandler(eventCallback);
138538     },
138539
138540     getEventHandler : function (handlerId) {
138541         return _self.eventsMap.getHandlerById(handlerId);
138542     }
138543 };
138544
138545 module.exports = _self;
138546
138547 });
138548 define('ripple/platform/webworks.core/2.0.0/client/utils', function (require, exports, module) {
138549 /*
138550  * Copyright 2011 Research In Motion Limited.
138551  *
138552  * Licensed under the Apache License, Version 2.0 (the "License");
138553  * you may not use this file except in compliance with the License.
138554  * You may obtain a copy of the License at
138555  *
138556  *     http://www.apache.org/licenses/LICENSE-2.0
138557  *
138558  * Unless required by applicable law or agreed to in writing, software
138559  * distributed under the License is distributed on an "AS IS" BASIS,
138560  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138561  * See the License for the specific language governing permissions and
138562  * limitations under the License.
138563  */
138564 var _blobs = {};
138565
138566 function _blobBuilder() {
138567     var BlobBuilder = BlobBuilder || WebKitBlobBuilder;
138568     return new BlobBuilder();
138569 }
138570
138571 module.exports = {
138572     parseURL: function (theUrl) {
138573         /********START IDEA BORROWING*******/
138574         // parseUri 1.2.2
138575         // (c) Steven Levithan <stevenlevithan.com>
138576         // MIT License
138577
138578         function parseUri(str) {
138579             var o   = parseUri.options,
138580                 m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
138581                 uri = {},
138582                 i   = 14;
138583
138584             while (i--) {
138585                 uri[o.key[i]] = m[i] || "";
138586             }
138587
138588             uri[o.q.name] = {};
138589             uri[o.q.arrayName] = [];
138590             uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
138591                 if ($1) {
138592                     uri[o.q.name][$1] = $2;
138593                     uri[o.q.arrayName].push($2);
138594                 }
138595             });
138596
138597             return uri;
138598         }
138599
138600         parseUri.options = {
138601                 strictMode: false,
138602                 key: ["source", "protocol", "authority", "userInfo", "user", "password", "host", "port", "relative", "path", "directory", "file", "query", "anchor"],
138603                 q:   {
138604                     name:   "queryKey",
138605                     arrayName:   "queryArray",
138606                     parser: /(?:^|&)([^&=]*)=?([^&]*)/g
138607                 },
138608                 parser: {
138609                     strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
138610                     loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
138611                 }
138612             };
138613         /********END IDEA BORROWING*******/
138614
138615         parseUri.strictMode = "strict";
138616         var uri = parseUri(theUrl),
138617             retVal = {
138618                 getURLParameter : function (key) {
138619                     return uri.queryKey[key];
138620                 },
138621
138622                 getURLParameterByIndex : function (index) {
138623                     return uri.queryArray[index];
138624                 }
138625             };
138626
138627         //Add default values for the http/https port if they weren't specified in the URL. The above parser returns undefined. We need the values
138628         //to be compatible with the BB version of API.
138629         if (uri["port"] === "") {
138630             if (uri["protocol"] === "http") {
138631                 uri["port"] = "80";
138632             }
138633             else if (uri["protocol"] === "https") {
138634                 uri["port"] = "443";
138635             }
138636             else {
138637                 uri["port"] = "0";
138638             }
138639         }
138640
138641         retVal.__defineGetter__("host", function () {
138642             return uri["host"];
138643         });
138644         retVal.__defineGetter__("port", function () {
138645             return parseInt(uri["port"], 10);
138646         });
138647
138648         return retVal;
138649     },
138650
138651     generateUniqueId: function () {
138652         return Math.floor(Math.random() * Number.MAX_VALUE);
138653     },
138654
138655     blobToString: function (blob, encoding) {
138656         return _blobs[blob.id];
138657     },
138658
138659     stringToBlob: function (string, encoding) {
138660         var id = Math.uuid(undefined, 16),
138661             blob = _blobBuilder(),
138662             finalBlob;
138663
138664         _blobs[id] = string;
138665         blob.append(string);
138666
138667         finalBlob = blob.getBlob();
138668         finalBlob.id = id;
138669         finalBlob.length = finalBlob.size;
138670
138671         return finalBlob;
138672     }
138673 };
138674
138675 });
138676 define('ripple/platform/webworks.core/2.0.0/client/FileProperties', function (require, exports, module) {
138677 /*
138678  * Copyright 2011 Research In Motion Limited.
138679  *
138680  * Licensed under the Apache License, Version 2.0 (the "License");
138681  * you may not use this file except in compliance with the License.
138682  * You may obtain a copy of the License at
138683  *
138684  *     http://www.apache.org/licenses/LICENSE-2.0
138685  *
138686  * Unless required by applicable law or agreed to in writing, software
138687  * distributed under the License is distributed on an "AS IS" BASIS,
138688  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138689  * See the License for the specific language governing permissions and
138690  * limitations under the License.
138691  */
138692 function FileProperties(props) {
138693     props = props || {};
138694
138695     function _get(val) {
138696         return function () {
138697             return props[val];
138698         };
138699     }
138700
138701     this.__defineGetter__("dateCreated", _get("dateCreated")); //tablet only
138702     this.__defineGetter__("dateModified", _get("dateModified"));
138703     this.__defineGetter__("directory", _get("directory"));
138704     this.__defineGetter__("fileExtension", _get("fileExtension"));
138705     this.__defineGetter__("isHidden", _get("isHidden"));
138706     this.__defineGetter__("isReadonly", _get("isReadonly")); //handset only
138707     this.__defineGetter__("mimeType", _get("mimeType")); //handset only
138708     this.__defineGetter__("size", _get("size"));
138709 }
138710
138711 module.exports = FileProperties;
138712
138713 });
138714 define('ripple/platform/webworks.core/2.0.0/select', function (require, exports, module) {
138715 /*
138716  *  Copyright 2011 Research In Motion Limited.
138717  *
138718  * Licensed under the Apache License, Version 2.0 (the "License");
138719  * you may not use this file except in compliance with the License.
138720  * You may obtain a copy of the License at
138721  *
138722  * http://www.apache.org/licenses/LICENSE-2.0
138723  *
138724  * Unless required by applicable law or agreed to in writing, software
138725  * distributed under the License is distributed on an "AS IS" BASIS,
138726  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138727  * See the License for the specific language governing permissions and
138728  * limitations under the License.
138729  */
138730 var utils = require('ripple/utils'),
138731     _select,
138732     _predicates = {
138733         "==": function (left, right) {
138734             return left === right;
138735         },
138736         "!=": function (left, right) {
138737             return left !== right;
138738         },
138739         "<": function (left, right) {
138740             return left < right;
138741         },
138742         ">": function (left, right) {
138743             return left > right;
138744         },
138745         "<=": function (left, right) {
138746             return left <= right;
138747         },
138748         ">=": function (left, right) {
138749             return left >= right;
138750         },
138751         "REGEX": function (left, right) {
138752             return left && left.match(new RegExp(right));
138753         },
138754         "CONTAINS": function (left, right) {
138755             return left.indexOf(right) >= 0;
138756         }
138757     };
138758
138759 function isFilter(field) {
138760     return field && field.operator !== undefined && field.operator !== null;
138761 }
138762
138763 function extractValue(item, field) {
138764     return field.split(".").reduce(function (value, prop) {
138765         return value[prop];
138766     }, item);
138767 }
138768
138769 function copy(items) {
138770     //use a reduce to ensure that we always just return an array
138771     //not the most performant but will whitewash the result
138772     return utils.reduce(items, function (array, item) {
138773         array.push(item);
138774         return array;
138775     }, []);
138776 }
138777
138778 _select = {
138779     ops: {
138780         find: {
138781             0: "!=",
138782             1: "==",
138783             2: "<",
138784             3: "<=",
138785             4: ">",
138786             5: ">=",
138787             8: "REGEX",
138788             16: "AND",
138789             32: "OR",
138790             64: "CONTAINS"
138791         },
138792         phone: {
138793             0: "!=",
138794             1: "==",
138795             2: "<",
138796             3: "<=",
138797             4: ">",
138798             5: ">=",
138799             8: "AND",
138800             16: "OR",
138801             32: "CONTAINS"
138802         }
138803     },
138804     from: function (items) {
138805         var _getPredicate = function (filter, operators) {
138806
138807                 var noOp = function () {
138808                         return false;
138809                     },
138810                     operator = (function () {
138811                         var result = operators[filter.operator] || filter.operator,
138812                             exists = function (op) {
138813                                 return result === op;
138814                             };
138815
138816                         return utils.some(operators, exists) ? result : "";
138817                     }());
138818
138819                 return function (item) {
138820                     var left = extractValue(item, filter.leftField),
138821                         right = filter.rightField,
138822                         predicate = _predicates[operator] || noOp;
138823
138824                     return filter.negate ? !predicate(left, right) : predicate(left, right);
138825                 };
138826
138827             },
138828             _applyFilter = function (filter, operators) {
138829                 var result = [],
138830                     left,
138831                     right,
138832                     op;
138833
138834                 if (isFilter(filter.leftField) && isFilter(filter.rightField)) {
138835
138836                     left = _select.from(items).where(filter.leftField);
138837                     right = _select.from(items).where(filter.rightField);
138838                     op = operators[filter.operator] || filter.operator;
138839
138840                     switch (op) {
138841                     case "AND":
138842                         result = left.filter(function (item) {
138843                             return right.indexOf(item) >= 0;
138844                         });
138845                         break;
138846                     case "OR":
138847                         result = left.concat(right.filter(function (item) {
138848                             return left.indexOf(item) < 0;
138849                         }));
138850                         break;
138851                     }
138852
138853                     if (filter.negate) {
138854                         //reverse the result set.
138855                         result = utils.filter(items, function (item) {
138856                             return result.indexOf(item) < 0;
138857                         });
138858                     }
138859                 }
138860                 else {
138861                     result = utils.filter(items, _getPredicate(filter, operators));
138862                 }
138863
138864                 return result;
138865             },
138866             _orderBy,
138867             _max,
138868             _direction,
138869             _self = {
138870                 orderBy: function (prop, dir) {
138871                     _orderBy = prop;
138872                     _direction = dir || "asc";
138873                     return _self;
138874                 },
138875                 max: function (max) {
138876                     _max = max;
138877                     return _self;
138878                 },
138879                 where: function (filter, ops) {
138880                     var result = isFilter(filter) ? _applyFilter(filter, ops || _select.ops.find) : copy(items);
138881
138882                     result.sort(function (a, b) {
138883                         if (a[_orderBy] < b[_orderBy]) {
138884                             return _direction === "asc" ? -1 : 1;
138885                         }
138886                         else if (a[_orderBy] > b[_orderBy]) {
138887                             return _direction === "asc" ? 1: -1;
138888                         }
138889                         return 0;
138890                     });
138891
138892                     return result.slice(0, _max === null || _max === -1 ? undefined : _max); // slice in V8 returns empty array if null
138893                 }
138894             };
138895
138896         return _self;
138897     }
138898 };
138899
138900 module.exports = _select;
138901
138902 });
138903 define('ripple/platform/webworks.core/2.0.0/spec/config', function (require, exports, module) {
138904 /*
138905  *  Copyright 2011 Research In Motion Limited.
138906  *
138907  * Licensed under the Apache License, Version 2.0 (the "License");
138908  * you may not use this file except in compliance with the License.
138909  * You may obtain a copy of the License at
138910  *
138911  * http://www.apache.org/licenses/LICENSE-2.0
138912  *
138913  * Unless required by applicable law or agreed to in writing, software
138914  * distributed under the License is distributed on an "AS IS" BASIS,
138915  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138916  * See the License for the specific language governing permissions and
138917  * limitations under the License.
138918  */
138919 var utils = require('ripple/utils');
138920
138921 module.exports = {
138922     fileName: "config.xml",
138923     validateVersion: function (config) {
138924         return true;
138925     },
138926     extractInfo: function (config) {
138927         if (!config) {
138928             return null;
138929         }
138930
138931         var widgetInfo = {},
138932             widgetFeatures = config.widget.children.feature.validationResult,
138933             accessUrls = config.widget.children.access.validationResult,
138934             accessFeatures = config.widget.children.access.children.feature.validationResult,
138935             toFeature = function (validationResult) {
138936                 return {
138937                     id: validationResult.attributes.id.value,
138938                     required: !validationResult.attributes.required || validationResult.attributes.required.value,
138939                     URIs: []
138940                 };
138941             };
138942
138943         widgetInfo.id = config.widget.validationResult[0].attributes.id.value;
138944         widgetInfo.name = config.widget.children.name.validationResult[0].value;
138945         widgetInfo.icon = config.widget.children.icon.validationResult[0].attributes.src.value;
138946         widgetInfo.version = config.widget.validationResult[0].attributes.version.value;
138947         widgetInfo.author = config.widget.children.author.validationResult[0].value;
138948         widgetInfo.authorEmail = config.widget.children.author.validationResult[0].attributes.email.value;
138949         widgetInfo.authorURL = config.widget.children.author.validationResult[0].attributes.href.value;
138950         widgetInfo.copyright = config.widget.children.author.validationResult[0].attributes["rim:copyright"].value;
138951         widgetInfo.description = config.widget.children.description.validationResult[0].value;
138952         if (config.widget.children.license.validationResult[0]) {
138953             widgetInfo.license = config.widget.children.license.validationResult[0].value;
138954             widgetInfo.licenseURL = config.widget.children.license.validationResult[0].attributes.href.value;
138955         }
138956
138957         widgetInfo.features = widgetFeatures.reduce(function (features, validationResult) {
138958             if (validationResult.valid) {
138959                 var feature = toFeature(validationResult);
138960                 feature.URIs.push({
138961                     value: utils.location().href,
138962                     subdomains: true
138963                 });
138964                 features = features || {};
138965                 features[feature.id] = feature;
138966             }
138967             return features;
138968         }, {});
138969
138970         widgetInfo.features = accessUrls.map(function (access) {
138971             return {
138972                 uri: access.attributes.uri.value,
138973                 subdomains: access.attributes.subdomains.value,
138974                 features: accessFeatures ? accessFeatures.filter(function (f) {
138975                     return f.node && f.node.parentNode && f.node.parentNode.attributes.uri.value === access.attributes.uri.value;
138976                 }) : null
138977             };
138978         }).reduce(function (result, access) {
138979             return access.features ? access.features.reduce(function (features, validationResult) {
138980                 var feature = features[validationResult.attributes.id.value] || toFeature(validationResult);
138981                 feature.URIs.push({
138982                     value: access.uri,
138983                     subdomains: access.subdomains
138984                 });
138985                 features[feature.id] = feature;
138986                 return features;
138987             }, result) : result;
138988         }, widgetInfo.features);
138989
138990         return widgetInfo;
138991     },
138992     schema: {
138993         rootElement: "widget",
138994         widget: {
138995             nodeName: "widget",
138996             required: true,
138997             occurrence: 1,
138998             attributes: {
138999                 xmlns: {
139000                     attributeName: "xmlns",
139001                     required: true,
139002                     type: "list",
139003                     listValues: ["http://www.w3.org/ns/widgets"]
139004                 },
139005                 "xmlns:rim": {
139006                     attributeName: "xmlns:rim",
139007                     required: true,
139008                     type: "list",
139009                     listValues: ["http://www.blackberry.com/ns/widgets"]
139010                 },
139011                 "xml:lang": {
139012                     attributeName: "xml:lang",
139013                     required: false,
139014                     type: "iso-language"
139015                 },
139016                 id: {
139017                     attributeName: "id",
139018                     required: false,
139019                     type: "string"
139020                 },
139021                 version: {
139022                     attributeName: "version",
139023                     required: false,
139024                     type: "string"
139025                 },
139026                 "rim:header": {
139027                     attributeName: "rim:header",
139028                     required: false,
139029                     type: "string"
139030                 },
139031                 "rim:backButton": {
139032                     attributeName: "rim:backButton",
139033                     required: false,
139034                     type: "string"
139035                 }
139036             },
139037             children: {
139038                 name: {
139039                     nodeName: "name",
139040                     required: true,
139041                     occurrence: 1,
139042                     attributes: {
139043                         "xml:lang": {
139044                             attributeName: "xml:lang",
139045                             required: false,
139046                             type: "iso-language"
139047                         },
139048                         "its:dir": {
139049                             attributeName: "its:dir",
139050                             required: false,
139051                             type: "list",
139052                             listValues: ["rtl", "ltr", "lro", "rlo"]
139053                         }
139054                     }
139055                 },
139056                 description: {
139057                     nodeName: "description",
139058                     required: false,
139059                     occurrence: 1,
139060                     attributes: {
139061                         "xml:lang": {
139062                             attributeName: "xml:lang",
139063                             required: false,
139064                             type: "iso-language"
139065                         },
139066                         "its:dir": {
139067                             attributeName: "its:dir",
139068                             required: false,
139069                             type: "list",
139070                             listValues: ["rtl", "ltr", "lro", "rlo"]
139071                         }
139072                     }
139073                 },
139074                 icon: {
139075                     nodeName: "icon",
139076                     required: false,
139077                     occurrence: 0,
139078                     attributes: {
139079                         src: {
139080                             attributeName: "src",
139081                             type: "string",
139082                             required: true
139083                         },
139084                         "rim:hover": {
139085                             attributeName: "rim:hover",
139086                             type: "boolean",
139087                             required: false
139088                         }
139089                     }
139090                 },
139091                 author: {
139092                     nodeName: "author",
139093                     required: false,
139094                     occurrence: 1,
139095                     attributes: {
139096                         href: {
139097                             attributeName: "href",
139098                             type: "string",
139099                             required: false
139100                         },
139101                         "rim:copyright": {
139102                             attributeName: "rim:copyright",
139103                             type: "string",
139104                             required: false
139105                         },
139106                         email: {
139107                             attributeName: "email",
139108                             type: "string",
139109                             required: false
139110                         },
139111                         "xml:lang": {
139112                             attributeName: "xml:lang",
139113                             required: false,
139114                             type: "iso-language"
139115                         },
139116                         "its:dir": {
139117                             attributeName: "its:dir",
139118                             required: false,
139119                             type: "list",
139120                             listValues: ["rtl", "ltr", "lro", "rlo"]
139121                         }
139122                     }
139123                 },
139124                 license: {
139125                     nodeName: "license",
139126                     required: false,
139127                     occurrence: 1,
139128                     attributes : {
139129                         href: {
139130                             attributeName: "href",
139131                             type: "string",
139132                             required: false
139133                         },
139134                         "xml:lang": {
139135                             attributeName: "xml:lang",
139136                             required: false,
139137                             type: "iso-language"
139138                         },
139139                         "its:dir": {
139140                             attributeName: "its:dir",
139141                             required: false,
139142                             type: "list",
139143                             listValues: ["rtl", "ltr", "lro", "rlo"]
139144                         }
139145                     }
139146                 },
139147                 "rim:cache": {
139148                     nodeName: "rim:cache",
139149                     required: false,
139150                     occurrence: 1,
139151                     attributes: {
139152                         disableAllCache: {
139153                             attributeName: "disableAllCache",
139154                             required: false,
139155                             type: "boolean"
139156                         },
139157                         aggressiveCacheAge: {
139158                             attributeName: "aggressiveCacheAge",
139159                             required: false,
139160                             type: "number"
139161                         },
139162                         maxCacheSizeTotal: {
139163                             attributeName: "maxCacheSizeTotal",
139164                             required: false,
139165                             type: "number"
139166                         },
139167                         maxCacheSizeItem: {
139168                             attributeName: "maxCacheSizeItem",
139169                             required: false,
139170                             type: "number"
139171                         }
139172                     }
139173                 },
139174                 access: {
139175                     nodeName: "access",
139176                     required: false,
139177                     occurrence: 0,
139178                     attributes: {
139179                         uri: {
139180                             attributeName: "uri",
139181                             required: true,
139182                             type: "string"
139183                         },
139184                         subdomains: {
139185                             attributeName: "subdomains",
139186                             required: false,
139187                             type: "boolean"
139188                         }
139189                     },
139190                     children: {
139191                         feature: {
139192                             nodeName: "feature",
139193                             required: false,
139194                             occurrence: 0,
139195                             attributes: {
139196                                 id: {
139197                                     attributeName: "id",
139198                                     required: true,
139199                                     //TODO: this should be a list
139200                                     type: "string"
139201                                 },
139202                                 required: {
139203                                     attributeName: "required",
139204                                     required: false,
139205                                     type: "boolean"
139206                                 },
139207                                 version: {
139208                                     attributeName: "version",
139209                                     required: false,
139210                                     type: "string"
139211                                 }
139212                             }
139213                         }
139214                     }
139215                 },
139216                 feature: {
139217                     nodeName: "feature",
139218                     required: false,
139219                     occurrence: 0,
139220                     attributes: {
139221                         id: {
139222                             attributeName: "id",
139223                             required: true,
139224                             //TODO: this should be a list
139225                             type: "string"
139226                         },
139227                         required: {
139228                             attributeName: "required",
139229                             required: false,
139230                             type: "boolean"
139231                         },
139232                         version: {
139233                             attributeName: "version",
139234                             required: false,
139235                             type: "string"
139236                         }
139237                     }
139238                 },
139239                 "rim:loadingScreen": {
139240                     nodeName: "rim:loadingScreen",
139241                     required: false,
139242                     occurrence: 1,
139243                     attributes: {
139244                         backgroundColor: {
139245                             attributeName: "backgroundColor",
139246                             required: false,
139247                             type: "string"
139248                         },
139249                         backgroundImage: {
139250                             attributeName: "backgroundImage",
139251                             required: false,
139252                             type: "string"
139253                         },
139254                         foregroundImage: {
139255                             attributeName: "foregroundImage",
139256                             required: false,
139257                             type: "string"
139258                         },
139259                         onRemotePageLoad: {
139260                             attributeName: "onRemotePageLoad",
139261                             required: false,
139262                             type: "boolean"
139263                         },
139264                         onLocalPageLoad: {
139265                             attributeName: "onLocalPageLoad",
139266                             required : false,
139267                             type: "boolean"
139268                         },
139269                         onFirstLaunch: {
139270                             attributeName: "onFirstLaunch",
139271                             required: false,
139272                             type: "boolean"
139273                         }
139274                     },
139275                     children: {
139276                         "rim:transitionEffect": {
139277                             nodeName: "rim:transitionEffect",
139278                             required: false,
139279                             occurrence: 1,
139280                             attributes: {
139281                                 "type": {
139282                                     attributeName: "type",
139283                                     required: true,
139284                                     type: "list",
139285                                     listValues: ["slidePush", "slideOver", "fadeIn", "fadeOut", "wipeIn", "wipeOut", "zoomIn", "zoomOut"]
139286                                 },
139287                                 duration: {
139288                                     attributeName: "duration",
139289                                     required: false,
139290                                     type: "number"
139291                                 },
139292                                 direction: {
139293                                     attributeName: "direction",
139294                                     required: false,
139295                                     type: "list",
139296                                     listValues: ["left", "right", "up", "down"]
139297                                 }
139298                             }
139299                         }
139300                     }
139301                 },
139302                 "rim:connection": {
139303                     nodeName: "rim:connection",
139304                     required: false,
139305                     occurrence: 1,
139306                     attributes: {
139307                         timeout: {
139308                             attributeName: "timeout",
139309                             required: false,
139310                             type: "number"
139311                         }
139312                     },
139313                     children: {
139314                         id: {
139315                             nodeName: "id",
139316                             required: false,
139317                             occurrence: 0
139318                         }
139319                     }
139320                 },
139321                 "rim:navigation": {
139322                     nodeName: "rim:navigation",
139323                     required: false,
139324                     occurrence: 1,
139325                     attributes: {
139326                         mode: {
139327                             attributeName: "mode",
139328                             required: false,
139329                             type: "list",
139330                             listValues: ["focus"]
139331                         }
139332                     }
139333                 },
139334                 "content": {
139335                     nodeName: "content",
139336                     required: true,
139337                     occurrence: 1,
139338                     attributes: {
139339                         src: {
139340                             attributeName: "src",
139341                             required: true,
139342                             type: "string"
139343                         },
139344                         type: {
139345                             attributeName: "type",
139346                             required: false,
139347                             type: "string"
139348                         },
139349                         charset: {
139350                             attributeName: "charset",
139351                             required: false,
139352                             type: "string"
139353                         }
139354                     }
139355                 }
139356             }
139357         }
139358     }
139359 };
139360
139361 });
139362 define('ripple/platform/webworks.core/2.0.0/spec/events', function (require, exports, module) {
139363 /*
139364  *  Copyright 2011 Research In Motion Limited.
139365  *
139366  * Licensed under the Apache License, Version 2.0 (the "License");
139367  * you may not use this file except in compliance with the License.
139368  * You may obtain a copy of the License at
139369  *
139370  * http://www.apache.org/licenses/LICENSE-2.0
139371  *
139372  * Unless required by applicable law or agreed to in writing, software
139373  * distributed under the License is distributed on an "AS IS" BASIS,
139374  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139375  * See the License for the specific language governing permissions and
139376  * limitations under the License.
139377  */
139378 var event = require('ripple/event');
139379
139380 module.exports = {
139381     "app.event.onBackground": {
139382         callback: function () {
139383             event.trigger("AppRequestBackground");
139384         }
139385     },
139386     "app.event.onForeground": {
139387         callback: function () {
139388             event.trigger("AppRequestForeground");
139389         }
139390     }
139391 };
139392
139393 });
139394 define('ripple/platform/webworks.core/2.0.0/server/io/file', function (require, exports, module) {
139395 /*
139396  *  Copyright 2011 Research In Motion Limited.
139397  *
139398  * Licensed under the Apache License, Version 2.0 (the "License");
139399  * you may not use this file except in compliance with the License.
139400  * You may obtain a copy of the License at
139401  *
139402  * http://www.apache.org/licenses/LICENSE-2.0
139403  *
139404  * Unless required by applicable law or agreed to in writing, software
139405  * distributed under the License is distributed on an "AS IS" BASIS,
139406  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139407  * See the License for the specific language governing permissions and
139408  * limitations under the License.
139409  */
139410 var cache = require('ripple/platform/webworks.core/2.0.0/fsCache'),
139411     constants = require('ripple/constants'),
139412     notifications = require('ripple/notifications');
139413
139414 function _packet(data) {
139415     return {
139416         code: 1,
139417         data: data
139418     };
139419 }
139420
139421 module.exports = {
139422     copy: function (get, post, baton) {
139423         cache.file.copy(post.from, post.to);
139424         return _packet();
139425     },
139426     deleteFile: function (get, post, baton) {
139427         cache.file.deleteFile(post.path);
139428         return _packet();
139429     },
139430     exists: function (get, post, baton) {
139431         return _packet(cache.file.exists(post.path));
139432     },
139433     getFileProperties: function (get, post, baton) {
139434         return _packet(cache.file.getFileProperties(post.path));
139435     },
139436     open: function (get, post, baton) {
139437         var msg = "Attempting to open file: " + post.path;
139438         notifications.openNotification("normal", msg);
139439         return _packet(cache.file.exists(post.path));
139440     },
139441     readFile: function (get, post, baton) {
139442         var val;
139443
139444         if (post.async) {
139445             baton.take();
139446         }
139447
139448         cache.file.readFile(post.path, function (data) {
139449             if (post.async) {
139450                 baton.pass(_packet({
139451                     fullPath: post.path,
139452                     blobData: data
139453                 }));
139454             } else {
139455                 val = data;
139456             }
139457         }, post.async);
139458
139459         if (!post.async) {
139460             return _packet({
139461                 fullPath: post.path,
139462                 blobData: val
139463             });
139464         }
139465     },
139466     rename: function (get, post, baton) {
139467         cache.file.rename(post.path, post.newName);
139468         return _packet();
139469     },
139470     saveFile: function (get, post, baton) {
139471         cache.file.saveFile(post.path, post.blob);
139472         return _packet();
139473     }
139474 };
139475
139476 });
139477 define('ripple/platform/webworks.core/2.0.0/server/io/dir', function (require, exports, module) {
139478 /*
139479  * Copyright 2011 Research In Motion Limited.
139480  *
139481  * Licensed under the Apache License, Version 2.0 (the "License");
139482  * you may not use this file except in compliance with the License.
139483  * You may obtain a copy of the License at
139484  *
139485  *     http://www.apache.org/licenses/LICENSE-2.0
139486  *
139487  * Unless required by applicable law or agreed to in writing, software
139488  * distributed under the License is distributed on an "AS IS" BASIS,
139489  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139490  * See the License for the specific language governing permissions and
139491  * limitations under the License.
139492  */
139493 var cache = require('ripple/platform/webworks.core/2.0.0/fsCache');
139494
139495 function _packet(data) {
139496     return {
139497         code: 1,
139498         data: data
139499     };
139500 }
139501
139502 module.exports = {
139503     createNewDir: function (get, post, baton) {
139504         cache.dir.createNewDir(post.path);
139505         return _packet();
139506     },
139507     deleteDirectory: function (get, post, baton) {
139508         cache.dir.deleteDirectory(post.path, post.recursive);
139509         return _packet();
139510     },
139511     exists: function (get, post, baton) {
139512         return _packet(cache.dir.exists(post.path));
139513     },
139514     getParentDirectory: function (get, post, baton) {
139515         return _packet(cache.dir.getParentDirectory(post.path));
139516     },
139517     listDirectories: function (get, post, baton) {
139518         return _packet(cache.dir.listDirectories(post.path));
139519     },
139520     listFiles: function (get, post, baton) {
139521         return _packet(cache.dir.listFiles(post.path));
139522     },
139523     rename: function (get, post, baton) {
139524         cache.dir.rename(post.path, post.newName);
139525         return _packet();
139526     }
139527 };
139528
139529 });
139530 define('ripple/platform/webworks.core/2.0.0/server/system', function (require, exports, module) {
139531 /*
139532  *  Copyright 2011 Research In Motion Limited.
139533  *
139534  * Licensed under the Apache License, Version 2.0 (the "License");
139535  * you may not use this file except in compliance with the License.
139536  * You may obtain a copy of the License at
139537  *
139538  * http://www.apache.org/licenses/LICENSE-2.0
139539  *
139540  * Unless required by applicable law or agreed to in writing, software
139541  * distributed under the License is distributed on an "AS IS" BASIS,
139542  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139543  * See the License for the specific language governing permissions and
139544  * limitations under the License.
139545  */
139546 var deviceSettings = require('ripple/deviceSettings'),
139547     devices = require('ripple/devices'),
139548     app = require('ripple/app'),
139549     client = require('ripple/platform/webworks.core/2.0.0/client/system'),
139550     utils = require('ripple/utils'),
139551     notifications = require('ripple/notifications'),
139552     constants = require('ripple/constants'),
139553     platform = require('ripple/platform'),
139554     _self;
139555
139556 function _is(feature) {
139557     return {
139558         allowedFor: function (location) {
139559             return feature && feature.URIs.some(function (uri) {
139560                 return uri.value === location ||
139561                       (location.indexOf(uri.value) >= 0 && uri.subdomains);
139562             });
139563         }
139564     };
139565 }
139566
139567 _self = {
139568     hasCapability: function (args) {
139569         var capabilities = devices.getCurrentDevice().capabilities;
139570         return {
139571             code: 1,
139572             data: capabilities ? capabilities.some(function (type) {
139573                 return type === args.capability;
139574             }) : false
139575         };
139576     },
139577     isMassStorageActive: function () {
139578         return {code: 1, data: deviceSettings.retrieveAsBoolean("system.isMassStorageActive")};
139579     },
139580     hasDataCoverage: function () {
139581         return {code: 1, data: deviceSettings.retrieveAsBoolean("system.hasDataCoverage")};
139582     },
139583     softwareVersion: function () {
139584         return {code: 1, data: devices.getCurrentDevice().osVersion};
139585     },
139586     model: function () {
139587         return {code: 1, data: devices.getCurrentDevice().model};
139588     },
139589     scriptApiVersion: function () {
139590         return {code: 1, data: platform.current().version};
139591     },
139592     setHomeScreenBackground: function (args) {
139593         var path = args.filePath,
139594             msg = "Set home screen background to " + path + ".";
139595         notifications.openNotification("normal", msg);
139596         return {code: 1};
139597     },
139598     hasPermission: function (args) {
139599         var info = app.getInfo(),
139600             feature = info.features ? info.features[args.desiredModule] : null;
139601
139602         return {code: 1, data: feature === null || _is(feature).allowedFor(utils.location().href) ? client.ALLOW : client.DENY};
139603     },
139604     network: function () {
139605         return {code: 1, data: deviceSettings.retrieve("system.network")};
139606     }
139607 };
139608
139609 module.exports = _self;
139610
139611 });
139612 define('ripple/platform/webworks.core/2.0.0/server/dialog', function (require, exports, module) {
139613 /*
139614  *  Copyright 2011 Research In Motion Limited.
139615  *
139616  * Licensed under the Apache License, Version 2.0 (the "License");
139617  * you may not use this file except in compliance with the License.
139618  * You may obtain a copy of the License at
139619  *
139620  * http://www.apache.org/licenses/LICENSE-2.0
139621  *
139622  * Unless required by applicable law or agreed to in writing, software
139623  * distributed under the License is distributed on an "AS IS" BASIS,
139624  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139625  * See the License for the specific language governing permissions and
139626  * limitations under the License.
139627  */
139628 var event = require('ripple/event'),
139629     devices = require('ripple/devices'),
139630     ui = require('ripple/ui'),
139631     utils = require('ripple/utils'),
139632     isDialogVisible = false,
139633     visibleDialogArgs,
139634     _self;
139635
139636 function closeDialog() {
139637     var buttonsDiv = document.getElementById("dialog-buttons"),
139638         messageDiv = document.getElementById("dialog-message");
139639
139640     ui.hideOverlay("dialog-window", function (dialog) {
139641         buttonsDiv.innerHTML = "";
139642         messageDiv.innerHTML = "";
139643         isDialogVisible = false;
139644     });
139645 }
139646
139647 event.on("LayoutChanged", function () {
139648     if (isDialogVisible) {
139649         closeDialog();
139650         //Used to resize dialog on orientation change
139651         _self.ask(visibleDialogArgs);
139652     }
139653 });
139654
139655 _self = {
139656
139657     ask: function (args, post, baton) {
139658         if (!args) {
139659             throw ("No arguments provided");
139660         } else if (!args.buttons || !args.message) {
139661             throw ("Invalid arguments");
139662         }
139663         baton.take();
139664         visibleDialogArgs = args;
139665
139666         ui.showOverlay("dialog-window", function (dialog) {
139667             var container = document.getElementById("viewport-container"),
139668                 height = window.getComputedStyle(container, null).getPropertyValue("height"),
139669                 width = window.getComputedStyle(container, null).getPropertyValue("width"),
139670                 sizeDiv = document.getElementById("dialog-wrapper"),
139671                 positionDiv = document.getElementById("dialog-window"),
139672                 titleDiv = document.getElementById("dialog-title"),
139673                 buttonsDiv = document.getElementById("dialog-buttons"),
139674                 messageDiv = document.getElementById("dialog-message"),
139675                 position, size;
139676
139677             if (!messageDiv || !buttonsDiv) {
139678                 return;
139679             }
139680
139681             dialog.setAttribute("style", "display:-webkit-box;height:" + height + "; width:" + width + ";");
139682
139683             position = "overlay-dialog";
139684             size = "overlay-dialog-wrapper";
139685
139686             if (args.settings && args.settings.position) {
139687                 position += " overlay-dialog-" + args.settings.position;
139688             }
139689
139690             if (args.settings && args.settings.size) {
139691                 size += " overlay-dialog-wrapper-" + args.settings.size;
139692             }
139693
139694             positionDiv.setAttribute("class", position);
139695             sizeDiv.setAttribute("class", size);
139696
139697             titleDiv.innerHTML = args.settings && args.settings.title ? args.settings.title : "";
139698             messageDiv.innerHTML = args.message;
139699             isDialogVisible = true;
139700
139701             args.buttons.forEach(function (button) {
139702                 var buttonElement = utils.createElement("input", {
139703                     "type": "button",
139704                     "value": button
139705                 });
139706                 buttonElement.addEventListener("click", function () {
139707                     var buttonIndex = args.buttons.indexOf(button);
139708                     closeDialog();
139709                     baton.pass({code: 1, data: buttonIndex});
139710                 });
139711                 buttonsDiv.appendChild(buttonElement);
139712             });
139713         }, true);
139714     }
139715 };
139716
139717 module.exports = _self;
139718
139719 });
139720 define('ripple/platform/wac/1.0/CallRecordTypes', function (require, exports, module) {
139721 /*
139722  *  Copyright 2011 Research In Motion Limited.
139723  *
139724  * Licensed under the Apache License, Version 2.0 (the "License");
139725  * you may not use this file except in compliance with the License.
139726  * You may obtain a copy of the License at
139727  *
139728  * http://www.apache.org/licenses/LICENSE-2.0
139729  *
139730  * Unless required by applicable law or agreed to in writing, software
139731  * distributed under the License is distributed on an "AS IS" BASIS,
139732  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139733  * See the License for the specific language governing permissions and
139734  * limitations under the License.
139735  */
139736 module.exports = {
139737     RECEIVED: "received",
139738     OUTGOING: "outgoing",
139739     MISSED: "missed"
139740 };
139741
139742 });
139743 define('ripple/platform/wac/1.0/ApplicationTypes', function (require, exports, module) {
139744 /*
139745  *  Copyright 2011 Research In Motion Limited.
139746  *
139747  * Licensed under the Apache License, Version 2.0 (the "License");
139748  * you may not use this file except in compliance with the License.
139749  * You may obtain a copy of the License at
139750  *
139751  * http://www.apache.org/licenses/LICENSE-2.0
139752  *
139753  * Unless required by applicable law or agreed to in writing, software
139754  * distributed under the License is distributed on an "AS IS" BASIS,
139755  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139756  * See the License for the specific language governing permissions and
139757  * limitations under the License.
139758  */
139759 var utils = require('ripple/utils'),
139760     constants = require('ripple/constants'),
139761     _self = {};
139762
139763 utils.forEach(constants.PLATFORMS.WAC.APPLICATIONS, function (application) {
139764     _self.__defineGetter__(application, function () {
139765         return application;
139766     });
139767 });
139768
139769 module.exports = _self;
139770
139771 });
139772 define('ripple/platform/wac/1.0/Device', function (require, exports, module) {
139773 /*
139774  *  Copyright 2011 Research In Motion Limited.
139775  *
139776  * Licensed under the Apache License, Version 2.0 (the "License");
139777  * you may not use this file except in compliance with the License.
139778  * You may obtain a copy of the License at
139779  *
139780  * http://www.apache.org/licenses/LICENSE-2.0
139781  *
139782  * Unless required by applicable law or agreed to in writing, software
139783  * distributed under the License is distributed on an "AS IS" BASIS,
139784  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139785  * See the License for the specific language governing permissions and
139786  * limitations under the License.
139787  */
139788 var constants = require('ripple/constants'),
139789     exception = require('ripple/exception'),
139790     _console = require('ripple/console'),
139791     utils = require('ripple/utils'),
139792     notifications = require('ripple/notifications'),
139793     ApplicationTypes = require('ripple/platform/wac/1.0/ApplicationTypes'),
139794     Exception = require('ripple/platform/wac/1.0/Exception'),
139795     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
139796     _applicationTypes = {
139797         FILES: "FILES",
139798         MEDIAPLAYER: "MEDIAPLAYER",
139799         PHONECALL: "PHONECALL",
139800         PICTURES: "PICTURES"
139801     },
139802     _self;
139803
139804 function _throwUnsupportedException(method) {
139805     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
139806 }
139807
139808 _self = {
139809     // Properties
139810     clipboardString: undefined,
139811     widgetEngineName: undefined,
139812     widgetEngineProvider: undefined,
139813     widgetEngineVersion: undefined,
139814
139815     // Methods
139816     getAvailableApplications: function () {
139817         return constants.PLATFORMS.WAC.APPLICATIONS || [];
139818     },
139819
139820     getDirectoryFileNames: function () {
139821         _throwUnsupportedException("Device.getDirectoryFileNames");
139822     },
139823     getFile: function () {
139824         _throwUnsupportedException("Device.getFile");
139825     },
139826
139827     launchApplication: function launchApplication(application, startParameter) {
139828         if (!application || typeof(application) !== "string") {
139829             exception.raise(ExceptionTypes.INVALID_PARAMETER,
139830                     "Invalid argument 'application' at Device.launchApplication(): expected to be of type 'string' but was of type: " + (application ? typeof(application) : "null"),
139831                     Exception);
139832         }
139833
139834         if (startParameter && typeof(startParameter) !== "string") {
139835             exception.raise(ExceptionTypes.INVALID_PARAMETER,
139836                     "Invalid argument 'startParameter' at Device.launchApplication(): expected to be 'string' but was : " + typeof(startParameter),
139837                     Exception);
139838         }
139839
139840         // rudimentary implementation for now
139841         var message = "The widget has requested application: '" + application + "' to be launched. \n\n";
139842
139843         if (startParameter) {
139844             message += "The following start parameter was sent in: " + startParameter + "\n\n";
139845         }
139846
139847         if (_applicationTypes[application] && !startParameter) {
139848             message += "Launching this application can also be done with an optional startParameter which was not provided" + "\n\n";
139849         }
139850
139851         if (!ApplicationTypes[application]) {
139852             message += "Note: the application requested is not part of the common values specified by the WAC API.";
139853         }
139854
139855         notifications.openNotification("normal", message);
139856         _console.log(message);
139857     },
139858
139859     copyFile: function () {
139860         _throwUnsupportedException("Device.copyFile");
139861     },
139862     deleteFile: function () {
139863         _throwUnsupportedException("Device.deleteFile");
139864     },
139865     findFiles: function () {
139866         _throwUnsupportedException("Device.findFiles");
139867     },
139868     getFileSystemRoots: function () {
139869         _throwUnsupportedException("Device.getFileSystemRoots");
139870     },
139871     getFileSystemSize: function () {
139872         _throwUnsupportedException("Device.getFileSystemSize");
139873     },
139874     moveFile: function () {
139875         _throwUnsupportedException("Device.moveFile");
139876     },
139877     onFilesFound: function () {
139878         _throwUnsupportedException("Device.onFilesFound");
139879     },
139880     setRingtone: function () {
139881         _throwUnsupportedException("Device.setRingtone");
139882     },
139883
139884     vibrate: function (duration) {
139885         utils.validateArgumentType(duration, "number", ExceptionTypes.INVALID_PARAMETER, "duration paramter is not a number", new Exception());
139886         notifications.openNotification("normal", "Vibrating for " + duration + " second(s).");
139887     }
139888
139889 };
139890
139891 _self.__defineGetter__("widgetEngineName", function () {
139892     return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_NAME;
139893 });
139894
139895 _self.__defineGetter__("widgetEngineProvider", function () {
139896     return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_PROVIDER;
139897 });
139898
139899 _self.__defineGetter__("widgetEngineVersion", function () {
139900     return constants.PLATFORMS.WAC.DEVICE.WIDGET_ENGINE_VERSION;
139901 });
139902
139903 module.exports = _self;
139904
139905 });
139906 define('ripple/platform/wac/1.0/Account', function (require, exports, module) {
139907 /*
139908  *  Copyright 2011 Research In Motion Limited.
139909  *
139910  * Licensed under the Apache License, Version 2.0 (the "License");
139911  * you may not use this file except in compliance with the License.
139912  * You may obtain a copy of the License at
139913  *
139914  * http://www.apache.org/licenses/LICENSE-2.0
139915  *
139916  * Unless required by applicable law or agreed to in writing, software
139917  * distributed under the License is distributed on an "AS IS" BASIS,
139918  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139919  * See the License for the specific language governing permissions and
139920  * limitations under the License.
139921  */
139922 var deviceSettings = require('ripple/deviceSettings'),
139923     _self;
139924
139925 _self = {
139926     accountName: undefined,
139927     accountId: undefined
139928 };
139929
139930 _self.__defineGetter__("accountName", function () {
139931     return deviceSettings.retrieve("Account.accountName");
139932 });
139933
139934 _self.__defineGetter__("accountId", function () {
139935     return deviceSettings.retrieve("Account.accountId");
139936 });
139937
139938 module.exports = _self;
139939
139940 });
139941 define('ripple/platform/wac/1.0/AccountInfo', function (require, exports, module) {
139942 /*
139943  *  Copyright 2011 Research In Motion Limited.
139944  *
139945  * Licensed under the Apache License, Version 2.0 (the "License");
139946  * you may not use this file except in compliance with the License.
139947  * You may obtain a copy of the License at
139948  *
139949  * http://www.apache.org/licenses/LICENSE-2.0
139950  *
139951  * Unless required by applicable law or agreed to in writing, software
139952  * distributed under the License is distributed on an "AS IS" BASIS,
139953  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139954  * See the License for the specific language governing permissions and
139955  * limitations under the License.
139956  */
139957 var deviceSettings = require('ripple/deviceSettings'),
139958     _self = {
139959         phoneUserUniqueId: undefined,
139960         phoneMSISDN: undefined,
139961         phoneOperatorName: undefined,
139962         userAccountBalance: undefined,
139963         userSubscriptionType: undefined
139964     };
139965
139966 _self.__defineGetter__("phoneUserUniqueId", function () {
139967     return deviceSettings.retrieve("AccountInfo.phoneUserUniqueId");
139968 });
139969
139970 _self.__defineGetter__("phoneMSISDN", function () {
139971     return deviceSettings.retrieve("AccountInfo.phoneMSISDN");
139972 });
139973
139974 _self.__defineGetter__("phoneOperatorName", function () {
139975     return deviceSettings.retrieve("AccountInfo.phoneOperatorName");
139976 });
139977
139978 _self.__defineGetter__("userAccountBalance", function () {
139979     return deviceSettings.retrieve("AccountInfo.userAccountBalance");
139980 });
139981
139982 _self.__defineGetter__("userSubscriptionType", function () {
139983     return deviceSettings.retrieve("AccountInfo.userSubscriptionType");
139984 });
139985
139986 module.exports = _self;
139987
139988 });
139989 define('ripple/platform/wac/1.0/DataNetworkInfo', function (require, exports, module) {
139990 /*
139991  *  Copyright 2011 Research In Motion Limited.
139992  *
139993  * Licensed under the Apache License, Version 2.0 (the "License");
139994  * you may not use this file except in compliance with the License.
139995  * You may obtain a copy of the License at
139996  *
139997  * http://www.apache.org/licenses/LICENSE-2.0
139998  *
139999  * Unless required by applicable law or agreed to in writing, software
140000  * distributed under the License is distributed on an "AS IS" BASIS,
140001  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140002  * See the License for the specific language governing permissions and
140003  * limitations under the License.
140004  */
140005 var event = require('ripple/event'),
140006     utils = require('ripple/utils'),
140007     _console = require('ripple/console'),
140008     deviceSettings = require('ripple/deviceSettings'),
140009     DataNetworkConnectionTypes = require('ripple/platform/wac/1.0/DataNetworkConnectionTypes'),
140010     Exception = require('ripple/platform/wac/1.0/Exception'),
140011     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
140012
140013 _self = {
140014     isDataNetworkConnected: undefined,
140015     networkConnectionType: undefined,
140016     onNetworkConnectionChanged: undefined,
140017
140018     getNetworkConnectionName: function (networkConnectionType) {
140019         var foundConnectionType;
140020         utils.validateArgumentType(networkConnectionType, "string", ExceptionTypes.INVALID_PARAMETER, "networkConnectionType is invalid, expected a string", new Exception());
140021         foundConnectionType = DataNetworkConnectionTypes[networkConnectionType.toUpperCase()];
140022         return foundConnectionType || null;
140023     }
140024 };
140025
140026 event.on("DataNetworkConnectionChanged", function (newConnectionName) {
140027     var callback = _self.onNetworkConnectionChanged,
140028         msg = "Fired onNetworkConnectionChanged with newConnectionName: " + newConnectionName;
140029
140030     if (callback && typeof callback === "function") {
140031         callback.apply(null, [newConnectionName]);
140032     }
140033     else {
140034         msg += " --> BUT there was no registered callback found.";
140035     }
140036
140037     _console.log(msg);
140038 });
140039
140040 _self.__defineGetter__("isDataNetworkConnected", function () {
140041     return deviceSettings.retrieveAsBoolean("DataNetworkInfo.isDataNetworkConnected");
140042 });
140043
140044 _self.__defineGetter__("networkConnectionType", function () {
140045     var value = deviceSettings.retrieve("DataNetworkInfo.networkConnectionType");
140046     return value instanceof Array ? value : [value];
140047 });
140048
140049 module.exports = _self;
140050
140051 });
140052 define('ripple/platform/wac/1.0/MessageTypes', function (require, exports, module) {
140053 /*
140054  *  Copyright 2011 Research In Motion Limited.
140055  *
140056  * Licensed under the Apache License, Version 2.0 (the "License");
140057  * you may not use this file except in compliance with the License.
140058  * You may obtain a copy of the License at
140059  *
140060  * http://www.apache.org/licenses/LICENSE-2.0
140061  *
140062  * Unless required by applicable law or agreed to in writing, software
140063  * distributed under the License is distributed on an "AS IS" BASIS,
140064  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140065  * See the License for the specific language governing permissions and
140066  * limitations under the License.
140067  */
140068 module.exports = {
140069     EmailMessage: "email",
140070     MMSMessage: "mms",
140071     SMSMessage: "sms"
140072 };
140073
140074 });
140075 define('ripple/platform/wac/1.0/MessageFolderTypes', function (require, exports, module) {
140076 /*
140077  *  Copyright 2011 Research In Motion Limited.
140078  *
140079  * Licensed under the Apache License, Version 2.0 (the "License");
140080  * you may not use this file except in compliance with the License.
140081  * You may obtain a copy of the License at
140082  *
140083  * http://www.apache.org/licenses/LICENSE-2.0
140084  *
140085  * Unless required by applicable law or agreed to in writing, software
140086  * distributed under the License is distributed on an "AS IS" BASIS,
140087  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140088  * See the License for the specific language governing permissions and
140089  * limitations under the License.
140090  */
140091 module.exports = {
140092     DRAFTS: "drafts",
140093     INBOX: "inbox",
140094     OUTBOX: "outbox",
140095     SENTBOX: "sentbox"
140096 };
140097
140098 });
140099 define('ripple/platform/wac/1.0/spec', function (require, exports, module) {
140100 module.exports = {
140101
140102     id: "wac",
140103     version: "1.0",
140104     name: "WAC",
140105     type: "plaform",
140106
140107     persistencePrefix: "wac-",
140108
140109     config: require('ripple/platform/wac/1.0/spec/config'),
140110     device: require('ripple/platform/wac/1.0/spec/device'),
140111     ui: require('ripple/platform/wac/1.0/spec/ui'),
140112     events: require('ripple/platform/wac/1.0/spec/events'),
140113
140114     objects: {
140115         navigator: {
140116             path: "w3c/1.0/navigator"
140117         },
140118         WidgetManager: {
140119             path: "wac/1.0/WidgetManager",
140120             feature: "http://jil.org/jil/api/1.1.1/widgetmanager"
140121         },
140122         Widget: {
140123             path: "wac/1.0/Widget",
140124             feature: "http://jil.org/jil/api/1.1/widget",
140125             children: {
140126                 Device: {
140127                     path: "wac/1.0/Device",
140128                     feature: "http://jil.org/jil/api/1.1/device",
140129                     children: {
140130                         AccountInfo: {
140131                             path: "wac/1.0/AccountInfo",
140132                             feature: "http://jil.org/jil/api/1.1/accountinfo"
140133                         },
140134                         ApplicationTypes: {
140135                             path: "wac/1.0/ApplicationTypes",
140136                             feature: "http://jil.org/jil/api/1.1.5/applicationtypes"
140137                         },
140138                         DataNetworkInfo: {
140139                             path: "wac/1.0/DataNetworkInfo",
140140                             feature: "http://jil.org/jil/api/1.1.1/datanetworkinfo",
140141                             children: {
140142                                 DataNetworkConnectionTypes: {
140143                                     path: "wac/1.0/DataNetworkConnectionTypes"
140144                                 }
140145                             }
140146                         },
140147                         DeviceInfo: {
140148                             path: "wac/1.0/DeviceInfo",
140149                             feature: "http://jil.org/jil/api/1.1/deviceinfo"
140150                         },
140151                         DeviceStateInfo: {
140152                             path: "wac/1.0/DeviceStateInfo",
140153                             feature: "http://jil.org/jil/api/1.1/devicestateinfo",
140154                             children: {
140155                                 Config: {
140156                                     path: "wac/1.0/Config",
140157                                     feature: "http://jil.org/jil/api/1.1/config"
140158                                 },
140159                                 AccelerometerInfo: {
140160                                     path: "wac/1.0/AccelerometerInfo",
140161                                     feature: "http://jil.org/jil/api/1.1/accelerometerinfo"
140162                                 }
140163                             }
140164                         },
140165                         File: {
140166                             path: "wac/1.0/File",
140167                             feature: "http://jil.org/jil/api/1.1.1/file"
140168                         },
140169                         PositionInfo: {
140170                             path: "wac/1.0/PositionInfo",
140171                             feature: "http://jil.org/jil/api/1.1/positioninfo"
140172                         },
140173                         RadioInfo: {
140174                             path: "wac/1.0/RadioInfo",
140175                             feature: "http://jil.org/jil/api/1.1.1/radioinfo",
140176                             children: {
140177                                 RadioSignalSourceTypes: {
140178                                     path: "wac/1.0/RadioSignalSourceTypes",
140179                                     feature: "http://jil.org/jil/api/1.1.5/radiosignalsourcetypes"
140180                                 }
140181                             }
140182                         },
140183                         PowerInfo: {
140184                             path: "wac/1.0/PowerInfo",
140185                             feature: "http://jil.org/jil/api/1.1/powerinfo"
140186                         }
140187                     }
140188                 },
140189                 ExceptionTypes: {
140190                     path: "wac/1.0/ExceptionTypes",
140191                     feature: "http://jil.org/jil/api/1.1.5/exceptiontypes"
140192                 },
140193                 Exception: {
140194                     path: "wac/1.0/Exception",
140195                     feature: "http://jil.org/jil/api/1.1.5/exception"
140196                 },
140197                 Multimedia: {
140198                     path: "wac/1.0/Multimedia",
140199                     feature: "http://jil.org/jil/api/1.1/multimedia",
140200                     children: {
140201                         Camera: {
140202                             path: "wac/1.0/Camera",
140203                             feature: "http://jil.org/jil/api/1.1.2/camera"
140204                         },
140205                         AudioPlayer: {
140206                             path: "wac/1.0/AudioPlayer",
140207                             feature: "http://jil.org/jil/api/1.1/audioplayer"
140208                         },
140209                         VideoPlayer: {
140210                             path: "wac/1.0/VideoPlayer",
140211                             feature: "http://jil.org/jil/api/1.1.2/videoplayer"
140212                         }
140213                     }
140214                 },
140215                 Telephony: {
140216                     path: "wac/1.0/Telephony",
140217                     feature: "http://jil.org/jil/api/1.1.1/telephony",
140218                     children: {
140219                         CallRecord: {
140220                             path: "wac/1.0/CallRecord",
140221                             feature: "http://jil.org/jil/api/1.1/callrecord"
140222                         },
140223                         CallRecordTypes: {
140224                             path: "wac/1.0/CallRecordTypes",
140225                             feature: "http://jil.org/jil/api/1.1.1/callrecordtypes"
140226                         }
140227                     }
140228                 },
140229                 PIM: {
140230                     path: "wac/1.0/PIM",
140231                     feature: "http://jil.org/jil/api/1.1.1/pim",
140232                     children: {
140233                         AddressBookItem: {
140234                             path: "wac/1.0/AddressBookItem",
140235                             feature: "http://jil.org/jil/api/1.1/addressbookitem"
140236                         },
140237                         CalendarItem: {
140238                             path: "wac/1.0/CalendarItem",
140239                             feature: "http://jil.org/jil/api/1.1/calendaritem"
140240                         },
140241                         EventRecurrenceTypes: {
140242                             path: "wac/1.0/EventRecurrenceTypes",
140243                             feature: "http://jil.org/jil/api/1.1/eventrecurrencetypes"
140244                         }
140245                     }
140246                 },
140247                 Messaging: {
140248                     path: "wac/1.0/Messaging",
140249                     feature: "http://jil.org/jil/api/1.1/messaging",
140250                     children: {
140251                         Account: {
140252                             path: "wac/1.0/Account",
140253                             feature: "http://jil.org/jil/api/1.1/account"
140254                         },
140255                         Attachment: {
140256                             path: "wac/1.0/Attachment",
140257                             feature: "http://jil.org/jil/api/1.1/attachment"
140258                         },
140259                         Message: {
140260                             path: "wac/1.0/Message",
140261                             feature: "http://jil.org/jil/api/1.1/message"
140262                         },
140263                         MessageFolderTypes: {
140264                             path: "wac/1.0/MessageFolderTypes",
140265                             feature: "http://jil.org/jil/api/1.1.4/messagefoldertypes"
140266                         },
140267                         MessageQuantities: {
140268                             path: "wac/1.0/MessageQuantities",
140269                             feature: "http://jil.org/jil/api/1.1/messagequantities"
140270                         },
140271                         MessageTypes: {
140272                             path: "wac/1.0/MessageTypes",
140273                             feature: "http://jil.org/jil/api/1.1/messagetypes"
140274                         }
140275                     }
140276                 }
140277             }
140278         }
140279     }
140280
140281 };
140282
140283 });
140284 define('ripple/platform/wac/1.0/PIM', function (require, exports, module) {
140285 /*
140286  *  Copyright 2011 Research In Motion Limited.
140287  *
140288  * Licensed under the Apache License, Version 2.0 (the "License");
140289  * you may not use this file except in compliance with the License.
140290  * You may obtain a copy of the License at
140291  *
140292  * http://www.apache.org/licenses/LICENSE-2.0
140293  *
140294  * Unless required by applicable law or agreed to in writing, software
140295  * distributed under the License is distributed on an "AS IS" BASIS,
140296  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140297  * See the License for the specific language governing permissions and
140298  * limitations under the License.
140299  */
140300 var _self,
140301     exception = require('ripple/exception'),
140302     Exception = require('ripple/platform/wac/1.0/Exception'),
140303     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
140304     AddressBookItem = require('ripple/platform/wac/1.0/AddressBookItem'),
140305     CalendarItem = require('ripple/platform/wac/1.0/CalendarItem'),
140306     utils = require('ripple/utils'),
140307     db = require('ripple/db'),
140308     constants = require('ripple/constants');
140309
140310 function _throwUnsupportedException(method) {
140311     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
140312 }
140313
140314 function _toAddressBookItem(contact) {
140315     if (!contact) {
140316         return null;
140317     }
140318
140319     var addressBookItem = new AddressBookItem();
140320
140321     utils.forEach(contact, function (prop, key) {
140322         addressBookItem[key] = contact[key];
140323     });
140324
140325     return addressBookItem;
140326 }
140327
140328 function _toCalendarItem(item) {
140329     if (!item) {
140330         return null;
140331     }
140332
140333     var calendarItem = new CalendarItem();
140334
140335     utils.forEach(item, function (prop, key) {
140336         calendarItem[key] = item[key];
140337     });
140338
140339     return calendarItem;
140340 }
140341
140342 function _getData(type) {
140343     var data = db.retrieveObject(type) || [];
140344     return data;
140345 }
140346
140347 function _saveData(type, items) {
140348     db.saveObject(type, items);
140349 }
140350
140351 function _getContacts() {
140352     var contacts = _getData(constants.PIM.ADDRESS_LIST_KEY),
140353         gord,
140354         dan,
140355         brent,
140356         pj,
140357         mark;
140358
140359     if (contacts.length === 0) {
140360
140361         gord = new AddressBookItem();
140362         gord.addressBookItemId = "0";
140363         gord.fullName = "Gord Tanner";
140364         gord.eMail = "gord@tinyHippos.com";
140365         gord.company = "tinyHippos Inc";
140366         gord.title = "Code Poet";
140367         gord.address = "121 Charles Street W, Kitchener, Ontario, Canada";
140368
140369         dan = new AddressBookItem();
140370         dan.addressBookItemId = "1";
140371         dan.fullName = "Dan Silivestru";
140372         dan.eMail = "dan@tinyHippos.com";
140373         dan.company = "tinyHippos Inc";
140374         dan.title = "Co-Founder And Chief Technology Officer";
140375         dan.address = "121 Charles Street W, Kitchener, Ontario, Canada";
140376
140377         pj = new AddressBookItem();
140378         pj.addressBookItemId = "2";
140379         pj.fullName = "PJ Lowe";
140380         pj.eMail = "pj@tinyHippos.com";
140381         pj.company = "tinyHippos Inc";
140382         pj.title = "Co-Founder And Chief Operations Officer";
140383         pj.address = "121 Charles Street W, Kitchener, Ontario, Canada";
140384
140385         brent = new AddressBookItem();
140386         brent.addressBookItemId = "2";
140387         brent.fullName = "Brent Lintner";
140388         brent.eMail = "brent@tinyHippos.com";
140389         brent.company = "tinyHippos Inc";
140390         brent.title = "Co-Founder And Chief Operations Officer";
140391         brent.address = "121 Charles Street W, Kitchener, Ontario, Canada";
140392
140393         mark = new AddressBookItem();
140394         mark.addressBookItemId = "3";
140395         mark.fullName = "Mark McArdle";
140396         mark.eMail = "mark@tinyHippos.com";
140397         mark.company = "tinyHippos Inc";
140398         mark.title = "Chief Executive Officer";
140399         mark.address = "121 Charles Street W, Kitchener, Ontario, Canada";
140400
140401         contacts.push(gord);
140402         contacts.push(dan);
140403         contacts.push(pj);
140404         contacts.push(brent);
140405         contacts.push(mark);
140406
140407         _saveData(constants.PIM.ADDRESS_LIST_KEY, contacts);
140408     }
140409     return contacts.map(_toAddressBookItem);
140410 }
140411
140412 function _getEvents() {
140413     var events = _getData(constants.PIM.CALENDAR_LIST_KEY);
140414     return events.map(_toCalendarItem);
140415 }
140416
140417 function _get(type, id, fetchIDFunc) {
140418     var items = _getData(type);
140419     return items.reduceRight(function (match, item) {
140420         return fetchIDFunc(item) === id ? item : match;
140421     }, null);
140422 }
140423
140424 function _getAddressBookID(item) {
140425     return item.addressBookItemId;
140426 }
140427
140428 function _getCalendarID(item) {
140429     return item.calendarItemId;
140430 }
140431
140432 function _getContact(id) {
140433     return _toAddressBookItem(_get(constants.PIM.ADDRESS_LIST_KEY, id, _getAddressBookID));
140434 }
140435
140436 function _getEvent(id) {
140437     return _toCalendarItem(_get(constants.PIM.CALENDAR_LIST_KEY, id, _getCalendarID));
140438 }
140439
140440 function _add(type, item, idProp) {
140441     var items = _getData(type);
140442
140443     if (!item[idProp]) {
140444         item[idProp] = Math.uuid(undefined, 16);
140445     }
140446
140447     items.push(item);
140448     _saveData(type, items);
140449 }
140450
140451 function _delete(type, id, fetchIDFunc) {
140452     var items = _getData(type);
140453
140454     _saveData(type, items.filter(function (item) {
140455         return fetchIDFunc(item) !== id;
140456     }));
140457 }
140458
140459 function _validateArgs(min, max, len) {
140460     utils.validateNumberOfArguments(min, max, len,
140461         ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
140462 }
140463
140464 function _validateType(arg, argType) {
140465     utils.validateArgumentType(arg, argType,
140466         ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
140467         new Exception());
140468 }
140469
140470 function _validateAddressBookItem(item) {
140471     if ((item instanceof AddressBookItem) === false) {
140472         exception.raise(ExceptionTypes.INVALID_PARAMETER, "invalid contact, not instance of AddressBookItem.", new Exception());
140473     }
140474 }
140475
140476 _self = {
140477     addAddressBookItem: function (contact) {
140478         _validateArgs(1, 1, arguments.length);
140479         _validateAddressBookItem(contact);
140480
140481         _add(constants.PIM.ADDRESS_LIST_KEY, contact, "addressBookItemId");
140482     },
140483     createAddressBookGroup: function (groupName) {
140484         _throwUnsupportedException("Widget.PIM.createAddressBookGroup");
140485     },
140486     createAddressBookItem: function () {
140487         return new AddressBookItem();
140488     },
140489     deleteAddressBookItem: function (contactid) {
140490         _validateArgs(1, 1, arguments.length);
140491         _validateType(contactid, "string");
140492         _delete(constants.PIM.ADDRESS_LIST_KEY, contactid, _getAddressBookID);
140493     },
140494     deleteAddressBookGroup: function (groupName) {
140495         _throwUnsupportedException("Widget.PIM.deleteAddressBookGroup");
140496     },
140497     getAddressBookItem: function (contactid) {
140498         _validateArgs(1, 1, arguments.length);
140499         _validateType(contactid, "string");
140500         return _getContact(contactid);
140501     },
140502     getAddressBookItemsCount: function () {
140503         _validateArgs(0, 0, arguments.length);
140504         var items = _getContacts();
140505         return items.length;
140506     },
140507     getAvailableAddressGroupNames: function () {
140508         _throwUnsupportedException("Widget.PIM.getAvailableAddressGroupNames");
140509     },
140510     getAddressBookGroupMembers: function (groupName) {
140511         _throwUnsupportedException("Widget.PIM.getAddressBookGroupMembers");
140512     },
140513     findAddressBookItems: function (comparisonContact, startInx, endInx) {
140514         _validateArgs(3, 3, arguments.length);
140515         utils.validateMultipleArgumentTypes([comparisonContact, startInx, endInx], ["object", "number", "number"], ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
140516             new Exception());
140517
140518         if (endInx < 0) {
140519             exception.raise(ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
140520         }
140521
140522         startInx = startInx < 0 ? 0 : startInx;
140523
140524         var contacts = _getContacts();
140525         utils.find(comparisonContact, contacts, startInx, endInx, _self.onAddressBookItemsFound);
140526     },
140527
140528     addCalendarItem: function (calendarItem) {
140529         _validateArgs(1, 1, arguments.length);
140530         _add(constants.PIM.CALENDAR_LIST_KEY, calendarItem, "calendarItemId");
140531     },
140532     deleteCalendarItem: function (calendarId) {
140533         _validateArgs(1, 1, arguments.length);
140534         _delete(constants.PIM.CALENDAR_LIST_KEY, calendarId, _getCalendarID);
140535     },
140536     getCalendarItem: function (calendarId) {
140537         _validateArgs(1, 1, arguments.length);
140538         return _getEvent(calendarId);
140539     },
140540     findCalendarItems: function (itemToMatch, startInx, endInx) {
140541         _validateArgs(1, 3, arguments.length);
140542         var events = _getEvents();
140543         utils.find(itemToMatch, events, startInx, endInx, _self.onCalendarItemsFound);
140544     },
140545     getCalendarItems: function (startTime, endTime) {
140546         var events = _getEvents();
140547
140548         return events.reduce(function (matches, event) {
140549             if (event.eventStartTime >= startTime && event.eventStartTime <= endTime) {
140550                 matches.push(event);
140551             }
140552             return matches;
140553         }, []);
140554     },
140555     exportAsVCard: function (addressBookItems) {
140556         _throwUnsupportedException("Widget.PIM.exportAsVCard");
140557     },
140558
140559     onAddressBookItemsFound: undefined, // function (addressBookItemsFound) { }
140560     onCalendarItemsFound: undefined, // function (calendarItemsFound) { }
140561     onCalendarItemAlert: undefined, // function (calendarItem) { }
140562     onVCardExportingFinish: undefined // function (vCardFilePath) { }
140563 };
140564
140565 module.exports = _self;
140566
140567 });
140568 define('ripple/platform/wac/1.0/AudioPlayer', function (require, exports, module) {
140569 /*
140570  *  Copyright 2011 Research In Motion Limited.
140571  *
140572  * Licensed under the Apache License, Version 2.0 (the "License");
140573  * you may not use this file except in compliance with the License.
140574  * You may obtain a copy of the License at
140575  *
140576  * http://www.apache.org/licenses/LICENSE-2.0
140577  *
140578  * Unless required by applicable law or agreed to in writing, software
140579  * distributed under the License is distributed on an "AS IS" BASIS,
140580  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140581  * See the License for the specific language governing permissions and
140582  * limitations under the License.
140583  */
140584 var constants = require('ripple/constants'),
140585     event = require('ripple/event'),
140586     exception = require('ripple/exception'),
140587     utils = require('ripple/utils'),
140588     fileSystem = require('ripple/fileSystem'),
140589     _console = require('ripple/console'),
140590     Exception = require('ripple/platform/wac/1.0/Exception'),
140591     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
140592     _self,
140593     _state = null,
140594     _STATES = constants.MULTIMEDIA.AUDIO_STATES,
140595     _currentAudioFile,
140596     _audio, _loopCount;
140597
140598 event.on("MultimediaAudioStateChanged", function updateAudioState(state) {
140599     _state = state;
140600     if (typeof _self.onStateChange === 'function') {
140601         _self.onStateChange.apply(_self, arguments);
140602     }
140603 });
140604
140605 _audio = utils.createElement("audio", {
140606     "id": "multimedia-audio"
140607 });
140608
140609 _audio.addEventListener('error', function () {
140610     _console.warn("AudioPlayer encountered an error: " + _audio.error.code);
140611     if (_audio.error.code === 4) {
140612         _console.warn("AudioPlayer error 4 could be caused by missing codecs");
140613     }
140614     _state = null;
140615     event.trigger("MultimediaAudioStateChanged", [null], true);
140616 });
140617
140618 _audio.addEventListener('ended', function handleAudioEnded() {
140619     event.trigger("MultimediaAudioStateChanged", [_STATES.COMPLETED], true);
140620     if (_loopCount > 1) {
140621         _self.open(_currentAudioFile);
140622         _self.play(_loopCount--);
140623     }
140624 });
140625
140626 document.getElementById("ui").appendChild(_audio);
140627
140628 function _validateAndSet(state, validStates, callbackBeforeSuccess) {
140629     var i, valid = false;
140630
140631     for (i = 0; i < validStates.length; i++) {
140632         if (validStates[i] === _state) {
140633             valid = true;
140634         }
140635     }
140636
140637     if (!valid) {
140638         _console.warn("Attempted to initiate AudioPlayer." + state +
140639             " in invalid state. current state: " + _state);
140640     } else {
140641         if (typeof(callbackBeforeSuccess) === "function") {
140642             callbackBeforeSuccess.apply();
140643         }
140644         event.trigger("MultimediaAudioStateChanged", [state], true);
140645     }
140646
140647     return valid;
140648 }
140649
140650 function _validateAudioType(fileUrl) {
140651     var matched = fileUrl.match(/\.(\w*)$/),
140652         type = matched ? matched[1] : "";
140653
140654     if (_audio && _audio.canPlayType("audio/" + type) === "") {
140655         _console.warn("Attempting to load an audio that might not work in the current browser [" + fileUrl + "]");
140656     }
140657 }
140658
140659 _self = {
140660     onStateChange: undefined,
140661
140662     open: function (fileUrl) {
140663         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.open wrong number of arguments", new Exception());
140664         utils.validateArgumentType(fileUrl, "string", ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.open invalid parameter! expected string, fileUrl: " +
140665             fileUrl, new Exception());
140666
140667         if (fileUrl.match(/^rtsp:\/\//)) {
140668             exception.raise(exception.types.MethodNotImplemented, "rtsp:// scheme not yet supported. sorry :(");
140669         }
140670
140671         _validateAndSet(_STATES.OPENED, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED, null], function () {
140672             _validateAudioType(fileUrl);
140673             _currentAudioFile = fileSystem.getURI(fileUrl);
140674             _audio.setAttribute("src", _currentAudioFile);
140675             _audio.load();
140676         });
140677     },
140678
140679     play: function (repeatTimes) {
140680         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.play wrong number of arguments", new Exception());
140681         utils.validateArgumentType(repeatTimes, "integer", ExceptionTypes.INVALID_PARAMETER, "Multimedia.js.AudioPlayer.play invalid parameter! expected integer, repeatTimes: " + repeatTimes, new Exception());
140682
140683         if (repeatTimes < 0) {
140684             exception.raise(ExceptionTypes.INVALID_PARAMETER, "value of repeatTimes must be greater than 0", new Exception());
140685         }
140686
140687         if (repeatTimes !== 0) {
140688             _validateAndSet(_STATES.PLAYING, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED], function () {
140689                 _loopCount = repeatTimes;
140690                 _audio.play();
140691             });
140692         }
140693     },
140694
140695     pause: function () {
140696         _validateAndSet(_STATES.PAUSED, [_STATES.PLAYING], function () {
140697             _audio.pause();
140698         });
140699     },
140700
140701     resume: function () {
140702         _validateAndSet(_STATES.PLAYING, [_STATES.PAUSED], function () {
140703             _audio.play();
140704         });
140705     },
140706
140707     stop: function () {
140708         _validateAndSet(_STATES.STOPPED, [_STATES.PAUSED, _STATES.PLAYING], function () {
140709             try {
140710                 _audio.pause();
140711                 _audio.currentTime = 0;
140712             } catch (e) {
140713                 //HACK: do nothing, this could throw a dom exception 11 sometimes when playing an mp3 or before the file has loaded.
140714                 //see http://developer.palm.com/distribution/viewtopic.php?f=11&t=7568
140715             }
140716         });
140717     }
140718 };
140719
140720 module.exports = _self;
140721
140722 });
140723 define('ripple/platform/wac/1.0/PositionInfo', function (require, exports, module) {
140724 /*
140725  *  Copyright 2011 Research In Motion Limited.
140726  *
140727  * Licensed under the Apache License, Version 2.0 (the "License");
140728  * you may not use this file except in compliance with the License.
140729  * You may obtain a copy of the License at
140730  *
140731  * http://www.apache.org/licenses/LICENSE-2.0
140732  *
140733  * Unless required by applicable law or agreed to in writing, software
140734  * distributed under the License is distributed on an "AS IS" BASIS,
140735  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140736  * See the License for the specific language governing permissions and
140737  * limitations under the License.
140738  */
140739 var geo = require('ripple/geo'),
140740     event = require('ripple/event'),
140741     exception = require('ripple/exception'),
140742     utils = require('ripple/utils'),
140743     _self = {
140744         latitude: undefined,
140745         longitude: undefined,
140746         altitude: undefined,
140747         cellID: undefined,
140748         accuracy: undefined,
140749         altitudeAccuracy: undefined,
140750         timeStamp: undefined
140751     };
140752
140753 utils.forEach(_self, function (value, property) {
140754     _self.__defineGetter__(property, function () {
140755         return geo.getPositionInfo()[property];
140756     });
140757 });
140758
140759 module.exports = _self;
140760
140761 });
140762 define('ripple/platform/wac/1.0/spec/config', function (require, exports, module) {
140763 /*
140764  *  Copyright 2011 Research In Motion Limited.
140765  *
140766  * Licensed under the Apache License, Version 2.0 (the "License");
140767  * you may not use this file except in compliance with the License.
140768  * You may obtain a copy of the License at
140769  *
140770  * http://www.apache.org/licenses/LICENSE-2.0
140771  *
140772  * Unless required by applicable law or agreed to in writing, software
140773  * distributed under the License is distributed on an "AS IS" BASIS,
140774  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140775  * See the License for the specific language governing permissions and
140776  * limitations under the License.
140777  */
140778 var platform = require('ripple/platform'),
140779     utils = require('ripple/utils'),
140780     db = require('ripple/db'),
140781     constants = require('ripple/constants');
140782
140783 module.exports = {
140784     fileName: "config.xml",
140785     validateVersion: function (configValidationObject) {
140786         var valid = true;
140787         valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) ||
140788             (!configValidationObject.widget.validationResult[0].attributes["xmlns:JIL"].valid));
140789
140790         return valid;
140791     },
140792     extractInfo: function (configValidationObject) {
140793         if (!configValidationObject) {
140794             return null;
140795         }
140796
140797         var widgetInfo = {},
140798             configFeatures,
140799             configPreferences,
140800             preferenceName,
140801             platform;
140802
140803         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
140804         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
140805         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
140806         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
140807
140808         widgetInfo.features = {};
140809
140810         configFeatures = configValidationObject.widget.children.feature.validationResult;
140811         utils.forEach(configFeatures, function (f) {
140812             if (f.valid === true) {
140813                 var feature = {id: f.attributes.name.value,
140814                          required: f.attributes.required.valid};
140815                 widgetInfo.features[feature.id] = feature;
140816             }
140817         });
140818
140819         widgetInfo.preferences = {};
140820
140821         configPreferences = configValidationObject.widget.children.preference.validationResult;
140822
140823         platform = require('ripple/platform');
140824         utils.forEach(configPreferences, function (preference) {
140825             preferenceName = preference.attributes.name.value;
140826             if (preferenceName) {
140827                 widgetInfo.preferences[preferenceName] = {
140828                     "key": preferenceName,
140829                     "value": preference.attributes.value.value || "",
140830                     "readonly": preference.attributes.readonly.value === "true"
140831                 };
140832
140833                 db.save(preferenceName,
140834                         widgetInfo.preferences[preferenceName].value,
140835                         platform.getPersistencePrefix(widgetInfo.id));
140836             }
140837         });
140838
140839         return widgetInfo;
140840     },
140841     schema: {
140842         rootElement: "widget",
140843         widget: {
140844             nodeName: "widget",
140845             required: true,
140846             occurrence: 1,
140847             helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in configuration document and may have following child elments: name,description,icon,author,license,content,maximum_display_mode,update,feature,access,billing. \"widget\" element MAY have following attributes: id,version,height,width,xml:lang",
140848             attributes: {
140849                 xmlns: {
140850                     attributeName: "xmlns",
140851                     required: true,
140852                     type: "list",
140853                     listValues: ["http://www.w3.org/ns/widgets"]
140854                 },
140855                 "xmlns:JIL": {
140856                     attributeName: "xmlns:JIL",
140857                     required: true,
140858                     type: "list",
140859                     listValues: ["http://www.jil.org/ns/widgets1.2"]
140860                 },
140861                 "xmlns:its": {
140862                     attributeName: "xmlns:its",
140863                     helpText: "Indicates Text Directionality can be used. According to W3C spec, this feature is at risk, therefore we don't currently validate this.",
140864                     required: false,
140865                     type: "string"
140866                 },
140867                 id: {
140868                     attributeName: "id",
140869                     required: true,
140870                     type: "string"
140871                 },
140872                 version: {
140873                     attributeName: "version",
140874                     helpText: "Version must be in the following format: jil-rec-version-tag = major-version \".\" minor-version [\".\" version-desc]",
140875                     required: true,
140876                     type: "regex",
140877                     regex: /^\d{1,2}\.\d{1,2}(\.[A-Za-z0-9]{1,10})?$/
140878                 },
140879                 height: {
140880                     attributeName: "height",
140881                     required: true,
140882                     type: "integer"
140883                 },
140884                 width: {
140885                     attributeName: "width",
140886                     required: true,
140887                     type: "integer"
140888                 },
140889                 viewmodes: {
140890                     attributeName: "viewmodes",
140891                     required: false,
140892                     type: "list",
140893                     listValues: ["floating", "fullscreen"]
140894                 },
140895                 "xml:lang": {
140896                     attributeName: "xml:lang",
140897                     required: false,
140898                     type: "iso-language"
140899                 }
140900             },
140901             children: {
140902                 preference: {
140903                     nodeName: "preference",
140904                     required: false,
140905                     occurrence: 0,
140906                     attributes: {
140907                         name: {
140908                             attributeName: "name",
140909                             type: "string",
140910                             required: true
140911                         },
140912                         value: {
140913                             type: "string",
140914                             attributeName: "value",
140915                             required: false
140916                         },
140917                         readonly: {
140918                             attributeName: "readonly",
140919                             type: "boolean",
140920                             required: false
140921                         }
140922                     }
140923                 },
140924                 name: {
140925                     nodeName: "name",
140926                     required: false,
140927                     occurrence: 0,
140928                     type: "string",
140929                     attributes: {
140930                         "short": {
140931                             attributeName: "short",
140932                             type: "string",
140933                             required: false
140934                         },
140935                         "xml:lang": {
140936                             attributeName: "xml:lang",
140937                             type: "string",
140938                             required: false,
140939                             unique: true
140940                         }
140941                     }
140942                 },
140943                 description: {
140944                     nodeName: "description",
140945                     required: false,
140946                     occurrence: 0,
140947                     type: "string",
140948                     attributes: {
140949                         "xml:lang": {
140950                             attributeName: "xml:lang",
140951                             type: "string",
140952                             required: false,
140953                             unique: true
140954                         }
140955                     }
140956                 },
140957                 icon: {
140958                     nodeName: "icon",
140959                     required: false,
140960                     occurrence: 0,
140961                     attributes: {
140962                         src: {
140963                             attributeName: "src",
140964                             type: "string",
140965                             required: true
140966                         },
140967                         height: {
140968                             attributeName: "height",
140969                             required: false,
140970                             type: "integer"
140971                         },
140972                         width: {
140973                             attributeName: "width",
140974                             required: false,
140975                             type: "integer"
140976                         },
140977                         "xml:lang": {
140978                             attributeName: "xml:lang",
140979                             type: "string",
140980                             required: false,
140981                             unique: true
140982                         }
140983                     }
140984                 },
140985                 author: {
140986                     nodeName: "author",
140987                     required: false,
140988                     occurrence: 1,
140989                     type: "string",
140990                     attributes: {
140991                         email: {
140992                             attributeName: "email",
140993                             type: "regex",
140994                             required: false,
140995                             regex: constants.REGEX.EMAIL
140996                         },
140997                         href: {
140998                             attributeName: "href",
140999                             type: "regex",
141000                             required: false,
141001                             regex: constants.REGEX.URL
141002                         },
141003                         "xml:lang": {
141004                             attributeName: "xml:lang",
141005                             type: "string",
141006                             required: false,
141007                             unique: true
141008                         }
141009                     }
141010                 },
141011                 license: {
141012                     nodeName: "license",
141013                     required: false,
141014                     occurrence: 1,
141015                     type: "string",
141016                     attributes: {
141017                         href: {
141018                             attributeName: "href",
141019                             type: "regex",
141020                             required: false,
141021                             regex: constants.REGEX.URL
141022                         },
141023                         "xml:lang": {
141024                             attributeName: "xml:lang",
141025                             type: "string",
141026                             required: false,
141027                             unique: true
141028                         }
141029                     }
141030                 },
141031                 content: {
141032                     nodeName: "content",
141033                     required: false,
141034                     occurrence: 1,
141035                     attributes: {
141036                         src: {
141037                             attributeName: "src",
141038                             type: "string",
141039                             required: true
141040                         },
141041                         encoding: {
141042                             attributeName: "encoding",
141043                             type: "string",
141044                             required: false
141045                         },
141046                         type: {
141047                             attributeName: "type",
141048                             type: "string",
141049                             required: false
141050                         }
141051                     }
141052                 },
141053                 feature: {
141054                     nodeName: "feature",
141055                     required: false,
141056                     occurrence: 0,
141057                     attributes: {
141058                         name: {
141059                             attributeName: "name",
141060                             type: "list",
141061                             required: true,
141062                             listValues: ["http://jil.org/jil/api/1.1/widget", "http://jil.org/jil/api/1.1.5/exception",
141063                                             "http://jil.org/jil/api/1.1.5/exceptiontypes", "http://jil.org/jil/api/1.1/device",
141064                                             "http://jil.org/jil/api/1.1/accountinfo", "http://jil.org/jil/api/1.1/deviceinfo",
141065                                             "http://jil.org/jil/api/1.1.1/datanetworkinfo", "http://jil.org/jil/api/1.1/devicestateinfo",
141066                                             "http://jil.org/jil/api/1.1/accelerometerinfo", "http://jil.org/jil/api/1.1/config",
141067                                             "http://jil.org/jil/api/1.1.1/file", "http://jil.org/jil/api/1.1/positioninfo",
141068                                             "http://jil.org/jil/api/1.1/powerinfo", "http://jil.org/jil/api/1.1.1/radioinfo",
141069                                             "http://jil.org/jil/api/1.1.5/radiosignalsourcetypes", "http://jil.org/jil/api/1.1.5/applicationtypes",
141070                                             "http://jil.org/jil/api/1.1/messaging", "http://jil.org/jil/api/1.1/account",
141071                                             "http://jil.org/jil/api/1.1/attachment", "http://jil.org/jil/api/1.1/message",
141072                                             "http://jil.org/jil/api/1.1.4/messagefoldertypes", "http://jil.org/jil/api/1.1/messagequantities",
141073                                             "http://jil.org/jil/api/1.1/messagetypes", "http://jil.org/jil/api/1.1/multimedia",
141074                                             "http://jil.org/jil/api/1.1/audioplayer", "http://jil.org/jil/api/1.1.2/camera",
141075                                             "http://jil.org/jil/api/1.1.2/videoplayer", "http://jil.org/jil/api/1.1.1/pim",
141076                                             "http://jil.org/jil/api/1.1/addressbookitem", "http://jil.org/jil/api/1.1/calendaritem",
141077                                             "http://jil.org/jil/api/1.1/eventrecurrencetypes", "http://jil.org/jil/api/1.1.1/telephony",
141078                                             "http://jil.org/jil/api/1.1/callrecord", "http://jil.org/jil/api/1.1.1/callrecordtypes",
141079                                             "http://jil.org/jil/api/1.1.1/widgetmanager"]
141080                         },
141081                         required: {
141082                             attributeName: "required",
141083                             type: "boolean",
141084                             required: false
141085                         }
141086                     }
141087                 },
141088                 "JIL:maximum_display_mode": {
141089                     nodeName: "JIL:maximum_display_mode",
141090                     required: false,
141091                     occurrence: 1,
141092                     attributes: {
141093                         height: {
141094                             attributeName: "height",
141095                             type: "integer",
141096                             required: false
141097                         },
141098                         width: {
141099                             attributeName: "width",
141100                             type: "integer",
141101                             required: false
141102                         }
141103                     }
141104                 },
141105                 "JIL:update": {
141106                     nodeName: "JIL:update",
141107                     required: false,
141108                     occurrence: 1,
141109                     attributes: {
141110                         href: {
141111                             attributeName: "href",
141112                             type: "regex",
141113                             required: true,
141114                             regex: constants.REGEX.URL
141115                         },
141116                         period: {
141117                             attributeName: "period",
141118                             helpText: "Possible values for the period attribute are: 0, 1, 2, 3 meaning: every time the widget is opened in maximum display mode, every day, every week, every month; respectivly",
141119                             type: "list",
141120                             required: true,
141121                             listValues: ["0", "1", "2", "3"]
141122                         }
141123                     }
141124                 },
141125                 "JIL:access": {
141126                     nodeName: "JIL:access",
141127                     required: false,
141128                     occurrence: 1,
141129                     attributes: {
141130                         network: {
141131                             attributeName: "network",
141132                             type: "boolean",
141133                             required: false
141134                         },
141135                         localfs: {
141136                             attributeName: "localfs",
141137                             type: "boolean",
141138                             required: false
141139                         },
141140                         remote_scripts: {
141141                             attributeName: "remote_scripts",
141142                             type: "boolean",
141143                             required: false
141144                         }
141145                     }
141146                 },
141147                 "JIL:billing": {
141148                     nodeName: "JIL:billing",
141149                     required: false,
141150                     occurrence: 1,
141151                     attributes: {
141152                         required: {
141153                             attributeName: "required",
141154                             type: "boolean",
141155                             required: true
141156                         }
141157                     }
141158                 }
141159             }
141160         }
141161     }
141162 };
141163
141164 });
141165 define('ripple/platform/wac/1.0/spec/device', function (require, exports, module) {
141166 /*
141167  *  Copyright 2011 Research In Motion Limited.
141168  *
141169  * Licensed under the Apache License, Version 2.0 (the "License");
141170  * you may not use this file except in compliance with the License.
141171  * You may obtain a copy of the License at
141172  *
141173  * http://www.apache.org/licenses/LICENSE-2.0
141174  *
141175  * Unless required by applicable law or agreed to in writing, software
141176  * distributed under the License is distributed on an "AS IS" BASIS,
141177  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141178  * See the License for the specific language governing permissions and
141179  * limitations under the License.
141180  */
141181 var constants = require('ripple/constants'),
141182     event = require('ripple/event');
141183
141184 module.exports = {
141185     "AccountInfo": {
141186         "phoneUserUniqueId": {
141187             "name": "User Unique Id",
141188             "control": {
141189                 "type": "text",
141190                 "value": new Date().getTime().toString()
141191             }
141192         },
141193         "phoneMSISDN":  {
141194             "name": "MSISDN",
141195             "control": {
141196                 "type": "text",
141197                 "value": "15199999999"
141198             }
141199         },
141200         "phoneOperatorName":  {
141201             "name": "Operator Name",
141202             "control": {
141203                 "type": "text",
141204                 "value": ""
141205             }
141206         },
141207         "userAccountBalance":  {
141208             "name": "Account Balance",
141209             "control": {
141210                 "type": "number",
141211                 "value": 0
141212             }
141213         },
141214         "userSubscriptionType":  {
141215             "name": "Subscription Type",
141216             "control": {
141217                 "type": "select",
141218                 "value": "other"
141219             },
141220             "options": {
141221                 "other": "other",
141222                 "prepaid": "prepaid",
141223                 "postpaid": "postpaid"
141224             }
141225         }
141226     },
141227     "RadioInfo": {
141228         "isRoaming": {
141229             "name": "Is Roaming",
141230             "control": {
141231                 "type": "checkbox",
141232                 "value": false
141233             },
141234             "callback": function () {
141235                 event.trigger("RadioSignalSourceChanged");
141236             }
141237         },
141238         "isRadioEnabled":  {
141239             "name": "Is Radio Enabled",
141240             "control": {
141241                 "type": "checkbox",
141242                 "value": true
141243             }
141244         },
141245         "radioSignalSource": {
141246             "name": "Radio Signal Source",
141247             "control": {
141248                 "type": "select",
141249                 "value": "GSM"
141250             },
141251             // TODO: try not to duplicate from RadioSignalSourceTypes
141252             "options": {
141253                 "CDMA": "cdma",
141254                 "GSM": "gsm",
141255                 "LTE": "lte",
141256                 "TDSCDMA": "tdscdma",
141257                 "WCDMA": "wcdma"
141258             },
141259             "callback": function () {
141260                 event.trigger("RadioSignalSourceChanged");
141261             }
141262         },
141263         "radioSignalStrengthPercent": {
141264             "name": "Signal Strength %",
141265             "control": {
141266                 "type": "select",
141267                 "value": 80
141268             },
141269             "options": (function () {
141270                 var i,
141271                     optionList = {};
141272
141273                 for (i = 0; i <= 100; i++) {
141274                     optionList[i] = i;
141275                 }
141276
141277                 return optionList;
141278             }())
141279         }
141280     },
141281     "Config": {
141282         "ringtoneVolume": {
141283             "name": "Ringtone Volume",
141284             "control": {
141285                 "type": "select",
141286                 "value": 10
141287             },
141288             "options": (function () {
141289                 var i,
141290                     optionList = {};
141291
141292                 for (i = 0; i <= 10; i++) {
141293                     optionList[i] = i;
141294                 }
141295
141296                 return optionList;
141297             }())
141298         },
141299         "msgRingtoneVolume":  {
141300             "name": "Msg Ringtone Volume",
141301             "control": {
141302                 "type": "select",
141303                 "value": 10
141304             },
141305             "options": (function () {
141306                 var i,
141307                     optionList = {};
141308
141309                 for (i = 0; i <= 10; i++) {
141310                     optionList[i] = i;
141311                 }
141312
141313                 return optionList;
141314             }())
141315         },
141316         "vibrationSetting":  {
141317             "name": "Vibration",
141318             "control": {
141319                 "type": "select",
141320                 "value": "off"
141321             },
141322             "options": {
141323                 "on": "ON",
141324                 "off": "OFF"
141325             }
141326         }
141327     },
141328     "Account": {
141329         "accountName":  {
141330             "name": "Name",
141331             "control": {
141332                 "type": "text",
141333                 "value": ""
141334             }
141335         },
141336         "accountId":  {
141337             "name": "Id",
141338             "control": {
141339                 "type": "text",
141340                 "value": ""
141341             }
141342         }
141343     },
141344     "DeviceInfo": {
141345         "totalMemory": {
141346             "name": "Total Memory",
141347             "control": {
141348                 "type": "range",
141349                 "value": 262144,
141350                 "min": 0,
141351                 "max": 4096000
141352             }
141353         },
141354         "phoneColorDepthDefault": {
141355             "name": "Color Depth",
141356             "control": {
141357                 "type": "number",
141358                 "value": 24
141359             }
141360         }
141361     },
141362     "DeviceStateInfo": {
141363         "availableMemory": {
141364             "name": "Available Memory",
141365             "control": {
141366                 "type": "range",
141367                 "value": 262144,
141368                 "min": 0,
141369                 "max": 4096000
141370             }
141371         },
141372         "keypadLightOn":   {
141373             "name": "Keypad Light On",
141374             "control": {
141375                 "type": "checkbox",
141376                 "value": false
141377             }
141378         },
141379         "backLightOn": {
141380             "name": "Back Light On",
141381             "control": {
141382                 "type": "checkbox",
141383                 "value": false
141384             }
141385         },
141386         "audioPath":  {
141387             "name": "Audio Path",
141388             "control": {
141389                 "type": "select",
141390                 "value": "receiver"
141391             },
141392             "options": {
141393                 "speaker": "speaker",
141394                 "receiver": "receiver",
141395                 "earphone": "earphone"
141396             }
141397         },
141398         "processorUtilizationPercent":  {
141399             "name": "CPU Utilization %",
141400             "control": {
141401                 "type": "select",
141402                 "value": "5"
141403             },
141404             "options": (function () {
141405                 var i,
141406                     optionList = {};
141407
141408                 for (i = 0; i <= 100; i++) {
141409                     optionList[i] = i;
141410                 }
141411
141412                 return optionList;
141413             }())
141414         },
141415         "language":  {
141416             "name": "Language",
141417             "control": {
141418                 "type": "select",
141419                 "value": "eng"
141420             },
141421             "options": (function () {
141422                 var i,
141423                     optionList = {},
141424                     iterator = constants.LANG.ISO6392_LIST;
141425
141426                 for (i = 0; i <= iterator.length; i++) {
141427                     optionList[iterator[i]] = iterator[i];
141428                 }
141429
141430                 return optionList;
141431             }())
141432         }
141433     },
141434     "DataNetworkInfo": {
141435         "isDataNetworkConnected": {
141436             "name": "Data Network Is Connected",
141437             "control": {
141438                 "type": "checkbox",
141439                 "value": true
141440             }
141441         },
141442         "networkConnectionType": {
141443             "name": "Network Connection Type",
141444             "control": {
141445                 "type": "select",
141446                 "value": ["GPRS"]
141447             },
141448             // TODO: try not to duplicate from DataNetworkConnectionTypes
141449             "options": {
141450                 "BLUETOOTH": "bluetooth",
141451                 "EDGE": "edge",
141452                 "EVDO": "evdo",
141453                 "GPRS": "gprs",
141454                 "IRDA": "irda",
141455                 "LTE": "lte",
141456                 "ONEXRTT": "1xrtt",
141457                 "WIFI": "wifi"
141458             },
141459             "callback": function (setting) {
141460                 event.trigger("DataNetworkConnectionChanged", [setting]);
141461             }
141462         }
141463     },
141464     "PowerInfo": {
141465         "isCharging": {
141466             "name": "Battery Is Charging",
141467             "control": {
141468                 "type": "checkbox",
141469                 "value": true
141470             },
141471             "callback": function (setting) {
141472                 event.trigger("DeviceBatteryStateChanged", [setting]);
141473             }
141474         },
141475         "percentRemaining":  {
141476             "name": "Battery Remaining %",
141477             "control": {
141478                 "type": "select",
141479                 "value": 100
141480             },
141481             "options": (function () {
141482                 var i,
141483                     optionList = {};
141484
141485                 for (i = 0; i <= 100; i++) {
141486                     optionList[i] = i;
141487                 }
141488
141489                 return optionList;
141490             }()),
141491             "callback": function (setting) {
141492                 event.trigger("DeviceBatteryLevelChanged", [setting]);
141493             }
141494         }
141495     }
141496 };
141497
141498 });
141499 define('ripple/platform/wac/1.0/spec/events', function (require, exports, module) {
141500 /*
141501  *  Copyright 2011 Research In Motion Limited.
141502  *
141503  * Licensed under the Apache License, Version 2.0 (the "License");
141504  * you may not use this file except in compliance with the License.
141505  * You may obtain a copy of the License at
141506  *
141507  * http://www.apache.org/licenses/LICENSE-2.0
141508  *
141509  * Unless required by applicable law or agreed to in writing, software
141510  * distributed under the License is distributed on an "AS IS" BASIS,
141511  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
141512  * implied.
141513  * See the License for the specific language governing permissions and
141514  * limitations under the License.
141515  */
141516
141517 var event = require('ripple/event');
141518
141519 module.exports = {
141520     "WidgetWakeup": {
141521         callback: function () {
141522             event.trigger("WidgetWakeup");
141523         }
141524     },
141525     "WidgetMaximize": {
141526         callback: function () {
141527             event.trigger("WidgetMaximize");
141528         }
141529     },
141530     "WidgetFocus": {
141531         callback: function () {
141532             event.trigger("WidgetFocus");
141533         }
141534     },
141535     "WidgetRestore": {
141536         callback: function () {
141537             event.trigger("WidgetRestore");
141538         }
141539     }
141540 };
141541
141542 });
141543 define('ripple/platform/wac/1.0/spec/ui', function (require, exports, module) {
141544 /*
141545  *  Copyright 2011 Research In Motion Limited.
141546  *
141547  * Licensed under the Apache License, Version 2.0 (the "License");
141548  * you may not use this file except in compliance with the License.
141549  * You may obtain a copy of the License at
141550  *
141551  * http://www.apache.org/licenses/LICENSE-2.0
141552  *
141553  * Unless required by applicable law or agreed to in writing, software
141554  * distributed under the License is distributed on an "AS IS" BASIS,
141555  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141556  * See the License for the specific language governing permissions and
141557  * limitations under the License.
141558  */
141559 module.exports = {
141560     plugins: [
141561         "accelerometer",
141562         //"deviceSettings",
141563         "fileSystem",
141564         "geoView",
141565 /*
141566         "multimedia",
141567         "audioPlayer",
141568         "telephony",
141569 */
141570         "platformEvents",
141571         "storage",
141572         "widgetConfig"
141573     ]
141574 };
141575
141576 });
141577 define('ripple/platform/wac/1.0/RadioInfo', function (require, exports, module) {
141578 /*
141579  *  Copyright 2011 Research In Motion Limited.
141580  *
141581  * Licensed under the Apache License, Version 2.0 (the "License");
141582  * you may not use this file except in compliance with the License.
141583  * You may obtain a copy of the License at
141584  *
141585  * http://www.apache.org/licenses/LICENSE-2.0
141586  *
141587  * Unless required by applicable law or agreed to in writing, software
141588  * distributed under the License is distributed on an "AS IS" BASIS,
141589  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141590  * See the License for the specific language governing permissions and
141591  * limitations under the License.
141592  */
141593 var _self,
141594     event = require('ripple/event'),
141595     _console = require('ripple/console'),
141596     deviceSettings = require('ripple/deviceSettings');
141597
141598 _self = {
141599     isRoaming: undefined,
141600     radioSignalStrengthPercent: undefined,
141601     isRadioEnabled: undefined,
141602     radioSignalSource: undefined,
141603     onSignalSourceChange: undefined
141604 };
141605
141606 event.on("RadioSignalSourceChanged", function () {
141607     var callback = _self.onSignalSourceChange,
141608         isRoaming = _self.isRoaming,
141609         signalSource = _self.radioSignalSource,
141610         msg = "Fired onSignalSourceChange. signalSource: " + signalSource + ", isRoaming: " + isRoaming;
141611
141612     if (callback && typeof callback === "function") {
141613         callback.apply(null, [signalSource, isRoaming]);
141614     }
141615     else {
141616         msg += " --> BUT there was no registered callback found.";
141617     }
141618
141619     _console.log(msg);
141620 });
141621
141622 _self.__defineGetter__("radioSignalSource", function () {
141623     return deviceSettings.retrieve("RadioInfo.radioSignalSource");
141624 });
141625
141626 _self.__defineGetter__("isRoaming", function () {
141627     return deviceSettings.retrieveAsBoolean("RadioInfo.isRoaming");
141628 });
141629
141630 _self.__defineGetter__("isRadioEnabled", function () {
141631     return deviceSettings.retrieveAsBoolean("RadioInfo.isRadioEnabled");
141632 });
141633
141634 _self.__defineGetter__("radioSignalStrengthPercent", function () {
141635     return deviceSettings.retrieveAsInt("RadioInfo.radioSignalStrengthPercent");
141636 });
141637
141638 module.exports = _self;
141639
141640 });
141641 define('ripple/platform/wac/1.0/EventRecurrenceTypes', function (require, exports, module) {
141642 /*
141643  *  Copyright 2011 Research In Motion Limited.
141644  *
141645  * Licensed under the Apache License, Version 2.0 (the "License");
141646  * you may not use this file except in compliance with the License.
141647  * You may obtain a copy of the License at
141648  *
141649  * http://www.apache.org/licenses/LICENSE-2.0
141650  *
141651  * Unless required by applicable law or agreed to in writing, software
141652  * distributed under the License is distributed on an "AS IS" BASIS,
141653  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141654  * See the License for the specific language governing permissions and
141655  * limitations under the License.
141656  */
141657 module.exports = {
141658     NOT_REPEAT: "NOT_REPEAT",
141659     DAILY: "DAILY",
141660     EVERY_WEEKDAY: "EVERY_WEEKDAY",
141661     WEEKLY_ON_DAY: "WEEKLY_ON_DAY",
141662     MONTHLY_ON_DAY: "MONTHLY_ON_DAY",
141663     MONTHLY_ON_DAY_COUNT: "MONTHLY_ON_DAY_COUNT",
141664     YEARLY: "YEARLY"
141665 };
141666
141667 });
141668 define('ripple/platform/wac/1.0/DataNetworkConnectionTypes', function (require, exports, module) {
141669 /*
141670  *  Copyright 2011 Research In Motion Limited.
141671  *
141672  * Licensed under the Apache License, Version 2.0 (the "License");
141673  * you may not use this file except in compliance with the License.
141674  * You may obtain a copy of the License at
141675  *
141676  * http://www.apache.org/licenses/LICENSE-2.0
141677  *
141678  * Unless required by applicable law or agreed to in writing, software
141679  * distributed under the License is distributed on an "AS IS" BASIS,
141680  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141681  * See the License for the specific language governing permissions and
141682  * limitations under the License.
141683  */
141684 var utils = require('ripple/utils'),
141685     _self = {
141686         "BLUETOOTH": undefined,
141687         "EDGE": undefined,
141688         "EVDO": undefined,
141689         "GPRS": undefined,
141690         "IRDA": undefined,
141691         "LTE": undefined,
141692         "ONEXRTT": undefined,
141693         "WIFI": undefined
141694     };
141695
141696 utils.forEach(_self, function (value, property) {
141697     _self.__defineGetter__(property, function () {
141698         return property;
141699     });
141700 });
141701
141702 module.exports = _self;
141703
141704 });
141705 define('ripple/platform/wac/1.0/Message', function (require, exports, module) {
141706 /*
141707  *  Copyright 2011 Research In Motion Limited.
141708  *
141709  * Licensed under the Apache License, Version 2.0 (the "License");
141710  * you may not use this file except in compliance with the License.
141711  * You may obtain a copy of the License at
141712  *
141713  * http://www.apache.org/licenses/LICENSE-2.0
141714  *
141715  * Unless required by applicable law or agreed to in writing, software
141716  * distributed under the License is distributed on an "AS IS" BASIS,
141717  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141718  * See the License for the specific language governing permissions and
141719  * limitations under the License.
141720  */
141721 var exception = require('ripple/exception'),
141722     Attachment = require('ripple/platform/wac/1.0/Attachment'),
141723     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
141724     Exception = require('ripple/platform/wac/1.0/Exception');
141725
141726 function _throwUnsupportedException(method) {
141727     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
141728 }
141729
141730 module.exports = function () {
141731     this.messageId = Math.uuid(undefined, 16);
141732     this.callbackNumber = undefined;
141733     this.destinationAddress = [];
141734     this.isRead = undefined;
141735     this.messagePriority = undefined;
141736     this.messageType = undefined;
141737     this.subject = undefined;
141738     this.body = undefined;
141739     this.sourceAddress = undefined;
141740     this.validityPeriodHours = undefined;
141741     this.time = undefined;
141742     this.ccAddress = [];
141743     this.bccAddress = [];
141744     this.attachments = [];
141745
141746     this.addAttachment = function (fileFullName) {
141747         var attachment = new Attachment();
141748         attachment.fileName = fileFullName;
141749         this.attachments.push(attachment);
141750     };
141751     this.deleteAttachment = function (attachment) {
141752
141753         for (var i = this.attachments.length - 1; i >= 0; i--) {
141754             if (this.attachments[i].fileName === attachment.fileName) {
141755                 this.attachments.splice(i, 1);
141756             }
141757         }
141758     };
141759     this.saveAttachment = function (fileFullName, attachment) {
141760         _throwUnsupportedException("Widget.Messaging.Message.addAddress");
141761     };
141762     this.addAddress = function (type, address) {
141763
141764         var addresses = address.split(";");
141765
141766         switch (type) {
141767         case "destination":
141768             this.destinationAddress = this.destinationAddress.concat(addresses);
141769             break;
141770         case "cc":
141771             this.ccAddress = this.ccAddress.concat(addresses);
141772             break;
141773         case "bcc":
141774             this.bccAddress = this.bccAddress.concat(addresses);
141775             break;
141776         }
141777     };
141778
141779     this.deleteAddress = function (type, address) {
141780         var addresses = address.split(";"),
141781             filter = function (orig) {
141782                 return orig.filter(function (address) {
141783                     return !addresses.some(function (x) {
141784                         return address === x;
141785                     });
141786                 });
141787             };
141788
141789         switch (type) {
141790         case "destination":
141791             this.destinationAddress = filter(this.destinationAddress);
141792             break;
141793         case "cc":
141794             this.ccAddress = filter(this.ccAddress);
141795             break;
141796         case "bcc":
141797             this.bccAddress = filter(this.bccAddress);
141798             break;
141799         }
141800     };
141801
141802 };
141803
141804 });
141805 define('ripple/platform/wac/1.0/Exception', function (require, exports, module) {
141806 /*
141807  *  Copyright 2011 Research In Motion Limited.
141808  *
141809  * Licensed under the Apache License, Version 2.0 (the "License");
141810  * you may not use this file except in compliance with the License.
141811  * You may obtain a copy of the License at
141812  *
141813  * http://www.apache.org/licenses/LICENSE-2.0
141814  *
141815  * Unless required by applicable law or agreed to in writing, software
141816  * distributed under the License is distributed on an "AS IS" BASIS,
141817  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141818  * See the License for the specific language governing permissions and
141819  * limitations under the License.
141820  */
141821 module.exports = function () {
141822     this.message = "";
141823     this.type =  "";
141824
141825     this.toString = function () {
141826         var result = this.type + ': "' + this.message + '"';
141827
141828         if (this.stack) {
141829             result += "\n" + this.stack;
141830         }
141831         return result;
141832     };
141833 };
141834
141835 });
141836 define('ripple/platform/wac/1.0/MessageQuantities', function (require, exports, module) {
141837 /*
141838  *  Copyright 2011 Research In Motion Limited.
141839  *
141840  * Licensed under the Apache License, Version 2.0 (the "License");
141841  * you may not use this file except in compliance with the License.
141842  * You may obtain a copy of the License at
141843  *
141844  * http://www.apache.org/licenses/LICENSE-2.0
141845  *
141846  * Unless required by applicable law or agreed to in writing, software
141847  * distributed under the License is distributed on an "AS IS" BASIS,
141848  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141849  * See the License for the specific language governing permissions and
141850  * limitations under the License.
141851  */
141852 module.exports = {
141853     totalMessageCnt: undefined,
141854     totalMessageReadCnt: undefined,
141855     totalMessageUnreadCnt: undefined
141856 };
141857
141858 });
141859 define('ripple/platform/wac/1.0/AccelerometerInfo', function (require, exports, module) {
141860 /*
141861  *  Copyright 2011 Research In Motion Limited.
141862  *
141863  * Licensed under the Apache License, Version 2.0 (the "License");
141864  * you may not use this file except in compliance with the License.
141865  * You may obtain a copy of the License at
141866  *
141867  * http://www.apache.org/licenses/LICENSE-2.0
141868  *
141869  * Unless required by applicable law or agreed to in writing, software
141870  * distributed under the License is distributed on an "AS IS" BASIS,
141871  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141872  * See the License for the specific language governing permissions and
141873  * limitations under the License.
141874  */
141875 var accelerometer = require('ripple/accelerometer'),
141876     _self = {};
141877
141878 _self.__defineGetter__("xAxis", function () {
141879     return accelerometer.getInfo().accelerationIncludingGravity.x;
141880 });
141881
141882 _self.__defineGetter__("yAxis", function () {
141883     return accelerometer.getInfo(true).accelerationIncludingGravity.y;
141884 });
141885
141886 _self.__defineGetter__("zAxis", function () {
141887     return accelerometer.getInfo(true).accelerationIncludingGravity.z;
141888 });
141889
141890 module.exports = _self;
141891
141892 });
141893 define('ripple/platform/wac/1.0/VideoPlayer', function (require, exports, module) {
141894 /*
141895  *  Copyright 2011 Research In Motion Limited.
141896  *
141897  * Licensed under the Apache License, Version 2.0 (the "License");
141898  * you may not use this file except in compliance with the License.
141899  * You may obtain a copy of the License at
141900  *
141901  * http://www.apache.org/licenses/LICENSE-2.0
141902  *
141903  * Unless required by applicable law or agreed to in writing, software
141904  * distributed under the License is distributed on an "AS IS" BASIS,
141905  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141906  * See the License for the specific language governing permissions and
141907  * limitations under the License.
141908  */
141909 var _self,
141910     _console = require('ripple/console'),
141911     event = require('ripple/event'),
141912     utils = require('ripple/utils'),
141913     fileSystem = require('ripple/fileSystem'),
141914     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
141915     Exception = require('ripple/platform/wac/1.0/Exception'),
141916     exception = require('ripple/exception'),
141917     _currentlySet,
141918     _currentVideoFile,
141919     _state = null,
141920     _loopCount, _video,
141921     _STATES = {
141922         "OPENED": "opened",
141923         "STOPPED": "stopped",
141924         "PAUSED": "paused",
141925         "PLAYING": "playing",
141926         "COMPLETED": "completed"
141927     };
141928
141929 function _validateVideoType(fileUrl) {
141930     var matched = fileUrl.match(/\.(\w*)$/),
141931         maps = {
141932             "ogv": "ogg",
141933             "flv": "mp4"
141934         },
141935         type = matched ? matched[1] : "";
141936
141937     if (_video && _video.canPlayType("video/" + (maps[type] || type)) === "") {
141938         _console.warn("Attempting to load a video that might not work in the current browser [" + fileUrl + "]");
141939     }
141940 }
141941
141942 function _validateAndSet(state, validStates, callbackBeforeSuccess) {
141943     var i, valid = false;
141944
141945     for (i = 0; i < validStates.length; i++) {
141946         if (validStates[i] === _state) {
141947             valid = true;
141948         }
141949     }
141950
141951     if (!valid) {
141952         _console.warn("Attempted to initiate VideoPlayer." + state +
141953             " in invalid state. current state: " + _state);
141954     } else {
141955         if (typeof(callbackBeforeSuccess) === "function") {
141956             callbackBeforeSuccess.apply();
141957         }
141958         event.trigger("MultimediaVideoStateChanged", [state], true);
141959     }
141960
141961     return valid;
141962 }
141963
141964 event.on("MultimediaVideoStateChanged", function (state) {
141965     _state = state;
141966     if (typeof _self.onStateChange === "function") {
141967         _self.onStateChange.apply(_self, [state]);
141968     }
141969 });
141970
141971 _self = module.exports = {
141972     onStateChange: undefined,
141973
141974     open: function (fileUrl) {
141975         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER,
141976            "VideoPlayer.open invalid number of arguments", new Exception());
141977         utils.validateArgumentType(fileUrl, "string", ExceptionTypes.INVALID_PARAMETER,
141978            "VideoPlayer.open expected valid fileUrl but got ->" + fileUrl, new Exception());
141979
141980         if (!_video) {
141981             return;
141982         }
141983
141984         _validateAndSet(_STATES.OPENED, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED, null], function () {
141985             _validateVideoType(fileUrl);
141986             _currentVideoFile = fileSystem.getURI(fileUrl);
141987             _video.setAttribute("src", _currentVideoFile);
141988             _video.setAttribute("width", "100%");
141989             _video.addEventListener("ended", function () {
141990                 event.trigger("MultimediaVideoStateChanged", [_STATES.COMPLETED], true);
141991                 if (_loopCount > 1) {
141992                     _self.open(_currentVideoFile);
141993                     _self.play(_loopCount--);
141994                 }
141995             }, false);
141996         });
141997     },
141998
141999     setWindow: function (domObject) {
142000         utils.validateNumberOfArguments(0, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER,
142001            "VideoPlayer.setWindow invalid number of arguments", new Exception());
142002
142003         if (_currentlySet) {
142004             _currentlySet.removeChild(_video);
142005             _currentlySet = null;
142006             _video = null;
142007         }
142008
142009         if (domObject !== null) {
142010             _video = utils.createElement("video", {
142011                 "id": "multimedia-video"
142012             });
142013             domObject.appendChild(_video);
142014             _currentlySet = domObject;
142015             event.trigger("MultimediaAppVideoPlayerCreated", [_video], true);
142016         }
142017     },
142018
142019     play: function (repeatTimes) {
142020         utils.validateNumberOfArguments(1, 1, arguments.length,
142021             ExceptionTypes.INVALID_PARAMETER, "invalid number of arguments (expected one)", new Exception());
142022
142023         if (typeof repeatTimes !== "number" || repeatTimes < 0) {
142024             exception.raise(ExceptionTypes.INVALID_PARAMETER, "VideoPlayer.play was passed an invalid number of play times: " + repeatTimes, new Exception());
142025         }
142026         if (repeatTimes !== 0) {
142027             if (!_video) {
142028                 return;
142029             }
142030             _loopCount = repeatTimes;
142031             _validateAndSet(_STATES.PLAYING, [_STATES.OPENED, _STATES.STOPPED, _STATES.COMPLETED], function () {
142032                 _video.play();
142033             });
142034         }
142035     },
142036
142037     pause: function () {
142038         if (!_video) {
142039             return;
142040         }
142041         _validateAndSet(_STATES.PAUSED, [_STATES.PLAYING], function () {
142042             _video.pause();
142043         });
142044     },
142045
142046     resume: function () {
142047         if (!_video) {
142048             return;
142049         }
142050         _validateAndSet(_STATES.PLAYING, [_STATES.PAUSED], function () {
142051             _video.play();
142052         });
142053     },
142054
142055     stop: function () {
142056         if (!_video) {
142057             return;
142058         }
142059         _validateAndSet(_STATES.STOPPED, [_STATES.PAUSED, _STATES.PLAYING], function () {
142060             _video.pause();
142061             _video.setAttribute("src", _currentVideoFile); // hack
142062         });
142063     }
142064
142065 };
142066
142067 });
142068 define('ripple/platform/wac/1.0/CallRecord', function (require, exports, module) {
142069 /*
142070  *  Copyright 2011 Research In Motion Limited.
142071  *
142072  * Licensed under the Apache License, Version 2.0 (the "License");
142073  * you may not use this file except in compliance with the License.
142074  * You may obtain a copy of the License at
142075  *
142076  * http://www.apache.org/licenses/LICENSE-2.0
142077  *
142078  * Unless required by applicable law or agreed to in writing, software
142079  * distributed under the License is distributed on an "AS IS" BASIS,
142080  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142081  * See the License for the specific language governing permissions and
142082  * limitations under the License.
142083  */
142084 module.exports = function () {
142085     this.callRecordType = undefined;
142086     this.callRecordId = undefined;
142087     this.callRecordAddress = undefined;
142088     this.callRecordName = undefined;
142089     this.durationSeconds = undefined;
142090     this.startTime = undefined;
142091 };
142092
142093 });
142094 define('ripple/platform/wac/1.0/Widget', function (require, exports, module) {
142095 /*
142096  *  Copyright 2011 Research In Motion Limited.
142097  *
142098  * Licensed under the Apache License, Version 2.0 (the "License");
142099  * you may not use this file except in compliance with the License.
142100  * You may obtain a copy of the License at
142101  *
142102  * http://www.apache.org/licenses/LICENSE-2.0
142103  *
142104  * Unless required by applicable law or agreed to in writing, software
142105  * distributed under the License is distributed on an "AS IS" BASIS,
142106  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142107  * See the License for the specific language governing permissions and
142108  * limitations under the License.
142109  */
142110 var event = require('ripple/event'),
142111     _console = require('ripple/console'),
142112     app = require('ripple/app'),
142113     platform = require('ripple/platform'),
142114     exception = require('ripple/exception'),
142115     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
142116     Exception = require('ripple/platform/wac/1.0/Exception'),
142117     utils = require('ripple/utils'),
142118     db = require('ripple/db'),
142119     _self;
142120
142121 event.on("ScreenChangeDimensions", function (height, width) {
142122     try {
142123         // TODO: are these per spec to call?
142124         if (typeof app.onMaximize === 'function') {
142125             app.onMaximize();
142126         }
142127         if (typeof app.onRestore === 'function') {
142128             app.onRestore();
142129         }
142130         _console.log("called Widget.onRestore and Widget.onMaximize callback function");
142131     }
142132     catch (e) {
142133         exception.handle(e, false);
142134     }
142135 });
142136
142137 event.on("WidgetWakeup", function () {
142138     if (_self.onWakeup) {
142139         _self.onWakeup();
142140     }
142141 });
142142
142143 event.on("WidgetMaximize", function () {
142144     if (_self.onMaximize) {
142145         _self.onMaximize();
142146     }
142147 });
142148
142149 event.on("WidgetFocus", function () {
142150     if (_self.onFocus) {
142151         _self.onFocus();
142152     }
142153 });
142154
142155 event.on("WidgetRestore", function () {
142156     if (_self.onRestore) {
142157         _self.onRestore();
142158     }
142159 });
142160
142161 _self = {
142162     onWakeup: undefined,
142163     onMaximize: undefined,
142164     onFocus: undefined,
142165     onRestore: undefined,
142166
142167     openURL: function (url) {
142168         window.open(url);
142169     },
142170
142171     setPreferenceForKey: function (value, key) {
142172
142173         utils.validateNumberOfArguments(1, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "setPreferenceForKey invalid number of paramters", new Exception());
142174         utils.validateArgumentType(key, "string", ExceptionTypes.INVALID_PARAMETER, "setPreferenceForKey invalid parameter! Key:" +
142175             key + ", Value: " + value, new Exception());
142176
142177         var msg = "",
142178             prefix;
142179         if (app.isPreferenceReadOnly(key)) {
142180             msg += "Cannot modify a read only preference. Preference key: " + key;
142181         }
142182         else {
142183             prefix = platform.getPersistencePrefix();
142184             if (value === null) {
142185                 msg += "deleting preference " + key;
142186                 db.remove(key, prefix);
142187             }
142188             else {
142189                 msg += "setting preference " + key + " == " + value;
142190                 utils.validateArgumentType(value, "string", ExceptionTypes.INVALID_PARAMETER, msg, new Exception());
142191                 db.save(key, value, prefix);
142192             }
142193         }
142194
142195
142196         _console.log(msg);
142197
142198         // Trigger storageUpdatedEvent
142199         event.trigger("StorageUpdatedEvent");
142200
142201     },
142202
142203     // return value or undefined
142204     preferenceForKey: function (key) {
142205
142206         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "preferenceForKey invalid number of parameters", new Exception());
142207         utils.validateArgumentType(key, "string", ExceptionTypes.INVALID_PARAMETER, "preferenceForKey invalid paramters", new Exception());
142208
142209         var prefix = platform.getPersistencePrefix(),
142210             value = db.retrieve(key, prefix);
142211
142212         if (!value && value !== "") {
142213             value = undefined;
142214         }
142215
142216         _console.log("retrieving preference " + key + " == " + value);
142217
142218         return value;
142219
142220     }
142221 };
142222
142223 module.exports = _self;
142224
142225 });
142226 define('ripple/platform/wac/1.0/DeviceInfo', function (require, exports, module) {
142227 /*
142228  *  Copyright 2011 Research In Motion Limited.
142229  *
142230  * Licensed under the Apache License, Version 2.0 (the "License");
142231  * you may not use this file except in compliance with the License.
142232  * You may obtain a copy of the License at
142233  *
142234  * http://www.apache.org/licenses/LICENSE-2.0
142235  *
142236  * Unless required by applicable law or agreed to in writing, software
142237  * distributed under the License is distributed on an "AS IS" BASIS,
142238  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142239  * See the License for the specific language governing permissions and
142240  * limitations under the License.
142241  */
142242 var utils = require('ripple/utils'),
142243     deviceSettings = require('ripple/deviceSettings'),
142244     platform = require('ripple/platform'),
142245     devices = require('ripple/devices'),
142246     _self;
142247
142248 _self = {
142249     ownerInfo: undefined, // return AddressBookItem
142250     phoneColorDepthDefault: undefined,
142251     phoneFirmware: undefined,
142252     phoneManufacturer: undefined,
142253     phoneModel: undefined,
142254     phoneOS: undefined,
142255     phoneSoftware: undefined,
142256     phoneScreenHeightDefault: undefined,
142257     phoneScreenWidthDefault: undefined,
142258     totalMemory: undefined
142259 };
142260
142261 function _getDeviceAttribute(attr) {
142262     var devicePointer = devices.getCurrentDevice();
142263     utils.forEach(attr.split("."), function (dot) {
142264         devicePointer = devicePointer[dot];
142265     });
142266     return devicePointer;
142267 }
142268
142269 _self.__defineGetter__("phoneColorDepthDefault", function () {
142270     return deviceSettings.retrieveAsInt("DeviceInfo.phoneColorDepthDefault");
142271 });
142272
142273 _self.__defineGetter__("phoneFirmware", function () {
142274     return _getDeviceAttribute("firmware");
142275 });
142276
142277 _self.__defineGetter__("phoneManufacturer", function () {
142278     return _getDeviceAttribute("manufacturer");
142279 });
142280
142281 _self.__defineGetter__("phoneOS", function () {
142282     return _getDeviceAttribute("osName") + " " + _getDeviceAttribute("osVersion");
142283 });
142284
142285 _self.__defineGetter__("phoneModel", function () {
142286     return _getDeviceAttribute("model");
142287 });
142288
142289 _self.__defineGetter__("phoneSoftware", function () {
142290     return _getDeviceAttribute("osVersion");
142291 });
142292
142293 _self.__defineGetter__("phoneScreenHeightDefault", function () {
142294     return _getDeviceAttribute("screen.height");
142295 });
142296
142297 _self.__defineGetter__("phoneScreenWidthDefault", function () {
142298     return _getDeviceAttribute("screen.width");
142299 });
142300
142301 _self.__defineGetter__("totalMemory", function () {
142302     return deviceSettings.retrieveAsInt("DeviceInfo.totalMemory");
142303 });
142304
142305 module.exports = _self;
142306
142307 });
142308 define('ripple/platform/wac/1.0/Camera', function (require, exports, module) {
142309 /*
142310  *  Copyright 2011 Research In Motion Limited.
142311  *
142312  * Licensed under the Apache License, Version 2.0 (the "License");
142313  * you may not use this file except in compliance with the License.
142314  * You may obtain a copy of the License at
142315  *
142316  * http://www.apache.org/licenses/LICENSE-2.0
142317  *
142318  * Unless required by applicable law or agreed to in writing, software
142319  * distributed under the License is distributed on an "AS IS" BASIS,
142320  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142321  * See the License for the specific language governing permissions and
142322  * limitations under the License.
142323  */
142324 var exception = require('ripple/exception'),
142325     Exception = require('ripple/platform/wac/1.0/Exception'),
142326     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
142327     constants = require('ripple/constants'),
142328     _console = require('ripple/console'),
142329     utils = require('ripple/utils'),
142330     notifications = require('ripple/notifications'),
142331     _currentlySet,
142332     _img,
142333     _buttons,
142334     _self,
142335     _videoCapture;
142336
142337
142338 function _populateWindow(domObject) {
142339     var record = document.createElement("button"),
142340         pause = document.createElement("button"),
142341         stop = document.createElement("button");
142342
142343     _img = document.createElement("img");
142344     _img.setAttribute("id", "jil-camera-window");
142345     //_img.setAttribute("src", document.querySelector("#extension-url").innerHTML + constants.CAMERA.WINDOW_ANIMATION);
142346     _img.setAttribute("src", document.documentURI.replace(/index\.html$/, "") + constants.CAMERA.WINDOW_ANIMATION);
142347     _img.setAttribute("width", "100%");
142348     _currentlySet = domObject;
142349     domObject.appendChild(_img);
142350
142351     _buttons = document.createElement("div");
142352     _buttons.setAttribute("id", "jil-camera-window-buttons");
142353     _buttons.setAttribute("style", "display: none");
142354
142355     record.setAttribute("id", "jil-camera-window-buttons-record");
142356     record.innerHTML = "Record";
142357     pause.setAttribute("id", "jil-camera-window-buttons-pause");
142358     pause.innerHTML = "Pause";
142359     stop.setAttribute("id", "jil-camera-window-buttons-stop");
142360     stop.innerHTML = "Stop";
142361     stop.addEventListener("click", _self.stopVideoCapture);
142362
142363     _buttons.appendChild(record);
142364     _buttons.appendChild(pause);
142365     _buttons.appendChild(stop);
142366
142367     domObject.appendChild(_buttons);
142368
142369 }
142370
142371 function _verifySetWindow(method) {
142372     if (!_img) {
142373         exception.raise(ExceptionTypes.UNKNOWN, "Camera." +
142374           method + " was (most likely) called before using the setWindow method.", new Exception());
142375     }
142376 }
142377
142378 _self = {
142379     onCameraCaptured: undefined, //function (fileName) { }
142380
142381     captureImage: function (fileName, lowRes) {
142382         utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "captureImage invalid number of parameters", new Exception());
142383         utils.validateMultipleArgumentTypes([fileName, lowRes], ['string', 'boolean'], ExceptionTypes.INVALID_PARAMETER, "invalid parameter type", new Exception());
142384
142385         _verifySetWindow("captureImage");
142386         var msg = constants.CAMERA.WARNING_TEXT;
142387         msg = msg.replace("{file}", fileName);
142388         notifications.openNotification("normal", msg);
142389         _console.log("simulated saved image as: " + fileName);
142390         if (_self.onCameraCaptured) {
142391             _self.onCameraCaptured.apply(_self, [fileName]);
142392         }
142393
142394         return fileName;
142395     },
142396     setWindow: function (domObject) {
142397
142398         if (_currentlySet) {
142399             _currentlySet.removeChild(_img);
142400             _currentlySet.removeChild(_buttons);
142401             _currentlySet = null;
142402             _img = null;
142403             _buttons = null;
142404         }
142405         if (domObject !== null) {
142406             _populateWindow(domObject);
142407         }
142408     },
142409     startVideoCapture: function (fileName, lowRes, maxDurationSeconds, showDefaultControls) {
142410         _verifySetWindow("startVideoCapture");
142411         utils.validateNumberOfArguments(1, 4, arguments.length, ExceptionTypes.INVALID_PARAMETER, "startVideoCapture invalid number of parameters", new Exception());
142412         utils.validateMultipleArgumentTypes(
142413             [fileName, lowRes, maxDurationSeconds, showDefaultControls],
142414             ['string', 'boolean', 'integer', 'boolean'],
142415             ExceptionTypes.INVALID_PARAMETER,
142416             "invalid parameter type", new Exception());
142417         _console.log("started recording video");
142418         var interval = window.setTimeout(function () {
142419             _self.stopVideoCapture();
142420         }, maxDurationSeconds * 1000);
142421
142422         if (showDefaultControls) {
142423             _buttons.removeAttribute("style");
142424         }
142425
142426         _videoCapture = {
142427             fileName: fileName,
142428             stop: function () {
142429                 window.clearInterval(interval);
142430                 var msg = constants.CAMERA.WARNING_TEXT;
142431                 msg = msg.replace("{file}", fileName);
142432                 notifications.openNotification("normal", msg);
142433                 if (_self.onCameraCaptured) {
142434                     _self.onCameraCaptured.apply(_self, [fileName]);
142435                 }
142436             }
142437         };
142438
142439         return fileName;
142440     },
142441     stopVideoCapture: function () {
142442         utils.validateNumberOfArguments(0, 0, arguments.length, ExceptionTypes.INVALID_PARAMETER, "stopVideoCapture invalid number of parameters", new Exception());
142443         if (_videoCapture) {
142444             _console.log("simulated saving a video as: " + _videoCapture.fileName);
142445             if (_buttons) {
142446                 _buttons.setAttribute("style", "display: none");
142447             }
142448             _videoCapture.stop();
142449             _videoCapture = null;
142450         }
142451     }
142452
142453 };
142454
142455 module.exports = _self;
142456
142457 });
142458 define('ripple/platform/wac/1.0/RadioSignalSourceTypes', function (require, exports, module) {
142459 /*
142460  *  Copyright 2011 Research In Motion Limited.
142461  *
142462  * Licensed under the Apache License, Version 2.0 (the "License");
142463  * you may not use this file except in compliance with the License.
142464  * You may obtain a copy of the License at
142465  *
142466  * http://www.apache.org/licenses/LICENSE-2.0
142467  *
142468  * Unless required by applicable law or agreed to in writing, software
142469  * distributed under the License is distributed on an "AS IS" BASIS,
142470  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142471  * See the License for the specific language governing permissions and
142472  * limitations under the License.
142473  */
142474 var _self,
142475     utils = require('ripple/utils');
142476
142477 _self = {
142478     "CDMA": undefined,
142479     "GSM": undefined,
142480     "LTE": undefined,
142481     "TDSCDMA": undefined,
142482     "WCDMA": undefined
142483 };
142484
142485 utils.forEach(_self, function (value, property) {
142486     _self.__defineGetter__(property, function () {
142487         return property;
142488     });
142489 });
142490
142491 module.exports = _self;
142492
142493 });
142494 define('ripple/platform/wac/1.0/File', function (require, exports, module) {
142495 /*
142496  *  Copyright 2011 Research In Motion Limited.
142497  *
142498  * Licensed under the Apache License, Version 2.0 (the "License");
142499  * you may not use this file except in compliance with the License.
142500  * You may obtain a copy of the License at
142501  *
142502  * http://www.apache.org/licenses/LICENSE-2.0
142503  *
142504  * Unless required by applicable law or agreed to in writing, software
142505  * distributed under the License is distributed on an "AS IS" BASIS,
142506  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142507  * See the License for the specific language governing permissions and
142508  * limitations under the License.
142509  */
142510 module.expots = function () {
142511     this.createDate = undefined;
142512     this.fileName = undefined;
142513     this.filePath = undefined;
142514     this.fileSize = undefined;
142515     this.isDirectory = undefined;
142516     this.lastModifyDate = undefined;
142517 };
142518
142519 });
142520 define('ripple/platform/wac/1.0/AddressBookItem', function (require, exports, module) {
142521 /*
142522  *  Copyright 2011 Research In Motion Limited.
142523  *
142524  * Licensed under the Apache License, Version 2.0 (the "License");
142525  * you may not use this file except in compliance with the License.
142526  * You may obtain a copy of the License at
142527  *
142528  * http://www.apache.org/licenses/LICENSE-2.0
142529  *
142530  * Unless required by applicable law or agreed to in writing, software
142531  * distributed under the License is distributed on an "AS IS" BASIS,
142532  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142533  * See the License for the specific language governing permissions and
142534  * limitations under the License.
142535  */
142536 var utils = require('ripple/utils'),
142537     exception = require('ripple/exception'),
142538     db = require('ripple/db'),
142539     constants = require('ripple/constants'),
142540     Exception = require('ripple/platform/wac/1.0/Exception'),
142541     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
142542
142543 function _validateArgs(min, max, len) {
142544     utils.validateNumberOfArguments(min, max, len,
142545         ExceptionTypes.INVALID_PARAMETER, "invalid number of parameters", new Exception());
142546 }
142547
142548 function _validateType(arg, argType) {
142549     utils.validateArgumentType(arg, argType,
142550         ExceptionTypes.INVALID_PARAMETER,  "argument of wrong type provided",
142551         new Exception());
142552 }
142553
142554 module.exports = function () {
142555     function _throwUnsupportedException(method) {
142556         exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
142557     }
142558
142559     this.addressBookItemId = undefined;
142560     this.fullName = undefined;
142561     this.mobilePhone = undefined;
142562     this.homePhone = undefined;
142563     this.workPhone = undefined;
142564     this.eMail = undefined;
142565     this.company = undefined;
142566     this.title = undefined;
142567     this.address = undefined;
142568
142569     this.setAttributeValue = function (attribute, value) {
142570         _validateArgs(2, 2, arguments.length);
142571         _validateType(attribute, "string");
142572         this[attribute] = value;
142573     };
142574     this.setAddressGroupNames = function (groups) {
142575         _throwUnsupportedException("PIM.AddressBookItem.setAddressGroupNames");
142576     };
142577     this.getAttributeValue = function (attribute) {
142578         _validateArgs(1, 1, arguments.length);
142579         _validateType(attribute, "string");
142580         return this[attribute];
142581     };
142582     this.getAddressGroupNames = function () {
142583         _throwUnsupportedException("PIM.AddressBookItem.getAddressGroupNames");
142584     };
142585     this.getAvailableAttributes = function () {
142586         return utils.reduce(this, function (attributes, value, key) {
142587             if (typeof(value) !== 'function') {
142588                 attributes.push(key);
142589             }
142590             return attributes;
142591         }, []).sort();
142592     };
142593     this.update = function () {
142594         var items = db.retrieveObject(constants.PIM.ADDRESS_LIST_KEY),
142595             that = this,
142596             itemIndex = items.reduce(function (current, value, i) {
142597                 return value.addressBookItemId === that.addressBookItemId ?
142598                     i : current;
142599             }, -1);
142600
142601         if (itemIndex >= 0) {
142602             items[itemIndex] = this;
142603             db.saveObject(constants.PIM.ADDRESS_LIST_KEY, items);
142604         }
142605         else {
142606             exception.raise(ExceptionTypes.INVALID_PARAMETER, "Address Book Item not found: " + (this.addressBookItemId || ""), new Exception());
142607         }
142608
142609     };
142610 };
142611
142612 });
142613 define('ripple/platform/wac/1.0/DeviceStateInfo', function (require, exports, module) {
142614 /*
142615  *  Copyright 2011 Research In Motion Limited.
142616  *
142617  * Licensed under the Apache License, Version 2.0 (the "License");
142618  * you may not use this file except in compliance with the License.
142619  * You may obtain a copy of the License at
142620  *
142621  * http://www.apache.org/licenses/LICENSE-2.0
142622  *
142623  * Unless required by applicable law or agreed to in writing, software
142624  * distributed under the License is distributed on an "AS IS" BASIS,
142625  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142626  * See the License for the specific language governing permissions and
142627  * limitations under the License.
142628  */
142629 var utils = require('ripple/utils'),
142630     exception = require('ripple/exception'),
142631     _console = require('ripple/console'),
142632     geo = require('ripple/geo'),
142633     event = require('ripple/event'),
142634     deviceSettings = require('ripple/deviceSettings'),
142635     PositionInfo = require('ripple/platform/wac/1.0/PositionInfo'),
142636     Exception = require('ripple/platform/wac/1.0/Exception'),
142637     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
142638     _self;
142639
142640 event.on("ScreenChangeDimensions", function (width, height) {
142641     try {
142642         if (typeof _self.onScreenChangeDimensions === 'function') {
142643             _self.onScreenChangeDimensions(width, height);
142644         }
142645         _console.log("called DeviceStateInfo.onScreenChangeDimensions callback function with width = " + width + " and height = " + height);
142646     } catch (e) {
142647         exception.handle(e, false);
142648     }
142649 });
142650
142651 _self = {
142652     availableMemory: undefined,
142653     language: undefined,
142654     keypadLightOn: undefined,
142655     backLightOn: undefined,
142656     processorUtilizationPercent: undefined,
142657     audioPath: undefined,
142658
142659     onPositionRetrieved: undefined,
142660
142661     requestPositionInfo: function (method) {
142662         utils.validateNumberOfArguments(1, 1, arguments.length,
142663             ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid number of parameters", new Exception());
142664         utils.validateArgumentType(method, "string",
142665             ExceptionTypes.INVALID_PARAMETER, "requestPositionInfo invalid parameter", new Exception());
142666
142667         if (!(method.match(/gps|agps|cellid/))) {
142668             exception.raise(ExceptionTypes.INVALID_PARAMETER,
142669                     "Invalid method, expected (gps, agps or cellid)", Exception);
142670         }
142671
142672         if (typeof _self.onPositionRetrieved === "function") {
142673             var delay = geo.delay * 1000,
142674                 timeout = geo.timeout;
142675             setTimeout(function () {
142676                 var pos = PositionInfo,
142677                     errorObj = {};
142678
142679                 if (timeout) {
142680                     //create
142681                     utils.forEach(pos, function (val, key) {
142682                         errorObj[key] = undefined;
142683                     });
142684                     pos = errorObj;
142685                 }
142686                 _self.onPositionRetrieved(pos, method);
142687             }, delay);
142688         }
142689     },
142690
142691     onScreenChangeDimensions: undefined,
142692
142693     onFlipEvent: undefined
142694 };
142695
142696 _self.__defineGetter__("availableMemory", function () {
142697     return deviceSettings.retrieveAsInt("DeviceStateInfo.availableMemory");
142698 });
142699
142700 _self.__defineGetter__("language", function () {
142701     return deviceSettings.retrieve("DeviceStateInfo.language");
142702 });
142703
142704 _self.__defineGetter__("keypadLightOn", function () {
142705     return deviceSettings.retrieveAsBoolean("DeviceStateInfo.keypadLightOn");
142706 });
142707
142708 _self.__defineGetter__("backLightOn", function () {
142709     return deviceSettings.retrieveAsBoolean("DeviceStateInfo.backLightOn");
142710 });
142711
142712 _self.__defineGetter__("audioPath", function () {
142713     return deviceSettings.retrieve("DeviceStateInfo.audioPath");
142714 });
142715
142716 _self.__defineGetter__("processorUtilizationPercent", function () {
142717     return deviceSettings.retrieve("DeviceStateInfo.processorUtilizationPercent");
142718 });
142719
142720 module.exports = _self;
142721
142722
142723 });
142724 define('ripple/platform/wac/1.0/Attachment', function (require, exports, module) {
142725 /*
142726  *  Copyright 2011 Research In Motion Limited.
142727  *
142728  * Licensed under the Apache License, Version 2.0 (the "License");
142729  * you may not use this file except in compliance with the License.
142730  * You may obtain a copy of the License at
142731  *
142732  * http://www.apache.org/licenses/LICENSE-2.0
142733  *
142734  * Unless required by applicable law or agreed to in writing, software
142735  * distributed under the License is distributed on an "AS IS" BASIS,
142736  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142737  * See the License for the specific language governing permissions and
142738  * limitations under the License.
142739  */
142740 module.exports = function () {
142741     this.fileName = "";
142742     this.MIMEType = "";
142743     this.size = 0;
142744 };
142745
142746 });
142747 define('ripple/platform/wac/1.0/Multimedia', function (require, exports, module) {
142748 /*
142749  *  Copyright 2011 Research In Motion Limited.
142750  *
142751  * Licensed under the Apache License, Version 2.0 (the "License");
142752  * you may not use this file except in compliance with the License.
142753  * You may obtain a copy of the License at
142754  *
142755  * http://www.apache.org/licenses/LICENSE-2.0
142756  *
142757  * Unless required by applicable law or agreed to in writing, software
142758  * distributed under the License is distributed on an "AS IS" BASIS,
142759  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142760  * See the License for the specific language governing permissions and
142761  * limitations under the License.
142762  */
142763 var event = require('ripple/event'),
142764     VideoPlayer = require('ripple/platform/wac/1.0/VideoPlayer'),
142765     AudioPlayer = require('ripple/platform/wac/1.0/AudioPlayer'),
142766     constants = require('ripple/constants'),
142767     _volume = 5,
142768     _audioState,
142769     _videoState,
142770     _self;
142771
142772 event.on("MultimediaVolumeChanged", function updateVolume(volume) {
142773     _volume = volume;
142774 });
142775
142776 event.on("MultimediaAudioStateChanged", function updateAudioState(state) {
142777     _audioState = state;
142778 });
142779
142780 event.on("MultimediaVideoStateChanged", function updateVideoState(state) {
142781     _videoState = state;
142782 });
142783
142784 _self = {
142785
142786     isAudioPlaying: undefined,
142787     isVideoPlaying: undefined,
142788
142789     getVolume: function () {
142790         return _volume;
142791     },
142792
142793     stopAll: function () {
142794         VideoPlayer.stop();
142795         AudioPlayer.stop();
142796     }
142797 };
142798
142799 _self.__defineGetter__("isAudioPlaying", function () {
142800     return _audioState === constants.MULTIMEDIA.AUDIO_STATES.PLAYING;
142801 });
142802
142803 _self.__defineGetter__("isVideoPlaying", function () {
142804     return _videoState === "playing";
142805 });
142806
142807 module.exports = _self;
142808
142809 });
142810 define('ripple/platform/wac/1.0/CalendarItem', function (require, exports, module) {
142811 /*
142812  *  Copyright 2011 Research In Motion Limited.
142813  *
142814  * Licensed under the Apache License, Version 2.0 (the "License");
142815  * you may not use this file except in compliance with the License.
142816  * You may obtain a copy of the License at
142817  *
142818  * http://www.apache.org/licenses/LICENSE-2.0
142819  *
142820  * Unless required by applicable law or agreed to in writing, software
142821  * distributed under the License is distributed on an "AS IS" BASIS,
142822  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142823  * See the License for the specific language governing permissions and
142824  * limitations under the License.
142825  */
142826 var constants = require('ripple/constants'),
142827     db = require('ripple/db'),
142828     exception = require('ripple/exception'),
142829     Exception = require('ripple/platform/wac/1.0/Exception'),
142830     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
142831
142832 module.exports = function () {
142833     this.calendarItemId = undefined;
142834     this.alarmDate = undefined;
142835     this.eventStartTime = undefined;
142836     this.eventEndTime = undefined;
142837     this.eventName = undefined;
142838     this.eventNotes = undefined;
142839     this.alarmed = undefined;
142840
142841     this.update = function () {
142842         var events = db.retrieveObject(constants.PIM.CALENDAR_LIST_KEY) || [],
142843             that = this,
142844             eventIndex = events.reduce(function (match, value, i) {
142845                 return value.calendarItemId === that.calendarItemId ?
142846                     i : match;
142847             }, -1);
142848
142849
142850         if (eventIndex >= 0) {
142851             events[eventIndex] = this;
142852             db.saveObject(constants.PIM.CALENDAR_LIST_KEY, events);
142853         }
142854         else {
142855             exception.raise(ExceptionTypes.INVALID_PARAMETER, "Calendar Item not found: " + (this.calendarItemId || ""), new Exception());
142856         }
142857     };
142858 };
142859
142860 });
142861 define('ripple/platform/wac/1.0/Config', function (require, exports, module) {
142862 /*
142863  *  Copyright 2011 Research In Motion Limited.
142864  *
142865  * Licensed under the Apache License, Version 2.0 (the "License");
142866  * you may not use this file except in compliance with the License.
142867  * You may obtain a copy of the License at
142868  *
142869  * http://www.apache.org/licenses/LICENSE-2.0
142870  *
142871  * Unless required by applicable law or agreed to in writing, software
142872  * distributed under the License is distributed on an "AS IS" BASIS,
142873  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142874  * See the License for the specific language governing permissions and
142875  * limitations under the License.
142876  */
142877 var utils = require('ripple/utils'),
142878     notifications = require('ripple/notifications'),
142879     constants = require('ripple/constants'),
142880     deviceSettings = require('ripple/deviceSettings'),
142881     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
142882     Exception = require('ripple/platform/wac/1.0/Exception'),
142883     _self = {
142884         ringtoneVolume: undefined,
142885         msgRingtoneVolume: undefined,
142886         vibrationSetting: undefined,
142887
142888         setDefaultRingtone: function (ringtoneUrl) {
142889             utils.validateArgumentType(ringtoneUrl, "string", ExceptionTypes.INVALID_PARAMETER, "ringtoneUrl paramter is not a string", new Exception());
142890             notifications.openNotification("normal", "Setting default ringtone to: " + ringtoneUrl);
142891         },
142892
142893         setAsWallpaper: function (wallpaperUrl) {
142894             utils.validateArgumentType(wallpaperUrl, "string", ExceptionTypes.INVALID_PARAMETER, "wallpaperUrl paramter is not a string", new Exception());
142895             notifications.openNotification("normal", "Setting wallpaper to: " + wallpaperUrl);
142896         }
142897     };
142898
142899 _self.__defineGetter__("ringtoneVolume", function () {
142900     return deviceSettings.retrieve("Config.ringtoneVolume");
142901 });
142902
142903 _self.__defineGetter__("msgRingtoneVolume", function () {
142904     return deviceSettings.retrieve("Config.msgRingtoneVolume");
142905 });
142906
142907 _self.__defineGetter__("vibrationSetting", function () {
142908     return deviceSettings.retrieve("Config.vibrationSetting");
142909 });
142910
142911 module.exports = _self;
142912
142913 });
142914 define('ripple/platform/wac/1.0/WidgetManager', function (require, exports, module) {
142915 /*
142916  *  Copyright 2011 Research In Motion Limited.
142917  *
142918  * Licensed under the Apache License, Version 2.0 (the "License");
142919  * you may not use this file except in compliance with the License.
142920  * You may obtain a copy of the License at
142921  *
142922  * http://www.apache.org/licenses/LICENSE-2.0
142923  *
142924  * Unless required by applicable law or agreed to in writing, software
142925  * distributed under the License is distributed on an "AS IS" BASIS,
142926  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142927  * See the License for the specific language governing permissions and
142928  * limitations under the License.
142929  */
142930 var exception = require('ripple/exception'),
142931     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
142932     Exception = require('ripple/platform/wac/1.0/Exception');
142933
142934 module.exports = {
142935     // This method is used to check the installation status of a specific widget.
142936     checkWidgetInstallationStatus: function () {
142937
142938         exception.raise(ExceptionTypes.UNSUPPORTED, "WidgetManager.checkWidgetInstallationStatus not supported", new Exception());
142939     }
142940 };
142941
142942 });
142943 define('ripple/platform/wac/1.0/Telephony', function (require, exports, module) {
142944 /*
142945  *  Copyright 2011 Research In Motion Limited.
142946  *
142947  * Licensed under the Apache License, Version 2.0 (the "License");
142948  * you may not use this file except in compliance with the License.
142949  * You may obtain a copy of the License at
142950  *
142951  * http://www.apache.org/licenses/LICENSE-2.0
142952  *
142953  * Unless required by applicable law or agreed to in writing, software
142954  * distributed under the License is distributed on an "AS IS" BASIS,
142955  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142956  * See the License for the specific language governing permissions and
142957  * limitations under the License.
142958  */
142959 var _self,
142960     exception = require('ripple/exception'),
142961     utils = require('ripple/utils'),
142962     db = require('ripple/db'),
142963     constants = require('ripple/constants'),
142964     Device = require('ripple/platform/wac/1.0/Device'),
142965     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes'),
142966     Exception = require('ripple/platform/wac/1.0/Exception');
142967
142968
142969 function _throwUnsupportedException(method) {
142970     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
142971 }
142972
142973 _self = {
142974
142975     // Public Callbacks
142976     onCallEvent: undefined,// function (callType, phoneNumber) { },
142977     onCallRecordsFound: undefined,// function (callRecords) { };
142978
142979     // Public Methods
142980     initiateVoiceCall: function (phoneNumber) {
142981         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "initiateVoiceCall invalid number of parameters", new Exception());
142982         //HACK: should this be hardcoded?
142983         //I am still not even sure this is the correct behaviour
142984         Device.launchApplication("PHONECALL", phoneNumber);
142985
142986         if (_self.onCallEvent) {
142987             //HACK: shouldn't be hardcoded
142988             //also what should the context be? isn't spec'ed
142989             _self.onCallEvent.apply(_self, ["outgoing", phoneNumber]);
142990         }
142991     },
142992     getCallRecordCnt: function (callRecordType) {
142993         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "getCallRecordCnt invalid number of parameters", new Exception());
142994         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
142995
142996         return utils.sum(calls, function (call) {
142997             return call.callRecordType === callRecordType;
142998         });
142999     },
143000     getCallRecord: function (callRecordType, id) {
143001         utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "getCallRecord invalid number of parameters", new Exception());
143002         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
143003
143004         return utils.map(calls, function (call) {
143005             return call.callRecordType === callRecordType ? call : null;
143006         }).reduce(function (match, call) {
143007             return match || call.callRecordId === id || null;
143008         }, null);
143009     },
143010     deleteCallRecord: function (callRecordType, id) {
143011         utils.validateNumberOfArguments(2, 2, arguments.length, ExceptionTypes.INVALID_PARAMETER, "deleteCallRecord invalid number of parameters", new Exception());
143012         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY),
143013             indexToDelete = calls.reduce(function (result, call, index) {
143014                 return call.callRecordType === callRecordType &&
143015                        call.callRecordId === id ? index : result;
143016             }, -1);
143017
143018         if (indexToDelete >= 0) {
143019             calls.splice(indexToDelete, 1);
143020             db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls);
143021         }
143022
143023     },
143024
143025     deleteAllCallRecords: function (callRecordType) {
143026         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "deleteAllCallRecords invalid number of parameters", new Exception());
143027         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY),
143028             indexesToDelete = calls.reduce(function (result, call, index) {
143029                 if (call.callRecordType === callRecordType) {
143030                     result.push(index);
143031                 }
143032                 return result;
143033             }, []);
143034
143035         utils.forEach(indexesToDelete, function (index) {
143036             calls.splice(index, 1);
143037         });
143038
143039         if (indexesToDelete.length > 0) {
143040             db.saveObject(constants.TELEPHONY.CALL_LIST_KEY, calls);
143041         }
143042
143043     },
143044
143045     findCallRecords: function (comparisonRecord, startInx, endInx) {
143046         utils.validateNumberOfArguments(1, 3, arguments.length, ExceptionTypes.INVALID_PARAMETER, "findCallRecords invalid number of parameters", new Exception());
143047         var calls = db.retrieveObject(constants.TELEPHONY.CALL_LIST_KEY);
143048         utils.find(comparisonRecord, calls, startInx, endInx, _self.onCallRecordsFound);
143049
143050     }
143051
143052 };
143053
143054 module.exports = _self;
143055
143056 });
143057 define('ripple/platform/wac/1.0/Messaging', function (require, exports, module) {
143058 /*
143059  *  Copyright 2011 Research In Motion Limited.
143060  *
143061  * Licensed under the Apache License, Version 2.0 (the "License");
143062  * you may not use this file except in compliance with the License.
143063  * You may obtain a copy of the License at
143064  *
143065  * http://www.apache.org/licenses/LICENSE-2.0
143066  *
143067  * Unless required by applicable law or agreed to in writing, software
143068  * distributed under the License is distributed on an "AS IS" BASIS,
143069  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143070  * See the License for the specific language governing permissions and
143071  * limitations under the License.
143072  */
143073 var exception = require('ripple/exception'),
143074     utils = require('ripple/utils'),
143075     constants = require('ripple/constants'),
143076     notifications = require('ripple/notifications'),
143077     _console = require('ripple/console'),
143078     Message = require('ripple/platform/wac/1.0/Message'),
143079     MessageTypes = require('ripple/platform/wac/1.0/MessageTypes'),
143080     Exception = require('ripple/platform/wac/1.0/Exception'),
143081     ExceptionTypes = require('ripple/platform/wac/1.0/ExceptionTypes');
143082
143083 function _throwUnsupportedException(method) {
143084     exception.raise(ExceptionTypes.UNSUPPORTED, "Method not supported." + (method || ""), new Exception());
143085 }
143086
143087 module.exports = {
143088     onMessageArrived: undefined,
143089     onMessageSendingFailure: undefined,
143090     onMessagesFound: undefined,
143091
143092     createMessage: function (messageType) {
143093         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.INVALID_PARAMETER, "createMessage invalid number of arguments", new Exception());
143094         utils.validateArgumentType(messageType, "string", ExceptionTypes.INVALID_PARAMETER, "createMessage invalid arguments", new Exception());
143095
143096         if (!utils.some(MessageTypes, function (value) {
143097                 return value === messageType;
143098             })) {
143099             exception.raise(ExceptionTypes.INVALID_PARAMETER, "createMessage invalid arguments", new Exception());
143100         }
143101
143102         var message = new Message();
143103         message.messageType = messageType;
143104
143105         return message;
143106     },
143107     deleteMessage: function () {
143108         _throwUnsupportedException("Messaging.deleteMessage");
143109     },
143110     getMessage: function () {
143111         _throwUnsupportedException("Messaging.getMessage");
143112     },
143113     getMessageQuantities: function () {
143114         _throwUnsupportedException("Messaging.getMessageQuantities");
143115     },
143116     sendMessage: function (msg) {
143117         utils.validateNumberOfArguments(1, 1, arguments.length, ExceptionTypes.UNSUPPORTED, "sendMessage invalid number of arguments", new Exception());
143118         if (msg instanceof Message === false) {
143119             exception.raise(ExceptionTypes.INVALID_PARAMETER, "expected a valid Message object", new Exception());
143120         }
143121
143122         //TODO: Must be modded to fail and to then call the onMessageSendingFailure callback
143123         var message = "Sent " + msg.messageType + " " + msg.messageId + " to " + msg.destinationAddress;
143124
143125         // insert fail check here
143126         notifications.openNotification("normal", message);
143127         _console.log(message);
143128     },
143129     moveMessageToFolder: function () {
143130         _throwUnsupportedException("Messaging.moveMessageToFolder");
143131     },
143132     copyMessageToFolder: function () {
143133         _throwUnsupportedException("Messaging.copyMessageToFolder");
143134     },
143135     createFolder: function () {
143136         _throwUnsupportedException("Messaging.createFolder");
143137     },
143138     deleteFolder: function () {
143139         _throwUnsupportedException("Messaging.deleteFolder");
143140     },
143141     getFolderNames: function () {
143142         _throwUnsupportedException("Messaging.getFolderNames");
143143     },
143144     findMessages: function () {
143145         _throwUnsupportedException("Messaging.findMessages");
143146     },
143147     getCurrentEmailAccount: function () {
143148         _throwUnsupportedException("Messaging.getCurrentEmailAccount");
143149     },
143150     getEmailAccounts: function () {
143151         _throwUnsupportedException("Messaging.getEmailAccounts");
143152     },
143153     setCurrentEmailAccount: function () {
143154         _throwUnsupportedException("Messaging.setCurrentEmailAccount");
143155     },
143156     deleteEmailAccount: function () {
143157         _throwUnsupportedException("Messaging.deleteEmailAccount");
143158     }
143159
143160 };
143161
143162 });
143163 define('ripple/platform/wac/1.0/ExceptionTypes', function (require, exports, module) {
143164 /*
143165  *  Copyright 2011 Research In Motion Limited.
143166  *
143167  * Licensed under the Apache License, Version 2.0 (the "License");
143168  * you may not use this file except in compliance with the License.
143169  * You may obtain a copy of the License at
143170  *
143171  * http://www.apache.org/licenses/LICENSE-2.0
143172  *
143173  * Unless required by applicable law or agreed to in writing, software
143174  * distributed under the License is distributed on an "AS IS" BASIS,
143175  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143176  * See the License for the specific language governing permissions and
143177  * limitations under the License.
143178  */
143179 var _self =  {};
143180
143181 _self.__defineGetter__("INVALID_PARAMETER", function () {
143182     return "invalid_parameter";
143183 });
143184
143185 _self.__defineGetter__("SECURITY", function () {
143186     return "security";
143187 });
143188
143189 _self.__defineGetter__("UNKNOWN", function () {
143190     return "unknown";
143191 });
143192
143193 _self.__defineGetter__("UNSUPPORTED", function () {
143194     return "unsupported";
143195 });
143196
143197 module.exports = _self;
143198
143199 });
143200 define('ripple/platform/wac/1.0/PowerInfo', function (require, exports, module) {
143201 /*
143202  *  Copyright 2011 Research In Motion Limited.
143203  *
143204  * Licensed under the Apache License, Version 2.0 (the "License");
143205  * you may not use this file except in compliance with the License.
143206  * You may obtain a copy of the License at
143207  *
143208  * http://www.apache.org/licenses/LICENSE-2.0
143209  *
143210  * Unless required by applicable law or agreed to in writing, software
143211  * distributed under the License is distributed on an "AS IS" BASIS,
143212  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143213  * See the License for the specific language governing permissions and
143214  * limitations under the License.
143215  */
143216 var _self,
143217     event = require('ripple/event'),
143218     _console = require('ripple/console'),
143219     deviceSettings = require('ripple/deviceSettings'),
143220     _lastPercentRemaining;
143221
143222 _self = {
143223     isCharging: undefined,
143224     percentRemaining: undefined,
143225
143226     onChargeStateChange: undefined,
143227     onLowBattery: undefined,
143228     onChargeLevelChange: undefined
143229 };
143230
143231 function _getCurrentChargeState(percentRemaining, isCharging) {
143232     var batteryState;
143233     if (percentRemaining === 100 && isCharging) {
143234         batteryState = "full";
143235     }
143236     else if (!isCharging) {
143237         batteryState = "discharging";
143238     }
143239     else {
143240         batteryState = "charging";
143241     }
143242     return batteryState;
143243 }
143244
143245 event.on("DeviceBatteryStateChanged", function (isCharging) {
143246     var callback = _self.onChargeStateChange,
143247         msg = "",
143248         batteryLevel = _self.percentRemaining,
143249         batteryState;
143250
143251     batteryState = _getCurrentChargeState(batteryLevel, isCharging);
143252
143253     msg += "Fired onChargeStateChange with batteryState: " + batteryState;
143254
143255     if (callback && typeof callback === "function") {
143256         callback.apply(null, [batteryState]);
143257     }
143258     else {
143259         msg += " --> BUT there was no registered callback found.";
143260     }
143261
143262     _console.log(msg);
143263 });
143264
143265 event.on("DeviceBatteryLevelChanged", function (percentRemaining) {
143266
143267     var callback = _self.onChargeLevelChange,
143268         lowBatteryCallback = _self.onLowBattery,
143269         msg = "Fired onChargeLevelChange with percentRemaining: " + percentRemaining;
143270
143271     // blah, stupid Options returning strings
143272     percentRemaining = parseInt(percentRemaining, 10);
143273
143274     if (callback && typeof callback === "function") {
143275         callback.apply(null, [percentRemaining]);
143276     }
143277     else {
143278         msg += " --> BUT there was no registered callback found.";
143279     }
143280
143281     _console.log(msg);
143282
143283     if (percentRemaining <= 10) {
143284
143285         msg = "Fired onLowBattery with percentRemaining: " + percentRemaining;
143286
143287         if (lowBatteryCallback && typeof lowBatteryCallback === "function") {
143288             lowBatteryCallback.apply(null, [percentRemaining]);
143289         }
143290         else {
143291             msg += " --> BUT there was no registered callback found.";
143292         }
143293
143294         _console.log(msg);
143295     }
143296
143297     if (percentRemaining === 100 || (percentRemaining < 100 && _lastPercentRemaining === 100)) {
143298         event.trigger("DeviceBatteryStateChanged", [_self.isCharging]);
143299     }
143300
143301     _lastPercentRemaining = percentRemaining;
143302
143303 });
143304
143305 _self.__defineGetter__("isCharging", function () {
143306     return deviceSettings.retrieveAsBoolean("PowerInfo.isCharging");
143307 });
143308
143309 _self.__defineGetter__("percentRemaining", function () {
143310     return deviceSettings.retrieveAsInt("PowerInfo.percentRemaining");
143311 });
143312
143313 module.exports = _self;
143314
143315 });
143316 define('ripple/platform/wac/2.0/devicestatus', function (require, exports, module) {
143317 /*
143318  *  Copyright 2011 Intel Corporation.
143319  *
143320  * Licensed under the Apache License, Version 2.0 (the "License");
143321  * you may not use this file except in compliance with the License.
143322  * You may obtain a copy of the License at
143323  *
143324  * http://www.apache.org/licenses/LICENSE-2.0
143325  *
143326  * Unless required by applicable law or agreed to in writing, software
143327  * distributed under the License is distributed on an "AS IS" BASIS,
143328  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143329  * See the License for the specific language governing permissions and
143330  * limitations under the License.
143331  */
143332
143333 var utils = require('ripple/utils'),
143334     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
143335     errorcode = require('ripple/platform/wac/2.0/errorcode'),
143336     _console = require('ripple/console'),
143337     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
143338     deviceSettings = require('ripple/deviceSettings'),    
143339     event = require('ripple/event'),    
143340     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
143341     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
143342     _getDeviceInfoAspect = true,
143343     _getNetworkInfoAspect = true,    
143344     _deviceInfoAspect = ["Battery", "Device", "Display", "MemoryUnit", "OperatingSystem", "WebRuntime"],    
143345     _networkInfoAspect = ["CellularHardware", "CellularNetwork", "WiFiHardware", "WiFiNetwork"],
143346     _aspectArray = [], 
143347     _propertyMap = {},
143348     _watches = {},
143349     _self;
143350
143351 function _asynchErrorCallback(errorCallback, errorCode) {
143352     if (errorCallback) {        
143353         setTimeout(function () {
143354             errorCallback(errorCode);
143355         }, 1);  
143356     }
143357 }
143358
143359 function _initialize() {
143360     var aspectName, index, i;
143361
143362     _aspectArray = _deviceInfoAspect.concat(_networkInfoAspect);
143363     for (index = 0; index < _aspectArray.length; index++) {
143364         aspectName = _aspectArray[index];
143365         _propertyMap[aspectName] = [];
143366         for (i in deviceSettings.retrieve(aspectName)) {
143367             _propertyMap[aspectName].push(i);
143368         }
143369     }     
143370 }
143371
143372 function _isPropertyFound(aspect, property) {
143373     if (_aspectArray.length === 0) {
143374         _initialize();
143375     }
143376
143377     if (_propertyMap[aspect]) {
143378         if (property) {
143379             return _propertyMap[aspect].some(function (prop) {
143380                 return prop === property;
143381             });
143382         }
143383         return true;
143384     }
143385     return false;
143386 }
143387
143388 function _isPropertyAllowed(aspect) {
143389     function hasAspect(asp) {
143390         return asp === aspect;
143391     }
143392
143393     if ((_deviceInfoAspect.some(hasAspect) && _getDeviceInfoAspect === false) ||
143394         (_networkInfoAspect.some(hasAspect) && _getNetworkInfoAspect === false)) {
143395         return false;
143396     }
143397
143398     return true;
143399 }
143400
143401 function _isPropertyValid(prop, errorCallback) {
143402     var _prop = Object(prop);
143403
143404     if (_prop && _prop.aspect && _prop.property) {
143405         if (_isPropertyFound(_prop.aspect, _prop.property) === false) {
143406             _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.NOT_FOUND_ERR));
143407             return false;
143408         }
143409         else if (_isPropertyAllowed(_prop.aspect) === false) {
143410             _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.SECURITY_ERR));
143411             return false;
143412         }
143413     } 
143414     else {
143415         _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.INVALID_VALUES_ERR));
143416         return false;
143417     }
143418     return true;
143419 }
143420
143421 module.exports = function () {
143422     return {  
143423         getComponents: function (aspect) {
143424             if (_isPropertyFound(aspect))
143425                 return ["_default"];
143426             return null;              
143427         },
143428
143429         isSupported: function (aspect, property) {
143430             return _isPropertyFound(aspect, property);
143431         },
143432
143433         getPropertyValue: function (successCallback, errorCallback, prop) {
143434             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "getPropertyValue", function () {                                  
143435                 if (_isPropertyValid(prop, errorCallback) !== true)
143436                     return undefined;
143437                 
143438                 var value = deviceSettings.retrieve(prop.aspect + "." + prop.property);
143439                 if (value !== undefined) {
143440                     successCallback(value, prop);
143441                 }
143442                 else {
143443                     _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.NOT_AVAILABLE_ERR)); 
143444                 }
143445                 
143446                 return null;    
143447             });        
143448         },
143449        
143450         watchPropertyChange: function (successCallback, errorCallback, prop, options) {  
143451             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "watchPropertyChange", function () {
143452                 if (_isPropertyValid(prop, errorCallback) !== true)
143453                     return undefined;
143454
143455                 var _options = Object(options),
143456                     eventType = deviceSettings.retrieve(prop.aspect)[prop.property].event,
143457                     watchObj = {
143458                         eventType: eventType,
143459                         onEvent: function (newValue) {
143460                             if (watchObj.timeStamp && 
143461                                 ((new Date()).getTime() - watchObj.timeStamp < options.minNotificationInterval)) {
143462                                 return undefined;
143463                             }                       
143464                             else if (watchObj.value &&
143465                                      (newValue > watchObj.value * (1 - _options.minChangePercent) && 
143466                                       newValue < watchObj.value * (1 + _options.minChangePercent))) {
143467                                 return undefined;
143468                             }
143469
143470                             if (watchObj.intervalId) {
143471                                 clearInterval(watchObj.intervalId);
143472                                 watchObj.intervalId = setInterval(function () {
143473                                     successCallback(deviceSettings.retrieve(prop.aspect + "." + prop.property), prop);
143474                                 }, _options.maxNotificationInterval);
143475                             }
143476                             successCallback(newValue, prop);
143477                             if (watchObj.timeStamp) {
143478                                 watchObj.timeStamp = (new Date()).getTime();
143479                             }
143480                             if (watchObj.value) {
143481                                 watchObj.value = newValue;
143482                             }
143483                         }                              
143484                     },
143485                     watchId = (new Date()).getTime() | 0;
143486
143487                 if (options && _options.minNotificationInterval && _options.maxNotificationInterval && 
143488                     (_options.minNotificationInterval < 0 || _options.maxNotificationInterval < 0 || 
143489                      _options.minNotificationInterval >= _options.maxNotificationInterval)) {
143490                     _asynchErrorCallback(errorCallback, new DeviceApiError(errorcode.INVALID_VALUES_ERR));
143491                     return undefined;
143492                 }
143493
143494                 if (options && _options.maxNotificationInterval) {
143495                     watchObj.intervalId = setInterval(function () {
143496                         successCallback(deviceSettings.retrieve(prop.aspect + "." + prop.property), prop);
143497                     }, _options.maxNotificationInterval);
143498                 }    
143499
143500                 if (options && _options.minNotificationInterval) {
143501                     watchObj.timeStamp = (new Date()).getTime();
143502                 }                    
143503
143504                 if (options && _options.minChangePercent) {
143505                     if (_options.minNotificationInterval || _options.maxNotificationInterval) {}
143506                     else {                
143507                         watchObj.value = deviceSettings.retrieve(prop.aspect + "." + prop.property);
143508                     }
143509                 }
143510                
143511                 _watches[watchId] = watchObj;
143512                 if (watchObj.eventType) {
143513                     event.on(watchObj.eventType, watchObj.onEvent);
143514                 }
143515
143516                 return watchId;
143517             });             
143518         },
143519
143520         clearPropertyChange: function (watchHandler) {
143521             var _handler = watchHandler | 0;
143522             
143523             if (_watches[_handler]) {
143524                 event.deleteEventHandler(_watches[_handler].eventType, _watches[_handler].onEvent);            
143525                 if (_watches[_handler].intervalId) {
143526                     clearInterval(_watches[_handler].intervalId);
143527                 }
143528                 delete(_watches[_handler]); 
143529             }
143530             return null;
143531         },
143532
143533         handleSubFeatures: function (subFeatures) {
143534             if (wac2_utils.isEmptyObject(subFeatures) ||
143535                 subFeatures["http://wacapps.net/api/devicestatus"] || 
143536                 (subFeatures["http://wacapps.net/api/devicestatus.deviceinfo"] &&
143537                  subFeatures["http://wacapps.net/api/devicestatus.networkinfo"])) {
143538                 return;
143539             }
143540             if (subFeatures["http://wacapps.net/api/devicestatus.deviceinfo"]) {
143541                 _getNetworkInfoAspect = false;
143542                 return;
143543             }
143544             if (subFeatures["http://wacapps.net/api/devicestatus.networkinfo"]) {
143545                 _getDeviceInfoAspect = false;
143546                 return;
143547             }
143548             _console.warn("WAC-2.0-Devicestatus-handleSubFeatures: something wrong");
143549         }
143550     };
143551 };
143552
143553
143554 });
143555 define('ripple/platform/wac/2.0/messagefilter', function (require, exports, module) {
143556 /*
143557  *  Copyright 2011 Intel Corporation.
143558  *
143559  * Licensed under the Apache License, Version 2.0 (the "License");
143560  * you may not use this file except in compliance with the License.
143561  * You may obtain a copy of the License at
143562  *
143563  * http://www.apache.org/licenses/LICENSE-2.0
143564  *
143565  * Unless required by applicable law or agreed to in writing, software
143566  * distributed under the License is distributed on an "AS IS" BASIS,
143567  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143568  * See the License for the specific language governing permissions and
143569  * limitations under the License.
143570  */
143571
143572 var _self;
143573
143574 _self = function (criteria) {
143575     var pattern,
143576         messageFilter;
143577
143578     messageFilter = {
143579         match: function (target) {
143580             var result = false, index;
143581
143582             if (Object.prototype.toString.call(criteria) === "[object Array]") {
143583                 for (index in criteria) {
143584                     if (_self(criteria[index]).match(target))
143585                         return true;
143586                 }
143587                 return false;
143588             }
143589
143590             switch (Object.prototype.toString.call(target)) {
143591             case "[object Number]":
143592                 result = (criteria === target);
143593                 break;
143594
143595             case "[object String]":
143596                 result = pattern.test(target);
143597                 break;
143598
143599             case "[object Array]":
143600                 for (index in target) {
143601                     if (messageFilter.match(target[index]))
143602                         return true;
143603                 }
143604                 break;
143605             }
143606
143607             return result;
143608         }
143609     };
143610
143611     if (typeof criteria === "string")
143612         pattern = new RegExp(criteria.replace(/(^|[^\\])%+/g, "$1.*").replace(/\\%/g, "%").replace(/.*/, "^$&$"), "i");
143613
143614     return messageFilter;
143615 };
143616
143617 module.exports = _self;
143618
143619 });
143620 define('ripple/platform/wac/2.0/errorcode', function (require, exports, module) {
143621 /*
143622  *  Copyright 2011 Intel Corporation.
143623  *
143624  * Licensed under the Apache License, Version 2.0 (the "License"),
143625  * you may not use this file except in compliance with the License.
143626  * You may obtain a copy of the License at
143627  *
143628  * http://www.apache.org/licenses/LICENSE-2.0
143629  *
143630  * Unless required by applicable law or agreed to in writing, software
143631  * distributed under the License is distributed on an "AS IS" BASIS,
143632  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143633  * See the License for the specific language governing permissions and
143634  * limitations under the License.
143635  */
143636
143637 var _self = {
143638     message : []
143639 };
143640
143641 _self.__defineGetter__("UNKNOWN_ERR", function () {
143642     return 0;
143643 });
143644
143645 _self.__defineGetter__("INDEX_SIZE_ERR", function () {
143646     return 1;
143647 });
143648
143649 _self.__defineGetter__("DOMSTRING_SIZE_ERR", function () {
143650     return 2;
143651 });
143652
143653 _self.__defineGetter__("HIERARCHY_REQUEST_ERR", function () {
143654     return 3;
143655 });
143656
143657 _self.__defineGetter__("WRONG_DOCUMENT_ERR", function () {
143658     return 4;
143659 });
143660
143661 _self.__defineGetter__("INVALID_CHARACTER_ERR", function () {
143662     return 5;
143663 });
143664
143665 _self.__defineGetter__("NO_DATA_ALLOWED_ERR", function () {
143666     return 6;
143667 });
143668
143669 _self.__defineGetter__("NO_MODIFICATION_ALLOWED_ERR", function () {
143670     return 7;
143671 });
143672
143673 _self.__defineGetter__("NOT_FOUND_ERR", function () {
143674     return 8;
143675 });
143676
143677 _self.__defineGetter__("NOT_SUPPORTED_ERR", function () {
143678     return 9;
143679 });
143680
143681 _self.__defineGetter__("INUSE_ATTRIBUTE_ERR", function () {
143682     return 10;
143683 });
143684
143685 _self.__defineGetter__("INVALID_STATE_ERR", function () {
143686     return 11;
143687 });
143688
143689 _self.__defineGetter__("SYNTAX_ERR", function () {
143690     return 12;
143691 });
143692
143693 _self.__defineGetter__("INVALID_MODIFICATION_ERR", function () {
143694     return 13;
143695 });
143696
143697 _self.__defineGetter__("NAMESPACE_ERR", function () {
143698     return 14;
143699 });
143700
143701 _self.__defineGetter__("INVALID_ACCESS_ERR", function () {
143702     return 15;
143703 });
143704
143705 _self.__defineGetter__("VALIDATION_ERR", function () {
143706     return 16;
143707 });
143708
143709 _self.__defineGetter__("TYPE_MISMATCH_ERR", function () {
143710     return 17;
143711 });
143712
143713 _self.__defineGetter__("SECURITY_ERR", function () {
143714     return 18;
143715 });
143716
143717 _self.__defineGetter__("NETWORK_ERR", function () {
143718     return 19;
143719 });
143720
143721 _self.__defineGetter__("ABORT_ERR", function () {
143722     return 20;
143723 });
143724
143725 _self.__defineGetter__("TIMEOUT_ERR", function () {
143726     return 21;
143727 });
143728
143729 _self.__defineGetter__("INVALID_VALUES_ERR", function () {
143730     return 22;
143731 });
143732
143733 _self.__defineGetter__("IO_ERR", function () {
143734     return 100;
143735 });
143736
143737 _self.__defineGetter__("NOT_AVAILABLE_ERR", function () {
143738     return 101;
143739 });
143740
143741 function _setMessage(_self) {
143742     var c, g;
143743     for (c in _self) {
143744         g = _self.__lookupGetter__(c);
143745         if (g) {
143746             _self.message[g()] = c;
143747         }
143748     }
143749 }
143750
143751 _setMessage(_self);
143752
143753 module.exports = _self;
143754
143755
143756 });
143757 define('ripple/platform/wac/2.0/messaging', function (require, exports, module) {
143758 /*
143759  *  Copyright 2011 Intel Corporation.
143760  *
143761  * Licensed under the Apache License, Version 2.0 (the "License");
143762  * you may not use this file except in compliance with the License.
143763  * You may obtain a copy of the License at
143764  *
143765  * http://www.apache.org/licenses/LICENSE-2.0
143766  *
143767  * Unless required by applicable law or agreed to in writing, software
143768  * distributed under the License is distributed on an "AS IS" BASIS,
143769  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143770  * See the License for the specific language governing permissions and
143771  * limitations under the License.
143772  */
143773
143774 var utils = require('ripple/utils'),
143775     event = require('ripple/event'),
143776     db = require('ripple/db'),
143777     exception = require('ripple/exception'),
143778     errorcode = require('ripple/platform/wac/2.0/errorcode'),
143779     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
143780     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
143781     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
143782     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
143783     TypeCoerce = require('ripple/platform/wac/2.0/typecoerce'),
143784     Filter = require('ripple/platform/wac/2.0/messagefilter'),
143785     FileSystem = require('ripple/platform/wac/2.0/filesystem'),
143786     MessageSendCallback,
143787     Message,
143788     MessageFilter,
143789     Recipients,
143790     _KEY = "wac2-pim-messaging",
143791     _PENDING_TIME = 600,
143792     _messages = {},
143793     _subscriber = {
143794         onSMS: {},
143795         onMMS: {},
143796         onEmail: {}
143797     },
143798     _sentStatus = {},
143799     _security = {
143800         "http://wacapps.net/api/messaging": [],
143801         "http://wacapps.net/api/messaging.send": ["sendMessage"],
143802         "http://wacapps.net/api/messaging.find": ["findMessages"],
143803         "http://wacapps.net/api/messaging.subscribe": ["onSMS", "onMMS", "onEmail"],
143804         "http://wacapps.net/api/messaging.write": ["update"],
143805         all: true
143806     },
143807     _fileSystem,
143808     _initialized = false,
143809     _self;
143810
143811 function _initialize() {
143812     _get();
143813     if (!_fileSystem) {
143814         _fileSystem = new FileSystem();
143815     }
143816     _initialized = true;
143817 }
143818
143819 function _get() {
143820     _messages = db.retrieveObject(_KEY) || {1: [], 2: [], 3: [], 4: []};
143821     utils.forEach(_messages, function (folder) {
143822         utils.forEach(folder, function (messageItem) {
143823             if (messageItem.timestamp)
143824                 messageItem.timestamp = new Date(messageItem.timestamp);
143825         });
143826     });
143827 }
143828
143829 function _save() {
143830     db.saveObject(_KEY, _messages);
143831 }
143832
143833 function _updateDB(message, duplicate) {
143834     _get();
143835     _messages[message.folder].push(message);
143836     if (duplicate)
143837         _messages[duplicate.folder].push(duplicate);
143838     _save();
143839 }
143840
143841 function _processAttachments(message) {
143842     var attachmentsFileName = [],
143843         attachmentsContent = [];
143844
143845     function _generateAttachmentFileName(attachment) {
143846         var lastDot = attachment.filename.lastIndexOf(".");
143847         return attachment.filename.substring(0, lastDot) + "_" + Math.uuid(8, 16) + attachment.filename.substring(lastDot);
143848     }
143849
143850     function _onResolveSuccess(file) {
143851         var fileAttachment = file.createFile(attachmentsFileName[0]);
143852
143853         fileAttachment.openStream(
143854             function (fs) {
143855                 fs.write(attachmentsContent[0]);
143856                 fs.close();
143857             }, null, "w");
143858     }
143859
143860     function _onResolveError() {
143861     }
143862
143863     if (message.attachments.length === 0)
143864         return;
143865
143866     attachmentsFileName.push(_generateAttachmentFileName(message.attachments[0]));
143867     attachmentsContent.push(message.attachments[0].content);
143868
143869     _fileSystem.resolve(_onResolveSuccess, _onResolveError, "attachments", "rw");
143870
143871     message.attachments = utils.copy(attachmentsFileName);
143872 }
143873
143874 function _errorOccurred(onError, code) {
143875     if (!onError)
143876         return;
143877
143878     setTimeout(function () {
143879         onError(new DeviceApiError(code));
143880     }, 1);
143881 }
143882
143883 function _pendingOperate(operate, scope) {
143884     var i, argumentVector = [];
143885
143886     for (i = 0; i < arguments.length - 2; i++)
143887         argumentVector[i] = arguments[i + 2];
143888
143889     return function () {
143890         var pendingObj, pendingOperation;
143891
143892         pendingObj = new PendingObject();
143893         pendingObj.pendingID = window.setTimeout(function () {
143894             pendingObj.setCancelFlag(false);
143895             if (operate)
143896                 operate.apply(scope, argumentVector);
143897         }, _PENDING_TIME);
143898
143899         pendingOperation = new PendingOperation(pendingObj);
143900
143901         return pendingOperation;
143902     };
143903 }
143904
143905 function _onMessage(onMessage, messageHandler) {
143906     if (!messageHandler)
143907         exception.raise(exception.types.Argument,
143908             onMessage + " invalid messageHandler parameter",
143909             new DeviceApiError(errorcode.INVALID_VALUES_ERR));
143910
143911     utils.validateArgumentType(messageHandler, "function", null,
143912         "messageHandler invalid function parameter",
143913         new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
143914
143915     if (!_security.all && !_security[onMessage])
143916         exception.raise(exception.types.Argument,
143917             onMessage + " access denied", new DeviceApiError(errorcode.SECURITY_ERR));
143918
143919     var idSubscribe = (new Date()).getTime() | 0;
143920     _subscriber[onMessage][idSubscribe] = messageHandler;
143921
143922     return idSubscribe;
143923 }
143924
143925 function _validateRecipients(message) {
143926     var i;
143927
143928     for (i = 0; i < message.to.length;) {
143929         message.to[i] = message.to[i].replace(/^\s*(\S*)\s*$/, '$1');
143930         if (message.to[i] === "")
143931             message.to.splice(i, 1);
143932         else
143933             i++;
143934     }
143935     for (i = 0; i < message.cc.length;) {
143936         message.cc[i] = message.cc[i].replace(/^\s*(\S*)\s*$/, '$1');
143937         if (message.cc[i] === "")
143938             message.cc.splice(i, 1);
143939         else
143940             i++;
143941     }
143942     for (i = 0; i < message.bcc.length;) {
143943         message.bcc[i] = message.bcc[i].replace(/^\s*(\S*)\s*$/, '$1');
143944         if (message.bcc[i] === "")
143945             message.bcc.splice(i, 1);
143946         else
143947             i++;
143948     }
143949     if (message.to.length + message.cc.length + message.bcc.length === 0)
143950         exception.raise(exception.types.Argument,
143951             "sendMessage invalid message.to parameter",
143952             new DeviceApiError(errorcode.INVALID_VALUES_ERR));
143953 }
143954
143955 function _isValid(onSuccess, onError, message) {
143956     if (onSuccess &&
143957         typeof onSuccess !== "function" &&
143958         typeof onSuccess !== "object") {
143959         exception.raise(exception.types.Argument,
143960             "sendMessage invalid successCallback parameter",
143961             new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
143962     }
143963
143964     if (onError) {
143965         utils.validateArgumentType(onError, "function", null,
143966             "sendMessage invalid errorCallback parameter",
143967             new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
143968     }
143969
143970     if (!onSuccess) {
143971         _errorOccurred(onError, errorcode.INVALID_VALUES_ERR);
143972         return false;
143973     }
143974
143975     if (message) {
143976         utils.validateArgumentType(message, "object", null,
143977             "sendMessage invalid message parameter",
143978             new DeviceApiError(errorcode.INVALID_VALUES_ERR));
143979     } else {
143980         _errorOccurred(onError, errorcode.INVALID_VALUES_ERR);
143981         return false;
143982     }
143983
143984     if (message.type !== _self().TYPE_SMS &&
143985         message.type !== _self().TYPE_MMS &&
143986         message.type !== _self().TYPE_EMAIL)
143987         exception.raise(exception.types.Argument,
143988             "sendMessage invalid message.type parameter",
143989             new DeviceApiError(errorcode.INVALID_VALUES_ERR));
143990
143991     if (!_security.all && !_security.sendMessage) {
143992         _errorOccurred(onError, errorcode.SECURITY_ERR);
143993         return false;
143994     }
143995
143996     TypeCoerce(Message(0)).cast(message);
143997     _validateRecipients(message);
143998
143999     return true;
144000 }
144001
144002 function _getEachSentStatus(onMessageSentSuccess, onMessageSentError, message,
144003                             sucRecipients, failRecipients, recType) {
144004     utils.forEach(message[recType], function (recipient) {
144005         if (_sentStatus[recipient]) {
144006             sucRecipients[recType].push(recipient);
144007             if (onMessageSentSuccess) {
144008                 onMessageSentSuccess(recipient);
144009             }
144010         } else {
144011             failRecipients[recType].push(recipient);
144012             if (onMessageSentError) {
144013                 onMessageSentError(new DeviceApiError(errorcode.UNKNOWN_ERR), recipient);
144014             }
144015         }
144016     });
144017 }
144018
144019 function _getSentStatus(onSuccess, onError, message, onMessageSentSuccess, onMessageSentError) {
144020     var allSentSuccess,
144021         sucRecipients = new Recipients(),
144022         failRecipients = new Recipients(),
144023         duplicate;
144024
144025     _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
144026         message, sucRecipients, failRecipients, "to");
144027
144028     if (message.type === _self().TYPE_EMAIL) {
144029         _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
144030             message, sucRecipients, failRecipients, "cc");
144031         _getEachSentStatus(onMessageSentSuccess, onMessageSentError,
144032             message, sucRecipients, failRecipients, "bcc");
144033     }
144034
144035     allSentSuccess = (failRecipients.total() === 0);
144036
144037     if (allSentSuccess) {
144038         message.folder = _self().FOLDER_SENTBOX;
144039     } else if (sucRecipients.total() === 0) {
144040         message.folder = _self().FOLDER_DRAFTS;
144041     } else {
144042         duplicate = utils.copy(message);
144043
144044         message.to = sucRecipients.to;
144045         message.cc = sucRecipients.cc;
144046         message.bcc = sucRecipients.bcc;
144047         message.folder = _self().FOLDER_SENTBOX;
144048
144049         duplicate.to = failRecipients.to;
144050         duplicate.cc = failRecipients.cc;
144051         duplicate.bcc = failRecipients.bcc;
144052         duplicate.folder = _self().FOLDER_DRAFTS;
144053     }
144054
144055     _updateDB(message, duplicate);
144056
144057     if (allSentSuccess) {
144058         onSuccess();
144059     } else if (onError) {
144060         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
144061     }
144062 }
144063
144064 _self = function () {
144065     var messaging = {
144066         createMessage: function (type) {
144067             type = type | 0;
144068
144069             if (type < _self().TYPE_SMS || type > _self().TYPE_EMAIL)
144070                 exception.raise(exception.types.Argument,
144071                 "type invalid value", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
144072
144073             var msg = new Message(type);
144074
144075             return msg;
144076         },
144077
144078         sendMessage: function (successCallback, errorCallback, message) {
144079             var ret;
144080
144081             function _sendMessage() {
144082                 event.trigger("OutsideMessageReceived", [message]);
144083
144084                 return _pendingOperate(_getSentStatus, undefined,
144085                     successCallback, errorCallback, message)();
144086             }
144087
144088             function _sendEachMessage() {
144089                 utils.forEach(successCallback, function (value, key) {
144090                     utils.validateArgumentType(value, "function", null,
144091                         "sendMessage invalid successCallback." + key + " parameter",
144092                         new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
144093                 });
144094
144095                 event.trigger("OutsideMessageReceived", [message]);
144096
144097                 return _pendingOperate(_getSentStatus, undefined,
144098                     successCallback.onsuccess, errorCallback, message,
144099                     successCallback.onmessagesendsuccess, successCallback.onmessagesenderror)();
144100             }
144101
144102             if (!_isValid(successCallback, errorCallback, message))
144103                 return null;
144104
144105             switch (typeof successCallback) {
144106             case "function":
144107                 ret = _sendMessage();
144108                 break;
144109
144110             case "object":
144111                 ret = _sendEachMessage();
144112                 break;
144113             }
144114
144115             return ret;
144116         },
144117
144118         findMessages: function (successCallback, errorCallback, filter) {
144119             function _findMessages() {
144120                 var message, result = [];
144121
144122                 if (!_security.all && !_security.findMessages)
144123                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
144124
144125                 utils.forEach(_messages, function (folder) {
144126                     utils.forEach(folder, function (messageItem) {
144127                         if ((filter                 === undefined || filter === null) ||
144128                             (filter.id              === undefined || Filter(filter.id).match(messageItem.id)) &&
144129                             (filter.type            === undefined || Filter(filter.type).match(messageItem.type)) &&
144130                             (filter.folder          === undefined || Filter(filter.folder).match(messageItem.folder)) &&
144131                             (filter.startTimestamp  === undefined || (messageItem.timestamp >= filter.startTimestamp)) &&
144132                             (filter.endTimestamp    === undefined || (messageItem.timestamp <= filter.endTimestamp)) &&
144133                             (filter.from            === undefined || Filter(filter.from).match(messageItem.from)) &&
144134                             (filter.to              === undefined || Filter(filter.to).match(messageItem.to)) &&
144135                             (filter.cc              === undefined || Filter(filter.cc).match(messageItem.cc)) &&
144136                             (filter.bcc             === undefined || Filter(filter.bcc).match(messageItem.bcc)) &&
144137                             (filter.body            === undefined || Filter(filter.body).match(messageItem.body)) &&
144138                             (filter.isRead          === undefined || (messageItem.isRead === filter.isRead)) &&
144139                             (filter.messagePriority === undefined || (messageItem.priority === filter.messagePriority)) &&
144140                             (filter.subject         === undefined || Filter(filter.subject).match(messageItem.subject))) {
144141                             message = utils.copy(messageItem);
144142                             result.push(message);
144143                         }
144144                     });
144145                 });
144146                 successCallback(result);
144147             }
144148             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "findMessages", _pendingOperate(_findMessages));
144149         },
144150
144151         onSMS: function (messageHandler) {
144152             return _onMessage("onSMS", messageHandler);
144153         },
144154
144155         onMMS: function (messageHandler) {
144156             return _onMessage("onMMS", messageHandler);
144157         },
144158
144159         onEmail: function (messageHandler) {
144160             return _onMessage("onEmail", messageHandler);
144161         },
144162
144163         unsubscribe: function (subscriptionHandler) {
144164             var onMessage, idSubscribe;
144165
144166             utils.validateArgumentType(subscriptionHandler, "integer",
144167                 null, "subscriptionHandler invalid function parameter",
144168                 new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
144169
144170             for (onMessage in _subscriber) {
144171                 for (idSubscribe in _subscriber[onMessage]) {
144172                     if (idSubscribe == subscriptionHandler) {
144173                         delete _subscriber[onMessage][idSubscribe];
144174                         return;
144175                     }
144176                 }
144177             }
144178         },
144179
144180         handleSubFeatures: function (subFeatures) {
144181             for (var subFeature in subFeatures) {
144182                 if (_security[subFeature].length === 0) {
144183                     _security.all = true;
144184                     return;
144185                 }
144186                 _security.all = false;
144187                 utils.forEach(_security[subFeature], function (method) {
144188                     _security[method] = true;
144189                 });
144190             }
144191         }
144192     };
144193
144194     messaging.__defineGetter__("TYPE_SMS", function () {
144195         return 1;
144196     });
144197
144198     messaging.__defineGetter__("TYPE_MMS", function () {
144199         return 2;
144200     });
144201
144202     messaging.__defineGetter__("TYPE_EMAIL", function () {
144203         return 3;
144204     });
144205
144206     messaging.__defineGetter__("FOLDER_INBOX", function () {
144207         return 1;
144208     });
144209
144210     messaging.__defineGetter__("FOLDER_OUTBOX", function () {
144211         return 2;
144212     });
144213
144214     messaging.__defineGetter__("FOLDER_DRAFTS", function () {
144215         return 3;
144216     });
144217
144218     messaging.__defineGetter__("FOLDER_SENTBOX", function () {
144219         return 4;
144220     });
144221
144222     if (!_initialized)
144223         _initialize();
144224
144225     return messaging;
144226 };
144227
144228 MessageSendCallback = {
144229     onsuccess: function () {},
144230     onmessagesendsuccess: function (recipient) {},
144231     onmessagesenderror: function (error, recipient) {}
144232 };
144233
144234 Message = function (type) {
144235     this.id = Math.uuid(null, 16);
144236     this.type = type;
144237     this.folder = 0;
144238     this.timestamp = new Date();
144239     this.from = "";
144240     this.to = [""];
144241     this.cc = [""];
144242     this.bcc = [""];
144243     this.body = "";
144244     this.isRead = false;
144245     this.priority = false;
144246     this.subject = "";
144247     this.attachments = [""];
144248
144249     this.update = function (successCallback, errorCallback) {
144250         function _update() {
144251             var isFound = false;
144252
144253             if (!_security.all && !_security.update)
144254                 return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
144255
144256             TypeCoerce(new Message(0)).cast(this);
144257             _get();
144258             utils.forEach(_messages[this.folder], function (messageItem) {
144259                 if (messageItem.id === this.id) {
144260                     !this.isRead || (messageItem.isRead = this.isRead);
144261                     if (this.folder === _self().FOLDER_DRAFTS) {
144262                         !this.type        || (messageItem.type        = this.type);
144263                         !this.to          || (messageItem.to          = utils.copy(this.to));
144264                         !this.cc          || (messageItem.cc          = utils.copy(this.cc));
144265                         !this.bcc         || (messageItem.bcc         = utils.copy(this.bcc));
144266                         !this.body        || (messageItem.body        = this.body);
144267                         !this.priority    || (messageItem.priority    = this.priority);
144268                         !this.subject     || (messageItem.subject     = this.subject);
144269                         !this.attachments || (messageItem.attachments = utils.copy(this.attachments));
144270                     }
144271                     isFound = true;
144272                 }
144273             });
144274
144275             if (isFound) {
144276                 _save();
144277                 successCallback();
144278             } else {
144279                 _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
144280             }
144281         }
144282         return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "update", _pendingOperate(_update, this));
144283     };
144284 };
144285
144286 MessageFilter = {
144287     id: "",
144288     type: [0],
144289     folder: [0],
144290     startTimestamp: new Date(),
144291     endTimestamp: new Date(),
144292     from: "",
144293     to: [""],
144294     cc: [""],
144295     bcc: [""],
144296     body: "",
144297     isRead: false,
144298     messagePriority: false,
144299     subject: ""
144300 };
144301
144302 Recipients = function () {
144303     this.to  = [];
144304     this.cc  = [];
144305     this.bcc = [];
144306
144307     this.total = function () {
144308         return (this.to.length + this.cc.length + this.bcc.length);
144309     };
144310 };
144311
144312 event.on("MessageReceived", function (message) {
144313     var onMessage;
144314
144315     switch (message.type) {
144316     case "sms":
144317         message.type = _self().TYPE_SMS;
144318         onMessage = "onSMS";
144319         break;
144320
144321     case "mms":
144322         message.type = _self().TYPE_MMS;
144323         onMessage = "onMMS";
144324         break;
144325
144326     case "email":
144327         message.type = _self().TYPE_EMAIL;
144328         onMessage = "onEmail";
144329         break;
144330
144331     default:
144332         break;
144333     }
144334
144335     message.folder = _self().FOLDER_INBOX;
144336     _processAttachments(message);
144337     _updateDB(message);
144338     utils.forEach(_subscriber[onMessage], function (subscriberCallback) {
144339         subscriberCallback(message);
144340     });
144341 });
144342
144343 event.on("MessageSent", function (sentStatus) {
144344     _sentStatus = sentStatus;
144345 });
144346
144347 module.exports = _self;
144348
144349 });
144350 define('ripple/platform/wac/2.0/spec', function (require, exports, module) {
144351 /*
144352  *  Copyright 2011 Intel Corporation.
144353  *
144354  * Licensed under the Apache License, Version 2.0 (the "License");
144355  * you may not use this file except in compliance with the License.
144356  * You may obtain a copy of the License at
144357  *
144358  * http://www.apache.org/licenses/LICENSE-2.0
144359  *
144360  * Unless required by applicable law or agreed to in writing, software
144361  * distributed under the License is distributed on an "AS IS" BASIS,
144362  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144363  * See the License for the specific language governing permissions and
144364  * limitations under the License.
144365  */
144366
144367 module.exports = {
144368
144369     id: "wac",
144370     version: "2.0",
144371     name: "WAC",
144372
144373     persistencePrefix: "wac2-",
144374
144375     config: require('ripple/platform/wac/2.0/spec/config'),
144376     ui: require('ripple/platform/wac/2.0/spec/ui'),
144377     device: require('ripple/platform/wac/2.0/spec/device'),
144378
144379     objects: {
144380         Coordinates: {
144381             path: "w3c/1.0/Coordinates"
144382         },
144383         Position: {
144384             path: "w3c/1.0/Position"
144385         },
144386         PositionError: {
144387             path: "w3c/1.0/PositionError"
144388         },
144389         navigator: {
144390             path: "w3c/1.0/navigator",
144391             children: {
144392                 geolocation: {
144393                     path: "wac/2.0/geolocation",
144394                     feature: "http://www.w3.org/TR/geolocation-API/"
144395                 }
144396             }
144397         },
144398         deviceapis: {
144399             path: "wac/2.0/deviceapis",
144400             feature: "http://wacapps.net/api/deviceapis",
144401             /*
144402              * Before we inject those cloned objects into the simulated application
144403              * namespace, we will handle the feature requests from config.xml.
144404              * Especially for:
144405              * - camera.show, camera.capture
144406              * - devicestatus.deviceinfo, devicestatus.networkinfo
144407              * - filesystem.read, filesystem.write
144408              * - messaging.send, messaging.find, messaging.subscribe, messaging.write
144409              * - pim
144410              *  - contact.read, contact.write
144411              *  - calendar.read, calendar.write
144412              *  - task.read, task.write
144413              */
144414             children: {
144415                 accelerometer: {
144416                     path: "wac/2.0/accelerometer",
144417                     feature: "http://wacapps.net/api/accelerometer"
144418                 },
144419                 orientation: {
144420                     path: "wac/2.0/orientation",
144421                     feature: "http://wacapps.net/api/orientation"
144422                 },
144423                 camera: {
144424                     path: "wac/2.0/camera",
144425                     feature: "http://wacapps.net/api/camera|http://wacapps.net/api/camera.show|http://wacapps.net/api/camera.capture",
144426                     handleSubfeatures: true
144427                 },
144428                 devicestatus: {
144429                     path: "wac/2.0/devicestatus",
144430                     feature: "http://wacapps.net/api/devicestatus|http://wacapps.net/api/devicestatus.deviceinfo|http://wacapps.net/api/devicestatus.networkinfo",
144431                     handleSubfeatures: true
144432                 },
144433                 filesystem: {
144434                     path: "wac/2.0/filesystem",
144435                     feature: "http://wacapps.net/api/filesystem|http://wacapps.net/api/filesystem.read|http://wacapps.net/api/filesystem.write",
144436                     handleSubfeatures: true
144437                 },
144438                 messaging: {
144439                     path: "wac/2.0/messaging",
144440                     feature: "http://wacapps.net/api/messaging|http://wacapps.net/api/messaging.send|http://wacapps.net/api/messaging.find|http://wacapps.net/api/messaging.subscribe|http://wacapps.net/api/messaging.write",
144441                     handleSubfeatures: true
144442                 },
144443                 pim: {
144444                     children: {
144445                         contact: {
144446                             path: "wac/2.0/contact",
144447                             feature: "http://wacapps.net/api/pim.contact|http://wacapps.net/api/pim.contact.read|http://wacapps.net/api/pim.contact.write",
144448                             handleSubfeatures: true
144449                         },
144450                         calendar: {
144451                             path: "wac/2.0/calendar",
144452                             feature: "http://wacapps.net/api/pim.calendar.write|http://wacapps.net/api/pim.calendar.read|http://wacapps.net/api/pim.calendar",
144453                             handleSubfeatures: true
144454                         },
144455                         task: {
144456                             path: "wac/2.0/task",
144457                             feature: "http://wacapps.net/api/pim.task|http://wacapps.net/api/pim.task.read|http://wacapps.net/api/pim.task.write",
144458                             handleSubfeatures: true
144459                         }
144460                     }
144461                 },
144462                 deviceinteraction: {
144463                     path: "wac/2.0/deviceinteraction",
144464                     feature: "http://wacapps.net/api/deviceinteraction"
144465                 }
144466             }
144467         }
144468     }
144469 };
144470
144471
144472 });
144473 define('ripple/platform/wac/2.0/task', function (require, exports, module) {
144474 /*
144475  *  Copyright 2011 Intel Corporation.
144476  *
144477  * Licensed under the Apache License, Version 2.0 (the "License");
144478  * you may not use this file except in compliance with the License.
144479  * You may obtain a copy of the License at
144480  *
144481  * http://www.apache.org/licenses/LICENSE-2.0
144482  *
144483  * Unless required by applicable law or agreed to in writing, software
144484  * distributed under the License is distributed on an "AS IS" BASIS,
144485  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
144486  * See the License for the specific language governing permissions and
144487  * limitations under the License.
144488  */
144489
144490 var db = require('ripple/db'),
144491     utils = require('ripple/utils'),
144492     _console = require('ripple/console'),
144493     exception = require('ripple/exception'),
144494     errorcode = require('ripple/platform/wac/2.0/errorcode'),
144495     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
144496     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
144497     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
144498     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
144499     Task, TaskList, _get,
144500     _ID_WITHOUT = 0, _ID_GEN_NEW = 1, _ID_FROM_PROP = 2,
144501     _SIM_TASK_LIST = 0, _DEVICE_TASK_LIST = 1,
144502     _HIGH_PRIORITY = 0, _MEDIUM_PRIORITY = 1, _LOW_PRIORITY = 2,
144503     _STATUS_COMPLETED = 0, _STATUS_NEEDS_ACTION = 1, _STATUS_IN_PROCESS = 2, _STATUS_CANCELLED = 3,
144504     _TASK_OBJECTS = "wac2.0-pim-task-objects",
144505     _addTaskAllowed = true, _deleteTaskAllowed = true,
144506     _updateTaskAllowed = true, _findTasksAllowed = true;
144507
144508
144509 module.exports = function () {
144510     var _taskListArray = [],
144511         _PENDING_TIME = 10;
144512
144513     function _pendingOperate(operate) {
144514         var pendingObj, pendingOperation, i, argumentVector = [];
144515
144516         for (i = 0; i < arguments.length - 1; i++)
144517             argumentVector[i] = arguments[i + 1];
144518
144519         pendingObj = new PendingObject();
144520
144521         pendingObj.pendingID = window.setTimeout(function () {
144522             pendingObj.setCancelFlag(false);
144523             operate.apply(this, argumentVector);
144524         }, _PENDING_TIME);
144525
144526         pendingOperation = new PendingOperation(pendingObj);
144527
144528         return pendingOperation;
144529     }
144530
144531     /* taskProperties attribute check & paste */
144532     function _checkAndPasteProperties(p, dst) {
144533
144534         if (p.summary !== null && p.summary !== undefined)
144535             dst.summary = String(p.summary);
144536
144537         if (p.description !== null && p.description !== undefined)
144538             dst.description = String(p.description);
144539
144540         if (p.status !== null && p.status !== undefined) {
144541             if (p.status === _STATUS_COMPLETED ||
144542                 p.status === _STATUS_NEEDS_ACTION ||
144543                 p.status === _STATUS_IN_PROCESS ||
144544                 p.status === _STATUS_CANCELLED) {
144545                 dst.status = p.status;
144546             } else
144547                 return false;
144548         }
144549
144550         if (p.priority !== null && p.priority !== undefined) {
144551             if (p.priority === _HIGH_PRIORITY ||
144552                 p.priority === _MEDIUM_PRIORITY ||
144553                 p.priority === _LOW_PRIORITY) {
144554                 dst.priority = p.priority;
144555             } else
144556                 return false;
144557         }
144558
144559         if (p.dueDate !== null && p.dueDate !== undefined) {
144560             if (!wac2_utils.isValidDate(p.dueDate))
144561                 return false;
144562             dst.dueDate = new Date(p.dueDate);
144563         }
144564
144565         /* dueDate is a option properties.
144566            "The default value is undefined.
144567              If no value is provided, the task has no due date."
144568            If p.dueDate is set its default value 'undefined',
144569            we assign default value to dst.dueDate */
144570         if (p.dueDate === undefined) {
144571             dst.dueDate = undefined;
144572         }
144573
144574         return true;
144575     }
144576
144577     function _taskFilterCheck(filter) {
144578         var i;
144579         if (filter.id !== undefined && filter.id !== null) {
144580             filter.id = String(filter.id);
144581         } else {
144582             filter.id = undefined;
144583         }
144584         if (filter.summary !== undefined && filter.summary !== null) {
144585             filter.summary = String(filter.summary);
144586         } else {
144587             filter.summary = undefined;
144588         }
144589         if (filter.description !== undefined && filter.description !== null) {
144590             filter.description = String(filter.description);
144591         } else {
144592             filter.description = undefined;
144593         }
144594         if (filter.status !== undefined && filter.status !== null) {
144595             if (!wac2_utils.isValidArray(filter.status))  {
144596                 return false;
144597             }
144598             for (i = 0; i < filter.status.length; i++) {
144599                 filter.status[i] = filter.status[i] | 0;
144600                 if (filter.status[i] !== _STATUS_COMPLETED &&
144601                     filter.status[i] !== _STATUS_NEEDS_ACTION &&
144602                     filter.status[i] !== _STATUS_IN_PROCESS &&
144603                     filter.status[i] !== _STATUS_CANCELLED) {
144604                     return false;
144605                 }
144606             }
144607         } else {
144608             filter.status = undefined;
144609         }
144610         if (filter.priority !== undefined && filter.priority !== null) {
144611             if (!wac2_utils.isValidArray(filter.priority))  {
144612                 return false;
144613             }
144614             for (i = 0; i < filter.priority.length; i++) {
144615                 filter.priority[i] = filter.priority[i] | 0;
144616                 if (filter.priority[i] !== _HIGH_PRIORITY &&
144617                     filter.priority[i] !== _MEDIUM_PRIORITY &&
144618                     filter.priority[i] !== _LOW_PRIORITY) {
144619                     return false;
144620                 }
144621             }
144622         } else {
144623             filter.priority = undefined;
144624         }
144625         if (filter.dueDate !== undefined && filter.dueDate !== null) {
144626             if (!wac2_utils.isValidDate(filter.dueDate)) {
144627                 return false;
144628             }
144629             filter.dueDate = new Date(filter.dueDate);
144630         } else {
144631             filter.dueDate = undefined;
144632         }
144633         return true;
144634     }
144635
144636     function TaskProperties(prop) {
144637         var _self;
144638         _self = {
144639             priority : _LOW_PRIORITY,
144640             description : "",
144641             summary : "",
144642             dueDate : undefined,
144643             status : _STATUS_NEEDS_ACTION
144644         };
144645         if (prop) {
144646             if (_checkAndPasteProperties(prop, _self) === false)
144647                 return undefined;
144648         }
144649         return _self;
144650     }
144651
144652     function Task(prop, idChoice) {
144653         var id, _self = new TaskProperties(prop);
144654         /* if error occurs during checking, _self is an empty object.
144655            so i randomly pick description to check if property check fails */
144656         if (_self.description === undefined)
144657             return undefined;
144658
144659         switch (idChoice) {
144660         case _ID_WITHOUT:
144661             // do nothing
144662             break;
144663         case _ID_GEN_NEW:
144664             id = Math.uuid(undefined, 16);
144665             _self.__defineGetter__("id", function () {
144666                 return id;
144667             });
144668             break;
144669         case _ID_FROM_PROP:
144670             id = String(prop.id);
144671             _self.__defineGetter__("id", function () {
144672                 return id;
144673             });
144674             break;
144675         }
144676
144677         return _self;
144678     }
144679
144680     function _get() {
144681         var taskListArray = [],
144682             data = db.retrieveObject(_TASK_OBJECTS);
144683         utils.forEach(data, function (taskList) {
144684             for (var t in taskList._list) {
144685                 if (taskList._list[t].dueDate !== undefined &&
144686                     taskList._list[t].dueDate !== null)
144687                     taskList._list[t].dueDate = new Date(taskList._list[t].dueDate);
144688             }
144689             taskListArray.push(new TaskList(taskList._list, taskList.type, taskList.name));
144690         });
144691
144692         /* add default taskList if taskListArray is empty */
144693         if (taskListArray.length === 0) {
144694             taskListArray = [new TaskList({}, 0, "Office tasks"), new TaskList({}, 1, "Home tasks")];
144695         }
144696
144697         return taskListArray;
144698     }
144699
144700     function _save() {
144701         db.saveObject(_TASK_OBJECTS, _taskListArray);
144702     }
144703
144704     function TaskList(taskList, type, name) {
144705         var task;
144706         this._list = taskList;
144707         this.type = type;
144708         this.name = name;
144709
144710         this.createTask = function (properties) {
144711             task = new Task(properties, _ID_WITHOUT);
144712             /* if error occurs during checking, task is an empty object.
144713                so i randomly pick summary to check if property check fails */
144714             if (task.summary === undefined) {
144715                 exception.raise(exception.types.Argument,
144716                         "EventProperties: input parameter contains invalid values",
144717                         new DeviceApiError(errorcode.INVALID_VALUES_ERR));
144718                 return undefined;
144719             }
144720             return task;
144721         };
144722
144723         this.addTask = function (onSuccess, onError, task) {
144724             var inner = this,
144725                 newTask, _task = Object(task);
144726             function _addTask() {
144727                 var ret;
144728                 if (!_addTaskAllowed) {
144729                     if (onError) {
144730                         setTimeout(function () {
144731                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
144732                         }, 1);
144733                     }
144734                     return undefined;
144735                 }
144736                 newTask = new Task(_task, _ID_GEN_NEW);
144737                 /* if error occurs during checking, newTask is an empty object.
144738                     so i randomly pick id to check if property check fails */
144739                 if (newTask.id === undefined) {
144740                     if (onError) {
144741                         setTimeout(function () {
144742                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
144743                         }, 1);
144744                     }
144745                     return undefined;
144746                 }
144747                 ret = _pendingOperate(function () {
144748                     inner._list[newTask.id] = newTask;
144749                     _save();
144750                     onSuccess(new Task(newTask, _ID_FROM_PROP));
144751                 });
144752             }
144753
144754             return wac2_utils.validateTypeMismatch(onSuccess, onError, "addTask", _addTask);
144755         };
144756
144757         this.updateTask = function (onSuccess, onError, task) {
144758             var inner = this,
144759                 newTask, _task = Object(task);
144760             function _updateTask() {
144761                 var ret;
144762                 if (!_updateTaskAllowed) {
144763                     if (onError) {
144764                         setTimeout(function () {
144765                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
144766                         }, 1);
144767                     }
144768                     return undefined;
144769                 }
144770
144771                 if (_checkAndPasteProperties(_task, _task) === false) {
144772                     if (onError) {
144773                         setTimeout(function () {
144774                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
144775                         }, 1);
144776                     }
144777                     return undefined;
144778                 }
144779
144780                 ret = _pendingOperate(function () {
144781                     if (inner._list[_task.id]) {
144782                         newTask = new Task(inner._list[_task.id], _ID_FROM_PROP);
144783                         /* Don't need to double check the return of _checkAndPasteProperties 
144784                            _task has been checked & pasted already */
144785                         _checkAndPasteProperties(_task, newTask);
144786                         inner._list[newTask.id] = newTask;
144787                         _save();
144788                         onSuccess();
144789                     } else {
144790                         if (onError) {
144791                             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
144792                         }
144793                     }
144794                 });
144795                 return ret;
144796             }
144797
144798             return wac2_utils.validateTypeMismatch(onSuccess, onError, "updateTask", _updateTask);
144799         };
144800
144801         this.deleteTask = function (onSuccess, onError, id) {
144802             var inner = this;
144803             function _deleteTask() {
144804                 var ret;
144805                 /* according to spec  "If any of the input parameters are not 
144806                    compatible with the expected type for that parameter, 
144807                    a DeviceAPIError with code TYPE_MISMATCH_ERR MUST be 
144808                    synchronously thrown." so an error is raised synchronously */
144809                 utils.validateArgumentType(id, "string", null,
144810                         "Task:deleteTask: " + " invalid id parameter",
144811                         new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
144812                 if (!_deleteTaskAllowed) {
144813                     if (onError) {
144814                         setTimeout(function () {
144815                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
144816                         }, 1);
144817                     }
144818                     return undefined;
144819                 }
144820                 ret = _pendingOperate(function () {
144821                     if (inner._list[id]) {
144822                         delete inner._list[id];
144823                         _save();
144824                         onSuccess();
144825                     } else {
144826                         if (onError)
144827                             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
144828                     }
144829                 });
144830                 return ret;
144831             }
144832
144833             return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteTask", _deleteTask);
144834         };
144835
144836         this.findTasks = function (onSuccess, onError, filter) {
144837             var inner = this, _filter = Object(filter), tmp = [], rst = [], valid_tmp = false;
144838             function _findTasks() {
144839                 var ret;
144840                 if (!_taskFilterCheck(_filter)) {
144841                     if (onError) {
144842                         setTimeout(function () {
144843                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
144844                         }, 1);
144845                     }
144846                     return undefined;
144847                 }
144848                 if (!_findTasksAllowed) {
144849                     if (onError) {
144850                         setTimeout(function () {
144851                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
144852                         }, 1);
144853                     }
144854                     return undefined;
144855                 }
144856                 ret = _pendingOperate(function () {
144857                     var i, e;
144858                     if (_filter.id !== undefined) {
144859                         tmp = wac2_utils.matchOptionString(inner._list, "id", _filter.id);
144860                         valid_tmp = true;
144861                     }
144862                     if (_filter.summary !== undefined) {
144863                         if (valid_tmp) {
144864                             tmp = wac2_utils.matchOptionString(tmp, "summary", _filter.summary);
144865                         } else {
144866                             tmp = wac2_utils.matchOptionString(inner._list, "summary", _filter.summary);
144867                             valid_tmp = true;
144868                         }
144869                     }
144870                     if (_filter.description !== undefined) {
144871                         if (valid_tmp) {
144872                             tmp = wac2_utils.matchOptionString(tmp, "description", _filter.description);
144873                         } else {
144874                             tmp = wac2_utils.matchOptionString(inner._list, "description", _filter.description);
144875                             valid_tmp = true;
144876                         }
144877                     }
144878                     if (_filter.status !== undefined) {
144879                         if (valid_tmp) {
144880                             tmp = wac2_utils.matchOptionShortArray(tmp, "status", _filter.status);
144881                         } else {
144882                             tmp = wac2_utils.matchOptionShortArray(inner._list, "status", _filter.status);
144883                             valid_tmp = true;
144884                         }
144885                     }
144886                     if (_filter.priority !== undefined) {
144887                         if (valid_tmp) {
144888                             tmp = wac2_utils.matchOptionShortArray(tmp, "priority", _filter.priority);
144889                         } else {
144890                             tmp = wac2_utils.matchOptionShortArray(inner._list, "priority", _filter.priority);
144891                             valid_tmp = true;
144892                         }
144893                     }
144894                     if (_filter.initialDueDate !== undefined ||
144895                         _filter.endDueDate !== undefined) {
144896                         if (valid_tmp) {
144897                             tmp = wac2_utils.matchOptionDate(tmp, "dueDate", _filter.initialDueDate, _filter.endDueDate);
144898                         } else {
144899                             tmp = wac2_utils.matchOptionDate(inner._list, "dueDate", _filter.initialDueDate, _filter.endDueDate);
144900                             valid_tmp = true;
144901                         }
144902                     }
144903
144904                     if (valid_tmp) {
144905                         for (i = 0; i < tmp.length; i++) {
144906                             rst.push(new Task(tmp[i], _ID_FROM_PROP));
144907                         } 
144908                     } else {
144909                         for (e in inner._list) {
144910                             rst.push(new Task(inner._list[e], _ID_FROM_PROP));
144911                         }
144912                     }
144913                     onSuccess(rst);
144914                 });
144915                 return ret;
144916             }
144917
144918             return wac2_utils.validateTypeMismatch(onSuccess, onError, "findTasks", _findTasks);
144919         };
144920     }
144921
144922     this.getTaskLists = function (onSuccess, onError) {
144923         function _getTaskLists() {
144924             var ret;
144925             ret = _pendingOperate(function () {
144926                 if (_taskListArray.length === 0) {
144927                     _taskListArray = _get();
144928                 }
144929                 onSuccess(_taskListArray);
144930             }, 1);
144931             return ret;
144932         }
144933
144934         return wac2_utils.validateTypeMismatch(onSuccess, onError, "getTaskLists", _getTaskLists);
144935     };
144936
144937     this.__defineGetter__("SIM_TASK_LIST", function () {
144938         return 0;
144939     });
144940     this.__defineGetter__("DEVICE_TASK_LIST", function () {
144941         return 1;
144942     });
144943     this.__defineGetter__("HIGH_PRIORITY", function () {
144944         return 0;
144945     });
144946     this.__defineGetter__("MEDIUM_PRIORITY", function () {
144947         return 1;
144948     });
144949     this.__defineGetter__("LOW_PRIORITY", function () {
144950         return 2;
144951     });
144952     this.__defineGetter__("STATUS_COMPLETED", function () {
144953         return 0;
144954     });
144955     this.__defineGetter__("STATUS_NEEDS_ACTION", function () {
144956         return 1;
144957     });
144958     this.__defineGetter__("STATUS_IN_PROCESS", function () {
144959         return 2;
144960     });
144961     this.__defineGetter__("STATUS_CANCELLED", function () {
144962         return 3;
144963     });
144964
144965     this.handleSubFeatures = function (subFeatures) {
144966         if (wac2_utils.isEmptyObject(subFeatures) ||
144967             subFeatures["http://wacapps.net/api/pim.task"] ||
144968             (subFeatures["http://wacapps.net/api/pim.task.read"] &&
144969             subFeatures["http://wacapps.net/api/pim.task.write"])) {
144970             return;
144971         }
144972         if (subFeatures["http://wacapps.net/api/pim.task.read"] &&
144973            !subFeatures["http://wacapps.net/api/pim.task.write"]) {
144974             _addTaskAllowed = false;
144975             _deleteTaskAllowed = false;
144976             _updateTaskAllowed = false;
144977             return;
144978         }
144979         if (subFeatures["http://wacapps.net/api/pim.task.write"] &&
144980            !subFeatures["http://wacapps.net/api/pim.task.read"]) {
144981             _findTasksAllowed = false;
144982             return;
144983         }
144984         _console.warn("WAC-2.0-Task-handleSubFeatures: something wrong");
144985     };
144986
144987 };
144988
144989
144990 });
144991 define('ripple/platform/wac/2.0/pendingoperation', function (require, exports, module) {
144992 /*
144993  *  Copyright 2011 Intel Corporation.
144994  *
144995  * Licensed under the Apache License, Version 2.0 (the "License");
144996  * you may not use this file except in compliance with the License.
144997  * You may obtain a copy of the License at
144998  *
144999  * http://www.apache.org/licenses/LICENSE-2.0
145000  *
145001  * Unless required by applicable law or agreed to in writing, software
145002  * distributed under the License is distributed on an "AS IS" BASIS,
145003  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145004  * See the License for the specific language governing permissions and
145005  * limitations under the License.
145006  */
145007
145008 module.exports = function (pendingObj) {
145009     var pending = true;
145010     this.cancel = function () {
145011         if (pending === true) {
145012             if (typeof (pendingObj.getCancelFlag) === "function" && pendingObj.getCancelFlag() === false) {
145013                 pending = false;
145014                 // this clearTimeout is for the case when a 3rd party is invoked to do the task, and it's finished sooner than the intended timeout. therefore, the 3rd party set CancelFlag false, and this cancel is called before timeout
145015                 clearTimeout(pendingObj.pendingID);
145016                 return false;
145017             }
145018             if (typeof (pendingObj.userCancel) === "function") {
145019                 pendingObj.userCancel();
145020             }
145021             clearTimeout(pendingObj.pendingID);
145022             pending = false;
145023             return true;
145024         } else {
145025             return false;
145026         }
145027     };
145028 };
145029
145030
145031 });
145032 define('ripple/platform/wac/2.0/dbfs', function (require, exports, module) {
145033 /*
145034  *  Copyright 2011 Research In Motion Limited.
145035  *  Copyright 2011 Intel Corporation.
145036  *
145037  * Licensed under the Apache License, Version 2.0 (the "License");
145038  * you may not use this file except in compliance with the License.
145039  * You may obtain a copy of the License at
145040  *
145041  * http://www.apache.org/licenses/LICENSE-2.0
145042  *
145043  * Unless required by applicable law or agreed to in writing, software
145044  * distributed under the License is distributed on an "AS IS" BASIS,
145045  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145046  * See the License for the specific language governing permissions and
145047  * limitations under the License.
145048  */
145049
145050 /* We know the dbfs is not an accurate simulation of WAC 2.0 filesystem.
145051  *
145052  * 1) We have tried W3C File API, as some of WAC filesystem APIs are synchronous, 
145053  * it is impossible to simulate them by using the asynchronous API in the main
145054  * UI thread and although we could use synchronous W3C API in a worker, it is
145055  * not reasonable to limit WAC filesystem API usage in a worker.
145056  *
145057  * 2) The problem is partially solved by using database to simulate the filesystem,
145058  * For the asynchronous aspect, actually all the files are read into memory (cache 
145059  * object in this file) and the cache operation is synchronous. It is not perfect.
145060  * And the database has 5MB limitation when running in Chrome.
145061  *
145062  * In the future, we might use ajax or NPAPI to get a better simulation.
145063  */
145064
145065 /* Note: The entry object is shared between this module and filesystem */
145066
145067 var db = require('ripple/db'),
145068     utils = require('ripple/utils'),
145069     _console = require('ripple/console'),
145070     _cache = {},
145071     _self;
145072
145073 function _get(path) {
145074     return path.replace(/^\//, '').split("/").reduce(function (obj, token) {
145075         return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
145076     }, _cache);
145077 }
145078
145079 function _getInfo(path) {
145080     var parent = ("/" + path.replace(/^\//, '').replace(/\/$/, '')).split("/"),
145081         name = parent.splice(parent.length - 1, 1).join("");
145082
145083     return {
145084         name: name,
145085         parent: parent.join("/") || "/"
145086     };
145087 }
145088
145089 function _set(path, obj) {
145090     var parent = _cache,
145091         tokens = path.replace(/^\//, '').split("/"),
145092         child = tokens.splice(tokens.length - 1, 1).join("");
145093
145094     tokens.forEach(function (token) {
145095         parent = parent.children[token];
145096     });
145097
145098     parent.children = parent.children || {};
145099     parent.children[child] = obj;
145100 }
145101
145102 function _delete(path) {
145103     var parent = _cache,
145104         tokens = path.replace(/^\//, '').split("/"),
145105         child = tokens.splice(tokens.length - 1, 1).join("");
145106
145107     tokens.forEach(function (token) {
145108         parent = parent.children[token];
145109     });
145110
145111     delete parent.children[child];
145112 }
145113
145114 function _save() {
145115     db.saveObject("wac2-db-filesystem", _cache);
145116 }
145117
145118 function _walk(path, parent) { 
145119     _self.ls(path, function (entries) { 
145120         parent.children = parent.children || {}; 
145121
145122         entries.forEach(function (entry) { 
145123             parent.children[entry.name] = entry; 
145124
145125             if (entry.isDirectory) { 
145126                 _walk(entry.fullPath, entry); 
145127             } else { 
145128                 /* after getting Date out of DB, Date will become 
145129                    a string, so need to recast it back to Date */
145130                 if (entry.lastModifiedDate !== null && entry.lastModifiedDate !== undefined)
145131                     entry.lastModifiedDate = new Date(entry.lastModifiedDate);
145132
145133                 _self.read(entry.fullPath, function (data) { 
145134                     parent.children[entry.name].data = data; 
145135                 }, function (e) { 
145136                     _console.error(e); 
145137                 }); 
145138             } 
145139         }); 
145140     }, function (e) { 
145141         _console.error(e); 
145142     }); 
145143
145144  
145145 function _createPath(path) { 
145146     var parts = path.replace(/^\//, '').split("/"), 
145147         workflow = jWorkflow.order(); 
145148  
145149     parts.forEach(function (part, index) { 
145150         var dir = "/" + utils.copy(parts).splice(0, index + 1).join("/"); 
145151  
145152         workflow.andThen(function (prev, baton) { 
145153             baton.take(); 
145154             _self.mkdir(dir, baton.pass, baton.pass); 
145155         }); 
145156     }); 
145157  
145158     workflow.start(); 
145159 }
145160
145161 _self = {
145162     // The order is consistent with _virtualRoots in filesystem.js
145163     roots: ["/opt/documents", "/opt/images", "/opt/music", "/opt/videos", "/opt/downloads", "/home/user/appdata/simulatedapp/wgt-package", "/home/user/appdata/simulatedapp/wgt-private", "/home/user/appdata/simulatedapp/wgt-private-tmp", "/SDCard", "/opt/attachments"],
145164     initialize: function () {
145165         // TODO: Initialize at bootstrap and emulatorBridge.link 
145166         _cache = db.retrieveObject("wac2-db-filesystem") || {};
145167         // create real root paths if empty
145168         _self.roots.every(function (root) {
145169             _createPath(root);
145170             return true;
145171         }); 
145172        // build the file system cache so that we could access information synchronously
145173         _walk("/", _cache);
145174     },
145175     ls: function (path, success, error) {
145176         try {
145177             var dir = _get(path),
145178                 items = [];
145179
145180             if (dir) {
145181                 utils.forEach(dir.children, function (item) {
145182                     items.push(item);
145183                 });
145184             }
145185             else {
145186                 items = {};
145187             }
145188
145189             success(items);
145190         }
145191         catch (e) {
145192             e.code = 1;
145193             error(e);
145194         }
145195     },
145196     rm: function (path, success, error, options) {
145197         _delete(path);
145198         _save();
145199         success();
145200     },
145201     rmdir: function (path, success, error, options) {
145202         _delete(path);
145203         _save();
145204         success();
145205     },
145206     mkdir: function (path, success, error) {
145207         var entry = _get(path),
145208             info = _getInfo(path);
145209
145210         if (!entry) {
145211             _set(path, {
145212                 name: info.name,
145213                 isDirectory: true,
145214                 fullPath: path
145215             });
145216             entry = _get(path);
145217             _save();
145218         }
145219         
145220         if (entry) {
145221             success(entry);
145222         }
145223         else {
145224             error({code: 1});
145225         }
145226     },
145227     mv: function (from, to, success, error) {
145228         try {
145229             var fromEntry = _get(from),
145230                 toInfo = _getInfo(to);
145231
145232             fromEntry.fullPath = to;
145233             fromEntry.name = toInfo.name;
145234
145235             _set(to, fromEntry);
145236             _delete(from);
145237             _save();
145238             success();
145239         }
145240         catch (e) {
145241             e.code = 1;
145242             error(e);
145243         }
145244     },
145245     touch: function (path, success, error) {
145246         var entry = _get(path),
145247             info  = _getInfo(path);
145248
145249         if (!entry) {
145250             _set(path, {
145251                 lastModifiedDate: new Date(),
145252                 name: info.name,
145253                 isDirectory: false,
145254                 fullPath: path,
145255                 data: ""
145256             });
145257             entry = _get(path);
145258         }
145259         _save();
145260         success(entry);
145261     },
145262     cp: function (from, to, success, error) {
145263         try {
145264             var fromEntry = _get(from),
145265                 copied = utils.copy(fromEntry);
145266
145267             copied.name  = _getInfo(to).name;
145268             copied.fullPath = to;
145269             _set(to, copied);
145270             _save();
145271             success();
145272         }
145273         catch (e) {
145274             e.code = 1;
145275             error(e);
145276         }
145277     },
145278     stat: function (path, success, error) {
145279         var entry = _get(path);
145280         
145281         if (entry) {
145282             success(entry);
145283         } else {
145284             error({code: 1});
145285         }
145286     },
145287     write: function (path, contents, success, error, options) {
145288         var entry = _get(path);
145289
145290         if (entry) {
145291             entry.lastModifiedDate = new Date();
145292             entry.data = contents;
145293             _save();
145294             success();
145295         } else {
145296             error({code: 1});
145297         }
145298
145299     },
145300     read: function (path, success, error) {
145301         var entry = _get(path);
145302
145303         if (entry) {
145304             success(utils.copy(entry.data));
145305         }
145306         else {
145307             error({code: 1});
145308         }
145309     }
145310 };
145311
145312 module.exports = _self;
145313
145314
145315 });
145316 define('ripple/platform/wac/2.0/spec/config', function (require, exports, module) {
145317 /*
145318  *  Copyright 2011 Research In Motion Limited.
145319  *
145320  * Licensed under the Apache License, Version 2.0 (the "License");
145321  * you may not use this file except in compliance with the License.
145322  * You may obtain a copy of the License at
145323  *
145324  * http://www.apache.org/licenses/LICENSE-2.0
145325  *
145326  * Unless required by applicable law or agreed to in writing, software
145327  * distributed under the License is distributed on an "AS IS" BASIS,
145328  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145329  * See the License for the specific language governing permissions and
145330  * limitations under the License.
145331  */
145332 var platform = require('ripple/platform'),
145333     utils = require('ripple/utils'),
145334     db = require('ripple/db'),
145335     constants = require('ripple/constants');
145336
145337 module.exports = {
145338     fileName: "config.xml",
145339     validateVersion: function (configValidationObject) {
145340         var valid = true;
145341         // no xmlns:JIL in wac 2.0 spec
145342         valid = !!configValidationObject.widget.validationResult[0].attributes.xmlns.valid;
145343
145344         return valid;
145345     },
145346     extractInfo: function (configValidationObject) {
145347         if (!configValidationObject) {
145348             return null;
145349         }
145350
145351         var widgetInfo = {},
145352             configFeatures,
145353             configPreferences,
145354             preferenceName,
145355             platform;
145356
145357         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
145358         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
145359         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
145360         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
145361
145362         widgetInfo.features = {};
145363
145364         configFeatures = configValidationObject.widget.children.feature.validationResult;
145365         utils.forEach(configFeatures, function (f) {
145366             if (f.valid === true) {
145367                 var feature = {id: f.attributes.name.value,
145368                          required: f.attributes.required.valid};
145369                 widgetInfo.features[feature.id] = feature;
145370             }
145371         });
145372
145373         widgetInfo.preferences = {};
145374
145375         configPreferences = configValidationObject.widget.children.preference.validationResult;
145376
145377         platform = require('ripple/platform');
145378         utils.forEach(configPreferences, function (preference) {
145379             preferenceName = preference.attributes.name.value;
145380             if (preferenceName) {
145381                 widgetInfo.preferences[preferenceName] = {
145382                     "key": preferenceName,
145383                     "value": preference.attributes.value.value || "",
145384                     "readonly": preference.attributes.readonly.value === "true"
145385                 };
145386
145387                 db.save(preferenceName,
145388                         widgetInfo.preferences[preferenceName].value,
145389                         platform.getPersistencePrefix(widgetInfo.id));
145390             }
145391         });
145392
145393         return widgetInfo;
145394     },
145395     schema: {
145396         rootElement: "widget",
145397         widget: {
145398             nodeName: "widget",
145399             required: true,
145400             occurrence: 1,
145401             helpText: "\"widget\" element describes widget information in configuration documents and serves as a container for other elements. It must be used in configuration document and may have following child elments: name,description,icon,author,license,content,feature and preference. \"widget\" element MAY have following attributes: id,version,height,width, defaultlocale, xml:lang and dir",
145402             attributes: {
145403                 xmlns: {
145404                     attributeName: "xmlns",
145405                     required: true,
145406                     type: "list",
145407                     listValues: ["http://www.w3.org/ns/widgets"]
145408                 },
145409                 "xml:lang": {
145410                     attributeName: "xml:lang",
145411                     required: false,
145412                     type: "iso-language"
145413                 },
145414                 dir: {
145415                     attributeName: "dir",
145416                     required: false,
145417                     type: "list",
145418                     listValues: ["ltr", "rtl", "lro", "rlo"]
145419                 },
145420                 id: {
145421                     attributeName: "id",
145422                     required: false,
145423                     type: "string"
145424                 },
145425                 version: {
145426                     attributeName: "version",
145427                     required: false,
145428                     type: "string"
145429                 },
145430                 height: {
145431                     attributeName: "height",
145432                     required: false,
145433                     type: "integer"
145434                 },
145435                 width: {
145436                     attributeName: "width",
145437                     required: false,
145438                     type: "integer"
145439                 },
145440                 viewmodes: {
145441                     attributeName: "viewmodes",
145442                     required: false,
145443                     type: "list",
145444                     listValues: ["windowed", "floating", "fullscreen", "maximized", "minimized"]
145445                 },
145446                 defaultlocale: {
145447                     attributeName: "defaultlocale",
145448                     required: false,
145449                     type: "iso-language"
145450                 },
145451             },
145452             children: {
145453                 name: {
145454                     nodeName: "name",
145455                     required: false,
145456                     occurrence: 0,
145457                     type: "string",
145458                     attributes: {
145459                         "xml:lang": {
145460                             attributeName: "xml:lang",
145461                             required: false,
145462                             type: "iso-language",
145463                             unique: true
145464                         },
145465                         dir: {
145466                             attributeName: "dir",
145467                             required: false,
145468                             type: "list",
145469                             listValues: ["ltr", "rtl", "lro", "rlo"]
145470                         },
145471                         "short": {
145472                             attributeName: "short",
145473                             required: false,
145474                             type: "string"
145475                         }
145476                     },
145477                     children: {
145478                         span: {
145479                             nodeName: "span",
145480                             required: false,
145481                             type: "string",
145482                             attributes: {
145483                                 "xml:lang": {
145484                                     attributeName: "xml:lang",
145485                                     required: false,
145486                                     type: "iso-language",
145487                                     unique: true
145488                                 },
145489                                 dir: {
145490                                     attributeName: "dir",
145491                                     required: false,
145492                                     type: "list",
145493                                     listValues: ["ltr", "rtl", "lro", "rlo"]
145494                                 }
145495                             }
145496                         }
145497                     }
145498                 },
145499                 description: {
145500                     nodeName: "description",
145501                     required: false,
145502                     occurrence: 0,
145503                     type: "string",
145504                     attributes: {
145505                         "xml:lang": {
145506                             attributeName: "xml:lang",
145507                             required: false,
145508                             type: "iso-language",
145509                             unique: true
145510                         },
145511                         dir: {
145512                             attributeName: "dir",
145513                             required: false,
145514                             type: "list",
145515                             listValues: ["ltr", "rtl", "lro", "rlo"]
145516                         }
145517                     },
145518                     children: {
145519                         span: {
145520                             nodeName: "span",
145521                             required: false,
145522                             type: "string",
145523                             attributes: {
145524                                 "xml:lang": {
145525                                     attributeName: "xml:lang",
145526                                     required: false,
145527                                     type: "iso-language",
145528                                     unique: true
145529                                 },
145530                                 dir: {
145531                                     attributeName: "dir",
145532                                     required: false,
145533                                     type: "list",
145534                                     listValues: ["ltr", "rtl", "lro", "rlo"]
145535                                 }
145536                             }
145537                         }
145538                     }
145539                 },
145540                 author: {
145541                     nodeName: "author",
145542                     required: false,
145543                     occurrence: 0,
145544                     type: "string",
145545                     attributes: {
145546                         "xml:lang": {
145547                             attributeName: "xml:lang",
145548                             required: false,
145549                             type: "iso-language",
145550                         },
145551                         dir: {
145552                             attributeName: "dir",
145553                             required: false,
145554                             type: "list",
145555                             listValues: ["ltr", "rtl", "lro", "rlo"]
145556                         },
145557                         href: {
145558                             attributeName: "href",
145559                             required: false,
145560                             type: "regex",
145561                             regex: constants.REGEX.URL
145562                         },
145563                         email: {
145564                             attributeName: "email",
145565                             required: false,
145566                             type: "regex",
145567                             regex: constants.REGEX.EMAIL
145568                         }
145569                     },
145570                     children: {
145571                         span: {
145572                             nodeName: "span",
145573                             required: false,
145574                             type: "string",
145575                             attributes: {
145576                                 "xml:lang": {
145577                                     attributeName: "xml:lang",
145578                                     required: false,
145579                                     type: "iso-language",
145580                                     unique: true
145581                                 },
145582                                 dir: {
145583                                     attributeName: "dir",
145584                                     required: false,
145585                                     type: "list",
145586                                     listValues: ["ltr", "rtl", "lro", "rlo"]
145587                                 }
145588                             }
145589                         }
145590                     }
145591                 },
145592                 license: {
145593                     nodeName: "license",
145594                     required: false,
145595                     occurrence: 0,
145596                     type: "string",
145597                     attributes: {
145598                         "xml:lang": {
145599                             attributeName: "xml:lang",
145600                             required: false,
145601                             type: "iso-language",
145602                         },
145603                         dir: {
145604                             attributeName: "dir",
145605                             required: false,
145606                             type: "list",
145607                             listValues: ["ltr", "rtl", "lro", "rlo"]
145608                         },
145609                         href: {
145610                             attributeName: "href",
145611                             type: "regex",
145612                             required: false,
145613                             regex: constants.REGEX.URL
145614                         }
145615                     },
145616                     children: {
145617                         span: {
145618                             nodeName: "span",
145619                             required: false,
145620                             type: "string",
145621                             attributes: {
145622                                 "xml:lang": {
145623                                     attributeName: "xml:lang",
145624                                     required: false,
145625                                     type: "iso-language",
145626                                     unique: true
145627                                 },
145628                                 dir: {
145629                                     attributeName: "dir",
145630                                     required: false,
145631                                     type: "list",
145632                                     listValues: ["ltr", "rtl", "lro", "rlo"]
145633                                 }
145634                             }
145635                         }
145636                     }
145637                 },
145638                 icon: {
145639                     nodeName: "icon",
145640                     required: false,
145641                     occurrence: 0,
145642                     attributes: {
145643                         "xml:lang": {
145644                             attributeName: "xml:lang",
145645                             required: false,
145646                             type: "iso-language",
145647                         },
145648                         dir: {
145649                             attributeName: "dir",
145650                             required: false,
145651                             type: "list",
145652                             listValues: ["ltr", "rtl", "lro", "rlo"]
145653                         },
145654                         src: {
145655                             attributeName: "src",
145656                             required: true,
145657                             type: "string"
145658                         },
145659                         width: {
145660                             attributeName: "width",
145661                             required: false,
145662                             type: "integer"
145663                         },
145664                         height: {
145665                             attributeName: "height",
145666                             required: false,
145667                             type: "integer"
145668                         }
145669                     }
145670                 },
145671                 content: {
145672                     nodeName: "content",
145673                     required: false,
145674                     occurrence: 1,
145675                     attributes: {
145676                         "xml:lang": {
145677                             attributeName: "xml:lang",
145678                             required: false,
145679                             type: "iso-language",
145680                             unique: true
145681                         },
145682                         dir: {
145683                             attributeName: "dir",
145684                             required: false,
145685                             type: "list",
145686                             listValues: ["ltr", "rtl", "lro", "rlo"]
145687                         },
145688                         src: {
145689                             attributeName: "src",
145690                             required: true,
145691                             type: "string"
145692                         },
145693                         encoding: {
145694                             attributeName: "encoding",
145695                             required: false,
145696                             type: "string"
145697                         },
145698                         type: {
145699                             attributeName: "type",
145700                             required: false,
145701                             type: "string"
145702                         }
145703                     }
145704                 },
145705                 feature: {
145706                     nodeName: "feature",
145707                     required: false,
145708                     occurrence: 0,
145709                     attributes: {
145710                         "xml:lang": {
145711                             attributeName: "xml:lang",
145712                             required: false,
145713                             type: "iso-language",
145714                         },
145715                         dir: {
145716                             attributeName: "dir",
145717                             required: false,
145718                             type: "list",
145719                             listValues: ["ltr", "rtl", "lro", "rlo"]
145720                         },
145721                         name: {
145722                             attributeName: "name",
145723                             required: true,
145724                             type: "list",
145725                             listValues: ["http://www.w3.org/TR/geolocation-API/",
145726                                             "http://wacapps.net/api/deviceapis", "http://wacapps.net/api/accelerometer",
145727                                             "http://wacapps.net/api/orientation", "http://wacapps.net/api/camera",
145728                                             "http://wacapps.net/api/camera.show", "http://wacapps.net/api/camera.capture",
145729                                             "http://wacapps.net/api/devicestatus", "http://wacapps.net/api/devicestatus.deviceinfo",
145730                                             "http://wacapps.net/api/devicestatus.networkinfo", "http://wacapps.net/api/filesystem",
145731                                             "http://wacapps.net/api/filesystem.read", "http://wacapps.net/api/filesystem.write",
145732                                             "http://wacapps.net/api/messaging", "http://wacapps.net/api/messaging.send", 
145733                                             "http://wacapps.net/api/messaging.find", "http://wacapps.net/api/messaging.subscribe",
145734                                             "http://wacapps.net/api/messaging.write", "http://wacapps.net/api/pim.contact",
145735                                             "http://wacapps.net/api/pim.contact.read", "http://wacapps.net/api/pim.contact.write",
145736                                             "http://wacapps.net/api/pim.calendar", "http://wacapps.net/api/pim.calendar.read",
145737                                             "http://wacapps.net/api/pim.calendar.write", "http://wacapps.net/api/pim.task", 
145738                                             "http://wacapps.net/api/pim.task.read", "http://wacapps.net/api/pim.task.write",
145739                                             "http://wacapps.net/api/deviceinteraction"]
145740                         },
145741                         required: {
145742                             attributeName: "required",
145743                             type: "boolean",
145744                             required: false
145745                         }
145746                     },
145747                     children: {
145748                         param: {
145749                             nodeName: "param",
145750                             required: false,
145751                             occurrence: 0,
145752                             attributes: {
145753                                 "xml:lang": {
145754                                     attributeName: "xml:lang",
145755                                     required: false,
145756                                     type: "iso-language",
145757                                 },
145758                                 dir: {
145759                                     attributeName: "dir",
145760                                     required: false,
145761                                     type: "list",
145762                                     listValues: ["ltr", "rtl", "lro", "rlo"]
145763                                 },
145764                                 name: {
145765                                     attributeName: "name",
145766                                     required: true,
145767                                     type: "string",
145768                                 },
145769                                 value: {
145770                                     attributeName: "value",
145771                                     required: true,
145772                                     type: "string",
145773                                 }
145774                             }
145775                         }
145776                     }
145777                 },
145778                 preference: {
145779                     nodeName: "preference",
145780                     required: false,
145781                     occurrence: 0,
145782                     attributes: {
145783                         "xml:lang": {
145784                             attributeName: "xml:lang",
145785                             required: false,
145786                             type: "iso-language",
145787                         },
145788                         dir: {
145789                             attributeName: "dir",
145790                             required: false,
145791                             type: "list",
145792                             listValues: ["ltr", "rtl", "lro", "rlo"]
145793                         },
145794                         name: {
145795                             attributeName: "name",
145796                             required: true,
145797                             type: "string"
145798                         },
145799                         value: {
145800                             type: "string",
145801                             required: false,
145802                             attributeName: "value"
145803                         },
145804                         readonly: {
145805                             attributeName: "readonly",
145806                             type: "boolean",
145807                             required: false
145808                         }
145809                     }
145810                 }
145811             }
145812         }
145813     }
145814 };
145815
145816 });
145817 define('ripple/platform/wac/2.0/spec/device', function (require, exports, module) {
145818 /*
145819  *  Copyright 2011 Intel Corporation.
145820  *
145821  * Licensed under the Apache License, Version 2.0 (the "License");
145822  * you may not use this file except in compliance with the License.
145823  * You may obtain a copy of the License at
145824  *
145825  * http://www.apache.org/licenses/LICENSE-2.0
145826  *
145827  * Unless required by applicable law or agreed to in writing, software
145828  * distributed under the License is distributed on an "AS IS" BASIS,
145829  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145830  * See the License for the specific language governing permissions and
145831  * limitations under the License.
145832  */
145833 var event = require('ripple/event');
145834
145835 function deviceStatusEventTrigger(setting) {
145836     event.trigger("DeviceStatusChanged", [setting]);
145837 }
145838
145839 module.exports = {
145840     "Config": {
145841         "vibratingMode": {
145842             "name": "Vibrator",
145843             "control": {
145844                 "type": "checkbox",
145845                 "value": true
145846             },
145847             "callback": function (setting) {
145848                 event.trigger("VibratingModeChanged", [setting]);
145849             }
145850         },
145851         "soundVolume": {
145852             "name": "Sound Volume",
145853             "control": {
145854                 "type": "range",
145855                 "value": 100,
145856                 "min": 0,
145857                 "max": 100
145858             },
145859             "callback": function (setting) {
145860                 event.trigger("VolumeChanged", [setting]);
145861             }
145862         },
145863         "backlight": {
145864             "name": "Backlight",
145865             "control": {
145866                 "type": "checkbox",
145867                 "value": true
145868             },
145869             "callback": function (setting) {
145870                 event.trigger("BacklightChanged", [setting]);
145871             }
145872         }
145873     },
145874     "Battery": {
145875         "batteryLevel": {
145876             "name": "Battery Remaining %",
145877             "control": {
145878                 "type": "select",
145879                 "value": 100
145880             },
145881             "options": (function () {
145882                 var i,
145883                     optionList = {};
145884
145885                 for (i = 0; i <= 100; i += 10) {
145886                     optionList[i] = i;
145887                 }
145888
145889                 return optionList;
145890             }()),
145891             "event": "BatteryLevelChanged",
145892             "callback": function (setting) {
145893                 event.trigger("BatteryLevelChanged", [setting]);
145894             }
145895         },
145896
145897         "batteryBeingCharged": {
145898             "name": "Battery Is Charging",
145899             "control": {
145900                 "type": "checkbox",
145901                 "value": true
145902             },
145903             "event": "BatteryBeingChargedChanged",
145904             "callback": function (setting) {
145905                 event.trigger("BatteryBeingChargedChanged", [setting]);
145906             }
145907         },
145908     },
145909     "CellularHardware": {
145910         "status": {
145911             "name": "status",
145912             "control": {
145913                 "type": "checkbox",
145914                 "value": true
145915             },
145916             "event": "CellularHardwareStatusChanged",
145917             "callback": function (setting) {
145918                 event.trigger("CellularHardwareStatusChanged", [setting]);
145919             }
145920         }
145921     },
145922     "CellularNetwork": {
145923         "isInRoaming": {
145924             "name": "Roaming",
145925             "control": {
145926                 "type": "checkbox",
145927                 "value": true
145928             },
145929             "event": "CellularNetworkIsInRoamingChanged",
145930             "callback": function (setting) {
145931                 event.trigger("CellularNetworkIsInRoamingChanged", [setting]);
145932             }
145933         }, 
145934         "mcc": {
145935             "name": "mcc",
145936             "control": {
145937                 "type": "text",
145938                 "value": "460",
145939                 "readonly": "readonly"
145940             }
145941         }, 
145942         "mnc": {
145943             "name": "mnc",
145944             "control": {
145945                 "type": "text",
145946                 "value": "0",
145947                 "readonly": "readonly"
145948             }
145949         }, 
145950         "signalStrength": {
145951             "name": "Signal Strength",
145952             "control": {
145953                 "type": "select",
145954                 "value": 100
145955             },
145956             "options": (function () {
145957                 var i,
145958                     optionList = {};
145959
145960                 for (i = 0; i <= 100; i += 10) {
145961                     optionList[i] = i;
145962                 }
145963
145964                 return optionList;
145965             }()),
145966             "event": "CellularNetworkSignalStrengthChanged",
145967             "callback": function (setting) {
145968                 event.trigger("CellularNetworkSignalStrengthChanged", [setting]);
145969             }
145970         }, 
145971         "operatorName": {
145972             "name": "Operator Name",
145973             "control": {
145974                 "type": "text",
145975                 "value": "CMCC",
145976                 "readonly": "readonly"
145977             }
145978         }
145979     },
145980     "Device": {
145981         "imei": {
145982             "name": "IMEI",
145983             "control": {
145984                 "type": "text",
145985                 "value": "860398001689659",
145986                 "readonly": "readonly"
145987             }
145988         }, 
145989         "model": {
145990             "name": "Model",
145991             "control": {
145992                 "type": "text",
145993                 "value": "",
145994                 "readonly": "readonly"
145995             }
145996         }, 
145997         "version": {
145998             "name": "Version",
145999             "control": {
146000                 "type": "text",
146001                 "value": "",
146002                 "readonly": "readonly"
146003             }
146004         }, 
146005         "vendor": {
146006             "name": "Vendor.",
146007             "control": {
146008                 "type": "text",
146009                 "value": "",
146010                 "readonly": "readonly"
146011             }
146012         }
146013     },
146014     "Display": {
146015         "resolutionHeight": {
146016             "name": "Resolution Height",
146017             "control": {
146018                 "type": "number",
146019                 "value": 0,
146020                 "readonly": "readonly"
146021             }
146022         }, 
146023         "resolutionWidth": {
146024             "name": "Resolution Width",
146025             "control": {
146026                 "type": "number",
146027                 "value": 0,
146028                 "readonly": "readonly"
146029             }
146030         }, 
146031         "pixelAspectRatio": {
146032             "name": "Pixel Aspectratio",
146033             "control": {
146034                 "type": "number",
146035                 "value": 0,
146036                 "readonly": "readonly"
146037             }
146038         }, 
146039         "dpiY": {
146040             "name": "DPI-Y",
146041             "control": {
146042                 "type": "number",
146043                 "value": 0,
146044                 "readonly": "readonly"
146045             }
146046         },         
146047         "dpiX": {
146048             "name": "DPI-X",
146049             "control": {
146050                 "type": "number",
146051                 "value": 0,
146052                 "readonly": "readonly"
146053             }
146054         }, 
146055         "colorDepth": {
146056             "name": "Color Depth",
146057             "control": {
146058                 "type": "number",
146059                 "value": 32,
146060                 "readonly": "readonly"
146061             }
146062         }
146063     },
146064     "MemoryUnit": {
146065         "removable": {
146066             "name": "Removable",
146067             "control": {
146068                 "type": "checkbox",
146069                 "value": true,
146070                 "readonly": "readonly"
146071             }
146072         },
146073         "size": {
146074             "name": "Total Memory",
146075             "control": {
146076                 "type": "number",
146077                 "value": 262144,
146078                 "readonly": "readonly"
146079             }
146080         },        
146081         "availableSize": {
146082             "name": "Available Size",
146083             "control": {
146084                 "type": "range",
146085                 "value": 16384,
146086                 "min": 0,
146087                 "max": 262144
146088             },
146089             "event": "MemoryUnitAvailableSizeChanged",
146090             "callback": function (setting) {
146091                 event.trigger("MemoryUnitAvailableSizeChanged", [setting]);
146092             }
146093         }
146094     },
146095     "OperatingSystem": {
146096         "language": {
146097             "name": "Language",
146098             "control": {
146099                 "type": "text",
146100                 "value": "English",
146101                 "readonly": "readonly"
146102             }
146103         }, 
146104         "version": {
146105             "name": "Version",
146106             "control": {
146107                 "type": "text",
146108                 "value": "",
146109                 "readonly": "readonly"
146110             }
146111         }, 
146112         "name": {
146113             "name": "Name",
146114             "control": {
146115                 "type": "text",
146116                 "value": "",
146117                 "readonly": "readonly"
146118             }
146119         }, 
146120         "vendor": {
146121             "name": "Vendor",
146122             "control": {
146123                 "type": "text",
146124                 "value": "",
146125                 "readonly": "readonly"
146126             }
146127         }
146128     },
146129     "WebRuntime": {
146130         "wacVersion": {
146131             "name": "WAC Version",
146132             "control": {
146133                 "type": "text",
146134                 "value": "2.0",
146135                 "readonly": "readonly"
146136             }
146137         }, 
146138         "supportedImageFormats": {
146139             "name": "Image Formats",
146140             "control": {
146141                 "type": "text",
146142                 "value": "gif87, gif89, png, jpeg",
146143                 "readonly": "readonly"
146144             },
146145             "event": "WebRuntimeSupportedImageFormatsChanged",
146146             "callback": function (setting) {
146147                 event.trigger("WebRuntimeSupportedImageFormatsChanged", [setting]);
146148             }
146149         }, 
146150         "version": {
146151             "name": "Web Runtime Version",
146152             "control": {
146153                 "type": "text",
146154                 "value": "1.0",
146155                 "readonly": "readonly"
146156             }
146157         }, 
146158         "name": {
146159             "name": "Web Runtime Name",
146160             "control": {
146161                 "type": "text",
146162                 "value": "Tizen Web Simulator",
146163                 "readonly": "readonly"
146164             }
146165         }, 
146166         "vendor": {
146167             "name": "Vendor Name",
146168             "control": {
146169                 "type": "text",
146170                 "value": "Tizen SDK team",
146171                 "readonly": "readonly"
146172             }
146173         }
146174     },
146175     "WiFiHardware": {
146176         "status": {
146177             "name": "Status",
146178             "control": {
146179                 "type": "checkbox",
146180                 "value": true
146181             },
146182             "event": "WiFiHardwareStatusChanged",
146183             "callback": function (setting) {
146184                 event.trigger("WiFiHardwareStatusChanged", [setting]);
146185             }
146186         }
146187     },
146188     "WiFiNetwork": {
146189         "ssid": {
146190             "name": "SSID",
146191             "control": {
146192                 "type": "text",
146193                 "value": "OfficeWLAN"
146194             },
146195             "event": "WiFiHardwareSsidChanged",
146196             "callback": function (setting) {
146197                 event.trigger("WiFiHardwareSsidChanged", [setting]);
146198             }
146199         }, 
146200         "signalStrength": {
146201             "name": "Signal Strength",
146202             "control": {
146203                 "type": "select",
146204                 "value": 10
146205             },
146206             "options": (function () {
146207                 var i,
146208                     optionList = {};
146209
146210                 for (i = 0; i <= 10; i++) {
146211                     optionList[i] = i;
146212                 }
146213
146214                 return optionList;
146215             }()),
146216             "event": "WiFiHardwareSignalStrengthChanged",
146217             "callback": function (setting) {
146218                 event.trigger("WiFiHardwareSignalStrengthChanged", [setting]);
146219             }
146220         }, 
146221         "networkStatus": {
146222             "name": "Network Status",
146223             "control": {
146224                 "type": "checkbox",
146225                 "value": true
146226             },
146227             "event": "WiFiHardwareNetworkStatusChanged",
146228             "callback": function (setting) {
146229                 event.trigger("WiFiHardwareNetworkStatusChanged", [setting]);
146230             }
146231         }
146232     }
146233 };
146234
146235
146236 });
146237 define('ripple/platform/wac/2.0/spec/ui', function (require, exports, module) {
146238 /*
146239  *  Copyright 2011 Intel Corporation.
146240  *
146241  * Licensed under the Apache License, Version 2.0 (the "License");
146242  * you may not use this file except in compliance with the License.
146243  * You may obtain a copy of the License at
146244  *
146245  * http://www.apache.org/licenses/LICENSE-2.0
146246  *
146247  * Unless required by applicable law or agreed to in writing, software
146248  * distributed under the License is distributed on an "AS IS" BASIS,
146249  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146250  * See the License for the specific language governing permissions and
146251  * limitations under the License.
146252  */
146253 module.exports = {
146254     plugins: [
146255         "accelerometer",
146256         "messaging",
146257         "geoView",
146258         "widgetConfig",
146259         "deviceSettings"
146260     ]
146261 };
146262
146263 });
146264 define('ripple/platform/wac/2.0/pendingObject', function (require, exports, module) {
146265 /*
146266  *  Copyright 2011 Intel Corporation.
146267  *
146268  * Licensed under the Apache License, Version 2.0 (the "License");
146269  * you may not use this file except in compliance with the License.
146270  * You may obtain a copy of the License at
146271  *
146272  * http://www.apache.org/licenses/LICENSE-2.0
146273  *
146274  * Unless required by applicable law or agreed to in writing, software
146275  * distributed under the License is distributed on an "AS IS" BASIS,
146276  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146277  * See the License for the specific language governing permissions and
146278  * limitations under the License.
146279  */
146280
146281 module.exports = function (pendingObj) {
146282     var cancelFlag = true;
146283     this.setCancelFlag = function (flag) {
146284         cancelFlag = flag;
146285     };
146286     this.getCancelFlag = function () {
146287         return cancelFlag;
146288     };
146289     this.userCancel = null;
146290     this.pendingID = null;
146291 };
146292
146293 });
146294 define('ripple/platform/wac/2.0/deviceinteraction', function (require, exports, module) {
146295 /*
146296  *  Copyright 2011 Intel Corporation.
146297  *
146298  * Licensed under the Apache License, Version 2.0 (the "License");
146299  * you may not use this file except in compliance with the License.
146300  * You may obtain a copy of the License at
146301  *
146302  * http://www.apache.org/licenses/LICENSE-2.0
146303  *
146304  * Unless required by applicable law or agreed to in writing, software
146305  * distributed under the License is distributed on an "AS IS" BASIS,
146306  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146307  * See the License for the specific language governing permissions and
146308  * limitations under the License.
146309  */
146310
146311 var notifications = require('ripple/notifications'),
146312     constants = require('ripple/constants'),
146313     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
146314     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
146315     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
146316     errorcode = require('ripple/platform/wac/2.0/errorcode'),
146317     utils = require('ripple/utils'),
146318     event = require('ripple/event'),
146319     deviceSettings = require('ripple/deviceSettings'),
146320     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
146321     _self,
146322     NOTIFY_DURATION_LIMIT = 5000;
146323
146324 function pendingOperation(f) {
146325     var _FAKEWAITTIME = 0,
146326         pendingObj;
146327     
146328     if (_FAKEWAITTIME === 0) {
146329         f();
146330         return undefined;
146331     }
146332     else {
146333         pendingObj = new PendingObject();
146334         pendingObj.pendingID = setTimeout(function () {
146335             pendingObj.setCancelFlag(false);
146336             f();
146337         }, _FAKEWAITTIME);
146338         return new PendingOperation(pendingObj);
146339     }
146340 }
146341
146342 function checkDuration(duration) {
146343     if (duration) {
146344         duration = duration | 0;  
146345         if (duration <= 0 || duration > NOTIFY_DURATION_LIMIT) {
146346             return NOTIFY_DURATION_LIMIT;
146347         } else {
146348             return duration;
146349         }
146350     } else {
146351         return NOTIFY_DURATION_LIMIT;
146352     }
146353 }
146354
146355 function isMute() {
146356     return deviceSettings.retrieve("Config.soundVolume") <= 0;
146357 }
146358
146359 function isInVibrateMode() {
146360     return deviceSettings.retrieve("Config.vibratingMode");
146361 }
146362
146363 function isBacklightOn() {
146364     return deviceSettings.retrieve("Config.backlight");
146365 }
146366
146367 var vibrator = (function () {
146368     var isVibrating = false,
146369         terminateAfterPattern = false,
146370         pattern = null,
146371         pulseIndex = 0,
146372         vibrateTimeout = null,
146373         terminateTimeout = null,
146374         MILLILSECONDS_OF_ONE_VIBRATION = 100,
146375         node = jQuery("#" + constants.COMMON.DEVICE_CONTAINER),
146376         movementIndex = 0,
146377         movement = [{ left: -10 }, { left: 0 }, { left: 10 }, { left: 0 },
146378              {top: -10 }, { top: 0 }, {top: 10 }, { top: 0 }];
146379
146380     function _clearTimeout() {
146381         if (vibrateTimeout) {
146382             clearInterval(vibrateTimeout);
146383             vibrateTimeout = null;        
146384         }
146385         if (terminateTimeout) {
146386             clearTimeout(terminateTimeout);
146387             terminateTimeout = null;        
146388         }
146389     }  
146390     
146391     function stopVibrate() {
146392         isVibrating = false;
146393         _clearTimeout();
146394         node.css({left: 0, top: 0}, MILLILSECONDS_OF_ONE_VIBRATION);
146395     }
146396     
146397     function vibrate() {
146398         //node.animate(movement[movementIndex], MILLILSECONDS_OF_ONE_VIBRATION);
146399         node.css(movement[movementIndex]);
146400         movementIndex = (movementIndex + 1) % 8;
146401     }
146402     
146403     function changePulse() {
146404         //pattern != null
146405         var pulse = pattern[pulseIndex];
146406         if (pulse === '.') vibrate();
146407         ++pulseIndex;
146408         if (pulseIndex >= pattern.length) {
146409             if (terminateAfterPattern) {
146410                 setTimeout(stopVibrate, 1);
146411                 return;
146412             }
146413             pulseIndex = 0;
146414         }
146415     }
146416     
146417     function terminateVibrate() {
146418         terminateAfterPattern = true;
146419         terminateTimeout = null;
146420         if (pattern === null) {
146421             stopVibrate();        
146422         }
146423     }  
146424   
146425     function startVibrate(duration, _pattern) {
146426         if (!isInVibrateMode()) return;
146427         _clearTimeout();
146428         terminateAfterPattern = false;
146429         movementIndex = 0;
146430         
146431         if (_pattern) {
146432             pattern = _pattern;
146433             pulseIndex = 0;
146434             vibrateTimeout = setInterval(changePulse, MILLILSECONDS_OF_ONE_VIBRATION);
146435             if (duration) 
146436                 terminateAfterPattern = false;
146437             else 
146438                 terminateAfterPattern = true;
146439         } else {
146440             pattern = null;
146441             vibrateTimeout = setInterval(vibrate, MILLILSECONDS_OF_ONE_VIBRATION);
146442         }
146443         terminateTimeout = setTimeout(terminateVibrate, checkDuration(duration));        
146444         isVibrating = true;
146445     }
146446
146447     event.on("VibratingModeChanged", function (value) {
146448         if (value === false) {
146449             stopVibrate();
146450         }
146451     });
146452
146453     return {
146454         startVibrate: startVibrate,
146455         stopVibrate: stopVibrate
146456     };
146457 }()); //jslint style
146458
146459 var backlight = (function () {
146460     var timeout = null,
146461         isNotifying = false,
146462         node = jQuery("#" + constants.COMMON.VIEWPORT_CONTAINER);
146463         
146464     function _clearTimeout() {
146465         if (timeout) {
146466             clearTimeout(timeout); 
146467             timeout = null;
146468         }
146469     }
146470     
146471     function _switch(on) {
146472         node.css('opacity', on ? '':'0.4');
146473     }
146474     
146475     function switchOff() {
146476         if (!isNotifying) return;
146477         _clearTimeout();
146478         _switch(false);
146479         isNotifying = false;
146480     }
146481     
146482     function switchOn(duration) {
146483         if (isBacklightOn()) return;
146484         _clearTimeout();
146485         _switch(true);
146486         timeout = setTimeout(switchOff, checkDuration(duration));
146487         isNotifying = true;
146488     }
146489
146490     _switch(isBacklightOn());
146491     event.on("BacklightChanged", function (value) {
146492         _clearTimeout();
146493         isNotifying = false;
146494         _switch(value);
146495     });
146496
146497     return {
146498         switchOn  : switchOn,
146499         switchOff : switchOff
146500     };
146501 }()); //jslint style
146502
146503 var beeper = (function () {
146504     var isBeeping = false,
146505         timeout = null,
146506         beepFile = "beep.wav", //TODO: license issues
146507         errorHandler = null,
146508         _beeper = utils.createElement("audio", {"id": "notify-beeper"});
146509         
146510     document.getElementById("ui").appendChild(_beeper);
146511     _beeper.setAttribute("src", beepFile);
146512     _beeper.setAttribute("loop", "true");
146513     _beeper.load();
146514     
146515     function _clearTimeout() {
146516         if (timeout) {
146517             clearTimeout(timeout);
146518             timeout = false;
146519         }
146520     }
146521     
146522     function raiseError() {
146523         if (errorHandler) {
146524             setTimeout(function () {
146525                 errorHandler(new DeviceApiError(errorcode.UNKNOWN_ERR));
146526             }, 1);
146527         }
146528     }
146529     
146530     function stopBeep() {
146531         _clearTimeout();
146532         if (isBeeping) {
146533             try {
146534                 _beeper.pause();
146535             } catch (e) {}
146536             isBeeping = false;
146537         }
146538     }
146539     
146540     _beeper.addEventListener('error', function () {
146541         stopBeep();
146542         raiseError();
146543     });
146544    
146545     function startBeep(onSuccess, onError, duration) {
146546         errorHandler = onError;
146547         try {
146548             stopBeep();
146549             _beeper.currentTime = 0;
146550             _beeper.play();
146551             isBeeping = true;
146552             timeout = setTimeout(stopBeep, checkDuration(duration));
146553             setTimeout(function () {
146554                 onSuccess();
146555             }, 1);
146556         }catch (e) {
146557             raiseError();
146558         }
146559     }
146560     
146561     event.on("VolumeChanged", function (value) {
146562         value = value | 0;
146563         if (value < 0) value = 0;
146564         else if (value > 100) value = 100;       
146565         _beeper.volume = value / 100.0;
146566     });
146567     
146568     return {
146569         startBeep : startBeep,
146570         stopBeep  : stopBeep
146571     };
146572 }()); //jslint style
146573
146574 module.exports = _self = {
146575
146576     startNotify : function (onSuccess, onError, duration) {
146577         return wac2_utils.validateTypeMismatch(onSuccess, onError, "startNotify", function () {
146578             if (!isMute()) {
146579                 return pendingOperation(function () {
146580                     beeper.startBeep(onSuccess, onError, duration);
146581                 });
146582             } else if (isInVibrateMode()) {
146583                 return _self.startVibrate(onSuccess, onError, duration);
146584             } else {
146585                 return _self.lightOn(onSuccess, onError, duration);
146586             }
146587         });
146588     },
146589
146590     stopNotify : function () {
146591         beeper.stopBeep();
146592         vibrator.stopVibrate();
146593         backlight.switchOff();
146594     },
146595
146596     startVibrate : function (onSuccess, onError, duration, pattern) {       
146597         return wac2_utils.validateTypeMismatch(onSuccess, onError, "startVibrate", function () {
146598             if (pattern) {
146599                 pattern = String(pattern);
146600                 if (!pattern.match(/[\._]{1,10}/)) {
146601                     if (onError) {
146602                         setTimeout(function () {
146603                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
146604                         }, 1);
146605                     }
146606                     return undefined;
146607                 }   
146608             }
146609             
146610             if (!isInVibrateMode()) {
146611                 if (onError) {
146612                     setTimeout(function () {
146613                         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
146614                     }, 1);
146615                 }
146616                 return undefined;          
146617             }
146618   
146619             setTimeout(function () {
146620                 onSuccess();
146621             }, 1);
146622             return pendingOperation(function () {
146623                 vibrator.startVibrate(duration, pattern);
146624             });
146625
146626         });
146627     },
146628     
146629     stopVibrate : function () {
146630         vibrator.stopVibrate();
146631     },
146632
146633     lightOn : function (onSuccess, onError, duration) {
146634         return wac2_utils.validateTypeMismatch(onSuccess, onError, "lightOn", function () {
146635             if (isBacklightOn()) {
146636                 if (onError) {
146637                     setTimeout(function () {
146638                         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
146639                     }, 1);
146640                 }
146641                 return undefined;               
146642             }
146643         
146644             setTimeout(function () {
146645                 onSuccess();
146646             }, 1);
146647             return pendingOperation(function () {
146648                 backlight.switchOn(duration);
146649             });
146650         });
146651     },
146652
146653     lightOff : function () {
146654         backlight.switchOff();
146655     },
146656
146657     setWallpaper : function (onSuccess, onError, fileName) {
146658         //TODO: file name, existance, extension checking.
146659         return wac2_utils.validateTypeMismatch(onSuccess, onError, "setWallpaper", function () {
146660             return pendingOperation(function () {
146661                 notifications.openNotification("normal", "setWallpaper:" + fileName);
146662                 setTimeout(function () {
146663                     onSuccess();
146664                 }, 1);
146665             });
146666         });
146667     }
146668 };
146669
146670
146671 });
146672 define('ripple/platform/wac/2.0/deviceapierror', function (require, exports, module) {
146673 /*
146674  *  Copyright 2011 Intel Corporation.
146675  *
146676  * Licensed under the Apache License, Version 2.0 (the "License");
146677  * you may not use this file except in compliance with the License.
146678  * You may obtain a copy of the License at
146679  *
146680  * http://www.apache.org/licenses/LICENSE-2.0
146681  *
146682  * Unless required by applicable law or agreed to in writing, software
146683  * distributed under the License is distributed on an "AS IS" BASIS,
146684  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146685  * See the License for the specific language governing permissions and
146686  * limitations under the License.
146687  */
146688
146689 var errorcode = require('ripple/platform/wac/2.0/errorcode');
146690
146691 module.exports = function (code) {
146692     for (var c in errorcode) {
146693         var g = errorcode.__lookupGetter__(c);
146694         if (g) {
146695             this.__defineGetter__(c, g);
146696         }
146697     }
146698
146699     this.code = code;
146700     this.message = errorcode.message[code];
146701     this.type =  "";
146702
146703     this.toString = function () {
146704         var result = this.type + ': "' + this.message + '"';
146705
146706         if (this.stack) {
146707             result += "\n" + this.stack;
146708         }
146709         return result;
146710     };
146711 };
146712
146713
146714 });
146715 define('ripple/platform/wac/2.0/camera', function (require, exports, module) {
146716 /*
146717  *  Copyright 2011 Intel Corporation.
146718  *
146719  * Licensed under the Apache License, Version 2.0 (the "License");
146720  * you may not use this file except in compliance with the License.
146721  * You may obtain a copy of the License at
146722  *
146723  * http://www.apache.org/licenses/LICENSE-2.0
146724  *
146725  * Unless required by applicable law or agreed to in writing, software
146726  * distributed under the License is distributed on an "AS IS" BASIS,
146727  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146728  * See the License for the specific language governing permissions and
146729  * limitations under the License.
146730  */
146731
146732 var utils = require('ripple/utils'),
146733     constants = require('ripple/constants'),
146734     _console = require('ripple/console'),
146735     errorcode = require('ripple/platform/wac/2.0/errorcode'),
146736     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
146737     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
146738     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
146739     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils');
146740
146741 module.exports = function () {
146742     var _cameraArray, Camera, _videoStatus = {},
146743         _captureImage, _startVideoCapture,
146744         _doCaptureImage, _doStartVideoCapture,
146745         _doGetPreview, _doGetCameras,
146746         _stopVideoCapture, _createPreviewNode,
146747         _FAKEWAITTIME = 5,
146748         _defaultHighRes = true,
146749         _defaultImageFilename = "_capture.jpg",
146750         _defaultVideoFilename = "_capture.avi",
146751         _captureImageAllowed = true,
146752         _startVideoCaptureAllowed = true,
146753         _stopVideoCaptureAllowed = true,
146754         _createPreviewNodeAllowed = true;
146755
146756     _doCaptureImage = function (onSuccess, onError, capFilename, capHighRes, pendingObj) {
146757         pendingObj.pendingID = setTimeout(function () {
146758             var dname = "", fname = "";
146759             //pretend to do sth.
146760             pendingObj.setCancelFlag(false);  // too late to cancel
146761             if (capFilename.indexOf("/") !== -1) {
146762                 dname = capFilename.replace(/(.*\/)[^\/]+$/i, "$1");
146763                 fname = capFilename.replace(/.*\/([^\/]*)$/i, "$1");
146764                 //replace extension with jpg
146765                 fname = fname.replace(/\.[^\/\.]+$/i, ".jpg");
146766             } else {
146767                 dname = "";
146768                 fname = capFilename.replace(/\.[^\/\.]+$/i, ".jpg");
146769             }
146770             if (fname === "") {
146771                 fname = _defaultImageFilename;
146772             }
146773             if (fname.search(/\.jpg$/) === -1) {
146774                 fname = fname + ".jpg";
146775             }
146776             if (capHighRes) {
146777                 onSuccess(dname + "high-" + fname);
146778             } else {
146779                 onSuccess(dname + "low-" + fname);
146780             }
146781         }, _FAKEWAITTIME);
146782     };
146783
146784     _captureImage = function (onSuccess, onError, options) {
146785         var pendingOperation = {}, pendingObj,
146786             filename = this.id + _defaultImageFilename,
146787             highRes = _defaultHighRes, opt;
146788
146789         if (onSuccess) {
146790             utils.validateArgumentType(onSuccess, "function", null, "captureImage: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
146791         }
146792         if (onError) {
146793             utils.validateArgumentType(onError, "function", null, "captureImage: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
146794         }
146795         if (options) {
146796             opt = new Object(options);
146797             /* NOTE: if desktinationFilename or highRes is not provided by
146798                user, i.e. undefined or null, a default value is used.
146799              */
146800             if (opt.destinationFilename !== null && opt.destinationFilename !== undefined) {
146801             // TODO: validate filename via Filesystem.resolve()
146802                 filename = String(opt.destinationFilename);
146803             }
146804             if (opt.highRes !== null && opt.highRes !== undefined) {
146805                 highRes = Boolean(opt.highRes);
146806             }
146807         }
146808         if (!_captureImageAllowed) {
146809             if (onError) {
146810                 setTimeout(function () {
146811                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
146812                 }, 1);
146813             }
146814             return undefined;
146815         }
146816
146817         if (onSuccess) {
146818             pendingObj = new PendingObject();
146819             _doCaptureImage(onSuccess, onError, filename, highRes, pendingObj);
146820             pendingOperation = new PendingOperation(pendingObj);
146821             return pendingOperation;
146822         } else {
146823             if (onError) {
146824                 setTimeout(function () {
146825                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
146826                 }, 1);
146827             }
146828         }
146829         return undefined;
146830     };
146831
146832     _stopVideoCapture = function () {
146833         var dname = "", fname = "", capFilename = _videoStatus[this.id].capFilename;
146834         if (_videoStatus[this.id]) {
146835             if (capFilename.indexOf("/") !== -1) {
146836                 dname = capFilename.replace(/(.*\/)[^\/]+$/i, "$1");
146837                 fname = capFilename.replace(/.*\/([^\/]*)$/i, "$1");
146838                 //replace extension with avi
146839                 fname = fname.replace(/\.[^\/\.]+$/i, ".avi");
146840             } else {
146841                 dname = "";
146842                 fname = capFilename.replace(/\.[^\/\.]+$/i, ".avi");
146843             }
146844             if (fname === "") {
146845                 fname = _defaultVideoFilename;
146846             }
146847             if (fname.search(/\.avi$/) === -1) {
146848                 fname = fname + ".avi";
146849             }
146850             if (_videoStatus[this.id].capHighRes) {
146851                 _videoStatus[this.id].capSuccess(dname + "high-" + fname);
146852             } else {
146853                 _videoStatus[this.id].capSuccess(dname + "low-" + fname);
146854             }
146855             delete _videoStatus[this.id];
146856         }
146857     };
146858
146859     _doStartVideoCapture = function (camID, onSuccess, onError, filename, highRes, pendingObj) {
146860         var videoStatus = {};
146861         _videoStatus[camID] = videoStatus;
146862         pendingObj.userCancel = function () {
146863             delete _videoStatus[camID];
146864         };
146865         pendingObj.getCancelFlag = function () {
146866             return !!_videoStatus[camID];
146867         };
146868         pendingObj.pendingID = setTimeout(function () {
146869             // waiting to be cancelled
146870             videoStatus = {
146871                 capSuccess: onSuccess,
146872                 capError: onError,
146873                 capFilename: filename,
146874                 capHighRes: highRes
146875             };
146876             _videoStatus[camID] = videoStatus;
146877         }, _FAKEWAITTIME);
146878     };
146879
146880     _startVideoCapture = function (onSuccess, onError, options) {
146881         var pendingOperation = {}, pendingObj,
146882             filename = this.id + _defaultVideoFilename,
146883             highRes = _defaultHighRes, opt;
146884
146885         if (onSuccess) {
146886             utils.validateArgumentType(onSuccess, "function", null, "startVideoCapture: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
146887         }
146888         if (onError) {
146889             utils.validateArgumentType(onError, "function", null, "startVideoCapture: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
146890         }
146891         if (options) {
146892             opt = new Object(options);
146893             /* NOTE: if desktinationFilename or highRes is not provided by
146894                user, i.e. undefined or null, a default value is used.
146895              */
146896             if (opt.destinationFilename !== null && opt.destinationFilename !== undefined) {
146897             // TODO: validate filename via Filesystem.resolve()
146898                 filename = String(opt.destinationFilename);
146899             }
146900             if (opt.highRes !== null && opt.highRes !== undefined) {
146901                 highRes = Boolean(opt.highRes);
146902             }
146903         }
146904         if (!_captureImageAllowed) {
146905             if (onError) {
146906                 setTimeout(function () {
146907                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
146908                 }, 1);
146909             }
146910             return undefined;
146911         }
146912         if (_videoStatus[this.id]) { 
146913             // capture already started
146914             _console.warn("WAC-2.0-startVideoCapture: capture already started");
146915             if (onError) {
146916                 setTimeout(function () {
146917                     onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
146918                 }, 1);
146919             }
146920             return undefined;
146921         }
146922
146923         if (onSuccess) {
146924             pendingObj = new PendingObject();
146925             _doStartVideoCapture(this.id, onSuccess, onError, filename, highRes, pendingObj);
146926             
146927             pendingOperation = new PendingOperation(pendingObj);
146928             return pendingOperation;
146929         } else {
146930             if (onError) {
146931                 setTimeout(function () {
146932                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
146933                 }, 1);
146934             }
146935         }
146936         return undefined;
146937     };
146938
146939     _doGetPreview = function (camID, onSuccess, onError, pendingObj) {
146940         var container, demoImg, loc, imageSrc;
146941         container = document.createElement("div");
146942         container.setAttribute("id", camID + "-wac-2-0-camera-preview-container");
146943         demoImg = document.createElement("img");
146944         demoImg.setAttribute("id", camID + "-wac-2-0-camera-demo-image");
146945         loc = document.location;
146946         imageSrc = loc.protocol + "//" + loc.hostname + loc.pathname.replace(/index\.html$/, "") + constants.CAMERA.WINDOW_ANIMATION;
146947         demoImg.setAttribute("src", imageSrc);
146948         demoImg.setAttribute("width", "100%");
146949         container.appendChild(demoImg);
146950         
146951         pendingObj.pendingID = setTimeout(function () {
146952             pendingObj.setCancelFlag(false);  // too late to cancel
146953             onSuccess(container);
146954         }, _FAKEWAITTIME);
146955     };
146956
146957     _createPreviewNode = function (onSuccess, onError) {
146958         var pendingOperation, pendingObj = {};
146959         if (onSuccess) {
146960             utils.validateArgumentType(onSuccess, "function", null, "createPreviewNode: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
146961         }
146962         if (onError) {
146963             utils.validateArgumentType(onError, "function", null, "createPreviewNode: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
146964         }
146965         if (!_createPreviewNodeAllowed) {
146966             if (onError) {
146967                 setTimeout(function () {
146968                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
146969                 }, 1);
146970             }
146971             return undefined;
146972         }
146973         if (onSuccess) {
146974             pendingObj = new PendingObject();
146975             _doGetPreview(this.id, onSuccess, onError, pendingObj);
146976             pendingOperation = new PendingOperation(pendingObj);
146977             return pendingOperation;
146978         } else {
146979             if (onError) {
146980                 setTimeout(function () {
146981                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
146982                 }, 1);
146983             }
146984         }
146985         return undefined;
146986     };
146987
146988     Camera = function (cameraID) {
146989         return {
146990             id: cameraID,
146991             captureImage: _captureImage,
146992             startVideoCapture: _startVideoCapture,
146993             stopVideoCapture: _stopVideoCapture,
146994             createPreviewNode: _createPreviewNode
146995         };
146996     };
146997
146998     _cameraArray = [new Camera("rear"), new Camera("front")];
146999
147000     _doGetCameras = function (onSuccess, onError, pendingObj) {
147001         pendingObj.pendingID = setTimeout(function () {
147002             pendingObj.setCancelFlag(false);  // too late to cancel
147003             if (_cameraArray.length !== 0) {
147004                 onSuccess(utils.copy(_cameraArray));
147005             } else {
147006                 // no camera
147007                 if (onError) {
147008                     setTimeout(function () {
147009                         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
147010                     }, 1);
147011                 }
147012             }
147013         }, _FAKEWAITTIME);
147014     };
147015
147016     this.getCameras = function (onSuccess, onError) {
147017         var pendingOperation, pendingObj = {};
147018         if (onSuccess) {
147019             utils.validateArgumentType(onSuccess, "function", null, "getCameras: invalid successCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
147020         }
147021         if (onError) {
147022             utils.validateArgumentType(onError, "function", null, "getCameras: invalid errorCallback parameter", new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
147023         }
147024         if (onSuccess) {
147025             pendingObj = new PendingObject();
147026             _doGetCameras(onSuccess, onError, pendingObj);
147027             pendingOperation = new PendingOperation(pendingObj);
147028             return pendingOperation;
147029         } else {
147030             if (onError) {
147031                 setTimeout(function () {
147032                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
147033                 }, 1);
147034             }
147035         }
147036         return undefined;
147037     };
147038
147039     this.handleSubFeatures = function (subFeatures) {
147040         if (wac2_utils.isEmptyObject(subFeatures) ||
147041             subFeatures["http://wacapps.net/api/camera"] ||
147042             (subFeatures["http://wacapps.net/api/camera.capture"] &&
147043             subFeatures["http://wacapps.net/api/camera.show"])) {
147044             return;
147045         }
147046         if (subFeatures["http://wacapps.net/api/camera.show"] &&
147047            !subFeatures["http://wacapps.net/api/camera.capture"]) {
147048             _captureImageAllowed = false;
147049             _startVideoCaptureAllowed = false;
147050             _stopVideoCaptureAllowed = false;
147051             return;
147052         }
147053         if (subFeatures["http://wacapps.net/api/camera.capture"] &&
147054            !subFeatures["http://wacapps.net/api/camera.show"]) {
147055             _createPreviewNodeAllowed = false;
147056             return;
147057         }
147058         _console.warn("WAC-2.0-Camera-handleSubFeatures: something wrong");
147059     };
147060 };
147061
147062 });
147063 define('ripple/platform/wac/2.0/wac2_utils', function (require, exports, module) {
147064 /*
147065  *  Copyright 2011 Intel Corporation.
147066  *
147067  * Licensed under the Apache License, Version 2.0 (the "License");
147068  * you may not use this file except in compliance with the License.
147069  * You may obtain a copy of the License at
147070  *
147071  * http://www.apache.org/licenses/LICENSE-2.0
147072  *
147073  * Unless required by applicable law or agreed to in writing, software
147074  * distributed under the License is distributed on an "AS IS" BASIS,
147075  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147076  * See the License for the specific language governing permissions and
147077  * limitations under the License.
147078  */
147079
147080 var utils = require('ripple/utils'),
147081     errorcode = require('ripple/platform/wac/2.0/errorcode'),
147082     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror');
147083
147084 module.exports = {
147085     _wac2_regexSanitize: function (regexString) {
147086         var escapePattern = /([^\\]|^)(%)/g, percentPattern = /\\%/g;
147087         return regexString.replace("^", "\\^")
147088                 .replace("$", "\\$")
147089                 .replace("(", "\\(")
147090                 .replace(")", "\\)")
147091                 .replace("<", "\\<")
147092                 .replace("[", "\\[")
147093                 .replace("{", "\\{")
147094                 .replace(/\\([^%])/, "\\\\$1")    /* don't replace \\% */
147095                 .replace("|", "\\|")
147096                 .replace(">", "\\>")
147097                 .replace(".", "\\.")
147098                 .replace("*", "\\*")
147099                 .replace("+", "\\+")
147100                 .replace("?", "\\?")
147101                 .replace(escapePattern, "$1.*")  /* replace % with .* */
147102                 .replace(percentPattern, "%");   /* strip excape of % */ 
147103     }, 
147104
147105     isValidDate: function (d) {
147106         if (Object.prototype.toString.call(d) !== "[object Date]")
147107             return false;
147108         return !isNaN(d.getTime());
147109     },
147110
147111     isValidArray: function (a) {
147112         return (Object.prototype.toString.call(a) === "[object Array]");
147113     },
147114     
147115     matchOptionArrayString: function (src, attr, pattern) {
147116         /* src.obj[attr] is a StringArray */
147117         var _pattern, re, _stringMatch;
147118         _pattern = this._wac2_regexSanitize(pattern); 
147119         re = new RegExp("^" + _pattern + "$", "i");
147120
147121         _stringMatch = function (obj, index) {
147122             if (pattern.search(/^%*$/i) === 0) 
147123                 return true;
147124             if (obj[attr] === undefined || obj[attr] === null)
147125                 return false;
147126             return obj[attr].some(function (f) {
147127                 return f.search(re) !== -1;
147128             });
147129         };
147130         return utils.filter(src, _stringMatch);
147131     },
147132
147133     matchOptionString: function (src, attr, pattern) {
147134         /* src.obj[attr] is a string */
147135         var _stringMatch, _pattern, _re;
147136         _pattern = this._wac2_regexSanitize(pattern); 
147137         _re = new RegExp("^" + _pattern + "$", "mi");
147138
147139         _stringMatch = function (obj, index) {
147140             return (obj[attr].search(_re) !== -1);
147141         };
147142         return utils.filter(src, _stringMatch);
147143     },
147144
147145     matchOptionDate: function (src, attr, filterStart, filterEnd) {
147146         var _dateMatch;
147147         _dateMatch = function (obj, index) {
147148             var matched = true, valueDate = obj[attr];
147149     
147150             if (filterStart !== undefined && filterStart !== null) {
147151                 matched = (valueDate.getTime() >= filterStart.getTime());
147152             }
147153             if (matched && (filterEnd !== undefined && filterEnd !== null)) {
147154                 matched = (valueDate.getTime() <= filterEnd.getTime());
147155             }
147156             return matched;
147157         };
147158         return utils.filter(src, _dateMatch);
147159     },
147160
147161     matchOptionShortArray: function (src, attr, filterArray) {
147162         /* src.obj[attr] is a short, filterArray is an array 
147163            i.e. find status is [CONFRIMED or TENTATIVE] */
147164         var arraySome = function (obj, index) {
147165             return filterArray.some(function (f) {
147166                 return f === obj[attr];  
147167             });
147168         };
147169         return utils.filter(src, arraySome);
147170     },
147171
147172     validateTypeMismatch: function (onSuccess, onError, name, callback) {
147173         if (onSuccess) {
147174             utils.validateArgumentType(onSuccess, "function", null,
147175                                        name + " invalid successCallback parameter",
147176                                        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
147177         }
147178
147179         if (onError) {
147180             utils.validateArgumentType(onError, "function", null,
147181                                        name + " invalid errorCallback parameter",
147182                                        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
147183         }
147184
147185         if (onSuccess) {
147186             return callback && callback();
147187         } else {
147188             if (onError) {
147189                 setTimeout(function () {
147190                     onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
147191                 }, 1);
147192             }
147193         }
147194         return undefined;
147195     },
147196
147197     isEmptyObject: function (obj) {
147198         var prop;
147199
147200         for (prop in obj) {
147201             return false;
147202         }
147203         return true;
147204     }
147205 };
147206
147207
147208 });
147209 define('ripple/platform/wac/2.0/contactfilter', function (require, exports, module) {
147210 /*\r
147211  *  Copyright 2011 Intel Corporation.\r
147212  *\r
147213  * Licensed under the Apache License, Version 2.0 (the "License");\r
147214  * you may not use this file except in compliance with the License.\r
147215  * You may obtain a copy of the License at\r
147216  *\r
147217  * http://www.apache.org/licenses/LICENSE-2.0\r
147218  *\r
147219  * Unless required by applicable law or agreed to in writing, software\r
147220  * distributed under the License is distributed on an "AS IS" BASIS,\r
147221  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
147222  * See the License for the specific language governing permissions and\r
147223  * limitations under the License.\r
147224  */\r
147225 \r
147226 var utils = require('ripple/utils'),\r
147227     _self;\r
147228 \r
147229 _self = function (criteria) {\r
147230     var pattern,\r
147231         contactFilter;\r
147232 \r
147233     contactFilter = {\r
147234         match: function (target) {\r
147235             var result = false, key, value, index;\r
147236 \r
147237             switch (Object.prototype.toString.call(target)) {\r
147238             case "[object String]":\r
147239                 result = pattern.test(target);\r
147240                 break;\r
147241 \r
147242             case "[object Object]":\r
147243                 for (key in criteria) {\r
147244                     result = true;\r
147245                     value = criteria[key];\r
147246                     if ((value !== undefined) && (!_self(value).match(target[key])))\r
147247                         return false;\r
147248                 }\r
147249                 break;\r
147250 \r
147251             case "[object Array]":\r
147252                 for (index in target) {\r
147253                     if (contactFilter.match(target[index]))\r
147254                         return true;\r
147255                 }\r
147256                 break;\r
147257             }\r
147258 \r
147259             return result;\r
147260         }\r
147261     };\r
147262 \r
147263     if (typeof criteria === "string")\r
147264         pattern = new RegExp(criteria.replace(/(^|[^\\])%+/g, "$1.*").replace(/\\%/g, "%").replace(/.*/, "^$&$"), "i");\r
147265 \r
147266     return contactFilter;\r
147267 };\r
147268 \r
147269 module.exports = _self;\r
147270
147271 });
147272 define('ripple/platform/wac/2.0/contact', function (require, exports, module) {
147273 /*
147274  *  Copyright 2011 Intel Corporation.
147275  *
147276  * Licensed under the Apache License, Version 2.0 (the "License");
147277  * you may not use this file except in compliance with the License.
147278  * You may obtain a copy of the License at
147279  *
147280  * http://www.apache.org/licenses/LICENSE-2.0
147281  *
147282  * Unless required by applicable law or agreed to in writing, software
147283  * distributed under the License is distributed on an "AS IS" BASIS,
147284  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147285  * See the License for the specific language governing permissions and
147286  * limitations under the License.
147287  */
147288
147289 var utils = require('ripple/utils'),
147290     db = require('ripple/db'),
147291     constants = require('ripple/constants'),
147292     exception = require('ripple/exception'),
147293     errorcode = require('ripple/platform/wac/2.0/errorcode'),
147294     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
147295     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
147296     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
147297     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
147298     TypeCoerce = require('ripple/platform/wac/2.0/typecoerce'),
147299     Filter = require('ripple/platform/wac/2.0/contactfilter'),
147300     AddressBook,
147301     ContactProperties,
147302     Contact,
147303     Address,
147304     ContactAddress,
147305     PhoneNumber,
147306     EmailAddress,
147307     ContactFilter,
147308     _KEY = "wac2-pim-contact",
147309     _PENDING_TIME = 600,
147310     _addressBooks = [],
147311     _contacts = {},
147312     _security = {
147313         "http://wacapps.net/api/pim.contact": [],
147314         "http://wacapps.net/api/pim.contact.read": ["findContacts"],
147315         "http://wacapps.net/api/pim.contact.write": ["addContact", "updateContact", "deleteContact"],
147316         all: true
147317     },
147318     _self;
147319
147320 function _errorOccurred(onError, code) {
147321     if (!onError)
147322         return;
147323
147324     setTimeout(function () {
147325         onError(new DeviceApiError(code));
147326     }, 1);
147327 }
147328
147329 function _pendingOperate(operate, scope) {
147330     var i, argumentVector = [];
147331
147332     for (i = 0; i < arguments.length - 2; i++)
147333         argumentVector[i] = arguments[i + 2];
147334
147335     return function () {
147336         var pendingObj, pendingOperation;
147337
147338         pendingObj = new PendingObject();
147339         pendingObj.pendingID = window.setTimeout(function () {
147340             pendingObj.setCancelFlag(false);
147341             operate.apply(scope, argumentVector);
147342         }, _PENDING_TIME);
147343
147344         pendingOperation = new PendingOperation(pendingObj);
147345
147346         return pendingOperation;
147347     };
147348 }
147349
147350 function _defaultContacts() {
147351     var id1 = Math.uuid(null, 16),
147352         id2 = Math.uuid(null, 16),
147353         id3 = Math.uuid(null, 16),
147354         id4 = Math.uuid(null, 16),
147355         contacts = {};
147356
147357     contacts.PHONE_ADDRESS_BOOK = {
147358         type: _self().PHONE_ADDRESS_BOOK,
147359         items: [{
147360             id: id1,
147361             firstName: "Leonardo",
147362             lastName: "Gates",
147363             nicknames: ["Leo"],
147364             phoneticName: "",
147365             addresses: [{streetAddress: "Gran Via, 32", postalCode: "50013", city: "Zaragoza", country: "ES"}],
147366             photoURI: "",
147367             phoneNumbers: [],
147368             emails: ["leo@underground.com"]
147369         }, {
147370             id: id2,
147371             firstName: "Jordan",
147372             lastName: "",
147373             nicknames: [""],
147374             phoneticName: "",
147375             addresses: [],
147376             photoURI: "",
147377             phoneNumbers: [],
147378             emails: ["jordan@underground.com"]
147379         }]
147380     };
147381
147382     contacts.SIM_ADDRESS_BOOK = {
147383         type: _self().SIM_ADDRESS_BOOK,
147384         items: [{
147385             id: id3,
147386             firstName: "Raphael",
147387             lastName: "",
147388             nicknames: [""],
147389             phoneticName: "",
147390             addresses: [],
147391             photoURI: "",
147392             phoneNumbers: [],
147393             emails: ["raph@underground.com"]
147394         }]
147395     };
147396
147397     contacts.DEVICE_ADDRESS_BOOK = {
147398         type: _self().DEVICE_ADDRESS_BOOK,
147399         items: [{
147400             id: id4,
147401             firstName: "Michelangelo",
147402             lastName: "",
147403             nicknames: [""],
147404             phoneticName: "",
147405             addresses: [],
147406             photoURI: "",
147407             phoneNumbers: [],
147408             emails: ["mike@underground.com"]
147409         }]
147410     };
147411
147412     return contacts;
147413 }
147414
147415 function _get() {
147416     _contacts = db.retrieveObject(_KEY) || _defaultContacts();
147417 }
147418
147419 function _save() {
147420     db.saveObject(_KEY, _contacts);
147421 }
147422
147423 function _initAddressBooks() {
147424     _get();
147425     utils.forEach(_contacts, function (contactObj, name) {
147426         _addressBooks.push(new AddressBook(contactObj.type, name));
147427     });
147428 }
147429
147430 _self = function () {
147431     var contact = {
147432         getAddressBooks: function (successCallback, errorCallback) {
147433             function _getAddressBooks() {
147434                 if (_addressBooks.length === 0) {
147435                     _initAddressBooks();
147436                 }
147437                 successCallback(_addressBooks);
147438             }
147439             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "getAddressBooks", _getAddressBooks);
147440         },
147441
147442         handleSubFeatures: function (subFeatures) {
147443             for (var subFeature in subFeatures) {
147444                 if (_security[subFeature].length === 0) {
147445                     _security.all = true;
147446                     return;
147447                 }
147448                 _security.all = false;
147449                 utils.forEach(_security[subFeature], function (method) {
147450                     _security[method] = true;
147451                 });
147452             }
147453         }
147454     };
147455
147456     contact.__defineGetter__("SIM_ADDRESS_BOOK", function () {
147457         return 0x0000;
147458     });
147459
147460     contact.__defineGetter__("DEVICE_ADDRESS_BOOK", function () {
147461         return 0x000F;
147462     });
147463
147464     contact.__defineGetter__("PHONE_ADDRESS_BOOK", function () {
147465         return 0x00FF;
147466     });
147467
147468     return contact;
147469 };
147470
147471 AddressBook = function (type, name) {
147472     var addressBook,
147473         contactItems = _contacts[name].items;
147474
147475     addressBook = {
147476         createContact: function (contactProperties) {
147477             var cp, contact = new Contact();
147478
147479             if ((contactProperties !== undefined) &&
147480                 (contactProperties !== null)) {
147481                 cp = TypeCoerce(ContactProperties).cast(contactProperties);
147482                 !cp.firstName    || (contact.firstName    = utils.copy(cp.firstName));
147483                 !cp.lastName     || (contact.lastName     = utils.copy(cp.lastName));
147484                 !cp.nicknames    || (contact.nicknames    = utils.copy(cp.nicknames));
147485                 !cp.phoneticName || (contact.phoneticName = utils.copy(cp.phoneticName));
147486                 !cp.addresses    || (contact.addresses    = utils.copy(cp.addresses));
147487                 !cp.photoURI     || (contact.photoURI     = utils.copy(cp.photoURI));
147488                 !cp.phoneNumbers || (contact.phoneNumbers = utils.copy(cp.phoneNumbers));
147489                 !cp.emails       || (contact.emails       = utils.copy(cp.emails));
147490             }
147491
147492             return contact;
147493         },
147494
147495         addContact: function (successCallback, errorCallback, contact) {
147496             function _addContact() {
147497                 var c;
147498
147499                 if (!contact)
147500                     exception.raise(exception.types.Argument, "addContact invalid message parameter", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
147501
147502                 if (!_security.all && !_security.addContact)
147503                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
147504
147505                 c = TypeCoerce(new Contact()).cast(contact);
147506                 contactItems.push(c);
147507                 _save();
147508                 successCallback(c);
147509             }
147510             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "addContact", _pendingOperate(_addContact));
147511         },
147512
147513         updateContact: function (successCallback, errorCallback, contact) {
147514             function _updateContact() {
147515                 var c, isFound = false;
147516
147517                 if (!contact)
147518                     exception.raise(exception.types.Argument, "updateContact invalid message parameter", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
147519
147520                 if (!_security.all && !_security.updateContact)
147521                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
147522
147523                 c = TypeCoerce(new Contact()).cast(contact);
147524                 utils.forEach(contactItems, function (contactItem) {
147525                     if (contactItem.id === c.id) {
147526                         !c.firstName    || (contactItem.firstName    = utils.copy(c.firstName));
147527                         !c.lastName     || (contactItem.lastName     = utils.copy(c.lastName));
147528                         !c.nicknames    || (contactItem.nicknames    = utils.copy(c.nicknames));
147529                         !c.phoneticName || (contactItem.phoneticName = utils.copy(c.phoneticName));
147530                         !c.addresses    || (contactItem.addresses    = utils.copy(c.addresses));
147531                         !c.photoURI     || (contactItem.photoURI     = utils.copy(c.photoURI));
147532                         !c.phoneNumbers || (contactItem.phoneNumbers = utils.copy(c.phoneNumbers));
147533                         !c.emails       || (contactItem.emails       = utils.copy(c.emails));
147534
147535                         _save();
147536                         isFound = true;
147537                         successCallback();
147538                     }
147539                 });
147540
147541                 if (!isFound)
147542                     _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
147543             }
147544             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "updateContact", _pendingOperate(_updateContact));
147545         },
147546
147547         deleteContact: function (successCallback, errorCallback, id) {
147548             function _deleteContact() {
147549                 var isFound = false;
147550
147551                 if (!_security.all && !_security.deleteContact)
147552                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
147553
147554                 utils.forEach(contactItems, function (contactItem, index) {
147555                     if (contactItem.id === id) {
147556                         contactItems.splice(index, 1);
147557                         _save();
147558                         isFound = true;
147559                         successCallback();
147560                     }
147561                 });
147562
147563                 if (!isFound)
147564                     _errorOccurred(errorCallback, errorcode.NOT_FOUND_ERR);
147565             }
147566             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "deleteContact", _pendingOperate(_deleteContact));
147567         },
147568
147569         findContacts: function (successCallback, errorCallback, filter) {
147570             function _findContacts() {
147571                 var contact, result = [];
147572
147573                 if (!_security.all && !_security.findContacts)
147574                     return _errorOccurred(errorCallback, errorcode.SECURITY_ERR);
147575
147576                 utils.forEach(contactItems, function (contactItem) {
147577                     if ((filter              === undefined || filter === null) ||
147578                         (filter.id           === undefined || Filter(filter.id).match(contactItem.id)) &&
147579                         (filter.firstName    === undefined || Filter(filter.firstName).match(contactItem.firstName)) &&
147580                         (filter.lastName     === undefined || Filter(filter.lastName).match(contactItem.lastName)) &&
147581                         (filter.phoneticName === undefined || Filter(filter.phoneticName).match(contactItem.phoneticName)) &&
147582                         (filter.nickname     === undefined || Filter(filter.nickname).match(contactItem.nicknames)) &&
147583                         (filter.phoneNumber  === undefined || Filter(filter.phoneNumber).match(contactItem.phoneNumbers)) &&
147584                         (filter.email        === undefined || Filter(filter.email).match(contactItem.emails)) &&
147585                         (filter.address      === undefined || Filter(filter.address).match(contactItem.addresses))) {
147586                         contact = new Contact(contactItem.id);
147587
147588                         contact.firstName    = utils.copy(contactItem.firstName);
147589                         contact.lastName     = utils.copy(contactItem.lastName);
147590                         contact.nicknames    = utils.copy(contactItem.nicknames);
147591                         contact.phoneticName = utils.copy(contactItem.phoneticName);
147592                         contact.addresses    = utils.copy(contactItem.addresses);
147593                         contact.photoURI     = utils.copy(contactItem.photoURI);
147594                         contact.phoneNumbers = utils.copy(contactItem.phoneNumbers);
147595                         contact.emails       = utils.copy(contactItem.emails);
147596
147597                         result.push(contact);
147598                     }
147599                 });
147600                 successCallback(result);
147601             }
147602             return wac2_utils.validateTypeMismatch(successCallback, errorCallback, "findContacts", _pendingOperate(_findContacts));
147603         }
147604     };
147605
147606     addressBook.__defineGetter__("type", function () {
147607         return type;
147608     });
147609
147610     addressBook.__defineGetter__("name", function () {
147611         return name;
147612     });
147613
147614     return addressBook;
147615 };
147616
147617 Address = {
147618     country: "",
147619     region: "",
147620     county: "",
147621     city: "",
147622     streetAddress: "",
147623     additionalInformation: "",
147624     postalCode: ""
147625 };
147626
147627 ContactAddress = function () {
147628     this.types = [""]; // "WORK", "PREF", "HOME"
147629 };
147630
147631 ContactAddress.prototype = Address;
147632
147633 PhoneNumber = {
147634     number: "",
147635     types: [""] // "WORK", "PREF", "HOME", "VOICE", "FAX", "MSG", "CELL",
147636                 // "PAGER", "BBS", "MODEM", "CAR", "ISDN", "VIDEO", "PCS"
147637 };
147638
147639 EmailAddress = {
147640     email: "",
147641     types: [""] // "WORK", "PREF", "HOME"
147642 };
147643
147644 ContactProperties = {
147645     firstName: "",
147646     lastName: "",
147647     nicknames: [""],
147648     phoneticName: "",
147649     addresses: [new ContactAddress()],
147650     photoURI: "",
147651     phoneNumbers: [PhoneNumber],
147652     emails: [EmailAddress]
147653 };
147654
147655 Contact = function (id) {
147656     id = id || Math.uuid(null, 16);
147657
147658     this.__defineGetter__("id", function () {
147659         return id;
147660     });
147661 };
147662
147663 Contact.prototype = ContactProperties;
147664
147665 ContactFilter = {
147666     id: "",
147667     firstName: "",
147668     lastName: "",
147669     phoneticName: "",
147670     nickname: "",
147671     phoneNumber: "",
147672     email: "",
147673     address: ""
147674 };
147675
147676 module.exports = _self;
147677
147678 });
147679 define('ripple/platform/wac/2.0/orientation', function (require, exports, module) {
147680 /*
147681  *  Copyright 2011 Intel Corporation.
147682  *
147683  * Licensed under the Apache License, Version 2.0 (the "License");
147684  * you may not use this file except in compliance with the License.
147685  * You may obtain a copy of the License at
147686  *
147687  * http://www.apache.org/licenses/LICENSE-2.0
147688  *
147689  * Unless required by applicable law or agreed to in writing, software
147690  * distributed under the License is distributed on an "AS IS" BASIS,
147691  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147692  * See the License for the specific language governing permissions and
147693  * limitations under the License.
147694  */
147695
147696 var utils = require('ripple/utils'),
147697     event = require('ripple/event'),
147698     Rotation = function (alpha, beta, gamma) {
147699         return {
147700             alpha: alpha || 0,
147701             beta:  beta  || 0,
147702             gamma: gamma || 0
147703         };
147704     },
147705     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
147706     _rotationInfo = new Rotation(),
147707     _defaultInterval = 100,
147708     _watches = {},
147709     _self;
147710
147711 module.exports = _self = {
147712     getCurrentOrientation: function (onSuccess, onError) {
147713         function _getCurrentOrientation() {
147714             setTimeout(function () {
147715                 onSuccess(utils.copy(_rotationInfo));
147716             }, 1);
147717             return null;
147718         }
147719
147720         return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCurrentOrientation", _getCurrentOrientation);
147721     },
147722
147723     watchOrientation: function (orientationSuccess, orientationError, options) {
147724         function _watchOrientation() {
147725             var watchId = (new Date()).getTime() | 0,
147726                 watchObj = {},
147727                 opt = Object(options),
147728                 minNotificationInterval = opt.minNotificationInterval | 0,
147729                 orientationInterval = _defaultInterval;
147730
147731             if (minNotificationInterval > 0) {
147732                 orientationInterval = minNotificationInterval;
147733             }
147734
147735             watchObj = {
147736                 onSuccess: orientationSuccess,
147737                 onError: orientationError,
147738                 interval: orientationInterval
147739             };
147740
147741             _watches[watchId] = watchObj;
147742
147743             _watches[watchId].intervalId = setInterval(function () {
147744                 _self.getCurrentOrientation(_watches[watchId].onSuccess, _watches[watchId].onError);
147745             }, _watches[watchId].interval);
147746
147747             return watchId;
147748         }
147749
147750         return wac2_utils.validateTypeMismatch(orientationSuccess, orientationError, "watchOrientation", _watchOrientation);
147751     },
147752
147753     clearWatch: function (watchId) {
147754
147755         var id = watchId | 0;
147756         if (_watches[id]) {
147757             clearInterval(_watches[id].intervalId);
147758             delete(_watches[id]);
147759             return null;
147760         }
147761
147762         return undefined;
147763     }
147764 };
147765
147766 event.on("AccelerometerInfoChangedEvent", function (orientationInfo) {
147767     _rotationInfo.alpha = orientationInfo.orientation.alpha;
147768     _rotationInfo.beta  = orientationInfo.orientation.beta;
147769     _rotationInfo.gamma = orientationInfo.orientation.gamma;
147770 });
147771
147772
147773 });
147774 define('ripple/platform/wac/2.0/geolocation', function (require, exports, module) {
147775 /*
147776  *  Copyright 2011 Intel Corporation.
147777  *
147778  * Licensed under the Apache License, Version 2.0 (the "License");
147779  * you may not use this file except in compliance with the License.
147780  * You may obtain a copy of the License at
147781  *
147782  * http://www.apache.org/licenses/LICENSE-2.0
147783  *
147784  * Unless required by applicable law or agreed to in writing, software
147785  * distributed under the License is distributed on an "AS IS" BASIS,
147786  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147787  * See the License for the specific language governing permissions and
147788  * limitations under the License.
147789  */
147790
147791 var geo = require('ripple/geo'),
147792     Position = require('ripple/platform/w3c/1.0/Position'),
147793     PositionError = require('ripple/platform/w3c/1.0/PositionError'),
147794     _lastPosition = null,
147795     _watches = {},
147796     _defaultInterval = 100,
147797     _defaultDelay = 50,
147798     _self;
147799
147800 function _createPosition() {
147801     var position = new Position(),
147802         positionInfo = geo.getPositionInfo();
147803
147804     position.coords.latitude = positionInfo.latitude;
147805     position.coords.longitude = positionInfo.longitude;
147806     position.coords.altitude = positionInfo.altitude;
147807     position.coords.altitudeAccuracy = positionInfo.altitudeAccuracy;
147808     position.coords.accuracy = positionInfo.accuracy;
147809     position.coords.heading = positionInfo.heading;
147810     position.coords.speed = positionInfo.speed;
147811     position.timestamp = positionInfo.timeStamp.getTime();
147812
147813     return position;
147814 }
147815
147816 function _isValid(onSuccess, onError, options, argLength) {
147817     if (argLength < 1 || argLength > 3)
147818         return false;
147819
147820     if (typeof onSuccess !== "function")   // imply onSuccess == null
147821         return false;
147822
147823     if (onError && (typeof onError !== "function"))
147824         return false;
147825
147826     if ((options !== undefined) &&
147827         ((typeof options !== "object") ||
147828         (options.enableHighAccuracy !== undefined) && (typeof options.enableHighAccuracy !== "boolean") ||
147829         (options.timeout            !== undefined) && (typeof options.timeout            !== "number") ||
147830         (options.maximumAge         !== undefined) && (typeof options.maximumAge         !== "number")))
147831         return false;
147832
147833     return true;
147834 }
147835
147836 function _processOptions(options) {
147837     var validOptions = {
147838         enableHighAccuracy: false,
147839         timeout: 0,
147840         maximumAge: 0
147841     };
147842
147843     if (options !== undefined &&
147844         options.maximumAge !== undefined &&
147845         options.maximumAge === Math.floor(options.maximumAge) &&
147846         options.maximumAge >= 0) {
147847         validOptions.maximumAge = options.maximumAge | 0;
147848     } else {
147849         validOptions.maximumAge = 0;
147850     }
147851
147852     if (options !== undefined &&
147853         options.timeout !== undefined &&
147854         options.timeout === Math.floor(options.timeout)) {
147855         validOptions.timeout = (options.timeout >= 0) ? (options.timeout | 0) : 0;
147856     } else {
147857         validOptions.timeout = Infinity;
147858     }
147859
147860     if (options !== undefined && options.enableHighAccuracy !== undefined) {
147861         validOptions.enableHighAccuracy = options.enableHighAccuracy;
147862     } else {
147863         validOptions.enableHighAccuracy = false;
147864     }
147865
147866     validOptions.delay = geo.delay * 1000 || _defaultDelay;
147867
147868     return validOptions;
147869 }
147870
147871 function _errorOccur(code, onError) {
147872     if (!onError)
147873         return;
147874
147875     var error = new PositionError();
147876
147877     error.code = code;
147878     switch (code) {
147879     case PositionError.POSITION_UNAVAILABLE:
147880         error.message = "Position unavailable";
147881         break;
147882
147883     case PositionError.TIMEOUT:
147884         error.message = "Position timed out";
147885         break;
147886     }
147887
147888     onError(error);
147889 }
147890
147891 function _execute(data) {
147892     return function () {
147893         if (_lastPosition !== null &&
147894             ((new Date()).getTime() - _lastPosition.timestamp <= data.maximumAge)) {
147895             window.setTimeout(function () {
147896                 data.onSuccess(_lastPosition);
147897             }, 1);
147898         } else if (data.timeout === 0) {
147899             _errorOccur(PositionError.TIMEOUT, data.onError);
147900         } else {
147901             window.setTimeout(function () {
147902                 if (data.delay <= data.timeout) {
147903                     _lastPosition = _createPosition();
147904
147905                     if (_lastPosition !== null) {
147906                         data.onSuccess(_lastPosition);
147907                     } else {
147908                         _errorOccur(PositionError.POSITION_UNAVAILABLE, data.onError);
147909                     }
147910                 } else {
147911                     _errorOccur(PositionError.TIMEOUT, data.onError);
147912                 }
147913             }, Math.min(data.delay, data.timeout));
147914         }
147915     };
147916 }
147917
147918 function _interval(k, n) { 
147919     return k * Math.floor((n + k - 1) / k) || k;
147920 }
147921
147922 _self = {
147923     getCurrentPosition: function (onSuccess, onError, options) {
147924         if (!_isValid(onSuccess, onError, options, arguments.length))
147925             return;
147926
147927         var validData = _processOptions(options);
147928
147929         validData.onSuccess = onSuccess;
147930         validData.onError   = onError;
147931
147932         _execute(validData)();
147933     },
147934
147935     watchPosition: function (geolocationSuccess, geolocationError, geolocationOptions) {
147936         if (!_isValid(geolocationSuccess, geolocationError, geolocationOptions, arguments.length))
147937             return undefined;
147938
147939         var validData = _processOptions(geolocationOptions),
147940             watchId = (new Date()).getTime() | 0,
147941             watchObj = {
147942                 onSuccess:          geolocationSuccess,
147943                 onError:            geolocationError,
147944                 enableHighAccuracy: validData.enableHighAccuracy,
147945                 timeout:            validData.timeout,
147946                 maximumAge:         validData.maximumAge,
147947                 delay:              validData.delay,
147948                 interval:           _interval(validData.maximumAge || _defaultInterval,
147949                                         Math.min(validData.delay, validData.timeout)),
147950             };
147951
147952         _watches[watchId] = watchObj;
147953
147954         _watches[watchId].intervalId = window.setInterval(_execute(_watches[watchId]),
147955             _watches[watchId].interval);
147956
147957         return watchId;
147958     },
147959
147960     clearWatch: function (watchId) {
147961         if (arguments.length !== 1)
147962             return undefined;
147963
147964         var id = watchId | 0;
147965
147966         if (_watches[id]) {
147967             window.clearInterval(_watches[id].intervalId);
147968             delete _watches[id];
147969
147970             return null;
147971         }
147972
147973         return undefined;
147974     }
147975 };
147976
147977 module.exports = _self;
147978
147979 });
147980 define('ripple/platform/wac/2.0/deviceapis', function (require, exports, module) {
147981 /*
147982  *  Copyright 2011 Intel Corporation.
147983  *
147984  * Licensed under the Apache License, Version 2.0 (the "License");
147985  * you may not use this file except in compliance with the License.
147986  * You may obtain a copy of the License at
147987  *
147988  * http://www.apache.org/licenses/LICENSE-2.0
147989  *
147990  * Unless required by applicable law or agreed to in writing, software
147991  * distributed under the License is distributed on an "AS IS" BASIS,
147992  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
147993  * See the License for the specific language governing permissions and
147994  * limitations under the License.
147995  */
147996
147997 var platform = require('ripple/platform'),
147998     app = require('ripple/app'),
147999     utils = require('ripple/utils'),
148000     init_done = false,
148001     _activatedSet = {},
148002     _activatedFeatures = [],
148003     _availableSet = {},
148004     _availableFeatures = [],
148005     _features = {},
148006     initFeaturesSet,
148007     populateFeatures;
148008
148009 populateFeatures = function (objects) {
148010     utils.forEach(objects, function (obj, key) {
148011         var objFeatures = {}, rpt, i, j;
148012         if (obj.feature) {
148013             objFeatures = obj.feature.split('|');
148014             utils.forEach(objFeatures, function (feature) {
148015                 var avail = {uri: feature,
148016                              required: false,
148017                              param: null};
148018                 _availableSet[feature] = avail;
148019             });
148020             if (_features) {
148021                 rpt = objFeatures.length;
148022                 j = 0;
148023                 for (i = 0; i < rpt; i++) {
148024                     if (!_features[objFeatures[j]]) {
148025                         objFeatures.splice(j, 1);
148026                     } else {
148027                         j++;
148028                     }
148029                 }
148030             }
148031             utils.forEach(objFeatures, function (feature) {
148032                 var avail = {uri: feature,
148033                              required: true,
148034                              param: null};
148035                 _activatedSet[feature] = avail;
148036             });
148037         }
148038         if (obj.children) {
148039             populateFeatures(obj.children);
148040         }
148041     });
148042 };
148043
148044 initFeaturesSet = function () {
148045     _features = utils.copy(app.getInfo().features);
148046     populateFeatures(platform.current().objects);
148047     utils.forEach(_activatedSet, function (obj, key) {
148048             _activatedFeatures.push(obj);
148049         });
148050     utils.forEach(_availableSet, function (obj, key) {
148051             _availableFeatures.push(obj);
148052         });
148053     init_done = true;
148054 };
148055
148056 module.exports = {
148057     listAvailableFeatures: function () {
148058         if (!init_done)
148059             initFeaturesSet();
148060         return _availableFeatures;
148061     },
148062
148063     listActivatedFeatures: function () {
148064         if (!init_done)
148065             initFeaturesSet();
148066         return _activatedFeatures;
148067     }
148068 };
148069
148070
148071 });
148072 define('ripple/platform/wac/2.0/calendar', function (require, exports, module) {
148073 /*
148074  *  Copyright 2011 Intel Corporation.
148075  *
148076  * Licensed under the Apache License, Version 2.0 (the "License");
148077  * you may not use this file except in compliance with the License.
148078  * You may obtain a copy of the License at
148079  *
148080  * http://www.apache.org/licenses/LICENSE-2.0
148081  *
148082  * Unless required by applicable law or agreed to in writing, software
148083  * distributed under the License is distributed on an "AS IS" BASIS,
148084  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148085  * See the License for the specific language governing permissions and
148086  * limitations under the License.
148087  */
148088
148089 var db = require('ripple/db'),
148090     utils = require('ripple/utils'),
148091     exception = require('ripple/exception'),
148092     constants = require('ripple/constants'),
148093     errorcode = require('ripple/platform/wac/2.0/errorcode'),
148094     PendingOperation = require('ripple/platform/wac/2.0/pendingoperation'),
148095     PendingObject = require('ripple/platform/wac/2.0/pendingObject'),
148096     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
148097     _console = require('ripple/console'),
148098     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
148099     _SIM_CALENDAR = 0, _DEVICE_CALENDAR = 1,
148100     _NO_RECURRENCE = 0, _DAILY_RECURRENCE = 1, _WEEKLY_RECURRENCE = 2,
148101     _MONTHLY_RECURRENCE = 3, _YEARLY_RECURRENCE = 4,
148102     _TENTATIVE_STATUS = 0, _CONFIRMED_STATUS = 1, _CANCELLED_STATUS = 2,
148103     _NO_ALARM = 0, _SILENT_ALARM = 1, _SOUND_ALARM = 2,
148104     _calendars = [], _DB_CALENDARS_KEY = "wac2-db-calendars",
148105     _FAKEWAITTIME = 5, _FAKE_LONG_WAITTIME = 10,
148106     _save_calendars, _eventPropCheck, _eventFilterCheck,
148107     _addEventAllowed = true, _deleteEventAllowed = true,
148108     _updateEventAllowed = true, _findEventsAllowed = true,
148109     CalendarEventProperties, Calendar, CalendarEvent;
148110
148111 _save_calendars = function (_name, _type, _events) {
148112     var i;
148113     for (i = 0; i < _calendars.length; i++) {
148114         if (_calendars[i].name === _name && _calendars[i].type === _type) {
148115             _calendars[i].events = _events;
148116             break;
148117         }
148118     }
148119     db.saveObject(_DB_CALENDARS_KEY, _calendars);
148120 };
148121
148122 _eventPropCheck = function (prop, dst) {
148123     var i;
148124     if (prop.description !== null && prop.description !== undefined) {
148125         dst.description = String(prop.description);
148126     }
148127     if (prop.summary !== null && prop.summary !== undefined) {
148128         dst.summary = String(prop.summary);
148129     } 
148130     if (prop.startTime !== null && prop.startTime !== undefined) {
148131         if (!wac2_utils.isValidDate(prop.startTime)) {
148132             return false;
148133         }
148134         dst.startTime = new Date(prop.startTime);
148135     }
148136     dst.duration = prop.duration | 0;
148137     if (prop.location !== null && prop.location !== undefined) {
148138         dst.location = String(prop.location);
148139     }
148140     if (prop.categories !== null && prop.categories !== undefined) {
148141         if (!wac2_utils.isValidArray(prop.categories))  {
148142             return false;
148143         }
148144         dst.categories = [];
148145         for (i = 0; i < prop.categories.length; i++) {
148146             dst.categories.push(String(prop.categories[i]));
148147         }
148148     }
148149     if (prop.recurrence !== null && prop.recurrence !== undefined) {
148150         if (prop.recurrence === _NO_RECURRENCE ||
148151             prop.recurrence === _DAILY_RECURRENCE ||
148152             prop.recurrence === _WEEKLY_RECURRENCE ||
148153             prop.recurrence === _MONTHLY_RECURRENCE ||
148154             prop.recurrence === _YEARLY_RECURRENCE) {
148155             dst.recurrence = prop.recurrence | 0;
148156         } else {
148157             return false;
148158         }
148159     }
148160     if (dst.recurrence === _NO_RECURRENCE) {
148161         dst.expires = null;
148162         dst.interval = null;
148163     } else {
148164         // expires and interval matters when recurrence is not NO_RECURRENCE
148165         if (prop.expires !== null && prop.expires !== undefined) {
148166             if (!wac2_utils.isValidDate(prop.expires)) {
148167                 return false;
148168             }
148169             dst.expires = new Date(prop.expires);
148170         }
148171         // expires === undefined -> to recur indefinitely
148172         // expires === null -> keep dst.expires unchanged, even it's null
148173         if (prop.expires === undefined) {
148174             dst.expires = null;
148175         }
148176         if (prop.interval !== null && prop.interval !== undefined) {
148177             dst.interval = prop.interval | 0;
148178         }
148179     }
148180
148181     if (prop.status !== null && prop.status !== undefined) {
148182         if (prop.status === _TENTATIVE_STATUS ||
148183             prop.status === _CONFIRMED_STATUS ||
148184             prop.status === _CANCELLED_STATUS) {
148185             dst.status = prop.status | 0;
148186         } else {
148187             return false;
148188         }
148189     }
148190
148191     if (prop.alarmType !== null && prop.alarmType !== undefined) {
148192         if (prop.alarmType === _NO_ALARM ||
148193             prop.alarmType === _SILENT_ALARM ||
148194             prop.alarmType === _SOUND_ALARM) {
148195             dst.alarmType = prop.alarmType;
148196         } else {
148197             return false;
148198         }
148199     } 
148200     if (dst.alarmType !== _NO_ALARM && prop.alarmTrigger !== undefined && prop.alarmTrigger !== undefined) {
148201         dst.alarmTrigger = prop.alarmTrigger | 0;
148202     }
148203 };
148204
148205 _eventFilterCheck = function (filter) {
148206     if (filter.id !== undefined && filter.id !== null) {
148207         filter.id = String(filter.id);
148208     } else {
148209         filter.id = undefined;
148210     }
148211     if (filter.summary !== undefined && filter.summary !== null) {
148212         filter.summary = String(filter.summary);
148213     } else {
148214         filter.summary = undefined;
148215     }
148216     if (filter.description !== undefined && filter.description !== null) {
148217         filter.description = String(filter.description);
148218     } else {
148219         filter.description = undefined;
148220     }
148221     if (filter.location !== undefined && filter.location !== null) {
148222         filter.location = String(filter.location);
148223     } else {
148224         filter.location = undefined;
148225     }
148226     if (filter.catetory !== undefined && filter.catetory !== null) {
148227         filter.catetory = String(filter.catetory);
148228     } else {
148229         filter.catetory = undefined;
148230     }
148231     if (filter.status !== undefined && filter.status !== null) {
148232         var i;
148233         if (!wac2_utils.isValidArray(filter.status))  {
148234             return false;
148235         }
148236         for (i = 0; i < filter.status.length; i++) {
148237             filter.status[i] = filter.status[i] | 0;
148238             if (filter.status[i] > _CANCELLED_STATUS || filter.status[i] < _TENTATIVE_STATUS)
148239                 return false;
148240         }
148241     } else {
148242         filter.status = undefined;
148243     }
148244     if (filter.initialStartDate !== undefined && filter.initialStartDate !== null) {
148245         if (!wac2_utils.isValidDate(filter.initialStartDate)) {
148246             return false;
148247         }
148248         filter.initialStartDate = new Date(filter.initialStartDate);
148249     } else {
148250         filter.initialStartDate = undefined;
148251     }
148252     if (filter.endStartDate !== undefined && filter.endStartDate !== null) {
148253         if (!wac2_utils.isValidDate(filter.endStartDate)) {
148254             return false;
148255         }
148256         filter.endStartDate = new Date(filter.endStartDate);
148257     } else {
148258         filter.endStartDate = undefined;
148259     }
148260     return true;
148261 };
148262
148263 CalendarEventProperties = function (prop) {
148264     var _self;
148265     _self = {
148266         description : "",
148267         summary : "",
148268         startTime : new Date(),
148269         duration : 0,
148270         location : "",
148271         categories : undefined,
148272         recurrence : _NO_RECURRENCE,
148273         expires : null,  // ignored if recurrence == NO_RECURRENCE
148274         interval : null, // ignored if recurrence == NO_RECURRENCE
148275         status : _CONFIRMED_STATUS,
148276         alarmTrigger : 0,
148277         alarmType : _NO_ALARM
148278     };
148279     if (prop) {
148280         if (_eventPropCheck(prop, _self) === false) {
148281             return undefined;
148282         }
148283     }
148284     return _self;
148285 };
148286
148287 CalendarEvent = function (prop, genNewID) {
148288     var id, _self = new CalendarEventProperties(prop);
148289
148290     /* if error occurs during checking, _self is an empty object.
148291        so i randomly pick description to check if property check fails */
148292     if (_self.description === undefined) {
148293         return undefined;
148294     }
148295
148296     if (genNewID === true) {
148297         id = Math.uuid(undefined, 16);
148298     } else {
148299         id = prop.id;
148300     }
148301     _self.__defineGetter__("id", function () {
148302         return id;
148303     });
148304     return _self;
148305 };
148306
148307 Calendar = function (type, name, events) {
148308     var _type = type,
148309         _name = name,
148310         _events = events, _self;
148311
148312     _self = {
148313         createEvent: function (evtProp) {
148314             var rst = {};
148315             rst = new CalendarEventProperties(evtProp);
148316             /* if error occurs during checking, rst is an empty object.
148317                so i randomly pick description to check if property check fails */
148318             if (rst.description === undefined) {
148319                 exception.raise(exception.types.Argument, "EventProperties: input parameter contains invalid values", new DeviceApiError(errorcode.INVALID_VALUES_ERR));
148320                 return undefined;
148321             } else {
148322                 return rst;
148323             }
148324         },
148325
148326         addEvent: function (onSuccess, onError, calEvent) {
148327             var pendingOperation, pendingObj = {},
148328                 newEvent = {}, _doAddEvent, _calEvent = Object(calEvent);
148329
148330             _doAddEvent = function () {
148331                 if (!_addEventAllowed) {
148332                     if (onError) {
148333                         setTimeout(function () {
148334                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
148335                         }, 1);
148336                     }
148337                     return undefined;
148338                 }
148339                 newEvent = new CalendarEvent(_calEvent, true);
148340                 /* if newEvent.id === undefined,
148341                    means somthing wrong in calEvent  */
148342                 if (newEvent.id === undefined) {
148343                     if (onError) {
148344                         setTimeout(function () {
148345                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
148346                         }, 1);
148347                     }
148348                     return undefined;
148349                 }
148350
148351                 pendingObj = new PendingObject();
148352                 pendingObj.pendingID = setTimeout(function () {
148353                     pendingObj.setCancelFlag(false);
148354                     _events[newEvent.id] = newEvent;
148355                     _save_calendars(_name, _type, _events);
148356                     onSuccess(new CalendarEvent(newEvent), false);
148357                 }, _FAKEWAITTIME);
148358                 pendingOperation = new PendingOperation(pendingObj);
148359                 return pendingOperation;
148360             };
148361
148362             return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:addEvent", _doAddEvent);
148363         },
148364
148365         updateEvent: function (onSuccess, onError, calEvent) {
148366             var pendingOperation, pendingObj = {},
148367                 chkEvent, _doUpdateEvent, _calEvent = Object(calEvent);
148368
148369             _doUpdateEvent = function () {
148370                 if (!_updateEventAllowed) {
148371                     if (onError) {
148372                         setTimeout(function () {
148373                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
148374                         }, 1);
148375                     }
148376                     return undefined;
148377                 }
148378                 if (!_events[_calEvent.id]) {
148379                     if (onError) {
148380                         setTimeout(function () {
148381                             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
148382                         }, 1);
148383                     }
148384                     return undefined;
148385                 }
148386
148387                 chkEvent = new CalendarEvent(_events[_calEvent.id], false);
148388                 /* _eventPropCheck will also update chkEvent btw */
148389                 if (_eventPropCheck(_calEvent, chkEvent) === false) {
148390                     if (onError) {
148391                         setTimeout(function () {
148392                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
148393                         }, 1);
148394                     }
148395                     return undefined;
148396                 }
148397                 pendingObj = new PendingObject();
148398                 pendingObj.pendingID = setTimeout(function () {
148399                     pendingObj.setCancelFlag(false);
148400
148401                     _events[chkEvent.id] = chkEvent;
148402                     _save_calendars(_name, _type, _events);
148403                     onSuccess();
148404                 }, _FAKEWAITTIME);
148405                 pendingOperation = new PendingOperation(pendingObj);
148406                 return pendingOperation;
148407             };
148408
148409             return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:updateEvent", _doUpdateEvent);
148410         },
148411
148412         deleteEvent: function (onSuccess, onError, id) {
148413             var pendingOperation, pendingObj = {},
148414                 _doDeleteEvent;
148415
148416             _doDeleteEvent = function () {
148417                 /* according to spec  "If any of the input parameters are not 
148418                    compatible with the expected type for that parameter, 
148419                    a DeviceAPIError with code TYPE_MISMATCH_ERR MUST be 
148420                    synchronously thrown." 
148421                    so an error is raised synchronously */
148422                 utils.validateArgumentType(id, "string", null,
148423                                        "Calendar:deleteEvent: " + " invalid id parameter",
148424                                        new DeviceApiError(errorcode.TYPE_MISMATCH_ERR));
148425
148426                 if (!_deleteEventAllowed) {
148427                     if (onError) {
148428                         setTimeout(function () {
148429                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
148430                         }, 1);
148431                     }
148432                     return undefined;
148433                 }
148434                 if (!_events[id]) {
148435                     if (onError) {
148436                         setTimeout(function () {
148437                             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
148438                         }, 1);
148439                     }
148440                     return undefined;
148441                 }
148442
148443                 pendingObj = new PendingObject();
148444                 pendingObj.pendingID = setTimeout(function () {
148445                     pendingObj.setCancelFlag(false);
148446
148447                     delete _events[id];
148448                     _save_calendars(_name, _type, _events);
148449                     onSuccess();
148450                 }, _FAKEWAITTIME);
148451                 pendingOperation = new PendingOperation(pendingObj);
148452                 return pendingOperation;
148453             };
148454
148455             return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:deleteEvent", _doDeleteEvent);
148456         },
148457
148458         findEvents: function (onSuccess, onError, eventFilter) {
148459             var pendingOperation, pendingObj = {}, i,
148460                 tmp = [], valid_tmp = false, rst = [], _doFindEvents,
148461                 _eventFilter = Object(eventFilter);
148462
148463             _doFindEvents = function () {
148464                 if (!_eventFilterCheck(_eventFilter)) {
148465                     if (onError) {
148466                         setTimeout(function () {
148467                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
148468                         }, 1);
148469                     }
148470                     return undefined;
148471                 }
148472                 if (!_findEventsAllowed) {
148473                     if (onError) {
148474                         setTimeout(function () {
148475                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
148476                         }, 1);
148477                     }
148478                     return undefined;
148479                 }
148480
148481                 pendingObj = new PendingObject();
148482                 pendingObj.pendingID = setTimeout(function () {
148483                     pendingObj.setCancelFlag(false);
148484                     if (_eventFilter.id !== undefined) {
148485                         tmp = wac2_utils.matchOptionString(_events, "id", _eventFilter.id);
148486                         valid_tmp = true;
148487                     }
148488                     if (_eventFilter.summary !== undefined) {
148489                         if (valid_tmp) {
148490                             tmp = wac2_utils.matchOptionString(tmp, "summary", _eventFilter.summary);
148491                         } else {
148492                             tmp = wac2_utils.matchOptionString(_events, "summary", _eventFilter.summary);
148493                             valid_tmp = true;
148494                         }
148495                     }
148496                     if (_eventFilter.description !== undefined) {
148497                         if (valid_tmp) {
148498                             tmp = wac2_utils.matchOptionString(tmp, "description", _eventFilter.description);
148499                         } else {
148500                             tmp = wac2_utils.matchOptionString(_events, "description", _eventFilter.description);
148501                             valid_tmp = true;
148502                         }
148503                     }
148504                     if (_eventFilter.location !== undefined) {
148505                         if (valid_tmp) {
148506                             tmp = wac2_utils.matchOptionString(tmp, "location", _eventFilter.location);
148507                         } else {
148508                             tmp = wac2_utils.matchOptionString(_events, "location", _eventFilter.location);
148509                             valid_tmp = true;
148510                         }
148511                     }
148512                     if (_eventFilter.category !== undefined) {
148513                         if (valid_tmp) {
148514                             tmp = wac2_utils.matchOptionArrayString(tmp, "categories", _eventFilter.category);
148515                         } else {
148516                             tmp = wac2_utils.matchOptionArrayString(_events, "categories", _eventFilter.category);
148517                             valid_tmp = true;
148518                         }
148519                     }
148520                     if (_eventFilter.status !== undefined) {
148521                         if (valid_tmp) {
148522                             tmp = wac2_utils.matchOptionShortArray(tmp, "status", _eventFilter.status);
148523                         } else {
148524                             tmp = wac2_utils.matchOptionShortArray(_events, "status", _eventFilter.status);
148525                             valid_tmp = true;
148526                         }
148527                     }
148528                     if (_eventFilter.initialStartDate !== undefined ||
148529                         _eventFilter.endStartDate !== undefined) {
148530                         if (valid_tmp) {
148531                             tmp = wac2_utils.matchOptionDate(tmp, "startTime", _eventFilter.initialStartDate, _eventFilter.endStartDate);
148532                         } else {
148533                             tmp = wac2_utils.matchOptionDate(_events, "startTime", _eventFilter.initialStartDate, _eventFilter.endStartDate);
148534                             valid_tmp = true;
148535                         }
148536                     }
148537
148538                     // to make id readonly
148539                     if (valid_tmp) {
148540                         for (i = 0; i < tmp.length; i++) {
148541                             rst.push(new CalendarEvent(tmp[i], false));
148542                         }
148543                     } else {
148544                         for (var e in _events) {
148545                             rst.push(new CalendarEvent(_events[e], false));
148546                         }
148547                     }
148548                     onSuccess(rst);
148549                 }, _FAKE_LONG_WAITTIME);
148550                 pendingOperation = new PendingOperation(pendingObj);
148551                 return pendingOperation;
148552             };
148553
148554             return wac2_utils.validateTypeMismatch(onSuccess, onError, "Calendar:findEvent", _doFindEvents);
148555         },
148556     };
148557     _self.__defineGetter__("type", function () {
148558         return _type;
148559     });
148560     _self.__defineGetter__("name", function () {
148561         return name;
148562     });
148563     return _self;
148564 };
148565
148566 module.exports = function () {
148567     this.__defineGetter__("SIM_CALENDAR", function () {
148568         return 0;
148569     });
148570     this.__defineGetter__("DEVICE_CALENDAR", function () {
148571         return 1;
148572     });
148573     this.__defineGetter__("NO_RECURRENCE", function () { 
148574         return 0;
148575     });
148576     this.__defineGetter__("DAILY_RECURRENCE", function () {
148577         return 1;
148578     });
148579     this.__defineGetter__("WEEKLY_RECURRENCE", function () {
148580         return 2;
148581     });
148582     this.__defineGetter__("MONTHLY_RECURRENCE", function () {
148583         return 3;
148584     });
148585     this.__defineGetter__("YEARLY_RECURRENCE", function () {
148586         return 4;
148587     });
148588     this.__defineGetter__("TENTATIVE_STATUS", function () {
148589         return 0;
148590     });
148591     this.__defineGetter__("CONFIRMED_STATUS", function () {
148592         return 1;
148593     });
148594     this.__defineGetter__("CANCELLED_STATUS", function () {
148595         return 2;
148596     });
148597     this.__defineGetter__("NO_ALARM", function () {
148598         return 0;
148599     });
148600     this.__defineGetter__("SILENT_ALARM", function () {
148601         return 1;
148602     });
148603     this.__defineGetter__("SOUND_ALARM", function () {
148604         return 2;
148605     });
148606
148607     this.getCalendars = function (onSuccess, onError) {
148608         var i, pendingOperation, pendingObj = {}, cal, _doGetCalendars;
148609
148610         _doGetCalendars = function () {
148611             pendingObj = new PendingObject();
148612
148613             pendingObj.pendingID = setTimeout(function () {
148614                 pendingObj.setCancelFlag(false);
148615                 cal = db.retrieveObject(_DB_CALENDARS_KEY) || [];
148616                 _calendars = [];
148617                 if (cal.length === 0) {
148618                     _calendars.push(new Calendar(_SIM_CALENDAR, "sim cal", {}));
148619                     _calendars.push(new Calendar(_DEVICE_CALENDAR, "dev cal", {}));
148620                 } else {
148621                     for (i = 0; i < cal.length; i++) {
148622                         /* after getting Date out of DB, Date will become 
148623                            a string, so need to recast it back to Date */
148624                         /* NOTE: id becomes writable, so need to recast it
148625                            before passing to application */
148626                         for (var e in cal[i].events) {
148627                             if ((cal[i].events[e].startTime !== undefined) &&
148628                                 cal[i].events[e].startTime !== null) {
148629                                 cal[i].events[e].startTime = new Date(cal[i].events[e].startTime);
148630                             }
148631                             if ((cal[i].events[e].expires !== undefined) &&
148632                                 cal[i].events[e].expires !== null) {
148633                                 cal[i].events[e].expires = new Date(cal[i].events[e].expires);
148634                             }
148635                         }
148636                         _calendars.push(new Calendar(cal[i].type, cal[i].name, cal[i].events));
148637                     }
148638                 }
148639                 if (_calendars.length !== 0) {
148640                     onSuccess(utils.copy(_calendars));
148641                 } else {
148642                     if (onError) {
148643                         onError(new DeviceApiError(errorcode.UNKNOWN_ERR));
148644                     }
148645                 }
148646             }, _FAKEWAITTIME);
148647             pendingOperation = new PendingOperation(pendingObj);
148648             return pendingOperation;
148649         };
148650     
148651         return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCalendars", _doGetCalendars);
148652     };
148653
148654     this.handleSubFeatures = function (subFeatures) {
148655         if (wac2_utils.isEmptyObject(subFeatures) ||
148656             subFeatures["http://wacapps.net/api/pim.calendar"] ||
148657             (subFeatures["http://wacapps.net/api/pim.calendar.read"] &&
148658             subFeatures["http://wacapps.net/api/pim.calendar.write"])) {
148659             return;
148660         } 
148661         if (subFeatures["http://wacapps.net/api/pim.calendar.read"]) {
148662             _addEventAllowed = false;
148663             _deleteEventAllowed = false;
148664             _updateEventAllowed = false;
148665             return;
148666         } 
148667         if (subFeatures["http://wacapps.net/api/pim.calendar.write"]) {
148668             _findEventsAllowed = false;
148669             return;
148670         } 
148671         _console.warn("WAC-2.0-Calendar-handleSubFeatures: something wrong");
148672     };
148673 };
148674
148675 });
148676 define('ripple/platform/wac/2.0/filesystem', function (require, exports, module) {
148677 /*
148678  *  Copyright 2011 Intel Corporation.
148679  *
148680  * Licensed under the Apache License, Version 2.0 (the "License");
148681  * you may not use this file except in compliance with the License.
148682  * You may obtain a copy of the License at
148683  *
148684  * http://www.apache.org/licenses/LICENSE-2.0
148685  *
148686  * Unless required by applicable law or agreed to in writing, software
148687  * distributed under the License is distributed on an "AS IS" BASIS,
148688  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
148689  * See the License for the specific language governing permissions and
148690  * limitations under the License.
148691  */
148692
148693 var errorcode = require('ripple/platform/wac/2.0/errorcode'),
148694     DeviceApiError = require('ripple/platform/wac/2.0/deviceapierror'),
148695     utils = require('ripple/utils'),
148696     dbfs  = require('ripple/platform/wac/2.0/dbfs'),
148697     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
148698     _console = require('ripple/console'),
148699     _maxPathLength = 256,
148700     _virtualRoots = ["documents", "images", "music", "videos", "downloads", "wgt-package", "wgt-private", "wgt-private-tmp", "removable", "attachments"],
148701     _realRoots = dbfs.roots,
148702     _r2vmap = {},
148703     _v2rmap = {},
148704     _initialized = false,
148705     _readOnly  = false,
148706     _writeOnly = false,
148707     _defaultMode = "rw",
148708     File, 
148709     FileStream;
148710
148711 function _isValidChar(c) {
148712     return  (c >= '0' && c <= '9') || 
148713         (c >= 'a' && c <= 'z') || 
148714         (c >= 'A' && c <= 'Z') || 
148715         (c === ' ') || 
148716         (c === '_') ||
148717         (c === '-') ||
148718         (c === '.');
148719 }
148720
148721 function _isValidFileName(name) {
148722     var _valid = true,
148723         _c;
148724
148725     if (name === '' || name === '.' || name === '..' || (name.length > _maxPathLength)) {
148726         _valid = false;
148727     } else {
148728         for (_c = 0; _c < name.length; _c++) {
148729             if (!_isValidChar(name[_c])) {
148730                 _valid = false;
148731                 break;
148732             }
148733         }
148734     }
148735     
148736     return _valid;
148737 }
148738
148739 function _initialize() {
148740     var _i;
148741
148742     dbfs.initialize();
148743     
148744     // set up the map between real path and virtual path
148745     for (_i = 0; _i < _virtualRoots.length; _i++) {
148746         _r2vmap[_realRoots[_i]] = _virtualRoots[_i];
148747     }
148748
148749     utils.forEach(_r2vmap, function (value, key) {
148750         _v2rmap[value] = key;
148751     });
148752 }
148753
148754 function _resolveSync(srcLocation, onSuccess, onError, accessMode) {
148755     var _parts = srcLocation.replace(/\/$/, '').split("/"),
148756         _header, _fullPath,
148757         _i;
148758
148759     // TODO: Initialize at bootstrap and emulatorBridge.link 
148760     if (!_initialized) {
148761         _initialize();
148762         _initialized = true;
148763     }
148764
148765     for (_i = 0; _i < _parts.length; _i++) {
148766         if (!_isValidFileName(_parts[_i])) {
148767             if (onError) {
148768                 onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
148769             }
148770             return;
148771         }
148772     }
148773
148774     _header = _v2rmap[_parts[0]];
148775     if (_header === undefined) {
148776         if (onError) {
148777             onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
148778         }
148779         return;
148780     }
148781
148782     if (_parts.length === 1) {
148783         _fullPath = _header;
148784     } else {
148785         _fullPath = _header + "/" + _parts.splice(1, _parts.length - 1).join("/");
148786     }
148787
148788     dbfs.stat(_fullPath, 
148789             function (entry) {
148790                 onSuccess(new File(entry, accessMode));
148791             }, 
148792             function () {
148793                 if (onError) {
148794                     onError(new DeviceApiError(errorcode.NOT_FOUND_ERR));
148795                 }    
148796             });
148797 }
148798
148799 function _resolveAsync(onSuccess, onError, srcLocation, accessMode) {
148800     _resolveSync(srcLocation,
148801                 function (file) {
148802                     setTimeout(function () {
148803                         onSuccess(file);
148804                     }, 1);
148805                 },
148806                 function (e) {
148807                     setTimeout(function () {
148808                         onError(e);
148809                     }, 1);
148810                 },
148811                 accessMode);
148812 }
148813
148814 File = function (entry, mode) {
148815     var _entry = entry,
148816         _mode = mode,
148817         _parent,
148818         _self;
148819
148820     function _r2v(rpath) {
148821         var i, v, r, regExp;
148822
148823         for (i = 0; i < _virtualRoots.length; i++) {
148824             v = _virtualRoots[i];
148825             r = _v2rmap[v];
148826             if (rpath.match("^" + r)) {
148827                 regExp = new RegExp("^" + r);
148828                 return rpath.replace(regExp, v);
148829             }
148830         }
148831
148832         return ""; 
148833     }
148834
148835     function _v2r(vpath) {
148836         var i, v, r, regExp;
148837
148838         for (i = 0; i < _virtualRoots.length; i++) {
148839             v = _virtualRoots[i];
148840             r = _v2rmap[v];
148841             if (vpath.match("^" + v)) {
148842                 regExp = new RegExp("^" + v);
148843                 return vpath.replace(regExp, r);
148844             }
148845         }
148846
148847         return ""; 
148848     }
148849
148850     function _copyMoveInternal(onSuccess, onError, src, dst, overwrite, func) {
148851         var _srcName = String(src),
148852             _dstName = String(dst),
148853             _src = null,
148854             _dst = null,
148855             _error = false,
148856             _dstParent = null,
148857             _dstParts  = _dstName.split("/"),
148858             _dstParentName = _dstParts.splice(0, _dstParts.length - 1).join("/");
148859
148860         if (!_entry.isDirectory) {
148861             if (onError) {
148862                 setTimeout(function () {
148863                     onError(new DeviceApiError(errorcode.IO_ERR));
148864                 }, 1);
148865             }
148866             return undefined;
148867         }
148868
148869         _resolveSync(_srcName, 
148870                 function (file) {
148871                     _src = file;
148872                 },
148873                 function (e) {
148874                     setTimeout(function () {
148875                         onError(e);
148876                     }, 1);
148877                 },
148878                 _mode);
148879
148880         if (_src) {
148881             if (_src.parent.fullPath === _self.fullPath) {
148882                 if (!_readOnly && _mode !== "r") {
148883                     _resolveSync(_dstParentName, 
148884                             function (file) {
148885                                 _dstParent = file;
148886                             },
148887                             function (e) {
148888                                 setTimeout(function () {
148889                                     onError(e);
148890                                 }, 1);
148891                             },
148892                             _mode);
148893
148894                     if (_dstParent === null) {
148895                         return undefined;
148896                     }
148897
148898                     _resolveSync(_dstName, 
148899                             function (file) {
148900                                 _dst = file;
148901                             },
148902                             function (e) {
148903                                 if (e.code !== errorcode.NOT_FOUND_ERR) {
148904                                     setTimeout(function () {
148905                                         onError(e);
148906                                     }, 1);
148907                                     _error = true;
148908                                 } 
148909                             },
148910                             _mode);
148911
148912                     if (_error) {
148913                         return undefined;
148914                     }
148915
148916                     if (_src.isFile) {
148917                         if (_dst === null) {
148918                             func(_v2r(_srcName), _v2r(_dstName),
148919                                     function () {
148920                                         setTimeout(function () {
148921                                             onSuccess();
148922                                         }, 1);
148923                                     },
148924                                     function () {});
148925                             return null;
148926                         } else {
148927                             if (_dst.isFile && Boolean(overwrite) && (_srcName !== _dstName)) {
148928                                 func(_v2r(_srcName), _v2r(_dstName),
148929                                         function () {
148930                                             setTimeout(function () {
148931                                                 onSuccess();
148932                                             }, 1);
148933                                         },
148934                                         function () {});
148935                                 return null;
148936                             } else {
148937                                 setTimeout(function () {
148938                                     onError(new DeviceApiError(errorcode.IO_ERR));
148939                                 }, 1);
148940                             }
148941                         }
148942                     } else {
148943                         if (_dst === null) {
148944                             func(_v2r(_srcName), _v2r(_dstName),
148945                                 function () {
148946                                     setTimeout(function () {
148947                                         onSuccess();
148948                                     }, 1);
148949                                 },
148950                                 function () {});
148951                             return null;
148952                         } else {
148953                             setTimeout(function () {
148954                                 onError(new DeviceApiError(errorcode.IO_ERR));
148955                             }, 1);
148956                         } 
148957                     }
148958                 } else {
148959                     if (onError) {
148960                         setTimeout(function () {
148961                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
148962                         }, 1);
148963                     }
148964                 }
148965             } else {
148966                 if (onError) {
148967                     setTimeout(function () {
148968                         onError(new DeviceApiError(errorcode.IO_ERR));
148969                     }, 1);
148970                 }
148971             }
148972         }
148973
148974         return undefined;
148975     }
148976
148977     _self = {
148978         toURI: function () {
148979             return "file://" + _entry.fullPath;
148980         },
148981         listFiles: function (onSuccess, onError, filter) {
148982             var _filter = Object(filter),
148983                 _filterName = _filter.name,
148984                 _startModified = _filter.startModified,
148985                 _endModified   = _filter.endModified;
148986
148987             function _matchName(fileName) {
148988                 var _matched = true, 
148989                     _name1 = String(_filterName).toLowerCase(),
148990                     _name2 = fileName.toLowerCase(),
148991                     _pattern;
148992
148993                 if (_filterName !== undefined && _filterName !== null) {
148994                     if (!_name1.match("\\\\%")) {
148995                         if (_name1.match("%")) {
148996                             _pattern = new RegExp("^" + _name1.replace(/%/g, ".*") + "$");
148997                             _matched = _name2.match(_pattern) ? true : false;
148998                         } else {
148999                             _matched = (_name1 === _name2);
149000                         }
149001                     } else {
149002                         // % is not allowed as a part of file name
149003                         _matched = false;
149004                     }
149005                 }
149006                 
149007                 return _matched;
149008             }
149009
149010             function _matchDate(date) {
149011                 var _matched = true;
149012
149013                 if (_startModified !== undefined && _startModified !== null) {
149014                     _matched = (date.getTime() >= _startModified.getTime());
149015                 }
149016
149017                 if (_matched && (_endModified !== undefined && _endModified !== null)) {
149018                     _matched = (date.getTime() <= _endModified.getTime());
149019                 }
149020
149021                 return _matched;
149022             }
149023
149024             function _matchFilter(entry) {
149025                 return _matchName(entry.name) && _matchDate(entry.lastModifiedDate);
149026             } 
149027
149028             function _listFiles() {
149029                 var _files = [];
149030
149031                 if ((_startModified !== undefined && !wac2_utils.isValidDate(_startModified)) ||
149032                     (_endModified !== undefined && !wac2_utils.isValidDate(_endModified))) {
149033                     if (onError) {
149034                         setTimeout(function () {
149035                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
149036                         }, 1);
149037                     }
149038                     return undefined;
149039                 }
149040
149041                 if (!_entry.isDirectory) {
149042                     if (onError) {
149043                         setTimeout(function () {
149044                             onError(new DeviceApiError(errorcode.IO_ERR));
149045                         }, 1);
149046                     }
149047                     return undefined;
149048                 }
149049
149050                 utils.forEach(_entry.children, function (child) {
149051                     if (_matchFilter(child)) {
149052                         _files.push(new File(child, _mode));
149053                     }
149054                 });
149055
149056                 setTimeout(function () {
149057                     onSuccess(_files);
149058                 }, 1);
149059
149060                 return null;
149061             }
149062
149063             return wac2_utils.validateTypeMismatch(onSuccess, onError, "listFiles", _listFiles);
149064         },
149065         openStream: function (onSuccess, onError, mode, encoding) {
149066             function _openStream() {
149067                 var  _openMode = String(mode),
149068                     _encoding = encoding ? String(encoding) : "UTF-8";
149069
149070                 if (_openMode !== "r" && _openMode !== "w" && _openMode !== "a") {
149071                     if (onError) {
149072                         setTimeout(function () {
149073                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
149074                         }, 1);
149075                     }
149076                     return undefined;
149077                 }
149078                 if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
149079                     if (onError) {
149080                         setTimeout(function () {
149081                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
149082                         }, 1);
149083                     }
149084                     return undefined;
149085                 }
149086                 
149087                 if (((_readOnly || _mode === "r") && (_openMode === "w" || _openMode === "a")) ||
149088                     (_writeOnly && _openMode === "r")) {
149089                     if (onError) {
149090                         setTimeout(function () {
149091                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
149092                         }, 1);
149093                     }
149094                     return undefined;
149095                 }
149096                  
149097                 setTimeout(function () {
149098                     onSuccess(new FileStream(_entry, _openMode, _encoding));
149099                 }, 1);
149100
149101                 return null;
149102             }
149103
149104             return wac2_utils.validateTypeMismatch(onSuccess, onError, "openStream", _openStream);
149105         },
149106         readAsText: function (onSuccess, onError, encoding) {
149107             function _readAsText() {
149108                 var _encoding = encoding ? String(encoding) : "UTF-8";
149109                 if (_encoding !== "UTF-8" && _encoding !== "ISO-8859-1") {
149110                     if (onError) {
149111                         setTimeout(function () {
149112                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
149113                         }, 1);
149114                     }
149115                     return undefined;
149116                 }
149117
149118                 if (_writeOnly) {
149119                     if (onError) {
149120                         setTimeout(function () {
149121                             onError(new DeviceApiError(errorcode.SECURITY_ERR));
149122                         }, 1);
149123                     }
149124                     return undefined;
149125                 }
149126
149127                 if (_self.isFile) {
149128                     dbfs.read(_entry.fullPath, 
149129                             function (data) {
149130                                 setTimeout(function () {
149131                                     onSuccess(data);
149132                                 }, 1);
149133                             },
149134                             function () {});
149135                     return null;
149136                 } else {
149137                     if (onError) {
149138                         setTimeout(function () {
149139                             onError(new DeviceApiError(errorcode.IO_ERR));
149140                         }, 1);
149141                     }
149142                 }
149143
149144                 return undefined;
149145             }
149146
149147             return wac2_utils.validateTypeMismatch(onSuccess, onError, "readAsText", _readAsText);
149148         },
149149         copyTo: function (onSuccess, onError, src, dst, overwrite) {
149150             function _copyTo() {
149151                 return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.cp);
149152             }
149153             
149154             return wac2_utils.validateTypeMismatch(onSuccess, onError, "copyTo", _copyTo);
149155         },
149156         moveTo: function (onSuccess, onError, src, dst, overwrite) {
149157             function _moveTo() {
149158                 return _copyMoveInternal(onSuccess, onError, src, dst, overwrite, dbfs.mv);
149159             }
149160
149161             return wac2_utils.validateTypeMismatch(onSuccess, onError, "moveTo", _moveTo);
149162         },
149163         createDirectory: function (dirPath) {
149164             var _path  = String(dirPath),
149165                 _parts = _path.replace(/\/$/, "").split("/"),
149166                 _dir   = null,
149167                 _exist = null,
149168                 _current = _entry.fullPath,
149169                 _i;
149170
149171             function onSuccess(entry) {
149172                 _dir = entry;
149173             }
149174
149175             for (_i = 0; _i < _parts.length; _i++) {
149176                 if (!_isValidFileName(_parts[_i])) {
149177                     throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
149178                 }
149179             }
149180       
149181             if (!entry.isDirectory) {
149182                 throw new DeviceApiError(errorcode.IO_ERR);
149183             }
149184
149185             _exist = _parts.reduce(function (obj, token) {
149186                 return token === "" ? obj : (obj.children ? obj.children[token] || null : null);
149187             }, _entry);
149188
149189             if (_exist) {
149190                 throw new DeviceApiError(errorcode.IO_ERR);
149191             }
149192
149193             if (_readOnly || _mode === "r") {
149194                 throw new DeviceApiError(errorcode.SECURITY_ERR);
149195             }
149196
149197             for (_i = 0; _i < _parts.length; _i++) {
149198                 _current = _current + "/" + _parts[_i];
149199                 dbfs.mkdir(_current, onSuccess);
149200             }
149201             
149202             return new File(_dir, _mode);
149203         },
149204         createFile: function (filePath) {
149205             var _name = String(filePath),
149206                 _file = null;
149207
149208             if (!_isValidFileName(_name)) {
149209                 throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
149210             }
149211
149212             if (!entry.isDirectory || (_entry.children && _entry.children[_name])) {
149213                 throw new DeviceApiError(errorcode.IO_ERR);
149214             }
149215
149216             if (_readOnly || _mode === "r") {
149217                 throw new DeviceApiError(errorcode.SECURITY_ERR);
149218             }
149219
149220             dbfs.touch(_entry.fullPath + "/" + _name,
149221                         function (entry) {
149222                             _file = new File(entry, _mode);
149223                         },
149224                         function () {});
149225             
149226             return _file;
149227         },
149228         resolve: function (filePath) {
149229             var _fullPath = _self.fullPath + "/" + String(filePath),
149230                 _file = null;
149231  
149232             if (!_entry.isDirectory) {
149233                 throw new DeviceApiError(errorcode.IO_ERR); 
149234             }
149235
149236             _resolveSync(_fullPath,
149237                     function (file) {
149238                         _file = file;
149239                     },
149240                     function (e) {
149241                         throw (e);
149242                     },
149243                     _mode);
149244
149245             return _file;
149246         }, 
149247         deleteDirectory: function (onSuccess, onError, directory, recursive) {
149248             function _deleteDirectory() {
149249                 var _dir = null,
149250                     _dirName = String(directory);
149251                 _resolveSync(_dirName, 
149252                         function (file) {
149253                             _dir = file;
149254                         },
149255                         function (e) {
149256                             setTimeout(function () {
149257                                 onError(e);
149258                             }, 1);
149259                         },
149260                         _mode);
149261
149262                 if (_dir) {
149263                     if (_dir.isDirectory && 
149264                         _dir.parent.fullPath === _self.fullPath &&
149265                         (!recursive && _dir.length === 0)) {
149266                         if (!_readOnly && _mode !== "r") {
149267                             dbfs.rmdir(_v2r(_dirName),
149268                                     function () {
149269                                         setTimeout(function () {
149270                                             onSuccess();
149271                                         }, 1);
149272                                     },
149273                                     function () {});
149274                             return null;
149275                         } else {
149276                             if (onError) {
149277                                 setTimeout(function () {
149278                                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
149279                                 }, 1);
149280                             }
149281                         }
149282                     } else {
149283                         if (onError) {
149284                             setTimeout(function () {
149285                                 onError(new DeviceApiError(errorcode.IO_ERR));
149286                             }, 1);
149287                         }
149288                     }
149289                 }
149290
149291                 return undefined; 
149292             }
149293
149294             return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteDirectory", _deleteDirectory);
149295         },
149296         deleteFile: function (onSuccess, onError, fileName) {
149297             function _deleteFile() {
149298                 var _file = null;
149299                 _resolveSync(String(fileName),
149300                         function (file) {
149301                             _file = file;
149302                         },
149303                         function (e) {
149304                             if (onError) {
149305                                 setTimeout(function () {
149306                                     onError(e);
149307                                 }, 1);
149308                             }
149309                         },
149310                         _mode);
149311
149312                 if (_file) {
149313                     if (_file.isFile && _file.parent.fullPath === _self.fullPath) {
149314                         if (!_readOnly && _mode !== "r") {
149315                             dbfs.rm(_v2r(fileName),
149316                                     function () {
149317                                         setTimeout(function () {
149318                                             onSuccess();
149319                                         }, 1);
149320                                     },
149321                                     function () {});
149322                             return null;
149323                         } else {
149324                             if (onError) {
149325                                 setTimeout(function () {
149326                                     onError(new DeviceApiError(errorcode.SECURITY_ERR));
149327                                 }, 1);
149328                             }
149329                         }
149330                     } else {
149331                         if (onError) {
149332                             setTimeout(function () {
149333                                 onError(new DeviceApiError(errorcode.IO_ERR));
149334                             }, 1);
149335                         }
149336                     }
149337                 }
149338
149339                 return undefined; 
149340             }
149341
149342             return wac2_utils.validateTypeMismatch(onSuccess, onError, "deleteFile", _deleteFile);
149343         }
149344     };
149345
149346     _self.__defineGetter__("parent", function () {
149347         var _parts = _self.fullPath.split("/");
149348
149349         if (_parent === undefined) {
149350             if (_parts.length === 1) {
149351                 // virtual root's parent is null
149352                 _parent = null;
149353             } else {
149354                 _resolveSync(_parts.splice(0, _parts.length - 1).join("/"), 
149355                         function (file) {
149356                             _parent = file;
149357                         },
149358                         function () {},
149359                         _mode);
149360             }
149361             return _parent;
149362         } else { 
149363             return _parent;
149364         }
149365     });
149366
149367     _self.__defineGetter__("readOnly", function () {
149368         return false;
149369     });
149370
149371     _self.__defineGetter__("isFile", function () {
149372         return !_entry.isDirectory;
149373     });
149374
149375     _self.__defineGetter__("isDirectory", function () {
149376         return _entry.isDirectory;
149377     });
149378
149379     _self.__defineGetter__("created", function () {
149380         return undefined;
149381     });
149382
149383     _self.__defineGetter__("modified", function () {
149384         if (_entry.isDirectory) {
149385             return undefined;
149386         } else {
149387             return _entry.lastModifiedDate;
149388         }
149389     });
149390
149391     _self.__defineGetter__("path", function () {
149392         var _parts = _self.fullPath.split("/");
149393
149394         if (_parts.length === 1) {
149395             // virtual root
149396             return _parts.join("");
149397         } else {
149398             return _parts.splice(0, _parts.length - 1).join("/") + "/";
149399         }
149400     });
149401
149402     _self.__defineGetter__("name", function () {
149403         return _entry.name;
149404     });
149405
149406     _self.__defineGetter__("fullPath", function () {
149407         return _r2v(_entry.fullPath);
149408     });
149409
149410     _self.__defineGetter__("fileSize", function () {
149411         if (_entry.isDirectory) {
149412             return undefined;
149413         } else {
149414             return _entry.data.length;
149415         }
149416     });
149417
149418     _self.__defineGetter__("length", function () {
149419         var _l = 0;
149420         if (_entry.isDirectory) {
149421             utils.forEach(_entry.children, function () {
149422                 _l++;
149423             });
149424             return _l;
149425         } else {
149426             return undefined;
149427         }
149428     });
149429
149430     return _self;
149431 };
149432
149433 FileStream = function (entry, mode, encoding) {
149434     var _entry = entry,
149435         _data = entry.data,
149436         _mode = mode,
149437         _position = (_mode === "a" ? _data.length : 0),
149438         _self;
149439
149440     _self = {
149441         close: function () {
149442             var _element;
149443             if (mode === "a" || mode === "w") {
149444                 dbfs.write(_entry.fullPath, _data, function () {}, function () {});
149445             }
149446             for (_element in _self) {
149447                 delete _self[_element];
149448             }
149449         },
149450         read: function (charCount) {
149451             var _count  = charCount | 0,
149452                 _substr = _data.substring(_position, _position + _count);
149453
149454             if (_position + _count > _data.length) {
149455                 _position = _data.length;
149456             } else {
149457                 _position += _count;
149458             }
149459
149460             return _substr; 
149461         },
149462         readBytes: function (byteCount) {
149463             var _substr = _self.read(byteCount),
149464                 _bytes = [],
149465                 _i;
149466
149467             for (_i = 0; _i < _substr.length; _i++) {
149468                 _bytes.push(_substr.charCodeAt(_i));
149469             }
149470
149471             return _bytes;
149472         },
149473         readBase64: function (byteCount) {
149474             var _substr = _self.read(byteCount);
149475
149476             return window.atob(_substr);
149477         },
149478         write: function (stringData) {
149479             var _stringData = String(stringData),
149480                 _substr = _data.substring(0, _position);
149481
149482             _data = _substr.concat(_stringData);
149483             _position = _data.length;
149484         },
149485         writeBytes: function (byteData) {
149486             _self.write(String.fromCharCode.apply(String, byteData));
149487         },
149488         writeBase64: function (base64Data) {
149489             _self.write(window.btoa(String(base64Data)));
149490         }
149491     };
149492
149493     _self.__defineGetter__("eof", function () {
149494         return _position === _data.length;
149495     });
149496
149497     _self.__defineGetter__("position", function () {
149498         return _position;
149499     });
149500
149501     _self.__defineSetter__("position", function (value) {
149502         var _value = value | 0;
149503
149504         if (_value >= 0 && _value <= _data.length) {
149505             _position = _value;
149506         } else {
149507             throw new DeviceApiError(errorcode.INVALID_VALUES_ERR);
149508         }
149509     });
149510
149511     _self.__defineGetter__("bytesAvailable", function () {
149512         return (_data.length - _position) || -1;
149513     });
149514
149515     return _self;
149516 };
149517
149518 module.exports = function () {
149519     return {
149520         maxPathLength: _maxPathLength,
149521         resolve: function (onSuccess, onError, srcLocation, accessMode) {
149522             function _resolve() {
149523                 var _mode = accessMode ? String(accessMode) : _defaultMode;
149524
149525                 if (_mode === "r" || _mode === "rw") {
149526                     _resolveAsync(onSuccess, onError, String(srcLocation), _mode);
149527                     return null;
149528                 } else {
149529                     if (onError) {
149530                         setTimeout(function () {
149531                             onError(new DeviceApiError(errorcode.INVALID_VALUES_ERR));
149532                         }, 1);
149533                     }
149534                 }
149535                 return undefined;
149536             }
149537
149538             return wac2_utils.validateTypeMismatch(onSuccess, onError, "resolve", _resolve);
149539         },
149540         handleSubFeatures: function (subFeatures) {
149541             if (wac2_utils.isEmptyObject(subFeatures) ||
149542                 subFeatures["http://wacapps.net/api/filesystem"] ||
149543                 (subFeatures["http://wacapps.net/api/filesystem.read"] &&
149544                 subFeatures["http://wacapps.net/api/filesystem.write"])) {
149545                 return;
149546             }
149547             if (subFeatures["http://wacapps.net/api/filesystem.read"]) {
149548                 _readOnly = true;
149549                 return;
149550             }
149551             if (subFeatures["http://wacapps.net/api/filesystem.write"]) {
149552                 _writeOnly = true;
149553                 return;
149554             }
149555             _console.warn("WAC-2.0-Filesystem: something wrong in handleSubFeatures");
149556         }
149557     }; 
149558 };
149559
149560
149561 });
149562 define('ripple/platform/wac/2.0/accelerometer', function (require, exports, module) {
149563 /*
149564  *  Copyright 2011 Intel Corporation.
149565  *
149566  * Licensed under the Apache License, Version 2.0 (the "License");
149567  * you may not use this file except in compliance with the License.
149568  * You may obtain a copy of the License at
149569  *
149570  * http://www.apache.org/licenses/LICENSE-2.0
149571  *
149572  * Unless required by applicable law or agreed to in writing, software
149573  * distributed under the License is distributed on an "AS IS" BASIS,
149574  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149575  * See the License for the specific language governing permissions and
149576  * limitations under the License.
149577  */
149578
149579 var utils = require('ripple/utils'),
149580     event = require('ripple/event'),
149581     Acceleration = function (x, y, z) {
149582         return {
149583             xAxis: x || 0,
149584             yAxis: y || 0,
149585             zAxis: z || 0
149586         };
149587     },
149588     wac2_utils = require('ripple/platform/wac/2.0/wac2_utils'),
149589     _accelerometerInfo = new Acceleration(),
149590     _defaultInterval = 100,
149591     _watches = {},
149592     _self;
149593
149594 module.exports = _self = {
149595     getCurrentAcceleration: function (onSuccess, onError) {
149596         function _getCurrentAcceleration() {
149597             setTimeout(function () {
149598                 onSuccess(utils.copy(_accelerometerInfo));
149599             }, 1);
149600             return null;
149601         }
149602
149603         return wac2_utils.validateTypeMismatch(onSuccess, onError, "getCurrentAcceleration", _getCurrentAcceleration); 
149604     },
149605
149606     watchAcceleration: function (accelerometerSuccess, accelerometerError, options) {
149607         function _watchAcceleration() {
149608             var watchId = (new Date()).getTime() | 0,
149609                 watchObj = {},
149610                 opt = Object(options),
149611                 minNotificationInterval = opt.minNotificationInterval | 0,
149612                 accelerometerInterval = _defaultInterval;
149613
149614             if (minNotificationInterval > 0) {
149615                 accelerometerInterval = minNotificationInterval;
149616             }
149617
149618             watchObj = {
149619                 onSuccess: accelerometerSuccess,
149620                 onError: accelerometerError,
149621                 interval: accelerometerInterval
149622             };
149623
149624             _watches[watchId] = watchObj;
149625
149626             _watches[watchId].intervalId = setInterval(function () {
149627                 _self.getCurrentAcceleration(_watches[watchId].onSuccess, _watches[watchId].onError);
149628             }, _watches[watchId].interval);
149629
149630             return watchId;
149631         }
149632
149633         return wac2_utils.validateTypeMismatch(accelerometerSuccess, accelerometerError, "watchAcceleration", _watchAcceleration); 
149634     },
149635
149636     clearWatch: function (watchId) {
149637
149638         var id = watchId | 0;
149639
149640         if (_watches[id]) {
149641             clearInterval(_watches[id].intervalId);
149642             delete(_watches[id]);
149643             return null;
149644         }
149645
149646         return undefined;
149647     }
149648 };
149649
149650 event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
149651     _accelerometerInfo.xAxis = accelerometerInfo.accelerationIncludingGravity.x;
149652     _accelerometerInfo.yAxis = accelerometerInfo.accelerationIncludingGravity.y;
149653     _accelerometerInfo.zAxis = accelerometerInfo.accelerationIncludingGravity.z;
149654 });
149655
149656
149657 });
149658 define('ripple/platform/wac/2.0/typecoerce', function (require, exports, module) {
149659 /*\r
149660  *  Copyright 2011 Intel Corporation.\r
149661  *\r
149662  * Licensed under the Apache License, Version 2.0 (the "License");\r
149663  * you may not use this file except in compliance with the License.\r
149664  * You may obtain a copy of the License at\r
149665  *\r
149666  * http://www.apache.org/licenses/LICENSE-2.0\r
149667  *\r
149668  * Unless required by applicable law or agreed to in writing, software\r
149669  * distributed under the License is distributed on an "AS IS" BASIS,\r
149670  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
149671  * See the License for the specific language governing permissions and\r
149672  * limitations under the License.\r
149673  */\r
149674 \r
149675 var utils = require('ripple/utils'),\r
149676     _self;\r
149677 \r
149678 _self = function (pattern) {\r
149679     var typeCoerce,\r
149680         typeOfPattern = Object.prototype.toString.call(pattern);\r
149681 \r
149682     typeCoerce = {\r
149683         cast: function (obj) {\r
149684             var validObj,\r
149685                 validValue,\r
149686                 elementType,\r
149687                 typeOfObj = Object.prototype.toString.call(obj);\r
149688 \r
149689             switch (typeOfPattern) {\r
149690             case "[object String]":\r
149691                 validObj = (typeOfObj !== typeOfPattern) ? String(obj) : obj;\r
149692                 break;\r
149693 \r
149694             case "[object Number]":\r
149695                 validObj = (typeOfObj !== typeOfPattern) ? (Number(obj) | 0) : obj;\r
149696                 break;\r
149697 \r
149698             case "[object Object]":\r
149699                 if (typeOfObj !== typeOfPattern) {\r
149700                     validObj = {};\r
149701                 } else {\r
149702                     validObj = obj;\r
149703                     utils.forEach(validObj, function (value, key) {\r
149704                         if (pattern[key] === undefined) {\r
149705                             delete validObj[key];\r
149706                         } else {\r
149707                             validValue = _self(pattern[key]).cast(value);\r
149708                             if (validObj[key] !== validValue)\r
149709                                 validObj[key] = validValue;\r
149710                         }\r
149711                     });\r
149712                 }\r
149713                 break;\r
149714 \r
149715             case "[object Array]":\r
149716                 if (typeOfObj !== typeOfPattern) {\r
149717                     validObj = [];\r
149718                 } else {\r
149719                     validObj = obj;\r
149720                     elementType = _self(pattern[0]);\r
149721                     utils.forEach(validObj, function (element, index) {\r
149722                         validObj[index] = elementType.cast(element);\r
149723                     });\r
149724                 }\r
149725                 break;\r
149726             }\r
149727 \r
149728             return validObj;\r
149729         }\r
149730     };\r
149731 \r
149732     return typeCoerce;\r
149733 };\r
149734 \r
149735 module.exports = _self;\r
149736
149737 });
149738 define('ripple/platform/cordova/2.0.0/JavaPluginManager', function (require, exports, module) {
149739 module.exports = {
149740     exec: function () {
149741         throw "this really shouldn't be called. like ever!";
149742     },
149743     resume: function () {
149744         throw "this shouldn't be called";
149745     },
149746     pause: function () {
149747         throw "this shouldn't be called";
149748     },
149749     destroy: function () {
149750         throw "this shouldn't be called";
149751     }
149752 };
149753
149754 });
149755 define('ripple/platform/cordova/2.0.0/spec', function (require, exports, module) {
149756 function loadWebworks(win, device) {
149757     var builder = require('ripple/platform/builder'),
149758         platform = device.id === "Playbook" || device.id === "Colt" ? "tablet" : "handset",
149759         webworks = require('ripple/platform/webworks.' + platform + '/2.0.0/spec');
149760
149761     builder.build(webworks.objects).into(win);
149762     builder.build(webworks.objects).into(window);
149763 }
149764
149765 module.exports = {
149766     id: "cordova",
149767     version: "2.0.0",
149768     name: "Apache Cordova",
149769     type: "platform",
149770     nativeMethods: {},
149771
149772     config: require('ripple/platform/cordova/2.0.0/spec/config'),
149773     device: require('ripple/platform/cordova/2.0.0/spec/device'),
149774     ui: require('ripple/platform/cordova/2.0.0/spec/ui'),
149775     events: require('ripple/platform/cordova/2.0.0/spec/events'),
149776
149777     initialize: function (win) {
149778         var honeypot = require('ripple/honeypot'),
149779             devices = require('ripple/devices'),
149780             device = devices.getCurrentDevice(),
149781             bridge = require('ripple/platform/cordova/2.0.0/bridge'),
149782             cordova,
149783             topCordova = window.top.require('ripple/platform/cordova/2.0.0/spec'),
149784             get = function () {
149785                 return cordova;
149786             },
149787             set = function (orig) {
149788                 if (cordova) {
149789                     return;
149790                 }
149791
149792                 cordova = orig;
149793
149794                 cordova.define.remove("cordova/exec");
149795                 cordova.define("cordova/exec", function (require, exports, module) {
149796                     module.exports = bridge.exec;
149797                 });
149798
149799                 cordova.UsePolling = true;
149800
149801                 //do nothing here as we will just call the callbacks ourselves
149802                 cordova.define.remove("cordova/plugin/android/polling");
149803                 cordova.define("cordova/plugin/android/polling", function (require, exports, module) {
149804                     module.exports = function () {};
149805                 });
149806
149807                 var builder = cordova.require('cordova/builder'),
149808                     allTheThings = window,
149809                     base = cordova.require('cordova/common'),
149810                     iosPlugin;
149811
149812                 //HACK: Overwrite all the things, handles when cordova.js executes before we start booting
149813                 builder.build(base.objects).intoAndClobber(allTheThings);
149814                 cordova.require('cordova/channel').onNativeReady.fire();
149815                 //  DIRTY HACK: once cordova is cleaned up, we do not
149816                 //  need this.
149817                 // reference issue: https://issues.apache.org/jira/browse/CB-1013
149818                 try {
149819                     iosPlugin = cordova.require('cordova/plugin/ios/device');
149820                     bridge.exec(function (info) {
149821                         iosPlugin.setInfo(info);
149822                     }, null, 'Device', 'getDeviceInfo', []);
149823                 } catch (e) {
149824                     cordova.require('cordova/channel').onCordovaInfoReady.fire();
149825                 }
149826             };
149827
149828         if (window.FileReader && !topCordova.nativeMethods.FileReader) {
149829             topCordova.nativeMethods.FileReader = window.FileReader;
149830         }
149831
149832         if (device.manufacturer === "Research In Motion") {
149833             loadWebworks(win, device);
149834         }
149835
149836         honeypot.monitor(win, "cordova").andRun(get, set);
149837     },
149838
149839     objects: {
149840         MediaError: {
149841             path: "cordova/2.0.0/MediaError"
149842         },
149843         org: {
149844             children: {
149845                 apache: {
149846                     children: {
149847                         cordova: {
149848                             children: {
149849                                 Logger: {
149850                                     path: "cordova/2.0.0/logger"
149851                                 },
149852                                 JavaPluginManager: {
149853                                     path: "cordova/2.0.0/JavaPluginManager"
149854                                 }
149855                             }
149856                         }
149857                     }
149858                 }
149859             }
149860         }
149861     }
149862 };
149863
149864 });
149865 define('ripple/platform/cordova/2.0.0/logger', function (require, exports, module) {
149866 module.exports = {
149867     log: function (msg) {
149868         console.log(msg);
149869     }
149870 };
149871
149872 });
149873 define('ripple/platform/cordova/2.0.0/spec/config', function (require, exports, module) {
149874 /*
149875  *  Copyright 2011 Research In Motion Limited.
149876  *
149877  * Licensed under the Apache License, Version 2.0 (the "License");
149878  * you may not use this file except in compliance with the License.
149879  * You may obtain a copy of the License at
149880  *
149881  * http://www.apache.org/licenses/LICENSE-2.0
149882  *
149883  * Unless required by applicable law or agreed to in writing, software
149884  * distributed under the License is distributed on an "AS IS" BASIS,
149885  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149886  * See the License for the specific language governing permissions and
149887  * limitations under the License.
149888  */
149889 var constants = require('ripple/constants');
149890
149891 module.exports = {
149892     fileName: "config.xml",
149893     validateVersion: function (configValidationObject) {
149894         var valid = true;
149895         valid = !((!configValidationObject.widget.validationResult[0].attributes.xmlns.valid) ||
149896             (!configValidationObject.widget.validationResult[0].attributes["xmlns:gap"].valid));
149897
149898         return valid;
149899     },
149900     extractInfo: function (configValidationObject) {
149901         if (!configValidationObject) {
149902             return null;
149903         }
149904
149905         var widgetInfo = {};
149906
149907         widgetInfo.id = configValidationObject.widget.validationResult[0].attributes.id.value || "";
149908         widgetInfo.name = configValidationObject.widget.children.name.validationResult[0].value;
149909         widgetInfo.icon = configValidationObject.widget.children.icon.validationResult[0].attributes.src.value;
149910         widgetInfo.version = configValidationObject.widget.validationResult[0].attributes.version.value;
149911
149912         return widgetInfo;
149913     },
149914     schema: {
149915         rootElement: "widget",
149916         widget: {
149917             nodeName: "widget",
149918             required: true,
149919             occurrence: 1,
149920             attributes: {
149921                 xmlns: {
149922                     attributeName: "xmlns",
149923                     required: true,
149924                     type: "list",
149925                     listValues: ["http://www.w3.org/ns/widgets"]
149926                 },
149927                 "xmlns:gap": {
149928                     attributeName: "xmlns:gap",
149929                     required: true,
149930                     type: "list",
149931                     listValues: ["http://phonegap.com/ns/1.0"]
149932                 },
149933                 "xml:lang": {
149934                     attributeName: "xml:lang",
149935                     required: false,
149936                     type: "iso-language"
149937                 },
149938                 dir: {
149939                     attributeName: "dir",
149940                     required: false,
149941                     type: "list",
149942                     listValues: ["ltr", "rtl", "lro", "rlo"]
149943                 },
149944                 id: {
149945                     attributeName: "id",
149946                     required: false,
149947                     type: "string"
149948                 },
149949                 version: {
149950                     attributeName: "version",
149951                     required: false,
149952                     type: "string"
149953                 },
149954                 height: {
149955                     attributeName: "height",
149956                     required: false,
149957                     type: "integer"
149958                 },
149959                 width: {
149960                     attributeName: "width",
149961                     required: false,
149962                     type: "integer"
149963                 },
149964                 viewmodes: {
149965                     attributeName: "viewmodes",
149966                     required: false,
149967                     type: "list",
149968                     listValues: ["floating", "fullscreen"]
149969                 }
149970             },
149971             children: {
149972                 name: {
149973                     nodeName: "name",
149974                     required: false,
149975                     occurrence: 0,
149976                     type: "string",
149977                     attributes: {
149978                         "short": {
149979                             attributeName: "short",
149980                             type: "string",
149981                             required: false
149982                         },
149983                         "xml:lang": {
149984                             attributeName: "xml:lang",
149985                             type: "string",
149986                             required: false,
149987                             unique: true
149988                         }
149989                     }
149990                 },
149991                 description: {
149992                     nodeName: "description",
149993                     required: false,
149994                     occurrence: 0,
149995                     type: "string",
149996                     attributes: {
149997                         "xml:lang": {
149998                             attributeName: "xml:lang",
149999                             type: "string",
150000                             required: false,
150001                             unique: true
150002                         }
150003                     }
150004                 },
150005                 author: {
150006                     nodeName: "author",
150007                     required: false,
150008                     occurrence: 1,
150009                     type: "string",
150010                     attributes: {
150011                         email: {
150012                             attributeName: "email",
150013                             type: "regex",
150014                             required: false,
150015                             regex: constants.REGEX.EMAIL
150016                         },
150017                         href: {
150018                             attributeName: "href",
150019                             type: "regex",
150020                             required: false,
150021                             regex: constants.REGEX.URL
150022                         }
150023                     }
150024                 },
150025                 license: {
150026                     nodeName: "license",
150027                     required: false,
150028                     occurrence: 1,
150029                     type: "string",
150030                     attributes: {
150031                         href: {
150032                             attributeName: "href",
150033                             type: "regex",
150034                             required: false,
150035                             regex: constants.REGEX.URL
150036                         },
150037                         "xml:lang": {
150038                             attributeName: "xml:lang",
150039                             type: "string",
150040                             required: false,
150041                             unique: true
150042                         }
150043                     }
150044                 },
150045                 icon: {
150046                     nodeName: "icon",
150047                     required: false,
150048                     occurrence: 0,
150049                     attributes: {
150050                         src: {
150051                             attributeName: "src",
150052                             type: "string",
150053                             required: true
150054                         },
150055                         height: {
150056                             attributeName: "height",
150057                             required: false,
150058                             type: "integer"
150059                         },
150060                         width: {
150061                             attributeName: "width",
150062                             required: false,
150063                             type: "integer"
150064                         }
150065                     }
150066                 },
150067                 content: {
150068                     nodeName: "content",
150069                     required: false,
150070                     occurrence: 1,
150071                     attributes: {
150072                         src: {
150073                             attributeName: "src",
150074                             type: "string",
150075                             required: true
150076                         },
150077                         encoding: {
150078                             attributeName: "encoding",
150079                             type: "string",
150080                             required: false
150081                         },
150082                         type: {
150083                             attributeName: "type",
150084                             type: "string",
150085                             required: false
150086                         }
150087                     }
150088                 },
150089                 feature: {
150090                     nodeName: "feature",
150091                     required: false,
150092                     occurrence: 0,
150093                     attributes: {
150094                         name: {
150095                             attributeName: "name",
150096                             type: "list",
150097                             required: true,
150098                             listValues: ["http://api.phonegap.com/1.0/accelerometer", "http://api.phonegap.com/1.0/camera",
150099                                 "http://api.phonegap.com/1.0/compass", "http://api.phonegap.com/1.0/contacts", "http://api.phonegap.com/1.0/device",
150100                                 "http://api.phonegap.com/1.0/events", "http://api.phonegap.com/1.0/file", "http://api.phonegap.com/1.0/geolocation",
150101                                 "http://api.phonegap.com/1.0/media", "http://api.phonegap.com/1.0/network", "http://api.phonegap.com/1.0/notification",
150102                                 "http://api.phonegap.com/1.0/storage"]
150103                         },
150104                         required: {
150105                             attributeName: "required",
150106                             type: "boolean",
150107                             required: false
150108                         }
150109                     }
150110                 },
150111                 preference: {
150112                     nodeName: "preference",
150113                     required: false,
150114                     occurrence: 0,
150115                     attributes: {
150116                         name: {
150117                             attributeName: "name",
150118                             type: "string",
150119                             required: true
150120                         },
150121                         value: {
150122                             type: "string",
150123                             attributeName: "value",
150124                             required: false
150125                         },
150126                         readonly: {
150127                             attributeName: "readonly",
150128                             type: "boolean",
150129                             required: false
150130                         }
150131                     }
150132                 }
150133             }
150134         }
150135     }
150136 };
150137
150138 });
150139 define('ripple/platform/cordova/2.0.0/spec/device', function (require, exports, module) {
150140 /*
150141  *  Copyright 2011 Research In Motion Limited.
150142  *
150143  * Licensed under the Apache License, Version 2.0 (the "License");
150144  * you may not use this file except in compliance with the License.
150145  * You may obtain a copy of the License at
150146  *
150147  * http://www.apache.org/licenses/LICENSE-2.0
150148  *
150149  * Unless required by applicable law or agreed to in writing, software
150150  * distributed under the License is distributed on an "AS IS" BASIS,
150151  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150152  * See the License for the specific language governing permissions and
150153  * limitations under the License.
150154  */
150155 var event = require('ripple/event');
150156
150157 module.exports = {
150158     "NetworkStatus": {
150159         "connectionType": {
150160             "name": "Connection Type",
150161             "control": {
150162                 "type": "select",
150163                 "value": "ethernet"
150164             },
150165             "options": {
150166                 "unknown": "UNKNOWN",
150167                 "ethernet": "ETHERNET",
150168                 "wifi": "WIFI",
150169                 "2g": "CELL_2G",
150170                 "3g": "CELL_3G",
150171                 "4g": "CELL_4G",
150172                 "none": "none"
150173             },
150174             "callback": function (setting) {
150175                 var connected = setting !== "none";
150176                 require('ripple/bus').send("network", connected);
150177             }
150178         },
150179         "lag": {
150180             "name": "Lag the network",
150181             "control": {
150182                 type: "checkbox",
150183                 value: false
150184             },
150185             "callback": function (setting) {
150186                 require('ripple/bus').send("lag", setting);
150187             }
150188         },
150189     }
150190 };
150191
150192 });
150193 define('ripple/platform/cordova/2.0.0/spec/events', function (require, exports, module) {
150194 /*
150195  *  Copyright 2011 Research In Motion Limited.
150196  *
150197  * Licensed under the Apache License, Version 2.0 (the "License");
150198  * you may not use this file except in compliance with the License.
150199  * You may obtain a copy of the License at
150200  *
150201  * http://www.apache.org/licenses/LICENSE-2.0
150202  *
150203  * Unless required by applicable law or agreed to in writing, software
150204  * distributed under the License is distributed on an "AS IS" BASIS,
150205  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150206  * See the License for the specific language governing permissions and
150207  * limitations under the License.
150208  */
150209 function _fires(name, data) {
150210     return function () {
150211         cordova.fireDocumentEvent(name, data);
150212     };
150213 }
150214
150215 module.exports = {
150216     "deviceready": {
150217         callback: _fires("deviceready")
150218     },
150219     "backbutton": {
150220         callback: _fires("backbutton")
150221     },
150222     "menubutton": {
150223         callback: _fires("menubutton")
150224     },
150225     "pause": {
150226         callback: _fires("pause")
150227     },
150228     "resume": {
150229         callback: _fires("resume")
150230     },
150231     "searchbutton": {
150232         callback: _fires("searchbutton")
150233     },
150234     "online": {
150235         callback: _fires("online")
150236     },
150237     "offline": {
150238         callback: _fires("offline")
150239     }
150240 };
150241
150242 });
150243 define('ripple/platform/cordova/2.0.0/spec/ui', function (require, exports, module) {
150244 /*
150245  *  Copyright 2011 Research In Motion Limited.
150246  *
150247  * Licensed under the Apache License, Version 2.0 (the "License");
150248  * you may not use this file except in compliance with the License.
150249  * You may obtain a copy of the License at
150250  *
150251  * http://www.apache.org/licenses/LICENSE-2.0
150252  *
150253  * Unless required by applicable law or agreed to in writing, software
150254  * distributed under the License is distributed on an "AS IS" BASIS,
150255  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150256  * See the License for the specific language governing permissions and
150257  * limitations under the License.
150258  */
150259 module.exports = {
150260     plugins: [
150261         "accelerometer",
150262         "deviceSettings",
150263         "geoView",
150264         "widgetConfig",
150265         "platformEvents"
150266     ]
150267 };
150268
150269 });
150270 define('ripple/platform/cordova/2.0.0/bridge/file', function (require, exports, module) {
150271 // HACK: fs keeps a reference to the last-used FileSystem requested via requestFileSystem
150272 // this is a hack because if you keep switching between TEMPORARY vs. PERSISTENT file systems requested,
150273 // and run Cordova File API methods, no parameter is passed into exec specifying the underlying File System.
150274 // This should be fixed in Cordova!
150275 var fs, 
150276     topCordova = require('ripple/platform/cordova/2.0.0/spec'),
150277     rlfsu;
150278
150279 function cleanPath(path) {
150280     while (path[0] && path[0] === '/') {
150281         path = path.substr(1);
150282     }
150283     return path;
150284 }
150285
150286 module.exports = {
150287     requestFileSystem: function (win, fail, args) {
150288         // HACK: may not be webkit
150289         var rfs = window.webkitRequestFileSystem,
150290             type = args[0],
150291             size = args[1];
150292
150293         // HACK: assume any FS requested over a gig in size will throw an error
150294         if (size > (1024 * 1024 * 1024 /* gigabyte */)) {
150295             if (fail) fail(FileError.QUOTA_EXCEEDED_ERR);
150296         } else {
150297             return rfs(type, size, function (effes) {
150298                 fs = effes;
150299                 win(effes);
150300             }, fail);
150301         }
150302     },
150303     resolveLocalFileSystemURI: function (win, fail, args) {
150304         var uri = args[0],
150305             fulluri = fs.root.toURL();
150306
150307         // HACK: iOS-specific bs right here. See lib/ios/plugin/ios/Entry.js in cordova.js for details
150308         // Cordova badly needs a unified File System abstraction.
150309         if (uri.indexOf("file://localhost") === 0) {
150310             uri = uri.substr(16);
150311         }
150312         uri = cleanPath(uri);
150313
150314         fulluri += uri;
150315
150316         return window.webkitResolveLocalFileSystemURL(fulluri, function (entry) {
150317             if (win) win(entry);
150318         }, function (error) {
150319             if (fail) fail(error.code);
150320         });
150321     },
150322     getFile: function (win, fail, args) {
150323         var path = args[0],
150324             filename = args[1],
150325             options = args[2],
150326             file = '';
150327
150328         path = cleanPath(path);
150329         filename = cleanPath(filename);
150330
150331         if (path) {
150332             file = path + '/';
150333         }
150334         file += filename;
150335
150336         fs.root.getFile(file, options, function (entry) {
150337             if (win) win(entry);
150338         }, function (err) {
150339             if (fail) fail(err.code);
150340         });
150341     },
150342     remove: function (win, fail, args) {
150343         var file = args[0];
150344         window.webkitResolveLocalFileSystemURL(fs.root.toURL() + file, function (entry) {
150345             entry.remove(function () {
150346                 if (win) win();
150347             }, function (err) {
150348                 if (fail) fail(err.code);
150349             });
150350         }, fail);
150351     },
150352     readEntries: function (win, fail, args) {
150353         var root = fs.root.toURL(),
150354             path = args[0],
150355             reader;
150356
150357         path = cleanPath(path);
150358         path = root + path;
150359
150360         window.webkitResolveLocalFileSystemURL(path, function (entry) {
150361             reader = entry.createReader();
150362             reader.readEntries(function (entries) {
150363                 if (win) win(entries);
150364             }, function (err) {
150365                 if (fail) fail(err.code);
150366             });
150367         }, function (err) {
150368             if (fail) fail(err.code);
150369         });
150370     },
150371     getDirectory: function (win, fail, args) {
150372         var path = args[0],
150373             filename = args[1],
150374             options = args[2],
150375             file = '';
150376
150377         path = cleanPath(path);
150378         filename = cleanPath(filename);
150379
150380         if (path) {
150381             file = path + '/';
150382         }
150383         file += filename;
150384
150385         fs.root.getDirectory(file, options, function (entry) {
150386             if (win) win(entry);
150387         }, function (err) {
150388             if (fail) fail(err.code);
150389         });
150390     },
150391     removeRecursively: function (win, fail, args) {
150392         var root = fs.root.toURL(),
150393             path = args[0];
150394
150395         path = cleanPath(path);
150396
150397         window.webkitResolveLocalFileSystemURL(root + path, function (dirEntry) {
150398             dirEntry.removeRecursively(function () {
150399                 if (win) win();
150400             }, function (err) {
150401                 if (fail) fail(err.code);
150402             });
150403         }, function (err) {
150404             if (fail) fail(err.code);
150405         });
150406     },
150407     getFileMetadata: function (win, fail, args) {
150408         var path = args[0],
150409             root = fs.root.toURL();
150410
150411         path = cleanPath(path);
150412
150413         window.webkitResolveLocalFileSystemURL(root + path, function (entry) {
150414             entry.file(function (file) {
150415                 if (win) win(file);
150416             }, function (err) {
150417                 if (fail) fail(err.code);
150418             });
150419         }, function (err) {
150420             if (fail) fail(err.code);
150421         });
150422     },
150423     getMetadata: function (win, fail, args) {
150424         var path = args[0],
150425             root = fs.root.toURL();
150426
150427         path = cleanPath(path);
150428         
150429         window.webkitResolveLocalFileSystemURL(root + path, function (entry) {
150430             entry.getMetadata(function (data) {
150431                 if (win) win(data);
150432             }, function (err) {
150433                 if (fail) fail(err.code);
150434             });
150435         }, function (err) {
150436             if (fail) fail(err.code);
150437         });
150438     },
150439     getParent: function (win, fail, args) {
150440         var path = args[0],
150441             root = fs.root.toURL();
150442
150443         path = cleanPath(path);
150444
150445         window.webkitResolveLocalFileSystemURL(root + path, function (entry) {
150446             entry.getParent(function (dirEntry) {
150447                 if (win) win(dirEntry);
150448             }, function (err) {
150449                 if (fail) fail(err.code);
150450             });
150451         }, function (err) {
150452             if (fail) fail(err.code);
150453         });
150454     },
150455     copyTo: function (win, fail, args) {
150456         var src = args[0],
150457             parent = args[1],
150458             name = args[2],
150459             root = fs.root.toURL();
150460
150461         parent = cleanPath(parent);
150462         src = cleanPath(src);
150463
150464         rlfsu = window.webkitResolveLocalFileSystemURL;
150465         // get the directoryentry that we will copy TO
150466         rlfsu(root + parent, function (parentDirToCopyTo) {
150467             rlfsu(root + src, function (sourceDir) {
150468                 sourceDir.copyTo(parentDirToCopyTo, name, function (newEntry) {
150469                     if (win) win(newEntry);
150470                 }, function (err) {
150471                     if (fail) fail(err.code);
150472                 });
150473             }, function (err) {
150474                 if (fail) fail(err.code);
150475             });
150476         }, function (err) {
150477             if (fail) fail(err.code);
150478         });
150479     },
150480     moveTo: function (win, fail, args) {
150481         var src = args[0],
150482             parent = args[1],
150483             name = args[2],
150484             root = fs.root.toURL();
150485
150486         parent = cleanPath(parent);
150487         src = cleanPath(src);
150488
150489         rlfsu = window.webkitResolveLocalFileSystemURL;
150490         // get the directoryentry that we will move TO
150491         rlfsu(root + parent, function (parentDirToMoveTo) {
150492             rlfsu(root + src, function (sourceDir) {
150493                 sourceDir.moveTo(parentDirToMoveTo, name, function (newEntry) {
150494                     if (win) win(newEntry);
150495                 }, function (err) {
150496                     if (fail) fail(err.code);
150497                 });
150498             }, function (err) {
150499                 if (fail) fail(err.code);
150500             });
150501         }, function (err) {
150502             if (fail) fail(err.code);
150503         });
150504     },
150505     write: function (win, fail, args) {
150506         var file = args[0],
150507             text = args[1],
150508             position = args[2],
150509             sourcepath,
150510             BB = window.BlobBuilder || window.WebKitBlobBuilder,
150511             bb = new BB();
150512
150513         // Format source path
150514         sourcepath = (file.fullPath ? file.fullPath : '') + file.name;
150515         sourcepath = cleanPath(sourcepath);
150516
150517         // Create a blob for the text to be written
150518         bb.append(text);
150519
150520         // Get the FileEntry, create if necessary
150521         fs.root.getFile(sourcepath, {create: true}, function (entry) {
150522             // Create a FileWriter for this entry
150523             entry.createWriter(function (writer) {
150524                 writer.onwriteend = function (progressEvt) {
150525                     if (win) win(progressEvt.total);
150526                 };
150527                 writer.onerror = function (err) {
150528                     if (fail) fail(err.code);
150529                 };
150530
150531                 if (position && position > 0) {
150532                     writer.seek(position);
150533                 }
150534                 writer.write(bb.getBlob('text/plain'));
150535             }, function (err) {
150536                 if (fail) fail(err.code);
150537             });
150538         }, function (err) {
150539             if (fail) fail(err.code);
150540         });
150541     },
150542     readAsText: function (win, fail, args) {
150543         var path = args[0],
150544             encoding = args[1],
150545             FileReader = topCordova.nativeMethods.FileReader,
150546             fr = new window.FileReader();
150547
150548         // Set up FileReader events
150549         fr.onerror = function (err) {
150550             if (fail) fail(err.code);
150551         };
150552         fr.onload = function (evt) {
150553             if (win) win(evt.target.result);
150554         };
150555
150556         path = cleanPath(path);
150557
150558         fs.root.getFile(path, {create: false}, function (entry) {
150559             entry.file(function (blob) {
150560                 fr.readAsText(blob, encoding);
150561             }, function (err) {
150562                 if (fail) fail(err.code);
150563             });
150564         }, function (err) {
150565             if (fail) fail(err.code);
150566         });
150567     },
150568     readAsDataURL: function (win, fail, args) {
150569         var path = args[0],
150570             FileReader = topCordova.nativeMethods.FileReader,
150571             fr = new window.FileReader();
150572
150573         // Set up FileReader events
150574         fr.onerror = function (err) {
150575             if (fail) fail(err.code);
150576         };
150577         fr.onload = function (evt) {
150578             if (win) win(evt.target.result);
150579         };
150580
150581         path = cleanPath(path);
150582
150583         fs.root.getFile(path, {create: false}, function (entry) {
150584             entry.file(function (blob) {
150585                 fr.readAsDataURL(blob);
150586             }, function (err) {
150587                 if (fail) fail(err.code);
150588             });
150589         }, function (err) {
150590             if (fail) fail(err.code);
150591         });
150592     },
150593     truncate: function (win, fail, args) {
150594         var file = args[0],
150595             position = args[1],
150596             sourcepath;
150597
150598         // Format source path
150599         sourcepath = (file.fullPath ? file.fullPath : '') + file.name;
150600         sourcepath = cleanPath(sourcepath);
150601
150602         // Get the FileEntry, create if necessary
150603         fs.root.getFile(sourcepath, {create: false}, function (entry) {
150604             // Create a FileWriter for this entry
150605             entry.createWriter(function (writer) {
150606                 writer.onwriteend = function (progressEvt) {
150607                     if (win) win(progressEvt.target.length);
150608                 };
150609                 writer.onerror = function (err) {
150610                     if (fail) fail(err.code);
150611                 };
150612
150613                 writer.truncate(position);
150614             }, function (err) {
150615                 if (fail) fail(err.code);
150616             });
150617         }, function (err) {
150618             if (fail) fail(err.code);
150619         });
150620     }
150621 };
150622
150623 });
150624 define('ripple/platform/cordova/2.0.0/bridge/media', function (require, exports, module) {
150625 /*
150626  *  Copyright 2011 Research In Motion Limited.
150627  *
150628  * Licensed under the Apache License, Version 2.0 (the "License");
150629  * you may not use this file except in compliance with the License.
150630  * You may obtain a copy of the License at
150631  *
150632  * http://www.apache.org/licenses/LICENSE-2.0
150633  *
150634  * Unless required by applicable law or agreed to in writing, software
150635  * distributed under the License is distributed on an "AS IS" BASIS,
150636  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150637  * See the License for the specific language governing permissions and
150638  * limitations under the License.
150639  */
150640 var audioObjects = {},
150641     noop = function () {};
150642
150643 function createAudio(id, src, error) {
150644     var a = new Audio();
150645     a.addEventListener("error", function (e) {
150646         error(new window.MediaError(1, e.toString()));
150647     });
150648     a.addEventListener("durationchange", function () {
150649         //HACK: I don't like this but best way for us to update the duration
150650         cordova.require("cordova/plugin/Media").onStatus(id, 2, this.duration);
150651     });
150652     a.src = src;
150653
150654     return a;
150655 }
150656
150657 module.exports = {
150658     create: function (success, error, args) {
150659         if (!args.length) {
150660             error("Media Object id was not sent in arguments");
150661             return;
150662         }
150663
150664         var id = args[0],
150665             src = args[1];
150666
150667         error = error || noop;
150668         success = success || noop;
150669
150670         audioObjects[id] = createAudio(id, src, error);
150671         success();
150672     },
150673     startPlayingAudio: function (success, error, args) {
150674         error = error || noop;
150675         success = success || noop;
150676         if (!args.length) {
150677             error("Media Object id was not sent in arguments");
150678             return;
150679         }
150680
150681         var id = args[0],
150682             audio = audioObjects[id];
150683
150684         if (args.length === 1) {
150685             error("Media source argument not found");
150686             return;
150687         }
150688
150689         if (audio) {
150690             audio.pause();
150691             audioObjects[id] = undefined;
150692         }
150693
150694         audio = audioObjects[id] = createAudio(id, args[1], error);
150695         audio.play();
150696
150697         success();
150698     },
150699     stopPlayingAudio: function (success, error, args) {
150700         error = error || noop;
150701         success = success || noop;
150702         if (!args.length) {
150703             error("Media Object id was not sent in arguments");
150704             return;
150705         }
150706
150707         var id = args[0],
150708             audio = audioObjects[id];
150709
150710         if (!audio) {
150711             error("Audio Object has not been initialized");
150712             return;
150713         }
150714
150715         audio.pause();
150716         audioObjects[id] = undefined;
150717
150718         success();
150719     },
150720     seekToAudio: function (success, error, args) {
150721         error = error || noop;
150722         success = success || noop;
150723         if (!args.length) {
150724             error("Media Object id was not sent in arguments");
150725             return;
150726         }
150727
150728         var id = args[0],
150729             audio = audioObjects[id];
150730
150731         if (!audio) {
150732             error("Audio Object has not been initialized");
150733             return;
150734         } else if (args.length === 1) {
150735             error("Media seek time argument not found");
150736             return;
150737         } else {
150738             try {
150739                 audio.currentTime = args[1];
150740             } catch (e) {
150741                 error("Error seeking audio: " + e);
150742             }
150743         }
150744
150745         success();
150746     },
150747     pausePlayingAudio: function (success, error, args) {
150748         error = error || noop;
150749         success = success || noop;
150750         if (!args.length) {
150751             error("Media Object id was not sent in arguments");
150752             return;
150753         }
150754
150755         var id = args[0],
150756             audio = audioObjects[id];
150757
150758         if (!audio) {
150759             error("Audio Object has not been initialized");
150760             return;
150761         }
150762
150763         audio.pause();
150764         success();
150765     },
150766     getCurrentPositionAudio: function (success, error, args) {
150767         error = error || noop;
150768         success = success || noop;
150769         if (!args.length) {
150770             error("Media Object id was not sent in arguments");
150771             return;
150772         }
150773
150774         var id = args[0],
150775             audio = audioObjects[id];
150776
150777         if (!audio) {
150778             error("Audio Object has not been initialized");
150779             return;
150780         }
150781
150782         success(audio.currentTime);
150783     },
150784     getDuration: function (success, error, args) {
150785         error = error || noop;
150786         success = success || noop;
150787         if (!args.length) {
150788             error("Media Object id was not sent in arguments");
150789             return;
150790         }
150791
150792         var id = args[0],
150793             audio = audioObjects[id];
150794
150795         if (!audio) {
150796             error("Audio Object has not been initialized");
150797             return;
150798         }
150799
150800         success(audio.duration);
150801     },
150802     startRecordingAudio: function (success, error, args) {
150803         error = error || noop;
150804         error("Not supported");
150805     },
150806     stopRecordingAudio: function (success, error, args) {
150807         error = error || noop;
150808         error("Not supported");
150809     },
150810     release: function (success, error, args) {
150811         error = error || noop;
150812         success = success || noop;
150813         if (!args.length) {
150814             error("Media Object id was not sent in arguments");
150815             return;
150816         }
150817
150818         var id = args[0],
150819             audio = audioObjects[id];
150820
150821         if (audio) {
150822             audioObjects[id] = undefined;
150823             audio.src = undefined;
150824             //delete audio;
150825         }
150826
150827         success();
150828     }
150829 };
150830
150831 });
150832 define('ripple/platform/cordova/2.0.0/bridge/device', function (require, exports, module) {
150833 /*
150834  *  Copyright 2011 Research In Motion Limited.
150835  *
150836  * Licensed under the Apache License, Version 2.0 (the "License");
150837  * you may not use this file except in compliance with the License.
150838  * You may obtain a copy of the License at
150839  *
150840  * http://www.apache.org/licenses/LICENSE-2.0
150841  *
150842  * Unless required by applicable law or agreed to in writing, software
150843  * distributed under the License is distributed on an "AS IS" BASIS,
150844  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150845  * See the License for the specific language governing permissions and
150846  * limitations under the License.
150847  */
150848 var devices = require('ripple/devices');
150849
150850 module.exports = {
150851     getDeviceInfo: function (success, fail, args) {
150852         var device = devices.getCurrentDevice();
150853
150854         success({
150855             available: true,
150856             platform: device.osName,
150857             version: device.osVersion,
150858             name: device.name,
150859             uuid: device.uuid,
150860             cordova: "2.0.0"
150861         });
150862     }
150863 };
150864
150865 });
150866 define('ripple/platform/cordova/2.0.0/bridge/notification', function (require, exports, module) {
150867 /*
150868  *  Copyright 2011 Research In Motion Limited.
150869  *
150870  * Licensed under the Apache License, Version 2.0 (the "License");
150871  * you may not use this file except in compliance with the License.
150872  * You may obtain a copy of the License at
150873  *
150874  * http://www.apache.org/licenses/LICENSE-2.0
150875  *
150876  * Unless required by applicable law or agreed to in writing, software
150877  * distributed under the License is distributed on an "AS IS" BASIS,
150878  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150879  * See the License for the specific language governing permissions and
150880  * limitations under the License.
150881  */
150882 var notifications = require('ripple/notifications'),
150883     _console = require('ripple/console'),
150884     goodVibrations = require('ripple/ui/plugins/goodVibrations');
150885
150886 module.exports = {
150887     alert: function (success, error, args) {
150888         notifications.openNotification("normal", args[0]);
150889         return success && success();
150890     },
150891
150892     confirm: function (success, error, args) {
150893         throw "Not Implemented";
150894     },
150895
150896     activityStart: function (success, error, args) {
150897     },
150898
150899     activityStop: function (success, error, args) { 
150900     },
150901
150902     progressStart: function (success, error, args) {
150903     },
150904
150905     vibrate: function (success, error, args) {
150906         var ms = args[0] || 500;
150907         goodVibrations.vibrateDevice(ms);
150908     },
150909
150910     beep: function (success, error, args) {
150911         for (var i = args[0]; i > 0; i--) {
150912             _console.log("beep!");
150913         }
150914         notifications.openNotification("normal", "BEEP x " + args[0]);
150915     }
150916 };
150917
150918 });
150919 define('ripple/platform/cordova/2.0.0/bridge/contacts', function (require, exports, module) {
150920 /*
150921  *  Copyright 2011 Research In Motion Limited.
150922  *
150923  * Licensed under the Apache License, Version 2.0 (the "License");
150924  * you may not use this file except in compliance with the License.
150925  * You may obtain a copy of the License at
150926  *
150927  * http://www.apache.org/licenses/LICENSE-2.0
150928  *
150929  * Unless required by applicable law or agreed to in writing, software
150930  * distributed under the License is distributed on an "AS IS" BASIS,
150931  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
150932  * See the License for the specific language governing permissions and
150933  * limitations under the License.
150934  */
150935 var db = require('ripple/db'),
150936     utils = require('ripple/utils'),
150937     _self;
150938
150939 function _default() {
150940     return [{
150941         "name": {formatted: "Brent Lintner"},
150942         "displayName": "Brent Lintner",
150943         "emails": [{type: "work", value: "brent@tinyhippos.com", pref: false}]
150944     }, {
150945         "name": {formatted: "PJ Lowe"},
150946         "displayName": "PJ Lowe",
150947         "emails": [{type: "work", value: "pj@tinyhippos.com", pref: false}]
150948     }, {
150949         "name": {formatted: "Dan Silivestru"},
150950         "displayName": "Dan Silivestru",
150951         "emails": [{type: "work", value: "dan@tinyhippos.com", pref: false}]
150952     }, {
150953         "name": {formatted: "Gord Tanner"},
150954         "displayName": "Gord Tanner",
150955         "emails": [{type: "work", value: "gord@tinyhippos.com", pref: true}]
150956     }, {
150957         "name": {formatted: "Mark McArdle"},
150958         "displayName": "Mark McArdle",
150959         "emails": [{type: "work", value: "mark@tinyhippos.com", pref: false}]
150960     }].map(function (obj) {
150961         obj.id = Math.uuid(undefined, 16);
150962         return navigator.contacts.create(obj);
150963     });
150964 }
150965
150966 function _get() {
150967     return db.retrieveObject("cordova-contacts") || _default();
150968 }
150969
150970 function _save(contacts) {
150971     db.saveObject("cordova-contacts", contacts);
150972 }
150973
150974 function _filtered(compare, options) {
150975     // this could be done a lot better..
150976     var found = false;
150977     if (!options.filter || options.filter === "") {
150978         found = true;
150979     } else if (typeof compare === "string" &&
150980               compare.match(new RegExp(".*" + options.filter + ".*", "i"))) {
150981         found = true;
150982     } else if (typeof compare === "object" || compare instanceof Array) {
150983         utils.forEach(compare, function (value) {
150984             if (!found) {
150985                 found = _filtered(value, options);
150986             }
150987         });
150988     }
150989     return found;
150990 }
150991
150992 _self = {
150993     search: function (success, error, args) {
150994         var fields = args[0],
150995             options = args[1],
150996             foundContacts = [],
150997             tempContact = navigator.contacts.create(),
150998             contacts = _get();
150999
151000         options = options || {};
151001
151002         // handle special case of ["*"] to return all fields
151003         if (fields.length === 1 && fields[0] === "*") {
151004             fields = utils.map(tempContact, function (v, k) {
151005                 return k;
151006             });
151007         }
151008
151009         if (fields.length > 0) {
151010             contacts.forEach(function (contact, index) {
151011                 var newContact = navigator.contacts.create(contact);
151012
151013                 if (options && (!_filtered(contact, options))) {
151014                     return;
151015                 }
151016
151017                 utils.forEach(newContact, function (value, prop) {
151018                     if (typeof newContact[prop] !== "function" && prop !== "id" &&
151019                         !fields.some(function (field) {
151020                             return field === prop;
151021                         })) {
151022                         delete newContact[prop];
151023                     }
151024                 });
151025
151026                 foundContacts.push(newContact);
151027             });
151028         }
151029
151030         // TODO: don't loop over entire db just to slice the array
151031         if (options.multiple === false) {
151032             foundContacts = foundContacts.splice(0, 1);
151033         }
151034         success(foundContacts);
151035     },
151036
151037     save: function (success, error, args) {
151038         var contacts = _get(),
151039             contact = args[0],
151040             index;
151041
151042         if (!contact.id) {
151043             contact.id = Math.uuid(undefined, 16);
151044             contacts.push(contact);
151045         } else {
151046             index = contacts.reduce(function (result, value, index) {
151047                 return value.id === contact.id ? index : result;
151048             }, -1);
151049
151050             if (index >= 0) {
151051                 utils.mixin(contact, contacts[index]);
151052                 contact = contacts[index];
151053             } else {
151054                 contact = null;
151055             }
151056         }
151057
151058         _save(contacts);
151059         if (success) {
151060             success(contact);
151061         }
151062     },
151063
151064     remove: function (success, error, args) {
151065         var contacts = _get(),
151066             id = args[0],
151067             toDelete = contacts.reduce(function (result, current, index) {
151068                 return current.id === id ? index : result;
151069             }, -1);
151070
151071         if (toDelete >= 0) {
151072             contacts.splice(toDelete, 1);
151073             _save(contacts);
151074             if (success) {
151075                 success();
151076             }
151077         } else {
151078             error({code: 3, message: "could not find contact with id (" + id + ")"}); // PENDING_OPERATION_ERROR
151079         }
151080     }
151081 };
151082
151083 module.exports = _self;
151084
151085 });
151086 define('ripple/platform/cordova/2.0.0/bridge/app', function (require, exports, module) {
151087 /*
151088  *  Copyright 2011 Research In Motion Limited.
151089  *
151090  * Licensed under the Apache License, Version 2.0 (the "License");
151091  * you may not use this file except in compliance with the License.
151092  * You may obtain a copy of the License at
151093  *
151094  * http://www.apache.org/licenses/LICENSE-2.0
151095  *
151096  * Unless required by applicable law or agreed to in writing, software
151097  * distributed under the License is distributed on an "AS IS" BASIS,
151098  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151099  * See the License for the specific language governing permissions and
151100  * limitations under the License.
151101  */
151102 var camera = require('ripple/ui/plugins/camera'),
151103     event = require('ripple/event');
151104
151105 module.exports = {
151106     show: function (success, error, args) {
151107         return success && success();
151108     }
151109 };
151110
151111 });
151112 define('ripple/platform/cordova/2.0.0/bridge/camera', function (require, exports, module) {
151113 /*
151114  *  Copyright 2011 Research In Motion Limited.
151115  *
151116  * Licensed under the Apache License, Version 2.0 (the "License");
151117  * you may not use this file except in compliance with the License.
151118  * You may obtain a copy of the License at
151119  *
151120  * http://www.apache.org/licenses/LICENSE-2.0
151121  *
151122  * Unless required by applicable law or agreed to in writing, software
151123  * distributed under the License is distributed on an "AS IS" BASIS,
151124  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151125  * See the License for the specific language governing permissions and
151126  * limitations under the License.
151127  */
151128 var camera = require('ripple/ui/plugins/camera'),
151129     event = require('ripple/event');
151130
151131 module.exports = {
151132     takePicture: function (success, error, args) {
151133         event.once("captured-image", function (uri, file) {
151134             success(uri);
151135         });
151136         camera.show();
151137     },
151138     cleanup: function (success, error, args) {
151139         success();
151140     }
151141 };
151142
151143 });
151144 define('ripple/platform/cordova/2.0.0/bridge/network', function (require, exports, module) {
151145 /*
151146  *  Copyright 2011 Research In Motion Limited.
151147  *
151148  * Licensed under the Apache License, Version 2.0 (the "License");
151149  * you may not use this file except in compliance with the License.
151150  * You may obtain a copy of the License at
151151  *
151152  * http://www.apache.org/licenses/LICENSE-2.0
151153  *
151154  * Unless required by applicable law or agreed to in writing, software
151155  * distributed under the License is distributed on an "AS IS" BASIS,
151156  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151157  * See the License for the specific language governing permissions and
151158  * limitations under the License.
151159  */
151160
151161 var deviceSettings = require('ripple/deviceSettings'),
151162     event = require('ripple/event'),
151163     _success;
151164
151165 event.on("ConnectionChanged", function () {
151166     return _success && _success(deviceSettings.retrieve("NetworkStatus.connectionType"));
151167 });
151168
151169 module.exports = {
151170     getConnectionInfo: function (success, fail, args) {
151171         _success = success;
151172         success(deviceSettings.retrieve("NetworkStatus.connectionType"));
151173     }
151174 };
151175
151176 });
151177 define('ripple/platform/cordova/2.0.0/bridge/compass', function (require, exports, module) {
151178 /*
151179  *  Copyright 2011 Research In Motion Limited.
151180  *
151181  * Licensed under the Apache License, Version 2.0 (the "License");
151182  * you may not use this file except in compliance with the License.
151183  * You may obtain a copy of the License at
151184  *
151185  * http://www.apache.org/licenses/LICENSE-2.0
151186  *
151187  * Unless required by applicable law or agreed to in writing, software
151188  * distributed under the License is distributed on an "AS IS" BASIS,
151189  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151190  * See the License for the specific language governing permissions and
151191  * limitations under the License.
151192  */
151193 var geo = require('ripple/geo');
151194
151195 module.exports = {
151196     getHeading: function (success, error, args) {
151197         // TODO: build facility to trigger onError() from emulator
151198         // see pivotal item: https://www.pivotaltracker.com/story/show/7040343
151199         success({
151200             magneticHeading: geo.getPositionInfo().heading, 
151201             trueHeading: geo.getPositionInfo().heading, 
151202             headingAccuracy: 100, 
151203             timestamp: new Date().getSeconds()
151204         });
151205     },
151206
151207     stopHeading: function () { 
151208         //do nothing
151209     }
151210 };
151211
151212 });
151213 define('ripple/platform/cordova/2.0.0/bridge/geolocation', function (require, exports, module) {
151214 /*
151215  *  Copyright 2011 Research In Motion Limited.
151216  *
151217  * Licensed under the Apache License, Version 2.0 (the "License");
151218  * you may not use this file except in compliance with the License.
151219  * You may obtain a copy of the License at
151220  *
151221  * http://www.apache.org/licenses/LICENSE-2.0
151222  *
151223  * Unless required by applicable law or agreed to in writing, software
151224  * distributed under the License is distributed on an "AS IS" BASIS,
151225  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151226  * See the License for the specific language governing permissions and
151227  * limitations under the License.
151228  */
151229 var event = require('ripple/event'),
151230     geo = require('ripple/geo'),
151231     utils = require('ripple/utils'),
151232     PositionError = require('ripple/platform/w3c/1.0/PositionError'),
151233     _watches = {},
151234     _current = {
151235         "latitude": 43.465187,
151236         "longitude": -80.522372,
151237         "altitude": 100,
151238         "accuracy": 150,
151239         "altitudeAccuracy": 80,
151240         "heading": 0,
151241         "velocity": 0,
151242     },
151243     _error;
151244
151245 function _getCurrentPosition(win, fail) {
151246     if (geo.timeout) {
151247         if (fail) {
151248             var positionError = new PositionError();
151249
151250             positionError.code = PositionError.TIMEOUT;
151251             positionError.message = "postion timed out";
151252             fail(positionError);
151253         }
151254     }
151255     else {
151256         win(geo.getPositionInfo());
151257     }
151258 }
151259
151260 event.on("PositionInfoUpdatedEvent", function (pi) {
151261     _current.latitude = pi.latitude;
151262     _current.longitude = pi.longitude;
151263     _current.altitude = pi.altitude;
151264     _current.accuracy = pi.accuracy;
151265     _current.altitudeAccuracy = pi.altitudeAccuracy;
151266     _current.heading = pi.heading;
151267     _current.velocity = pi.speed;
151268
151269     utils.forEach(_watches, function (watch) {
151270         try {
151271             _getCurrentPosition(watch.win, watch.fail);
151272         } catch (e) {
151273             console.log(e);
151274         }
151275     });
151276 });
151277
151278 module.exports = {
151279     getLocation: function (success, error, args) {
151280         _getCurrentPosition(success, error);
151281     },
151282
151283     addWatch: function (success, error, args) {
151284         _watches[args[0]] = {
151285             win: success,
151286             fail: error
151287         };
151288         _getCurrentPosition(success, error);
151289     },
151290
151291     clearWatch: function (id) {
151292         delete _watches[id];
151293     }
151294 };
151295
151296 });
151297 define('ripple/platform/cordova/2.0.0/bridge/console', function (require, exports, module) {
151298 /*
151299  *  Copyright 2011 Research In Motion Limited.
151300  *
151301  * Licensed under the Apache License, Version 2.0 (the "License");
151302  * you may not use this file except in compliance with the License.
151303  * You may obtain a copy of the License at
151304  *
151305  * http://www.apache.org/licenses/LICENSE-2.0
151306  *
151307  * Unless required by applicable law or agreed to in writing, software
151308  * distributed under the License is distributed on an "AS IS" BASIS,
151309  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151310  * See the License for the specific language governing permissions and
151311  * limitations under the License.
151312  */
151313
151314 module.exports = {
151315     log: function (win, fail, args) {
151316         console.log(args[0]);
151317     }
151318 };
151319
151320 });
151321 define('ripple/platform/cordova/2.0.0/bridge/accelerometer', function (require, exports, module) {
151322 /*
151323  *  Copyright 2011 Research In Motion Limited.
151324  *
151325  * Licensed under the Apache License, Version 2.0 (the "License");
151326  * you may not use this file except in compliance with the License.
151327  * You may obtain a copy of the License at
151328  *
151329  * http://www.apache.org/licenses/LICENSE-2.0
151330  *
151331  * Unless required by applicable law or agreed to in writing, software
151332  * distributed under the License is distributed on an "AS IS" BASIS,
151333  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151334  * See the License for the specific language governing permissions and
151335  * limitations under the License.
151336  */
151337 var event = require('ripple/event'),
151338     _success,
151339     _error,
151340     _current = {x: 0, y: 0, z: 0, timestamp: (new Date()).getTime()},
151341     _interval;
151342
151343 event.on("AccelerometerInfoChangedEvent", function (accelerometerInfo) {
151344     _current.x = accelerometerInfo.accelerationIncludingGravity.x;
151345     _current.y = accelerometerInfo.accelerationIncludingGravity.y;
151346     _current.z = accelerometerInfo.accelerationIncludingGravity.z;
151347     _current.timestamp = (new Date()).getTime();
151348 });
151349
151350 module.exports = {
151351     start: function (success, error, args) {
151352         _success = success;
151353         _error = error;
151354         // Possible HACK? update the timestamp of the last data to something current
151355         _interval = window.setInterval(function () {
151356             _current.timestamp = (new Date()).getTime();
151357             _success(_current);
151358         }, 50);
151359     },
151360
151361     stop: function () {
151362         _success = null;
151363         _error = null;
151364         window.clearInterval(_interval);
151365     }
151366 };
151367
151368 });
151369 define('ripple/platform/cordova/2.0.0/bridge/capture', function (require, exports, module) {
151370 /*
151371  *  Copyright 2011 Research In Motion Limited.
151372  *
151373  * Licensed under the Apache License, Version 2.0 (the "License");
151374  * you may not use this file except in compliance with the License.
151375  * You may obtain a copy of the License at
151376  *
151377  * http://www.apache.org/licenses/LICENSE-2.0
151378  *
151379  * Unless required by applicable law or agreed to in writing, software
151380  * distributed under the License is distributed on an "AS IS" BASIS,
151381  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151382  * See the License for the specific language governing permissions and
151383  * limitations under the License.
151384  */
151385
151386 var camera = require('ripple/ui/plugins/camera'),
151387     event = require('ripple/event');
151388
151389 module.exports = {
151390     captureImage: function (success, error, args) {
151391         event.once("captured-image", function (uri, file) {
151392             file.fullPath = uri;
151393             success([file]);
151394         });
151395         camera.show();
151396     }
151397 };
151398
151399 });
151400 define('ripple/platform/cordova/2.0.0/bridge', function (require, exports, module) {
151401 /*
151402  *  Copyright 2011 Research In Motion Limited.
151403  *
151404  * Licensed under the Apache License, Version 2.0 (the "License");
151405  * you may not use this file except in compliance with the License.
151406  * You may obtain a copy of the License at
151407  *
151408  * http://www.apache.org/licenses/LICENSE-2.0
151409  *
151410  * Unless required by applicable law or agreed to in writing, software
151411  * distributed under the License is distributed on an "AS IS" BASIS,
151412  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151413  * See the License for the specific language governing permissions and
151414  * limitations under the License.
151415  */
151416 var _prompt = require('ripple/ui/plugins/exec-dialog');
151417
151418 module.exports = {
151419     exec: function (success, fail, service, action, args) {
151420         var emulator = {
151421             "App": require('ripple/platform/cordova/2.0.0/bridge/app'),
151422             "Accelerometer": require('ripple/platform/cordova/2.0.0/bridge/accelerometer'),
151423             "Compass": require('ripple/platform/cordova/2.0.0/bridge/compass'),
151424             "Camera": require('ripple/platform/cordova/2.0.0/bridge/camera'),
151425             "Capture": require('ripple/platform/cordova/2.0.0/bridge/capture'),
151426             "Contacts": require('ripple/platform/cordova/2.0.0/bridge/contacts'),
151427             "Debug Console": require('ripple/platform/cordova/2.0.0/bridge/console'),
151428             "Device": require('ripple/platform/cordova/2.0.0/bridge/device'),
151429             "File": require('ripple/platform/cordova/2.0.0/bridge/file'),
151430             "Geolocation": require('ripple/platform/cordova/2.0.0/bridge/geolocation'),
151431             "Media": require('ripple/platform/cordova/2.0.0/bridge/media'),
151432             "Network Status": require('ripple/platform/cordova/2.0.0/bridge/network'),
151433             "NetworkStatus": require('ripple/platform/cordova/2.0.0/bridge/network'),
151434             "Notification": require('ripple/platform/cordova/2.0.0/bridge/notification')
151435         };
151436
151437         try {
151438             emulator[service][action](success, fail, args);
151439         }
151440         catch (e) {
151441             console.log("missing exec:" + service + "." + action);
151442             console.log(args);
151443             console.log(e);
151444             console.log(e.stack);
151445             //TODO: this should really not log the above lines, but they are very nice for development right now
151446             _prompt.show(service, action, success, fail);
151447         }
151448     }
151449 };
151450
151451 });
151452 define('ripple/platform/cordova/2.0.0/MediaError', function (require, exports, module) {
151453 /*
151454  *  Copyright 2011 Research In Motion Limited.
151455  *
151456  * Licensed under the Apache License, Version 2.0 (the "License");
151457  * you may not use this file except in compliance with the License.
151458  * You may obtain a copy of the License at
151459  *
151460  * http://www.apache.org/licenses/LICENSE-2.0
151461  *
151462  * Unless required by applicable law or agreed to in writing, software
151463  * distributed under the License is distributed on an "AS IS" BASIS,
151464  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151465  * See the License for the specific language governing permissions and
151466  * limitations under the License.
151467  */
151468 var MediaError = function (code, msg) {
151469     this.code = (code !== undefined ? code : null);
151470     this.message = msg || "";
151471 };
151472
151473 MediaError.MEDIA_ERR_NONE_ACTIVE    = 0;
151474 MediaError.MEDIA_ERR_ABORTED        = 1;
151475 MediaError.MEDIA_ERR_NETWORK        = 2;
151476 MediaError.MEDIA_ERR_DECODE         = 3;
151477 MediaError.MEDIA_ERR_NONE_SUPPORTED = 4;
151478
151479 module.exports = MediaError;
151480
151481 });
151482 define('ripple/accelerometer', function (require, exports, module) {
151483 /*
151484  *  Copyright 2011 Research In Motion Limited.
151485  *
151486  * Licensed under the Apache License, Version 2.0 (the "License");
151487  * you may not use this file except in compliance with the License.
151488  * You may obtain a copy of the License at
151489  *
151490  * http://www.apache.org/licenses/LICENSE-2.0
151491  *
151492  * Unless required by applicable law or agreed to in writing, software
151493  * distributed under the License is distributed on an "AS IS" BASIS,
151494  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151495  * See the License for the specific language governing permissions and
151496  * limitations under the License.
151497  */
151498 var _self,
151499     utils = require('ripple/utils'),
151500     exception = require('ripple/exception'),
151501     event = require('ripple/event'),
151502     Rotation = require('ripple/platform/w3c/1.0/Rotation'),
151503     Acceleration = require('ripple/platform/w3c/1.0/Acceleration'),
151504     _motion = {
151505         acceleration: new Acceleration(0, 0, 0),
151506         accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
151507         rotationRate: new Rotation(0, 0, 0),
151508         orientation: new Rotation(0, 0, 0),
151509         interval: 60000,
151510         timestamp: new Date().getTime()
151511     };
151512
151513 function _validateAccelerometerInfo(x, y, z) {
151514     return !(isNaN(x) || isNaN(y) || isNaN(z));
151515 }
151516
151517 _self = {
151518     getInfo: function () {
151519         return utils.copy(_motion);
151520     },
151521
151522     setInfo: function (e) {
151523         var triggerDeviceMotion = false,
151524             triggerDeviceOrientation = false;
151525
151526         if (e.x !== undefined && e.y !== undefined && e.z !== undefined) {
151527             _motion = {
151528                 acceleration: new Acceleration(e.x, e.y, e.z),
151529                 accelerationIncludingGravity: new Acceleration(e.x, e.y, e.z),
151530                 rotationRate: new Rotation(0, 0, 0),
151531                 orientation: new Rotation(e.alpha, e.beta, e.gamma),
151532                 timestamp: new Date().getTime()
151533             };
151534             triggerDeviceMotion = true;
151535             triggerDeviceOrientation = true;
151536         }
151537         else {
151538             _motion = {
151539                 acceleration: new Acceleration(0, 0, 0),
151540                 accelerationIncludingGravity: new Acceleration(0, 0, -9.81),
151541                 rotationRate: new Rotation(0, 0, 0),
151542                 orientation: new Rotation(0, 0, 0),
151543                 timestamp: new Date().getTime()
151544             };
151545         }
151546
151547         if (triggerDeviceMotion) {
151548             event.trigger("DeviceMotionEvent", [_motion]);
151549         }
151550
151551         if (triggerDeviceOrientation) {
151552             event.trigger("DeviceOrientationEvent", [_motion]);
151553         }
151554
151555         event.trigger("AccelerometerInfoChangedEvent", [_motion]);
151556     },
151557
151558     triggerEvent: function() {
151559         event.trigger("DeviceMotionEvent", [_motion]);
151560         event.trigger("DeviceOrientationEvent", [_motion]);
151561         event.trigger("AccelerometerInfoChangedEvent", [_motion]);
151562     },
151563
151564     shake: function (shakeXtimes) {
151565         var id,
151566             count = 1,
151567             stopCount = shakeXtimes || 17,
151568             oldX = _motion.accelerationIncludingGravity.x;
151569
151570         id = setInterval(function () {
151571             var freq = 1,
151572                 amp = 30,
151573                 value = Math.round(amp * Math.sin(freq * count * (180 / Math.PI)) * 100) / 100;
151574
151575             if (count > stopCount) {
151576                 _motion.acceleration.x = oldX;
151577                 _motion.accelerationIncludingGravity.x = oldX;
151578                 event.trigger("AccelerometerInfoChangedEvent", [_motion]);
151579                 clearInterval(id);
151580                 return;
151581             }
151582
151583             _motion.acceleration.x = value;
151584             _motion.accelerationIncludingGravity.x = value;
151585
151586             event.trigger("AccelerometerInfoChangedEvent", [_motion]);
151587
151588             count++;
151589
151590         }, 80);
151591     },
151592
151593     init: function () {
151594         event.on("DeviceMotionEventAddedEvent", function () {
151595             _self.triggerEvent();
151596         });
151597         event.on("DeviceOrientationEventAddedEvent", function () {
151598             _self.triggerEvent();
151599         });
151600     }
151601 };
151602
151603 module.exports = _self;
151604
151605 });
151606 define('ripple/bus', function (require, exports, module) {
151607 /*
151608  *  Copyright 2011 Research In Motion Limited.
151609  *
151610  * Licensed under the Apache License, Version 2.0 (the "License");
151611  * you may not use this file except in compliance with the License.
151612  * You may obtain a copy of the License at
151613  *
151614  * http://www.apache.org/licenses/LICENSE-2.0
151615  *
151616  * Unless required by applicable law or agreed to in writing, software
151617  * distributed under the License is distributed on an "AS IS" BASIS,
151618  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151619  * See the License for the specific language governing permissions and
151620  * limitations under the License.
151621  */
151622
151623 var _send = document.getElementById("bus-send"),
151624     _receive = document.getElementById("bus-receive"),
151625     _evt = document.createEvent("Events");
151626
151627 _evt.initEvent('bus-init', true, true);
151628 document.dispatchEvent(_evt);
151629
151630 module.exports = {
151631     send: function (msg, data, callback) {
151632         var m = document.createElement("span");
151633         m.dataset.msg = msg;
151634         m.innerHTML = JSON.stringify(data);
151635
151636         if (callback) {
151637             m.dataset.callback = Math.uuid();
151638             this.receive(m.dataset.callback, callback);
151639         }
151640
151641         _send.appendChild(m);
151642     },
151643
151644     receive: function (msg, handler) {
151645         if (!handler) {
151646             return;
151647         }
151648
151649         _receive.addEventListener("DOMNodeInserted", function (evt) {
151650             if (evt.target.dataset.msg === msg) {
151651                 handler(JSON.parse(evt.target.innerHTML));
151652             }
151653         });
151654     },
151655
151656     ajax: function (method, url, data, success, fail) {
151657         this.send("xhr", {
151658             method: method,
151659             url: url,
151660             data: data
151661         }, function (result) {
151662             if (result.code === 200) {
151663                 success(result.data);
151664             }
151665             else {
151666                 fail(result);
151667             }
151668         });
151669     }
151670 };
151671
151672 });
151673 define('ripple/ui', function (require, exports, module) {
151674 /*
151675  *  Copyright 2011 Research In Motion Limited.
151676  *
151677  * Licensed under the Apache License, Version 2.0 (the "License");
151678  * you may not use this file except in compliance with the License.
151679  * You may obtain a copy of the License at
151680  *
151681  * http://www.apache.org/licenses/LICENSE-2.0
151682  *
151683  * Unless required by applicable law or agreed to in writing, software
151684  * distributed under the License is distributed on an "AS IS" BASIS,
151685  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
151686  * See the License for the specific language governing permissions and
151687  * limitations under the License.
151688  */
151689 var _self,
151690     db = require('ripple/db'),
151691     platform = require('ripple/platform'),
151692     constants = require('ripple/constants'),
151693     utils = require('ripple/utils'),
151694     exception = require('ripple/exception'),
151695     event = require('ripple/event'),
151696     themes = require('ripple/ui/themes'),
151697     _applicationStateId,
151698     _applicationState,
151699     _availablePanels,
151700     _applicationStateTmp,
151701     _systemPlugins = [
151702         "options",
151703         "about-dialog",
151704         "settings-dialog",
151705         "exec-dialog",
151706         "firstRunCheck",
151707         "eulaCheck",
151708         "devices",
151709         "goodVibrations",
151710         "panelCollapse",
151711         "platform",
151712         "information",
151713         "layout",
151714         "themeSwitcher",
151715         "settings-menu",
151716         "configWindow",
151717         "HWKeys"
151718         //"launchingHistory"
151719     ],
151720     _overlay = {
151721         getOrCreate: function (id) {
151722             var _container = document.getElementById(constants.COMMON.HTML_CONTAINER),
151723                 _overlays = document.getElementById("overlay-views"),
151724                 _overlay = _overlays.children[id],
151725                 _hide = function (node) {
151726                     node.setAttribute("style", "display: none");
151727                 },
151728                 _show = function (node) {
151729                     node.setAttribute("style", "display: block");
151730                 },
151731                 _trigger = function (callback) {
151732                     if (callback) {
151733                         callback.apply(null, [_overlay]);
151734                     }
151735                 };
151736
151737
151738             if (!_overlay) {
151739                 _overlay = utils.createElement("section", {id: id, "class": "overlay"});
151740                 _overlays.appendChild(_overlay);
151741             }
151742
151743             return {
151744                 hide: function (callback) {
151745                     _hide(_overlay);
151746                     _show(_container);
151747                     _trigger(callback);
151748                 },
151749                 show: function (callback, showContainer) {
151750                     _show(_overlay);
151751                     if (!showContainer) {
151752                         _hide(_container);
151753                     }
151754                     _trigger(callback);
151755                 }
151756             };
151757         }
151758     };
151759
151760 function _addUIPaneItemsToApplicationState(arrayObj, pane) {
151761     utils.forEach(arrayObj, function (domId) {
151762         var collapsed = jQuery("#" + domId + " .info")[0];
151763         collapsed = (collapsed.style && collapsed.style.display === "none") ? true : false;
151764         utils.forEach(_applicationStateTmp, function (obj) {
151765             if (obj.domId === domId) {
151766                 _applicationState.push({
151767                     "domId": domId,
151768                     "collapsed": collapsed,
151769                     "pane": pane,
151770                     "titleName" : obj.titleName,
151771                     "display" : obj.display
151772                 });
151773                 _applicationStateTmp.splice(_applicationStateTmp.indexOf(obj), 1);
151774                 return;
151775             }
151776         }, this);
151777     }, this);
151778
151779     utils.forEach(_applicationStateTmp, function (obj) {
151780         _applicationState.push({
151781             "domId": obj.domId,
151782             "collapsed": obj.collapsed,
151783             "pane": obj.pane,
151784             "titleName" : obj.titleName,
151785             "display" : obj.display
151786         });
151787     });
151788 }
151789
151790 function _currentlyEnabledTheme() {
151791     var qsSet = utils.queryString().theme,
151792         current = db.retrieve("ui-theme") || themes[0];
151793
151794     function matches(something) {
151795         return function (item) {
151796             return something === item;
151797         };
151798     }
151799
151800     if (qsSet && themes.some(matches(qsSet))) {
151801         current = qsSet;
151802         db.save("ui-theme", qsSet);
151803     }
151804
151805     return current;
151806 }
151807
151808 function _insertStyleSheets() {
151809     var uiTheme = db.retrieve("ui-theme") || require('ripple/ui/themes')[0],
151810         extensionURL = jQuery("#extension-url").text(),
151811         uiThemeURL = extensionURL + "themes/" + uiTheme + "/theme.css",
151812         head = document.getElementsByTagName('head')[0];
151813
151814     function stylesheet(src) {
151815         var scriptElement = document.createElement("link");
151816         scriptElement.setAttribute("href", src);
151817         scriptElement.setAttribute("type", "text/css");
151818         scriptElement.setAttribute("rel", "stylesheet");
151819         return scriptElement;
151820     }
151821
151822     head.appendChild(stylesheet(uiThemeURL));
151823 }
151824
151825 function _collapsePannels(side) {
151826     var collapseNode = [],
151827         event = document.createEvent("UIEvent");
151828
151829     collapseNode = side === "left" ? document.getElementsByClassName("left-panel-collapse") : 
151830                                      document.getElementsByClassName("right-panel-collapse");
151831     
151832     if (collapseNode.length > 0) {
151833         event.initEvent("click", true, true);
151834         collapseNode[0].dispatchEvent(event);    
151835     }
151836 }
151837
151838 function _initializeUI() {
151839     _applicationStateId = constants.COMMON.APPLICATION_STATE + platform.current().id;
151840     _applicationState = db.retrieveObject(_applicationStateId) || [];
151841     _insertStyleSheets();
151842
151843     var leftPanelSection = jQuery(".left"),
151844         uiBoxToggleEngaged = false;
151845
151846     //clean up
151847     db.remove("ui-application-state");
151848     utils.forEach(_availablePanels, function (obj) {
151849         var matchingDomId = function (panel) {
151850             return panel.domId === obj.domId;
151851         };
151852         if (!utils.some(_applicationState, matchingDomId)) {
151853             _applicationState.push({
151854                 "domId": obj.domId,
151855                 "collapsed": obj.collapsed,
151856                 "pane": obj.pane,
151857                 "titleName" : obj.titleName,
151858                 "display" : obj.display
151859             });
151860         }
151861     });
151862
151863     utils.forEach(_applicationState, function (obj) {
151864         var node = jQuery("#" + obj.domId),
151865             imgNode = node.find(".ui-box-TitleImage"),
151866             matchingDomId = function (panel) {
151867                 return panel.domId === obj.domId;
151868             };
151869
151870         if (node.length > 0) {
151871             if (!utils.some(_availablePanels, matchingDomId)) {
151872                 node.parent()[0].removeChild(node[0]);
151873             }
151874             else {
151875                 if (obj.display !== false) {
151876                     leftPanelSection.append(node.parent()[0].removeChild(node[0]));
151877                     if (!obj.collapsed) {
151878                         node.find(".info")
151879                             .css({
151880                             "display": "block"
151881                         })
151882                         .end()
151883                         .addClass("ui-box-open");
151884                         imgNode.addClass("ui-box-TitleImageOpen");
151885                     }
151886                 }
151887             }
151888         }
151889     });
151890
151891     db.saveObject(_applicationStateId, _applicationState);
151892
151893     event.on("ApplicationState", function () {
151894         try {
151895             var leftArray = jQuery(".left").sortable('toArray');
151896             _applicationStateTmp = [];
151897             _applicationStateTmp = utils.copy(_applicationState);
151898             _applicationState = [];
151899             _addUIPaneItemsToApplicationState(leftArray, "left");
151900
151901             if (leftArray.length === 0) {
151902                 _collapsePannels("left");
151903             }
151904
151905             db.saveObject(_applicationStateId, _applicationState);
151906         }
151907         catch (e) {
151908             exception.handle(e);
151909         }
151910     });
151911
151912     jQuery(".left").sortable({
151913         handle: ".drag-handle",
151914         revert: true,
151915         placeholder: 'ui-sortable-highlight ui-corner-all',
151916         connectWith: [".left"],
151917         scroll: true,
151918         update: function (uiEvent, ui) {
151919             event.trigger("ApplicationState");
151920         }
151921     });
151922
151923     jQuery(".left").sortable({ axis: 'y' });
151924
151925     jQuery(".collapse-handle").bind("click", function () {
151926         if (!uiBoxToggleEngaged) {
151927
151928             uiBoxToggleEngaged = true;
151929
151930             var jNode = jQuery(this).parentsUntil(".ui-box"),
151931                     pNode = jNode.parent(),
151932                     isOpen = pNode.hasClass("ui-box-open"),
151933                     imgNode = jQuery(this).find(".ui-box-TitleImage");
151934
151935             if (!isOpen) {
151936                 pNode.addClass("ui-box-open");
151937                 imgNode.removeClass("ui-box-TitleImageClosed");
151938                 imgNode.addClass("ui-box-TitleImageOpen");
151939             }
151940
151941             jQuery(this).parent().next().toggle("blind", {}, 300, function () {
151942                 if (isOpen) {
151943                     pNode.removeClass("ui-box-open");
151944                     imgNode.removeClass("ui-box-TitleImageOpen");
151945                     imgNode.addClass("ui-box-TitleImageClosed");
151946                 }
151947                 event.trigger("ApplicationState", [pNode]);
151948                 uiBoxToggleEngaged = false;
151949             });
151950         }
151951     });
151952 }
151953
151954 function _db_upgrade_for_release() {
151955     var version = db.retrieve(constants.RELEASE_VERSION);
151956
151957     // version: 20121115 is the first release version
151958     if (version === null || version === undefined || Number(version) < 20130722) {
151959         db.remove(constants.COMMON.APPLICATION_STATE + "tizen");
151960         db.remove(constants.COMMON.APPLICATION_STATE + "cordova");
151961         db.remove("tizen1-db-application");
151962         db.remove("tizen-db-package");
151963         version = 20130722;
151964         db.save(constants.RELEASE_VERSION, version);
151965     }
151966 }
151967
151968 _self = module.exports = {
151969     initialize: function () {
151970         var plugins = _systemPlugins.concat(platform.current().ui.plugins || []).map(function (name) {
151971                 return require('ripple/ui/plugins/' + name);
151972             }),
151973             boot = jWorkflow.order(_initializeUI);
151974
151975         _db_upgrade_for_release();
151976         _availablePanels = [];
151977
151978         plugins.forEach(function (plugin) {
151979             if (plugin.initialize) {
151980                 boot.andThen(plugin.initialize);
151981             }
151982
151983             if (plugin.panel) {
151984                 _availablePanels.push(plugin.panel);
151985             }
151986         });
151987
151988         boot.start();
151989     },
151990
151991     getSystemPlugins: function () {
151992         return utils.copy(_systemPlugins);
151993     },
151994
151995     register: function (plugin) {
151996         _systemPlugins.push(plugin);
151997     },
151998
151999     registered: function (plugin) {
152000         return _systemPlugins.indexOf(plugin) >= 0;
152001     },
152002
152003     getExtensionURL: function () {
152004         return jQuery("#" + constants.COMMON.EXTENSION_URL_CONTAINER).text();
152005     },
152006
152007     showOverlay: function (id, callback, showContainer) {
152008         _overlay.getOrCreate(id).show(callback, showContainer);
152009     },
152010
152011     hideOverlay: function (id, callback) {
152012         _overlay.getOrCreate(id).hide(callback);
152013     }
152014 };
152015
152016 });
152017 define('ripple/xhr/helpers', function (require, exports, module) {
152018 /*
152019  *  Copyright 2011 Research In Motion Limited.
152020  *
152021  * Licensed under the Apache License, Version 2.0 (the "License");
152022  * you may not use this file except in compliance with the License.
152023  * You may obtain a copy of the License at
152024  *
152025  * http://www.apache.org/licenses/LICENSE-2.0
152026  *
152027  * Unless required by applicable law or agreed to in writing, software
152028  * distributed under the License is distributed on an "AS IS" BASIS,
152029  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
152030  * See the License for the specific language governing permissions and
152031  * limitations under the License.
152032  */
152033 var constants = require('ripple/constants'),
152034     db = require('ripple/db');
152035
152036 module.exports = {
152037     isLocalRequest: function (url) {
152038         return (!!(url.match(constants.REGEX.LOCAL_URI)) || !url.match(constants.REGEX.EXTERNAL_URI)) || 
152039                 !!(location.host && url.match(location.host));
152040     },
152041
152042     proxyEnabled: function () {
152043         var isDisabled = db.retrieve(constants.XHR.PROXY_DISABLED_BUTTON);
152044         return !isDisabled || isDisabled === "false" ? true : false;
152045     }
152046 };
152047
152048 });
152049 define('ripple/xhr/base', function (require, exports, module) {
152050 /*
152051  *  Copyright 2011 Research In Motion Limited.
152052  *
152053  * Licensed under the Apache License, Version 2.0 (the "License");
152054  * you may not use this file except in compliance with the License.
152055  * You may obtain a copy of the License at
152056  *
152057  * http://www.apache.org/licenses/LICENSE-2.0
152058  *
152059  * Unless required by applicable law or agreed to in writing, software
152060  * distributed under the License is distributed on an "AS IS" BASIS,
152061  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
152062  * See the License for the specific language governing permissions and
152063  * limitations under the License.
152064  */
152065 var XHR = window.XMLHttpRequest;
152066
152067 function _handle(object, key) {
152068     return function () {
152069         return object[key].apply(object, Array.prototype.slice.call(arguments));
152070     };
152071 }
152072
152073 function _getter(object, key) {
152074     return function () {
152075         return object[key];
152076     };
152077 }
152078
152079 function _setter(object, key) {
152080     return function (val) {
152081         object[key] = val;
152082     };
152083 }
152084
152085 function _writeable(obj) {
152086     var newObj = {},
152087         key;
152088
152089     // need prototypes
152090     for (key in obj) {
152091         //HACK: don't even know what to say bout this, resonseBlob can go fly a kite: related to this issue:
152092         //https://github.com/blackberry/Ripple-UI/issues/394
152093         if (key !== "responseBlob" && typeof obj[key] === "function") {
152094             newObj[key] = _handle(obj, key);
152095         } else {
152096             newObj.__defineGetter__(key, _getter(obj, key));
152097             newObj.__defineSetter__(key, _setter(obj, key));
152098         }
152099     }
152100
152101     return newObj;
152102 }
152103
152104 function _XMLHttpRequest() {
152105     var Xhr = require('ripple/emulatorBridge').xhr() || XHR;
152106     return _writeable(new Xhr());
152107 }
152108
152109 module.exports = _XMLHttpRequest;
152110
152111 });
152112 define('ripple/xhr/jsonp', function (require, exports, module) {
152113 /*
152114  *  Copyright 2011 Research In Motion Limited.
152115  *
152116  * Licensed under the Apache License, Version 2.0 (the "License");
152117  * you may not use this file except in compliance with the License.
152118  * You may obtain a copy of the License at
152119  *
152120  * http://www.apache.org/licenses/LICENSE-2.0
152121  *
152122  * Unless required by applicable law or agreed to in writing, software
152123  * distributed under the License is distributed on an "AS IS" BASIS,
152124  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
152125  * See the License for the specific language governing permissions and
152126  * limitations under the License.
152127  */
152128 var constants = require('ripple/constants'),
152129     exception = require('ripple/exception'),
152130     utils = require('ripple/utils'),
152131     helpers = require('ripple/xhr/helpers'),
152132     _console = require('ripple/console'),
152133     XHR = require('ripple/xhr/base');
152134
152135 function _XMLHttpRequest() {
152136     var xhr = new XHR(),
152137         origMethods = {
152138             setRequestHeader: xhr.setRequestHeader,
152139             getResponseHeader: xhr.getResponseHeader,
152140             getAllResponseHeaders: xhr.getAllResponseHeaders,
152141             open: xhr.open,
152142             send: xhr.send,
152143             abort: xhr.abort
152144         },
152145         _jxhr = new window.jXHR(),
152146         _sendFlag = false,
152147         _headers = [],
152148         _errorFlag = false,
152149         _url,
152150         _async;
152151
152152     function _localURI() {
152153         return _url && helpers.isLocalRequest(_url);
152154     }
152155
152156     function _set(prop, value) {
152157         xhr.__defineGetter__(prop, function () {
152158             return value;
152159         });
152160     }
152161
152162     function _reset() {
152163         _set("response", "");
152164         _set("responseText", "");
152165         _set("responseXML", null);
152166     }
152167
152168     xhr.setRequestHeader = function (header, value) {
152169         if (_localURI()) {
152170             origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
152171         } else {
152172             _console.error("XMLHttpRequest :: setRequestHeader does not work with JSONP.");
152173         }
152174     };
152175
152176     xhr.getResponseHeader = function (header) {
152177         return _localURI() ?
152178                 origMethods.getAllResponseHeaders.apply(xhr, [header]) :
152179                 _headers[header] || null;
152180     };
152181
152182     xhr.getAllResponseHeaders = function () {
152183         return _localURI() ?
152184                 origMethods.getAllResponseHeaders.apply(xhr) :
152185                 utils.reduce(_headers, function (str, value, key) {
152186                     return str + key + ": " + value + '\n';
152187                 }, "").replace(/\n$/, '');
152188     };
152189
152190     xhr.open = function (method, url, async) {
152191         _url = url;
152192         _async = async !== false ? true : false;
152193
152194         if (_localURI()) {
152195             origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
152196         } else {
152197             _reset();
152198             method = method.toUpperCase();
152199
152200             if (method === "POST") {
152201                 //HACK: Switch the method to get for now to simulate post
152202                 method = "GET";
152203             }
152204
152205             if (method !== "GET") {
152206                 exception.raise(exception.types.MethodNotImplemented, "Method: " + method + " not supported!");
152207             }
152208
152209             _jxhr.onreadystatechange = function (data) {
152210                 var response;
152211
152212                 try {
152213                     _set("readyState", _jxhr.readyState);
152214
152215                     if (xhr.readyState === xhr.DONE) {
152216                         _sendFlag = false;
152217                         _set("status", data.status);
152218                         _set("statusText", data.statusText);
152219                         _headers = data.headers;
152220
152221                         if (data.responseXML) {
152222                             response = new DOMParser().parseFromString(unescape(data.responseXML), "text/xml");
152223                             _set("responseXML", response);
152224                         } else {
152225                             response = unescape(data.responseText);
152226                             _set("responseText", response);
152227                         }
152228
152229                         _set("response", response);
152230                     }
152231
152232                     if (typeof xhr.onreadystatechange === "function") {
152233                         xhr.onreadystatechange.apply(xhr);
152234                     }
152235                 } catch (e) {
152236                     exception.handle(e);
152237                 }
152238             };
152239
152240             _jxhr.onerror = xhr.onerror;
152241             _jxhr.open(method, constants.API_URL + "/jsonp_xhr_proxy?callback=?&tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url));
152242         }
152243     };
152244
152245     xhr.send = function (data) {
152246         if (_localURI()) {
152247             origMethods.send(data);
152248             return;
152249         }
152250
152251         if (!_async) {
152252             exception.raise(exception.types.MethodNotImplemented, "Synchronous not supported.");
152253         }
152254
152255         if (xhr.readyState !== xhr.OPENED || _sendFlag === true) {
152256             exception.raise(exception.types.InvalidState, "Ready state should be OPENED (1)");
152257         }
152258
152259         _errorFlag = false;
152260         _sendFlag = true;
152261         data = null;
152262
152263         _jxhr.send();
152264     };
152265
152266     xhr.abort = function () {
152267         if (_localURI()) {
152268             origMethods.abort();
152269             return;
152270         }
152271
152272         _reset();
152273
152274         _errorFlag = true;
152275
152276         if (xhr.readyState === xhr.UNSENT ||
152277                 (xhr.readyState === xhr.OPENED && _sendFlag === false) ||
152278                 xhr.readyState === xhr.DONE) {
152279             _set("readyState", xhr.UNSENT);
152280         } else {
152281             _set("readyState", xhr.DONE);
152282             _sendFlag = false;
152283
152284             if (typeof xhr.onreadystatechange === "function") {
152285                 xhr.onreadystatechange.apply(xhr);
152286             }
152287         }
152288
152289         _jxhr.onreadystatechange = null;
152290
152291         if (xhr.onabort) {
152292             xhr.onabort.apply(xhr, arguments);
152293         }
152294     };
152295
152296     return xhr;
152297 }
152298
152299 module.exports = _XMLHttpRequest;
152300
152301 });
152302 define('ripple/xhr/cors', function (require, exports, module) {
152303 /*
152304  *  Copyright 2011 Research In Motion Limited.
152305  *
152306  * Licensed under the Apache License, Version 2.0 (the "License");
152307  * you may not use this file except in compliance with the License.
152308  * You may obtain a copy of the License at
152309  *
152310  * http://www.apache.org/licenses/LICENSE-2.0
152311  *
152312  * Unless required by applicable law or agreed to in writing, software
152313  * distributed under the License is distributed on an "AS IS" BASIS,
152314  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
152315  * See the License for the specific language governing permissions and
152316  * limitations under the License.
152317  */
152318 var helpers = require('ripple/xhr/helpers'),
152319     constants = require('ripple/constants'),
152320     XHR = require('ripple/xhr/base');
152321
152322 function _XMLHttpRequest() {
152323     var xhr = new XHR(),
152324         origMethods = {
152325             setRequestHeader: xhr.setRequestHeader,
152326             open: xhr.open
152327         };
152328
152329     xhr.setRequestHeader = function (header, value) {
152330         // This is done to get around jQuery 1.3.2 setting a header that it shouldn't
152331         if (header && header.toUpperCase() !== "X-REQUESTED-WITH") {
152332             origMethods.setRequestHeader.apply(xhr, Array.prototype.slice.call(arguments));
152333         }
152334     };
152335
152336     xhr.open = function (method, url, async, user, password) {
152337         if (!helpers.isLocalRequest(url)) {
152338             url = constants.API_URL + "/xhr_proxy?tinyhippos_apikey=ABC&tinyhippos_rurl=" + escape(url);
152339         }
152340
152341         origMethods.open.apply(xhr, Array.prototype.slice.call(arguments));
152342     };
152343
152344     return xhr;
152345 }
152346
152347 module.exports = _XMLHttpRequest;
152348
152349 });
152350 define('ripple/omgwtf', function (require, exports, module) {
152351 /*
152352  *  Copyright 2011 Research In Motion Limited.
152353  *
152354  * Licensed under the Apache License, Version 2.0 (the "License");
152355  * you may not use this file except in compliance with the License.
152356  * You may obtain a copy of the License at
152357  *
152358  * http://www.apache.org/licenses/LICENSE-2.0
152359  *
152360  * Unless required by applicable law or agreed to in writing, software
152361  * distributed under the License is distributed on an "AS IS" BASIS,
152362  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
152363  * See the License for the specific language governing permissions and
152364  * limitations under the License.
152365  */
152366 var event = require('ripple/event'),
152367     db = require('ripple/db'),
152368     _loaded = false,
152369     _self;
152370
152371 function _delay(action) {
152372     window.setTimeout(function () {
152373         if (!_loaded) {
152374             if (jQuery(".first-run-window").is(":visible")) {
152375                 _delay(action);
152376             } else {
152377                 action();
152378             }
152379         }
152380     }, 10000);
152381 }
152382
152383 function _hide() {
152384     jQuery(".error-window").css({display: 'none'});
152385     jQuery(".error-dialog").css({display: 'none'});
152386 }
152387
152388 function _show() {
152389     jQuery(".error-window").css({display: 'block'});
152390
152391     jQuery(".error-dialog").css({
152392         display: 'block',
152393         left: (jQuery(document).width() / 2) - 277 + "px"
152394     });
152395
152396     jQuery("#error-wait").click(function () {
152397         _hide();
152398         _delay(_show);
152399     });
152400
152401     jQuery("#error-panic").click(function () {
152402         db.removeAll(null, function () {
152403             window.tinyHipposReload = true;
152404             localStorage.clear();
152405             location.reload();
152406         });
152407     });
152408 }
152409
152410 _delay(_show);
152411
152412 _self = {
152413     initialize: function (previous, baton) {
152414         event.on("TinyHipposLoaded", function () {
152415             _loaded = true;
152416         });
152417     },
152418     show: _show,
152419     hide: _hide
152420 };
152421
152422 module.exports = _self;
152423
152424 });
152425 define('ripple', function (require, exports, module) {
152426 /*
152427  *  Copyright 2011 Research In Motion Limited.
152428  *
152429  * Licensed under the Apache License, Version 2.0 (the "License");
152430  * you may not use this file except in compliance with the License.
152431  * You may obtain a copy of the License at
152432  *
152433  * http://www.apache.org/licenses/LICENSE-2.0
152434  *
152435  * Unless required by applicable law or agreed to in writing, software
152436  * distributed under the License is distributed on an "AS IS" BASIS,
152437  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
152438  * See the License for the specific language governing permissions and
152439  * limitations under the License.
152440  */
152441 var omgwtf = require('ripple/omgwtf'),
152442     db = require('ripple/db'),
152443     xhr = require('ripple/xhr'),
152444     geo = require('ripple/geo'),
152445     fileSystem = require('ripple/fileSystem'),
152446     fs = require('ripple/dbfs'),
152447     platform = require('ripple/platform'),
152448     emulatorBridge = require('ripple/emulatorBridge'),
152449     devices = require('ripple/devices'),
152450     widgetConfig = require('ripple/widgetConfig'),
152451     deviceSettings = require('ripple/deviceSettings'),
152452     sensorSettings = require('ripple/sensorSettings'),
152453     ui = require('ripple/ui'),
152454     appcache = require('ripple/appcache'),
152455     _self = {
152456         boot: function (booted) {
152457             // techdebt (event registration timing)
152458             // require('ripple/platform/webworks.core/2.0.0/fsCache');
152459
152460             window.addEventListener("keydown", function (event) {
152461                 var hasMetaOrAltPressed = (event.metaKey || event.ctrlKey),
152462                     key = parseInt(event.keyCode, 10);
152463
152464                 if (key === 37 && hasMetaOrAltPressed) { // cmd/ctrl + left arrow
152465                     event.preventDefault();
152466                     emulatorBridge.window().history.back();
152467                 }
152468
152469                 if (key === 39 && hasMetaOrAltPressed) { // cmd/ctrl + right arrow
152470                     event.preventDefault();
152471                     emulatorBridge.window().history.forward();
152472                 }
152473
152474                 if (key === 82 && hasMetaOrAltPressed) { // cmd/ctrl + r
152475                     event.preventDefault();
152476                     window.tinyHipposReload = true;
152477                     emulatorBridge.window().location.reload();
152478                 }
152479
152480                 if (key === 116) { // F5
152481                     event.preventDefault();
152482                     window.tinyHipposReload = true;
152483                     emulatorBridge.window().location.reload();
152484                 }
152485             });
152486
152487             window.onbeforeunload = function () { 
152488                 if (!window.tinyHipposReload) {
152489                     return "Web Simulator";
152490                 }
152491             };
152492
152493             jWorkflow.order(omgwtf.initialize, omgwtf)
152494                  .andThen(appcache.initialize, appcache)
152495                  .andThen(db.initialize, db)
152496                  .andThen(xhr.initialize, xhr)
152497                  .andThen(geo.initialize, geo)
152498                  .andThen(fileSystem.initialize, fileSystem)
152499                  .andThen(fs.initialize, fs)
152500                  .andThen(platform.initialize, platform)
152501                  .andThen(devices.initialize, devices)
152502                  .andThen(widgetConfig.initialize, widgetConfig)
152503                  .andThen(deviceSettings.initialize, deviceSettings)
152504                  .andThen(ui.initialize, ui)
152505                  .start(booted);
152506         }
152507     };
152508
152509 module.exports = _self;
152510
152511 });
152512 require('ripple/ui').register('omnibar');require('ripple/bootstrap').bootstrap();