bpm 1.0.0.beta.13 → 1.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/CHANGELOG.md +35 -1
  2. data/README.md +1 -1
  3. data/bin/bpm +18 -1
  4. data/bpm.gemspec +3 -3
  5. data/lib/bpm.rb +34 -1
  6. data/lib/bpm/cli/base.rb +32 -44
  7. data/lib/bpm/errors.rb +15 -3
  8. data/lib/bpm/execjs_ext.rb +99 -0
  9. data/lib/bpm/local.rb +1 -1
  10. data/lib/bpm/package.rb +53 -51
  11. data/lib/bpm/pipeline.rb +21 -14
  12. data/lib/bpm/pipeline/directive_processor.rb +9 -0
  13. data/lib/bpm/pipeline/generated_asset.rb +59 -13
  14. data/lib/bpm/pipeline/package_pipeline.rb +2 -2
  15. data/lib/bpm/pipeline/plugin_asset.rb +1 -1
  16. data/lib/bpm/pipeline/plugin_context.rb +12 -2
  17. data/lib/bpm/pipeline/plugin_processor.rb +27 -4
  18. data/lib/bpm/project.rb +171 -139
  19. data/lib/bpm/server.rb +14 -9
  20. data/lib/bpm/version.rb +1 -1
  21. data/man/{bpm-compile.1.ronn → bpm-rebuild.1.ronn} +0 -0
  22. data/man/bpm.1.ronn +112 -9
  23. data/spec/cli/add_spec.rb +15 -6
  24. data/spec/cli/init_spec.rb +7 -7
  25. data/spec/cli/pack_spec.rb +13 -8
  26. data/spec/cli/preview_spec.rb +10 -0
  27. data/spec/cli/rebuild_spec.rb +5 -5
  28. data/spec/cli/remove_spec.rb +1 -1
  29. data/spec/fixtures/gems/core-test-0.4.9.bpkg +0 -0
  30. data/spec/fixtures/packages/backbone/package.json +2 -2
  31. data/spec/fixtures/packages/core-test/package.json +1 -1
  32. data/spec/fixtures/projects/coffee/coffee.json +4 -4
  33. data/spec/fixtures/projects/coffee/{packages → vendor}/coffee-script/compiler.js +0 -0
  34. data/spec/fixtures/projects/coffee/{packages → vendor}/coffee-script/lib/main.js +0 -0
  35. data/spec/fixtures/projects/coffee/{packages → vendor}/coffee-script/package.json +0 -0
  36. data/spec/fixtures/projects/coffee/{packages/handlebars → vendor/handlebars-format}/format.js +0 -0
  37. data/spec/fixtures/projects/coffee/{packages/handlebars → vendor/handlebars-format}/lib/main.js +0 -0
  38. data/spec/fixtures/projects/coffee/{packages/handlebars → vendor/handlebars-format}/package.json +2 -2
  39. data/spec/fixtures/projects/coffee/vendor/handlebars/package.json +15 -0
  40. data/spec/fixtures/projects/coffee/vendor/spade-coffee/package.json +15 -0
  41. data/spec/fixtures/projects/coffee/vendor/spade-handlebars/package.json +15 -0
  42. data/spec/fixtures/projects/coffee/vendor/spade/lib/main.js +1 -0
  43. data/spec/fixtures/projects/coffee/{packages → vendor}/spade/package.json +0 -0
  44. data/spec/fixtures/projects/coffee/{packages → vendor}/spade/transport.js +0 -0
  45. data/spec/fixtures/projects/hello2/{packages → vendor}/a/lib/main.js +0 -0
  46. data/spec/fixtures/projects/hello2/{packages → vendor}/a/package.json +0 -0
  47. data/spec/fixtures/projects/hello2/{packages → vendor}/b/lib/main.js +0 -0
  48. data/spec/fixtures/projects/hello2/{packages → vendor}/b/package.json +0 -0
  49. data/spec/fixtures/projects/hello2/{packages → vendor}/c/lib/main.js +0 -0
  50. data/spec/fixtures/projects/hello2/{packages → vendor}/c/package.json +0 -0
  51. data/spec/fixtures/projects/hello_dev/{packages → vendor}/style_package/css/some_style.css +0 -0
  52. data/spec/fixtures/projects/hello_dev/{packages → vendor}/style_package/package.json +0 -0
  53. data/spec/fixtures/projects/hello_world/another/one.js +1 -0
  54. data/spec/fixtures/projects/hello_world/another/two.js +1 -0
  55. data/spec/fixtures/projects/hello_world/hello_world.json +6 -5
  56. data/spec/fixtures/projects/hello_world/lib2/something.js +1 -0
  57. data/spec/fixtures/projects/hello_world/{packages → vendor}/custom_package/assets/dummy.txt +0 -0
  58. data/spec/fixtures/projects/hello_world/{packages → vendor}/custom_package/css/sample_styles.css +0 -0
  59. data/spec/fixtures/projects/hello_world/{packages → vendor}/custom_package/custom_dir/basic-module.js +0 -0
  60. data/spec/fixtures/projects/hello_world/{packages → vendor}/custom_package/lib/main.js +0 -0
  61. data/spec/fixtures/projects/hello_world/{packages → vendor}/custom_package/package.json +1 -1
  62. data/spec/fixtures/projects/hello_world/vendor/prerelease_package/package.json +4 -0
  63. data/spec/fixtures/projects/init_app/new_project.json +3 -3
  64. data/spec/fixtures/projects/init_default/new_project.json +2 -2
  65. data/spec/fixtures/projects/minitest/minitest.json +1 -1
  66. data/spec/fixtures/projects/minitest/{packages → vendor}/uglyduck/lib/main.js +0 -0
  67. data/spec/fixtures/projects/minitest/{packages → vendor}/uglyduck/minifier/main.js +0 -0
  68. data/spec/fixtures/projects/minitest/{packages → vendor}/uglyduck/package.json +0 -0
  69. data/spec/fixtures/projects/minitrans/minitrans.json +1 -1
  70. data/spec/fixtures/projects/minitrans/{packages → vendor}/transport/lib/main.js +0 -0
  71. data/spec/fixtures/projects/minitrans/{packages → vendor}/transport/package.json +0 -0
  72. data/spec/fixtures/projects/minitrans/{packages → vendor}/transport/transports/wrapper.js +0 -0
  73. data/spec/fixtures/projects/minitrans/{packages → vendor}/uglyduck/lib/main.js +0 -0
  74. data/spec/fixtures/projects/minitrans/{packages → vendor}/uglyduck/minifier/main.js +0 -0
  75. data/spec/fixtures/projects/minitrans/{packages → vendor}/uglyduck/package.json +0 -0
  76. data/spec/fixtures/projects/transporter/{packages → vendor}/transport/lib/main.js +0 -0
  77. data/spec/fixtures/projects/transporter/{packages → vendor}/transport/package.json +0 -0
  78. data/spec/fixtures/projects/transporter/{packages → vendor}/transport/transports/wrapper.js +0 -0
  79. data/spec/package_pipeline_spec.rb +8 -5
  80. data/spec/package_spec.rb +31 -26
  81. data/spec/pipeline_spec.rb +72 -64
  82. data/spec/plugins/format_spec.rb +7 -7
  83. data/spec/project_spec.rb +6 -5
  84. data/spec/spec_helper.rb +5 -4
  85. data/spec/support/cli.rb +9 -7
  86. data/spec/support/env.rb +7 -4
  87. data/spec/support/path.rb +1 -0
  88. data/support/es5-shim.js +935 -0
  89. data/templates/init/project.json +2 -3
  90. metadata +112 -97
  91. data/lib/bpm/pipeline/transport_processor.rb +0 -34
  92. data/spec/fixtures/projects/coffee/packages/spade/lib/main.js +0 -1
  93. data/spec/fixtures/projects/hello_world/vendor/lib/something.js +0 -1
@@ -7,32 +7,32 @@ describe BPM::Pipeline, 'format' do
7
7
  set_host
8
8
  reset_libgems bpm_dir.to_s
9
9
  start_fake(FakeGemServer.new)
10
-
10
+
11
11
  FileUtils.cp_r project_fixture('coffee'), '.'
12
12
  cd home('coffee')
13
13
 
14
14
  bpm 'rebuild'
15
15
  wait
16
16
  end
17
-
17
+
18
18
  subject do
19
19
  File.read home('coffee', 'assets', 'bpm_libs.js')
20
20
  end
21
-
21
+
22
22
  it "should compile coffee file and wrap with transport" do
23
23
  subject.should include("spade(COFFEE(//coffee/lib/main\n))")
24
24
  end
25
-
25
+
26
26
  it "should compile handlebars template with transport" do
27
27
  subject.should include("spade(HANDLEBARS(//coffee/templates/section\n RUNTIME))")
28
28
  end
29
-
29
+
30
30
  it "should include coffeescript runtime" do
31
31
  subject.should include("//coffee-script/lib/main")
32
32
  end
33
-
33
+
34
34
  it "should include spade runtime" do
35
35
  subject.should include("//spade/lib/main")
36
36
  end
37
-
37
+
38
38
  end
data/spec/project_spec.rb CHANGED
@@ -181,7 +181,7 @@ describe BPM::Project, "package_and_module_from_path" do
181
181
 
182
182
  subject do
183
183
  proj = BPM::Project.nearest_project('.')
184
- with_env{ proj.fetch_dependencies }
184
+ proj.fetch_dependencies
185
185
  proj
186
186
  end
187
187
 
@@ -198,7 +198,7 @@ describe BPM::Project, "package_and_module_from_path" do
198
198
  end
199
199
 
200
200
  it "should find path in dependencies" do
201
- check_package_and_module(subject, home("hello_world", ".bpm", "packages", "core-test", "resources", "runner.css"),
201
+ check_package_and_module(subject, home(".bpm", "gems", "core-test-0.4.9", "resources", "runner.css"),
202
202
  "core-test", "~resources/runner")
203
203
  end
204
204
 
@@ -210,14 +210,15 @@ describe BPM::Project, "package_and_module_from_path" do
210
210
  it "should not match partial directories" do
211
211
  # We're verifying that core-testing doesn't match core-test
212
212
  # Since there is no core-testing package it will fall back to the base package, hello_world
213
- check_package_and_module(subject, home("hello_world", ".bpm", "packages", "core-testing", "resources", "runner.css"),
214
- "hello_world", "~.bpm/packages/core-testing/resources/runner")
213
+ path = home(".bpm", "gems", "core-testing", "resources", "runner.css")
214
+ l = lambda{ subject.package_and_module_from_path(path) }
215
+ l.should raise_error("#{path} is not within a known package")
215
216
  end
216
217
 
217
218
  it "should handle directory reference in package directories array" do
218
219
  check_package_and_module(subject, home("hello_world", "lib", "main.js"),
219
220
  "hello_world", "main")
220
- check_package_and_module(subject, home("hello_world", "vendor", "lib", "something.js"),
221
+ check_package_and_module(subject, home("hello_world", "lib2", "something.js"),
221
222
  "hello_world", "something")
222
223
  end
223
224
 
data/spec/spec_helper.rb CHANGED
@@ -25,7 +25,7 @@ module SpecHelpers
25
25
  # Use to avoid throwing errors just because an extra newline shows up
26
26
  # somewhere
27
27
  def normalize_whitespace(string)
28
- string.gsub(/ +/, ' ').gsub(/\n+/,"\n")
28
+ string.gsub(/ +/, ' ').gsub(/\n+/,"\n").strip
29
29
  end
30
30
 
31
31
  def compare_file_contents(actual_path, expected_path)
@@ -69,14 +69,15 @@ RSpec.configure do |config|
69
69
 
70
70
  config.include SpecHelpers
71
71
 
72
- config.around do |blk|
72
+ config.before do
73
73
  reset!
74
+ end
74
75
 
75
- blk.call
76
-
76
+ config.after do
77
77
  kill!
78
78
  stop_fake
79
79
  reset_host
80
+ reset_env
80
81
  Dir.chdir working_dir if Dir.pwd != working_dir
81
82
  end
82
83
  end
data/spec/support/cli.rb CHANGED
@@ -12,15 +12,17 @@ module SpecHelpers
12
12
  @pid = Process.fork do
13
13
  Dir.chdir opts[:chdir] if opts[:chdir]
14
14
 
15
- @stdout.close
16
- STDOUT.reopen @stdout_child
15
+ unless ENV['DEBUG_CLI']
16
+ @stdout.close
17
+ STDOUT.reopen @stdout_child
17
18
 
18
- @stdin.close
19
- STDIN.reopen @stdin_child
19
+ @stdin.close
20
+ STDIN.reopen @stdin_child
20
21
 
21
- if opts[:track_stderr]
22
- @stderr.close
23
- STDERR.reopen @stderr_child
22
+ if opts[:track_stderr]
23
+ @stderr.close
24
+ STDERR.reopen @stderr_child
25
+ end
24
26
  end
25
27
 
26
28
  env.each do |key, val|
data/spec/support/env.rb CHANGED
@@ -3,15 +3,18 @@ module SpecHelpers
3
3
  @env ||= {}
4
4
  end
5
5
 
6
- def with_env
6
+ def load_env
7
7
  original_values = {}
8
8
  env.each do |key, val|
9
9
  original_values[key] = ENV[key]
10
10
  ENV[key] = val
11
11
  end
12
- yield
13
- ensure
14
- original_values.each do |key, value|
12
+ @original_env = original_values.merge(@original_env || {})
13
+ end
14
+
15
+ def reset_env
16
+ return unless @original_env
17
+ @original_env.each do |key, value|
15
18
  ENV[key] = value
16
19
  end
17
20
  end
data/spec/support/path.rb CHANGED
@@ -63,6 +63,7 @@ module SpecHelpers
63
63
  env["HOME"] = home.to_s
64
64
  env["BPM_HOME"] = bpm_dir.to_s
65
65
  env["BPM_PATH"] = bpm_dir.to_s
66
+ load_env
66
67
  LibGems.clear_paths
67
68
  end
68
69
 
@@ -0,0 +1,935 @@
1
+ // vim:set ts=4 sts=4 sw=4 st:
2
+ // -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
3
+ // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project)
4
+ // -- dantman Daniel Friesen Copyright(C) 2010 XXX No License Specified
5
+ // -- fschaefer Florian Schäfer Copyright (C) 2010 MIT License
6
+ // -- Irakli Gozalishvili Copyright (C) 2010 MIT License
7
+ // -- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License
8
+
9
+ /*!
10
+ Copyright (c) 2009, 280 North Inc. http://280north.com/
11
+ MIT License. http://github.com/280north/narwhal/blob/master/README.md
12
+ */
13
+
14
+ (function (definition) {
15
+ // RequireJS
16
+ if (typeof define == "function") {
17
+ define(function () {
18
+ definition();
19
+ });
20
+ // CommonJS and <script>
21
+ } else {
22
+ definition();
23
+ }
24
+
25
+ })(function (undefined) {
26
+
27
+ /**
28
+ * Brings an environment as close to ECMAScript 5 compliance
29
+ * as is possible with the facilities of erstwhile engines.
30
+ *
31
+ * ES5 Draft
32
+ * http://www.ecma-international.org/publications/files/drafts/tc39-2009-050.pdf
33
+ *
34
+ * NOTE: this is a draft, and as such, the URL is subject to change. If the
35
+ * link is broken, check in the parent directory for the latest TC39 PDF.
36
+ * http://www.ecma-international.org/publications/files/drafts/
37
+ *
38
+ * Previous ES5 Draft
39
+ * http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
40
+ * This is a broken link to the previous draft of ES5 on which most of the
41
+ * numbered specification references and quotes herein were taken. Updating
42
+ * these references and quotes to reflect the new document would be a welcome
43
+ * volunteer project.
44
+ *
45
+ * @module
46
+ */
47
+
48
+ /*whatsupdoc*/
49
+
50
+ //
51
+ // Function
52
+ // ========
53
+ //
54
+
55
+ // ES-5 15.3.4.5
56
+ // http://www.ecma-international.org/publications/files/drafts/tc39-2009-025.pdf
57
+
58
+ if (!Function.prototype.bind) {
59
+ Function.prototype.bind = function bind(that) { // .length is 1
60
+ // 1. Let Target be the this value.
61
+ var target = this;
62
+ // 2. If IsCallable(Target) is false, throw a TypeError exception.
63
+ // XXX this gets pretty close, for all intents and purposes, letting
64
+ // some duck-types slide
65
+ if (typeof target.apply != "function" || typeof target.call != "function")
66
+ return new TypeError();
67
+ // 3. Let A be a new (possibly empty) internal list of all of the
68
+ // argument values provided after thisArg (arg1, arg2 etc), in order.
69
+ // XXX slicedArgs will stand in for "A" if used
70
+ var args = slice.call(arguments, 1); // for normal call
71
+ // 4. Let F be a new native ECMAScript object.
72
+ // 9. Set the [[Prototype]] internal property of F to the standard
73
+ // built-in Function prototype object as specified in 15.3.3.1.
74
+ // 10. Set the [[Call]] internal property of F as described in
75
+ // 15.3.4.5.1.
76
+ // 11. Set the [[Construct]] internal property of F as described in
77
+ // 15.3.4.5.2.
78
+ // 12. Set the [[HasInstance]] internal property of F as described in
79
+ // 15.3.4.5.3.
80
+ // 13. The [[Scope]] internal property of F is unused and need not
81
+ // exist.
82
+ var bound = function () {
83
+
84
+ if (this instanceof bound) {
85
+ // 15.3.4.5.2 [[Construct]]
86
+ // When the [[Construct]] internal method of a function object,
87
+ // F that was created using the bind function is called with a
88
+ // list of arguments ExtraArgs the following steps are taken:
89
+ // 1. Let target be the value of F's [[TargetFunction]]
90
+ // internal property.
91
+ // 2. If target has no [[Construct]] internal method, a
92
+ // TypeError exception is thrown.
93
+ // 3. Let boundArgs be the value of F's [[BoundArgs]] internal
94
+ // property.
95
+ // 4. Let args be a new list containing the same values as the
96
+ // list boundArgs in the same order followed by the same
97
+ // values as the list ExtraArgs in the same order.
98
+
99
+ var self = Object.create(target.prototype);
100
+ var result = target.apply(
101
+ self,
102
+ args.concat(slice.call(arguments))
103
+ );
104
+ if (result !== null && Object(result) === result)
105
+ return result;
106
+ return self;
107
+
108
+ } else {
109
+ // 15.3.4.5.1 [[Call]]
110
+ // When the [[Call]] internal method of a function object, F,
111
+ // which was created using the bind function is called with a
112
+ // this value and a list of arguments ExtraArgs the following
113
+ // steps are taken:
114
+ // 1. Let boundArgs be the value of F's [[BoundArgs]] internal
115
+ // property.
116
+ // 2. Let boundThis be the value of F's [[BoundThis]] internal
117
+ // property.
118
+ // 3. Let target be the value of F's [[TargetFunction]] internal
119
+ // property.
120
+ // 4. Let args be a new list containing the same values as the list
121
+ // boundArgs in the same order followed by the same values as
122
+ // the list ExtraArgs in the same order. 5. Return the
123
+ // result of calling the [[Call]] internal method of target
124
+ // providing boundThis as the this value and providing args
125
+ // as the arguments.
126
+
127
+ // equiv: target.call(this, ...boundArgs, ...args)
128
+ return target.apply(
129
+ that,
130
+ args.concat(slice.call(arguments))
131
+ );
132
+
133
+ }
134
+
135
+ };
136
+
137
+ // XXX bound.length is never writable, so don't even try
138
+ //
139
+ // 16. The length own property of F is given attributes as specified in
140
+ // 15.3.5.1.
141
+ // TODO
142
+ // 17. Set the [[Extensible]] internal property of F to true.
143
+ // TODO
144
+ // 18. Call the [[DefineOwnProperty]] internal method of F with
145
+ // arguments "caller", PropertyDescriptor {[[Value]]: null,
146
+ // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]:
147
+ // false}, and false.
148
+ // TODO
149
+ // 19. Call the [[DefineOwnProperty]] internal method of F with
150
+ // arguments "arguments", PropertyDescriptor {[[Value]]: null,
151
+ // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]:
152
+ // false}, and false.
153
+ // TODO
154
+ // NOTE Function objects created using Function.prototype.bind do not
155
+ // have a prototype property.
156
+ // XXX can't delete it in pure-js.
157
+ return bound;
158
+ };
159
+ }
160
+
161
+ // Shortcut to an often accessed properties, in order to avoid multiple
162
+ // dereference that costs universally.
163
+ // _Please note: Shortcuts are defined after `Function.prototype.bind` as we
164
+ // us it in defining shortcuts.
165
+ var call = Function.prototype.call;
166
+ var prototypeOfArray = Array.prototype;
167
+ var prototypeOfObject = Object.prototype;
168
+ var slice = prototypeOfArray.slice;
169
+ var toString = prototypeOfObject.toString;
170
+ var owns = call.bind(prototypeOfObject.hasOwnProperty);
171
+
172
+ var defineGetter, defineSetter, lookupGetter, lookupSetter, supportsAccessors;
173
+ // If JS engine supports accessors creating shortcuts.
174
+ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
175
+ defineGetter = call.bind(prototypeOfObject.__defineGetter__);
176
+ defineSetter = call.bind(prototypeOfObject.__defineSetter__);
177
+ lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
178
+ lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
179
+ }
180
+
181
+ //
182
+ // Array
183
+ // =====
184
+ //
185
+
186
+ // ES5 15.4.3.2
187
+ if (!Array.isArray) {
188
+ Array.isArray = function isArray(obj) {
189
+ return Object.prototype.toString.call(obj) == "[object Array]";
190
+ };
191
+ }
192
+
193
+ // ES5 15.4.4.18
194
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
195
+ if (!Array.prototype.forEach) {
196
+ Array.prototype.forEach = function forEach(fun /*, thisp*/) {
197
+ var self = Object(this),
198
+ thisp = arguments[1],
199
+ i = 0,
200
+ length = self.length >>> 0;
201
+
202
+ // If no callback function or if callback is not a callable function
203
+ if (!fun || !fun.call) {
204
+ throw new TypeError();
205
+ }
206
+
207
+ while (i < length) {
208
+ if (i in self) {
209
+ // Invoke the callback function with call, passing arguments:
210
+ // context, property value, property key, thisArg object context
211
+ fun.call(thisp, self[i], i, self);
212
+ }
213
+ i++;
214
+ }
215
+ };
216
+ }
217
+
218
+ // ES5 15.4.4.19
219
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
220
+ if (!Array.prototype.map) {
221
+ Array.prototype.map = function map(fun /*, thisp*/) {
222
+ var self = Object(this);
223
+ var length = self.length >>> 0;
224
+ if (typeof fun != "function")
225
+ throw new TypeError();
226
+ var result = new Array(length);
227
+ var thisp = arguments[1];
228
+ for (var i = 0; i < length; i++) {
229
+ if (i in self)
230
+ result[i] = fun.call(thisp, self[i], i, self);
231
+ }
232
+ return result;
233
+ };
234
+ }
235
+
236
+ // ES5 15.4.4.20
237
+ if (!Array.prototype.filter) {
238
+ Array.prototype.filter = function filter(fun /*, thisp */) {
239
+ var self = Object(this);
240
+ var length = self.length >>> 0;
241
+ if (typeof fun != "function")
242
+ throw new TypeError();
243
+ var result = [];
244
+ var thisp = arguments[1];
245
+ for (var i = 0; i < length; i++)
246
+ if (i in self && fun.call(thisp, self[i], i, self))
247
+ result.push(self[i]);
248
+ return result;
249
+ };
250
+ }
251
+
252
+ // ES5 15.4.4.16
253
+ if (!Array.prototype.every) {
254
+ Array.prototype.every = function every(fun /*, thisp */) {
255
+ if (this === void 0 || this === null)
256
+ throw new TypeError();
257
+ if (typeof fun !== "function")
258
+ throw new TypeError();
259
+ var self = Object(this);
260
+ var length = self.length >>> 0;
261
+ var thisp = arguments[1];
262
+ for (var i = 0; i < length; i++) {
263
+ if (i in self && !fun.call(thisp, self[i], i, self))
264
+ return false;
265
+ }
266
+ return true;
267
+ };
268
+ }
269
+
270
+ // ES5 15.4.4.17
271
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
272
+ if (!Array.prototype.some) {
273
+ Array.prototype.some = function some(fun /*, thisp */) {
274
+ if (this === void 0 || this === null)
275
+ throw new TypeError();
276
+ if (typeof fun !== "function")
277
+ throw new TypeError();
278
+ var self = Object(this);
279
+ var length = self.length >>> 0;
280
+ var thisp = arguments[1];
281
+ for (var i = 0; i < length; i++) {
282
+ if (i in self && fun.call(thisp, self[i], i, self))
283
+ return true;
284
+ }
285
+ return false;
286
+ };
287
+ }
288
+
289
+ // ES5 15.4.4.21
290
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
291
+ if (!Array.prototype.reduce) {
292
+ Array.prototype.reduce = function reduce(fun /*, initial*/) {
293
+ var self = Object(this);
294
+ var length = self.length >>> 0;
295
+ // Whether to include (... || fun instanceof RegExp)
296
+ // in the following expression to trap cases where
297
+ // the provided function was actually a regular
298
+ // expression literal, which in V8 and
299
+ // JavaScriptCore is a typeof "function". Only in
300
+ // V8 are regular expression literals permitted as
301
+ // reduce parameters, so it is desirable in the
302
+ // general case for the shim to match the more
303
+ // strict and common behavior of rejecting regular
304
+ // expressions. However, the only case where the
305
+ // shim is applied is IE's Trident (and perhaps very
306
+ // old revisions of other engines). In Trident,
307
+ // regular expressions are a typeof "object", so the
308
+ // following guard alone is sufficient.
309
+ if (Object.prototype.toString.call(fun) != "[object Function]")
310
+ throw new TypeError();
311
+
312
+ // no value to return if no initial value and an empty array
313
+ if (!length && arguments.length == 1)
314
+ throw new TypeError();
315
+
316
+ var i = 0;
317
+ var result;
318
+ if (arguments.length >= 2) {
319
+ result = arguments[1];
320
+ } else {
321
+ do {
322
+ if (i in self) {
323
+ result = self[i++];
324
+ break;
325
+ }
326
+
327
+ // if array contains no values, no initial value to return
328
+ if (++i >= length)
329
+ throw new TypeError();
330
+ } while (true);
331
+ }
332
+
333
+ for (; i < length; i++) {
334
+ if (i in self)
335
+ result = fun.call(null, result, self[i], i, self);
336
+ }
337
+
338
+ return result;
339
+ };
340
+ }
341
+
342
+ // ES5 15.4.4.22
343
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
344
+ if (!Array.prototype.reduceRight) {
345
+ Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
346
+ var self = Object(this);
347
+ var length = self.length >>> 0;
348
+ if (Object.prototype.toString.call(fun) != "[object Function]")
349
+ throw new TypeError();
350
+ // no value to return if no initial value, empty array
351
+ if (!length && arguments.length == 1)
352
+ throw new TypeError();
353
+
354
+ var result, i = length - 1;
355
+ if (arguments.length >= 2) {
356
+ result = arguments[1];
357
+ } else {
358
+ do {
359
+ if (i in self) {
360
+ result = self[i--];
361
+ break;
362
+ }
363
+
364
+ // if array contains no values, no initial value to return
365
+ if (--i < 0)
366
+ throw new TypeError();
367
+ } while (true);
368
+ }
369
+
370
+ do {
371
+ if (i in this)
372
+ result = fun.call(null, result, self[i], i, self);
373
+ } while (i--);
374
+
375
+ return result;
376
+ };
377
+ }
378
+
379
+ // ES5 15.4.4.14
380
+ // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
381
+ if (!Array.prototype.indexOf) {
382
+ Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
383
+ if (this === void 0 || this === null)
384
+ throw new TypeError();
385
+ var self = Object(this);
386
+ var length = self.length >>> 0;
387
+ if (!length)
388
+ return -1;
389
+ var i = 0;
390
+ if (arguments.length > 1)
391
+ i = toInteger(arguments[1]);
392
+ // handle negative indices
393
+ i = i >= 0 ? i : length - Math.abs(i);
394
+ for (; i < length; i++) {
395
+ if (i in self && self[i] === sought) {
396
+ return i;
397
+ }
398
+ }
399
+ return -1;
400
+ }
401
+ }
402
+
403
+ // ES5 15.4.4.15
404
+ if (!Array.prototype.lastIndexOf) {
405
+ Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
406
+ if (this === void 0 || this === null)
407
+ throw new TypeError();
408
+ var self = Object(this);
409
+ var length = self.length >>> 0;
410
+ if (!length)
411
+ return -1;
412
+ var i = length - 1;
413
+ if (arguments.length > 1)
414
+ i = toInteger(arguments[1]);
415
+ // handle negative indices
416
+ i = i >= 0 ? i : length - Math.abs(i);
417
+ for (; i >= 0; i--) {
418
+ if (i in self && sought === self[i])
419
+ return i;
420
+ }
421
+ return -1;
422
+ };
423
+ }
424
+
425
+ //
426
+ // Object
427
+ // ======
428
+ //
429
+
430
+ // ES5 15.2.3.2
431
+ if (!Object.getPrototypeOf) {
432
+ // https://github.com/kriskowal/es5-shim/issues#issue/2
433
+ // http://ejohn.org/blog/objectgetprototypeof/
434
+ // recommended by fschaefer on github
435
+ Object.getPrototypeOf = function getPrototypeOf(object) {
436
+ return object.__proto__ || object.constructor.prototype;
437
+ // or undefined if not available in this engine
438
+ };
439
+ }
440
+
441
+ // ES5 15.2.3.3
442
+ if (!Object.getOwnPropertyDescriptor) {
443
+ var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
444
+ "non-object: ";
445
+ Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
446
+ if ((typeof object != "object" && typeof object != "function") || object === null)
447
+ throw new TypeError(ERR_NON_OBJECT + object);
448
+ // If object does not owns property return undefined immediately.
449
+ if (!owns(object, property))
450
+ return undefined;
451
+
452
+ var descriptor, getter, setter;
453
+
454
+ // If object has a property then it's for sure both `enumerable` and
455
+ // `configurable`.
456
+ descriptor = { enumerable: true, configurable: true };
457
+
458
+ // If JS engine supports accessor properties then property may be a
459
+ // getter or setter.
460
+ if (supportsAccessors) {
461
+ // Unfortunately `__lookupGetter__` will return a getter even
462
+ // if object has own non getter property along with a same named
463
+ // inherited getter. To avoid misbehavior we temporary remove
464
+ // `__proto__` so that `__lookupGetter__` will return getter only
465
+ // if it's owned by an object.
466
+ var prototype = object.__proto__;
467
+ object.__proto__ = prototypeOfObject;
468
+
469
+ var getter = lookupGetter(object, property);
470
+ var setter = lookupSetter(object, property);
471
+
472
+ // Once we have getter and setter we can put values back.
473
+ object.__proto__ = prototype;
474
+
475
+ if (getter || setter) {
476
+ if (getter) descriptor.get = getter;
477
+ if (setter) descriptor.set = setter;
478
+
479
+ // If it was accessor property we're done and return here
480
+ // in order to avoid adding `value` to the descriptor.
481
+ return descriptor;
482
+ }
483
+ }
484
+
485
+ // If we got this far we know that object has an own property that is
486
+ // not an accessor so we set it as a value and return descriptor.
487
+ descriptor.value = object[property];
488
+ return descriptor;
489
+ };
490
+ }
491
+
492
+ // ES5 15.2.3.4
493
+ if (!Object.getOwnPropertyNames) {
494
+ Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
495
+ return Object.keys(object);
496
+ };
497
+ }
498
+
499
+ // ES5 15.2.3.5
500
+ if (!Object.create) {
501
+ Object.create = function create(prototype, properties) {
502
+ var object;
503
+ if (prototype === null) {
504
+ object = { "__proto__": null };
505
+ } else {
506
+ if (typeof prototype != "object")
507
+ throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
508
+ var Type = function () {};
509
+ Type.prototype = prototype;
510
+ object = new Type();
511
+ // IE has no built-in implementation of `Object.getPrototypeOf`
512
+ // neither `__proto__`, but this manually setting `__proto__` will
513
+ // guarantee that `Object.getPrototypeOf` will work as expected with
514
+ // objects created using `Object.create`
515
+ object.__proto__ = prototype;
516
+ }
517
+ if (typeof properties != "undefined")
518
+ Object.defineProperties(object, properties);
519
+ return object;
520
+ };
521
+ }
522
+
523
+ // ES5 15.2.3.6
524
+ var oldDefineProperty = Object.defineProperty;
525
+ var defineProperty = !!oldDefineProperty;
526
+ if (defineProperty) {
527
+ // detect IE 8's DOM-only implementation of defineProperty;
528
+ var subject = {};
529
+ Object.defineProperty(subject, "", {});
530
+ defineProperty = "" in subject;
531
+ }
532
+ if (!defineProperty) {
533
+ var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
534
+ var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
535
+ var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
536
+ "on this javascript engine";
537
+
538
+ Object.defineProperty = function defineProperty(object, property, descriptor) {
539
+ if (typeof object != "object" && typeof object != "function")
540
+ throw new TypeError(ERR_NON_OBJECT_TARGET + object);
541
+ if (typeof descriptor != "object" || descriptor === null)
542
+ throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
543
+ // make a valiant attempt to use the real defineProperty
544
+ // for I8's DOM elements.
545
+ if (oldDefineProperty && object.nodeType)
546
+ return oldDefineProperty(object, property, descriptor);
547
+
548
+ // If it's a data property.
549
+ if (owns(descriptor, "value")) {
550
+ // fail silently if "writable", "enumerable", or "configurable"
551
+ // are requested but not supported
552
+ /*
553
+ // alternate approach:
554
+ if ( // can't implement these features; allow false but not true
555
+ !(owns(descriptor, "writable") ? descriptor.writable : true) ||
556
+ !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) ||
557
+ !(owns(descriptor, "configurable") ? descriptor.configurable : true)
558
+ )
559
+ throw new RangeError(
560
+ "This implementation of Object.defineProperty does not " +
561
+ "support configurable, enumerable, or writable."
562
+ );
563
+ */
564
+
565
+ if (supportsAccessors && (lookupGetter(object, property) ||
566
+ lookupSetter(object, property)))
567
+ {
568
+ // As accessors are supported only on engines implementing
569
+ // `__proto__` we can safely override `__proto__` while defining
570
+ // a property to make sure that we don't hit an inherited
571
+ // accessor.
572
+ var prototype = object.__proto__;
573
+ object.__proto__ = prototypeOfObject;
574
+ // Deleting a property anyway since getter / setter may be
575
+ // defined on object itself.
576
+ delete object[property];
577
+ object[property] = descriptor.value;
578
+ // Setting original `__proto__` back now.
579
+ object.__proto__ = prototype;
580
+ } else {
581
+ object[property] = descriptor.value;
582
+ }
583
+ } else {
584
+ if (!supportsAccessors)
585
+ throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
586
+ // If we got that far then getters and setters can be defined !!
587
+ if (owns(descriptor, "get"))
588
+ defineGetter(object, property, descriptor.get);
589
+ if (owns(descriptor, "set"))
590
+ defineSetter(object, property, descriptor.set);
591
+ }
592
+
593
+ return object;
594
+ };
595
+ }
596
+
597
+ // ES5 15.2.3.7
598
+ if (!Object.defineProperties) {
599
+ Object.defineProperties = function defineProperties(object, properties) {
600
+ for (var property in properties) {
601
+ if (owns(properties, property))
602
+ Object.defineProperty(object, property, properties[property]);
603
+ }
604
+ return object;
605
+ };
606
+ }
607
+
608
+ // ES5 15.2.3.8
609
+ if (!Object.seal) {
610
+ Object.seal = function seal(object) {
611
+ // this is misleading and breaks feature-detection, but
612
+ // allows "securable" code to "gracefully" degrade to working
613
+ // but insecure code.
614
+ return object;
615
+ };
616
+ }
617
+
618
+ // ES5 15.2.3.9
619
+ if (!Object.freeze) {
620
+ Object.freeze = function freeze(object) {
621
+ // this is misleading and breaks feature-detection, but
622
+ // allows "securable" code to "gracefully" degrade to working
623
+ // but insecure code.
624
+ return object;
625
+ };
626
+ }
627
+
628
+ // detect a Rhino bug and patch it
629
+ try {
630
+ Object.freeze(function () {});
631
+ } catch (exception) {
632
+ Object.freeze = (function freeze(freezeObject) {
633
+ return function freeze(object) {
634
+ if (typeof object == "function") {
635
+ return object;
636
+ } else {
637
+ return freezeObject(object);
638
+ }
639
+ };
640
+ })(Object.freeze);
641
+ }
642
+
643
+ // ES5 15.2.3.10
644
+ if (!Object.preventExtensions) {
645
+ Object.preventExtensions = function preventExtensions(object) {
646
+ // this is misleading and breaks feature-detection, but
647
+ // allows "securable" code to "gracefully" degrade to working
648
+ // but insecure code.
649
+ return object;
650
+ };
651
+ }
652
+
653
+ // ES5 15.2.3.11
654
+ if (!Object.isSealed) {
655
+ Object.isSealed = function isSealed(object) {
656
+ return false;
657
+ };
658
+ }
659
+
660
+ // ES5 15.2.3.12
661
+ if (!Object.isFrozen) {
662
+ Object.isFrozen = function isFrozen(object) {
663
+ return false;
664
+ };
665
+ }
666
+
667
+ // ES5 15.2.3.13
668
+ if (!Object.isExtensible) {
669
+ Object.isExtensible = function isExtensible(object) {
670
+ return true;
671
+ };
672
+ }
673
+
674
+ // ES5 15.2.3.14
675
+ // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
676
+ if (!Object.keys) {
677
+
678
+ var hasDontEnumBug = true,
679
+ dontEnums = [
680
+ "toString",
681
+ "toLocaleString",
682
+ "valueOf",
683
+ "hasOwnProperty",
684
+ "isPrototypeOf",
685
+ "propertyIsEnumerable",
686
+ "constructor"
687
+ ],
688
+ dontEnumsLength = dontEnums.length;
689
+
690
+ for (var key in {"toString": null})
691
+ hasDontEnumBug = false;
692
+
693
+ Object.keys = function keys(object) {
694
+
695
+ if (
696
+ typeof object != "object" && typeof object != "function"
697
+ || object === null
698
+ )
699
+ throw new TypeError("Object.keys called on a non-object");
700
+
701
+ var keys = [];
702
+ for (var name in object) {
703
+ if (owns(object, name)) {
704
+ keys.push(name);
705
+ }
706
+ }
707
+
708
+ if (hasDontEnumBug) {
709
+ for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
710
+ var dontEnum = dontEnums[i];
711
+ if (owns(object, dontEnum)) {
712
+ keys.push(dontEnum);
713
+ }
714
+ }
715
+ }
716
+
717
+ return keys;
718
+ };
719
+
720
+ }
721
+
722
+ //
723
+ // Date
724
+ // ====
725
+ //
726
+
727
+ // ES5 15.9.5.43
728
+ // Format a Date object as a string according to a simplified subset of the ISO 8601
729
+ // standard as defined in 15.9.1.15.
730
+ if (!Date.prototype.toISOString) {
731
+ Date.prototype.toISOString = function toISOString() {
732
+ var result, length, value;
733
+ if (!isFinite(this))
734
+ throw new RangeError;
735
+
736
+ // the date time string format is specified in 15.9.1.15.
737
+ result = [this.getUTCFullYear(), this.getUTCMonth() + 1, this.getUTCDate(),
738
+ this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
739
+
740
+ length = result.length;
741
+ while (length--) {
742
+ value = result[length];
743
+ // pad months, days, hours, minutes, and seconds to have two digits.
744
+ if (value < 10)
745
+ result[length] = "0" + value;
746
+ }
747
+ // pad milliseconds to have three digits.
748
+ return result.slice(0, 3).join("-") + "T" + result.slice(3).join(":") + "." +
749
+ ("000" + this.getUTCMilliseconds()).slice(-3) + "Z";
750
+ }
751
+ }
752
+
753
+ // ES5 15.9.4.4
754
+ if (!Date.now) {
755
+ Date.now = function now() {
756
+ return new Date().getTime();
757
+ };
758
+ }
759
+
760
+ // ES5 15.9.5.44
761
+ if (!Date.prototype.toJSON) {
762
+ Date.prototype.toJSON = function toJSON(key) {
763
+ // This function provides a String representation of a Date object for
764
+ // use by JSON.stringify (15.12.3). When the toJSON method is called
765
+ // with argument key, the following steps are taken:
766
+
767
+ // 1. Let O be the result of calling ToObject, giving it the this
768
+ // value as its argument.
769
+ // 2. Let tv be ToPrimitive(O, hint Number).
770
+ // 3. If tv is a Number and is not finite, return null.
771
+ // XXX
772
+ // 4. Let toISO be the result of calling the [[Get]] internal method of
773
+ // O with argument "toISOString".
774
+ // 5. If IsCallable(toISO) is false, throw a TypeError exception.
775
+ // XXX this gets pretty close, for all intents and purposes, letting
776
+ // some duck-types slide
777
+ if (typeof this.toISOString.call != "function")
778
+ throw new TypeError();
779
+ // 6. Return the result of calling the [[Call]] internal method of
780
+ // toISO with O as the this value and an empty argument list.
781
+ return this.toISOString.call(this);
782
+
783
+ // NOTE 1 The argument is ignored.
784
+
785
+ // NOTE 2 The toJSON function is intentionally generic; it does not
786
+ // require that its this value be a Date object. Therefore, it can be
787
+ // transferred to other kinds of objects for use as a method. However,
788
+ // it does require that any such object have a toISOString method. An
789
+ // object is free to use the argument key to filter its
790
+ // stringification.
791
+ };
792
+ }
793
+
794
+ // 15.9.4.2 Date.parse (string)
795
+ // 15.9.1.15 Date Time String Format
796
+ // Date.parse
797
+ // based on work shared by Daniel Friesen (dantman)
798
+ // http://gist.github.com/303249
799
+ if (isNaN(Date.parse("2011-06-15T21:40:05+06:00"))) {
800
+ // XXX global assignment won't work in embeddings that use
801
+ // an alternate object for the context.
802
+ Date = (function(NativeDate) {
803
+
804
+ // Date.length === 7
805
+ var Date = function(Y, M, D, h, m, s, ms) {
806
+ var length = arguments.length;
807
+ if (this instanceof NativeDate) {
808
+ var date = length == 1 && String(Y) === Y ? // isString(Y)
809
+ // We explicitly pass it through parse:
810
+ new NativeDate(Date.parse(Y)) :
811
+ // We have to manually make calls depending on argument
812
+ // length here
813
+ length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) :
814
+ length >= 6 ? new NativeDate(Y, M, D, h, m, s) :
815
+ length >= 5 ? new NativeDate(Y, M, D, h, m) :
816
+ length >= 4 ? new NativeDate(Y, M, D, h) :
817
+ length >= 3 ? new NativeDate(Y, M, D) :
818
+ length >= 2 ? new NativeDate(Y, M) :
819
+ length >= 1 ? new NativeDate(Y) :
820
+ new NativeDate();
821
+ // Prevent mixups with unfixed Date object
822
+ date.constructor = Date;
823
+ return date;
824
+ }
825
+ return NativeDate.apply(this, arguments);
826
+ };
827
+
828
+ // 15.9.1.15 Date Time String Format. This pattern does not implement
829
+ // extended years ((15.9.1.15.1), as `Date.UTC` cannot parse them.
830
+ var isoDateExpression = new RegExp("^" +
831
+ "(\\d{4})" + // four-digit year capture
832
+ "(?:-(\\d{2})" + // optional month capture
833
+ "(?:-(\\d{2})" + // optional day capture
834
+ "(?:" + // capture hours:minutes:seconds.milliseconds
835
+ "T(\\d{2})" + // hours capture
836
+ ":(\\d{2})" + // minutes capture
837
+ "(?:" + // optional :seconds.milliseconds
838
+ ":(\\d{2})" + // seconds capture
839
+ "(?:\\.(\\d{3}))?" + // milliseconds capture
840
+ ")?" +
841
+ "(?:" + // capture UTC offset component
842
+ "Z|" + // UTC capture
843
+ "(?:" + // offset specifier +/-hours:minutes
844
+ "([-+])" + // sign capture
845
+ "(\\d{2})" + // hours offset capture
846
+ ":(\\d{2})" + // minutes offest capture
847
+ ")" +
848
+ ")?)?)?)?" +
849
+ "$");
850
+
851
+ // Copy any custom methods a 3rd party library may have added
852
+ for (var key in NativeDate)
853
+ Date[key] = NativeDate[key];
854
+
855
+ // Copy "native" methods explicitly; they may be non-enumerable
856
+ Date.now = NativeDate.now;
857
+ Date.UTC = NativeDate.UTC;
858
+ Date.prototype = NativeDate.prototype;
859
+ Date.prototype.constructor = Date;
860
+
861
+ // Upgrade Date.parse to handle simplified ISO 8601 strings
862
+ Date.parse = function parse(string) {
863
+ var match = isoDateExpression.exec(string);
864
+ if (match) {
865
+ match.shift(); // kill match[0], the full match
866
+ // parse months, days, hours, minutes, seconds, and milliseconds
867
+ for (var i = 1; i < 7; i++) {
868
+ // provide default values if necessary
869
+ match[i] = +(match[i] || (i < 3 ? 1 : 0));
870
+ // match[1] is the month. Months are 0-11 in JavaScript
871
+ // `Date` objects, but 1-12 in ISO notation, so we
872
+ // decrement.
873
+ if (i == 1)
874
+ match[i]--;
875
+ }
876
+
877
+ // parse the UTC offset component
878
+ var minutesOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop();
879
+
880
+ // compute the explicit time zone offset if specified
881
+ var offset = 0;
882
+ if (sign) {
883
+ // detect invalid offsets and return early
884
+ if (hourOffset > 23 || minuteOffset > 59)
885
+ return NaN;
886
+
887
+ // express the provided time zone offset in minutes. The offset is
888
+ // negative for time zones west of UTC; positive otherwise.
889
+ offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1);
890
+ }
891
+
892
+ // compute a new UTC date value, accounting for the optional offset
893
+ return NativeDate.UTC.apply(this, match) + offset;
894
+ }
895
+ return NativeDate.parse.apply(this, arguments);
896
+ };
897
+
898
+ return Date;
899
+ })(Date);
900
+ }
901
+
902
+ //
903
+ // String
904
+ // ======
905
+ //
906
+
907
+ // ES5 15.5.4.20
908
+ var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF";
909
+ if (!String.prototype.trim || ws.trim()) {
910
+ // http://blog.stevenlevithan.com/archives/faster-trim-javascript
911
+ // http://perfectionkills.com/whitespace-deviations/
912
+ ws = "[" + ws + "]";
913
+ var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
914
+ trimEndRegexp = new RegExp(ws + ws + "*$");
915
+ String.prototype.trim = function trim() {
916
+ return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
917
+ };
918
+ }
919
+
920
+ //
921
+ // Util
922
+ // ======
923
+ //
924
+
925
+ // http://jsperf.com/to-integer
926
+ var toInteger = function (n) {
927
+ n = +n;
928
+ if (n !== n) // isNaN
929
+ n = -1;
930
+ else if (n !== 0 && n !== (1/0) && n !== -(1/0))
931
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
932
+ return n;
933
+ };
934
+
935
+ });