closure 1.3.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. data/README.md +142 -9
  2. data/bin/closure-script +19 -0
  3. data/closure-compiler/README +18 -4
  4. data/closure-compiler/compiler.jar +0 -0
  5. data/closure-templates/SoyToJsSrcCompiler.jar +0 -0
  6. data/closure-templates/soydata.js +163 -0
  7. data/closure-templates/soyutils.js +1191 -159
  8. data/closure-templates/soyutils_usegoog.js +1107 -60
  9. data/docs/closure/Closure.html +58 -52
  10. data/docs/closure/Closure/BeanShell.html +6 -3
  11. data/docs/closure/Closure/Compiler.html +18 -15
  12. data/docs/closure/Closure/Compiler/Compilation.html +9 -3
  13. data/docs/closure/Closure/Compiler/Error.html +3 -3
  14. data/docs/closure/Closure/FileResponse.html +13 -7
  15. data/docs/closure/Closure/Goog.html +49 -85
  16. data/docs/closure/Closure/Middleware.html +5 -3
  17. data/docs/closure/Closure/Script.html +14 -5
  18. data/docs/closure/Closure/Script/NotFound.html +3 -3
  19. data/docs/closure/Closure/Script/RenderStackOverflow.html +3 -3
  20. data/docs/closure/Closure/Server.html +6 -3
  21. data/docs/closure/Closure/ShowExceptions.html +5 -3
  22. data/docs/closure/Closure/Sources.html +145 -37
  23. data/docs/closure/Closure/Templates.html +11 -10
  24. data/docs/closure/Closure/Templates/Error.html +3 -3
  25. data/docs/closure/_index.html +4 -4
  26. data/docs/closure/css/full_list.css +2 -0
  27. data/docs/closure/css/style.css +2 -0
  28. data/docs/closure/file.LICENSE.html +3 -3
  29. data/docs/closure/file.README.html +151 -10
  30. data/docs/closure/frames.html +1 -1
  31. data/docs/closure/index.html +151 -10
  32. data/docs/closure/js/full_list.js +23 -6
  33. data/docs/closure/method_list.html +91 -83
  34. data/docs/closure/top-level-namespace.html +3 -3
  35. data/lib/closure.rb +3 -16
  36. data/lib/closure/compiler.rb +135 -53
  37. data/lib/closure/goog.rb +5 -29
  38. data/lib/closure/sources.rb +22 -9
  39. data/lib/closure/version.rb +1 -1
  40. data/scripts/config.ru +0 -1
  41. data/scripts/hello/compiler_build.js +5 -5
  42. data/scripts/hello/compiler_build.map +518 -522
  43. data/scripts/hello/compiler_debug.js +7 -13
  44. data/scripts/hello/legume.js +2 -2
  45. data/scripts/index.erb +0 -3
  46. data/scripts/modules/compiler_build.js +3 -3
  47. data/scripts/modules/compiler_build.map +11569 -11476
  48. data/scripts/modules/compiler_build_api.js +1 -1
  49. data/scripts/modules/compiler_build_app.js +71 -70
  50. data/scripts/modules/compiler_build_settings.js +2 -2
  51. data/scripts/modules/compiler_debug.js +3 -3
  52. data/scripts/modules/compiler_debug_api.js +2 -2
  53. data/scripts/modules/compiler_debug_app.js +926 -1382
  54. data/scripts/modules/compiler_debug_settings.js +21 -24
  55. metadata +8 -18
  56. data/externs/chrome_extensions.externs +0 -968
  57. data/externs/jquery-1.3.2.externs +0 -718
  58. data/externs/jquery-1.4.3.externs +0 -1289
  59. data/externs/jquery-1.4.4.externs +0 -1302
  60. data/externs/jquery-1.5.externs +0 -1697
  61. data/externs/jquery-ui.externs +0 -10
  62. data/externs/jquery.externs +0 -4
  63. data/scripts/jquery/compiler.js.erb +0 -7
  64. data/scripts/jquery/compiler_out.js +0 -1
  65. data/scripts/jquery/index.erb +0 -25
  66. data/scripts/jquery/jquery_1.4.4.js +0 -167
  67. data/scripts/jquery/jquery_test.js +0 -8
@@ -6,7 +6,7 @@
6
6
  <title>
7
7
  Top Level Namespace
8
8
 
9
- &mdash; Documentation by YARD 0.7.2
9
+ &mdash; Documentation by YARD 0.7.3
10
10
 
11
11
  </title>
12
12
 
@@ -94,9 +94,9 @@
94
94
  </div>
95
95
 
96
96
  <div id="footer">
97
- Generated on Tue Jul 5 15:45:36 2011 by
97
+ Generated on Sun Oct 23 22:43:17 2011 by
98
98
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
99
- 0.7.2 (ruby-1.9.2).
99
+ 0.7.3 (ruby-1.9.2).
100
100
  </div>
101
101
 
102
102
  </body>
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ require 'rack'
15
16
  require 'ostruct'
16
17
  require 'tempfile'
17
18
 
@@ -28,19 +29,6 @@ require 'tempfile'
28
29
 
29
30
  class Closure
30
31
 
31
- autoload(:VERSION, 'closure/version')
32
- autoload(:BeanShell, 'closure/beanshell')
33
- autoload(:Script, 'closure/script')
34
- autoload(:Sources, 'closure/sources')
35
- autoload(:FileResponse, 'closure/file_response')
36
- autoload(:Middleware, 'closure/middleware')
37
- autoload(:Compiler, 'closure/compiler')
38
- autoload(:Server, 'closure/server')
39
- autoload(:Goog, 'closure/goog')
40
- autoload(:Templates, 'closure/templates')
41
- autoload(:ShowExceptions, 'closure/show_exceptions')
42
-
43
-
44
32
  # Filesystem location of the Closure Script install.
45
33
  # Typically, where the gem was installed. This is mainly used
46
34
  # internally but may be useful for experimental configurations.
@@ -53,7 +41,6 @@ class Closure
53
41
  # Scripts that are distributed with the gem. These will help get you started quickly.
54
42
  BUILT_INS = {
55
43
  :soy => File.join(base_path, 'closure-templates'),
56
- :externs => File.join(base_path, 'externs'),
57
44
  :docs => File.join(base_path, 'docs')
58
45
  }
59
46
 
@@ -61,7 +48,7 @@ class Closure
61
48
  # Easy config. This adds to the global instance of sources and
62
49
  # supports using the {BUILT_INS}.
63
50
  # @example
64
- # Closure.add_source :goog, '/goog'
51
+ # Closure.add_source :soy, '/soy_js'
65
52
  # Closure.add_source './myapp', '/myapp'
66
53
  # @overload add_source(directory, path=nil)
67
54
  # @overload add_source(built_in, path=nil)
@@ -135,7 +122,6 @@ class Closure
135
122
  end
136
123
  @@config
137
124
  end
138
- require 'closure/engines'
139
125
 
140
126
  # Run the welcome server. Handy for gem users.
141
127
  # @example
@@ -155,3 +141,4 @@ class Closure
155
141
 
156
142
  end
157
143
 
144
+ Dir.glob(File.expand_path('**/*.rb', File.dirname(__FILE__))).each {|f| require f}
@@ -184,49 +184,7 @@ class Closure
184
184
  args
185
185
  end
186
186
 
187
- # Transforms arguments to support --module name:* syntax.
188
- # @param [Array<String>] args
189
- # @return [Array<Hash>] mods
190
- def self.module_augment(args)
191
- found_starred = false
192
- found_numeric = false
193
- js_files = []
194
- mods = []
195
- args_index = args.length
196
- while args_index > 0
197
- args_index = args_index - 2
198
- option, value = args[args_index, 2]
199
- if option == '--js'
200
- js_files.unshift value
201
- elsif option == '--module'
202
- if js_files.empty?
203
- raise "No --js files for --module #{value}"
204
- end
205
- mod = value.split ':'
206
- if mod[1] == '*'
207
- mod[1] = js_files.size
208
- found_starred = true
209
- else
210
- found_numeric = true
211
- end
212
- mods.unshift({
213
- :name => mod[0],
214
- :requires => mod[2..-1],
215
- :files => js_files
216
- })
217
- js_files = []
218
- args[args_index+1] = mod.join ':'
219
- end
220
- end
221
- unless js_files.empty? or mods.empty?
222
- raise 'Automatic --module must appear before first --js option.'
223
- end
224
- if found_starred and found_numeric
225
- raise 'Static and automatic --module options can not be mixed.'
226
- end
227
- mods
228
- end
229
-
187
+
230
188
  # The javascript snippet for module info
231
189
  # @param [Array<Hash>] mods
232
190
  def self.module_info(mods)
@@ -262,6 +220,22 @@ class Closure
262
220
  js += "\n};\n"
263
221
  end
264
222
 
223
+
224
+ # Main function to convert --ns arguments into --js arguments.
225
+ # Returns module info when modules are processed.
226
+ # @param [Array<String>] args
227
+ # @return [Array<Hash>] mods
228
+ def self.augment(args, sources, env={})
229
+ mods = extract_modules args
230
+ if mods
231
+ module_augment args, sources, mods, env
232
+ else
233
+ namespace_augment args, sources, [], env
234
+ end
235
+ mods
236
+ end
237
+
238
+
265
239
  # Extracts the values for a options in the arguments.
266
240
  # Use Array#last to emulate compiler.jar for single options.
267
241
  # Will collect from an array of options.
@@ -281,12 +255,42 @@ class Closure
281
255
  values
282
256
  end
283
257
 
258
+
259
+ private
260
+
261
+
284
262
  # Converts --ns arguments into --js arguments
285
263
  # @param [Array<String>] args
286
- # @return [Array<String>] args
287
- def self.namespace_augment(args, sources, env={})
264
+ def self.module_augment(args, sources, mods, env)
265
+ walk_modules sources, mods, env
288
266
  files = []
289
- files_index = 0
267
+ mods.each do |mod|
268
+ mod_args = mod[:args]
269
+ mod_files = (mod[:files] ||= [])
270
+ # We are adding the bubbled namespaces to the end.
271
+ # This allows moduleManager.setLoaded to fire earlier
272
+ # since the bubbled files are needed only for the children.
273
+ (mod[:bubble]||[]).each do |mod_bubble|
274
+ namespaces = sources.namespaces_for mod_bubble, env
275
+ namespaces.each do |ns|
276
+ mod_args << '--ns' << ns
277
+ end
278
+ end
279
+ namespace_augment(mod_args, sources, files, env)
280
+ args << '--module'
281
+ args << "#{mod[:name]}:#{mod_args.size / 2}:#{mod[:requires].join(',')}"
282
+ mod_args.each_slice(2) do |a,b|
283
+ args << a << b
284
+ mod_files << b
285
+ end
286
+ end
287
+ end
288
+
289
+
290
+ # Converts --ns arguments into --js arguments
291
+ # @param [Array<String>] args
292
+ def self.namespace_augment(args, sources, files, env)
293
+ files_index = files.length
290
294
  args_index = 0
291
295
  while args_index < args.length
292
296
  option, value = args[args_index, 2]
@@ -294,12 +298,7 @@ class Closure
294
298
  sources.files_for(value, files, env)
295
299
  replacement = []
296
300
  while files_index < files.length
297
- if files[files_index] =~ /\.externs$/
298
- # use_externs_hack = true
299
- replacement.push '--externs'
300
- else
301
- replacement.push '--js'
302
- end
301
+ replacement.push '--js'
303
302
  replacement.push files[files_index]
304
303
  files_index = files_index + 1
305
304
  end
@@ -308,7 +307,90 @@ class Closure
308
307
  args_index = args_index + 2
309
308
  end
310
309
  end
311
- args
310
+ end
311
+
312
+
313
+ # Insanity-inducing recursive explorer to find common files in child modules.
314
+ # Try every branch in the tree and bubble up common files as we see them.
315
+ def self.walk_modules(sources, mods, env, seek=nil, mods_seen=[], files_seen=[])
316
+ files = []
317
+ mods_seen << seek
318
+ mods.each do |mod|
319
+ if (!seek and mod[:requires].empty?) or mod[:requires].include? seek
320
+ next if mods_seen.include? mod[:name]
321
+ # Find the needed files for this module's --ns args
322
+ files_seen_dup = files_seen.dup
323
+ mod[:args].each_slice(2) do |option, value|
324
+ if option == '--ns'
325
+ sources.files_for value, files_seen_dup, env
326
+ end
327
+ end
328
+ mod_files = files_seen_dup[files_seen.size..-1]
329
+ # Get the needed files for each of the modules requiring this mod
330
+ files_sets = walk_modules sources, mods, env, mod[:name], mods_seen, files_seen_dup
331
+ # Find the common files that will bubble up
332
+ common_files = []
333
+ child_files = files_sets.reduce([]){|memo, v|common_files |= memo&v; memo|v}
334
+ mod[:bubble] = common_files
335
+ # Clear bubbling files from children
336
+ mods.each do |child_mod|
337
+ if child_mod[:requires].include? mod[:name]
338
+ child_mod[:bubble] -= common_files
339
+ end
340
+ end
341
+ # Add to result array
342
+ files << (mod_files + child_files).uniq
343
+ end
344
+ end
345
+ files
346
+ end
347
+
348
+
349
+ # @param [Array<String>] args
350
+ # @return [Array<Hash>] mods
351
+ def self.extract_modules(args)
352
+ found_starred = false
353
+ found_numeric = false
354
+ mod_args = []
355
+ mods = []
356
+ args_index = args.length
357
+ while args_index > 0
358
+ args_index = args_index - 2
359
+ option, value = args[args_index, 2]
360
+ if %w{--js --ns}.include? option
361
+ mod_args.unshift args.delete_at args_index + 1
362
+ mod_args.unshift args.delete_at args_index
363
+ elsif option == '--module'
364
+ if mod_args.empty?
365
+ raise "No --js or --ns files for --module #{value}"
366
+ end
367
+ mod = value.split ':'
368
+ if mod[1] == '*'
369
+ found_starred = true
370
+ else
371
+ found_numeric = true
372
+ end
373
+ mods.unshift({
374
+ :name => mod[0],
375
+ :requires => (mod[2]||'').split(','),
376
+ :args => mod_args
377
+ })
378
+ mod_args = []
379
+ 2.times {args.delete_at args_index}
380
+ end
381
+ end
382
+ unless mod_args.empty? or mods.empty?
383
+ raise 'Automatic --module must appear before first --js or --ns option.'
384
+ end
385
+ if found_starred and found_numeric
386
+ raise 'Static and automatic --module options can not be mixed.'
387
+ end
388
+ if mods.empty?
389
+ args.insert -1, *mod_args
390
+ nil
391
+ else
392
+ mods
393
+ end
312
394
  end
313
395
 
314
396
  end
@@ -72,13 +72,11 @@ class Closure
72
72
  pre_js_tempfile = nil
73
73
  begin
74
74
  Compiler::Util.expand_paths args, File.dirname(@render_stack.last)
75
- orig_externs = Compiler::Util.arg_values args, '--externs'
76
- Compiler::Util.namespace_augment args, @sources, @env
77
- mods = Compiler::Util.module_augment args
75
+ mods = Compiler::Util.augment args, @sources, @env
78
76
  if Compiler::Util.arg_values(args, '--compilation_level').empty?
79
77
  # Raw mode
80
78
  comp = Compiler::Compilation.new @env
81
- unless mods.empty?
79
+ if mods
82
80
  comp << Compiler::Util.module_info(mods)
83
81
  comp << Compiler::Util.module_uris_raw(mods, @sources)
84
82
  end
@@ -92,41 +90,19 @@ class Closure
92
90
  comp << "document.write(#{script_tag.dump});\n"
93
91
  js_counter += 1
94
92
  # For modules, just the files for the first module
95
- break if !mods.empty? and js_counter >= mods[0][:files].length
93
+ break if mods and js_counter >= mods[0][:files].length
96
94
  end
97
95
  args_index = args_index + 2
98
96
  end
99
97
  else
100
98
  # Compiled mode
101
99
  module_output_path_prefix = Compiler::Util.arg_values(args, '--module_output_path_prefix').last
102
- if !mods.empty? and !module_output_path_prefix
100
+ if mods and !module_output_path_prefix
103
101
  # raise this before compilation so we don't write to a weird place
104
102
  raise "--module_output_path_prefix is required when using --module"
105
103
  end
106
- # If the externs were changed by namespace_augment then we need to include
107
- # a temp file containing the goog.provide statements that satisfy compiler.jar.
108
- if orig_externs != Compiler::Util.arg_values(args, '--externs')
109
- pre_js_tempfile = Tempfile.new 'closure_pre_js'
110
- # Insert before the first --js (in case of modules)
111
- args_index = 0
112
- while args_index < args.length
113
- if args[args_index] == '--js'
114
- args.insert args_index, '--js', pre_js_tempfile.path
115
- break
116
- end
117
- args_index = args_index + 2
118
- end
119
- pre_js_tempfile.open
120
- @sources.deps_response(File.dirname(base_js), @env).each do |s|
121
- next unless s =~ /^goog\.provide/
122
- pre_js_tempfile.write s
123
- end
124
- pre_js_tempfile.close
125
- # File mtime is rolled back to not trigger compilation.
126
- File.utime(Time.now, Time.at(0), pre_js_tempfile.path)
127
- end
128
104
  comp = Compiler.compile args, @dependencies, @env
129
- unless mods.empty?
105
+ if mods
130
106
  refresh # compilation may add new files, module_uris_compiled uses src_for
131
107
  prefix = File.expand_path module_output_path_prefix, File.dirname(@render_stack.last)
132
108
  if comp.js_output_file
@@ -131,11 +131,7 @@ class Closure
131
131
  response = @deps[base] ||= Rack::Response.new
132
132
  response.write "// Dynamic Deps by Closure Script\n"
133
133
  @files.sort{|a,b|(a[1][:path]||'')<=>(b[1][:path]||'')}.each do |filename, dep|
134
- if filename =~ /\.externs$/
135
- dep[:provide].each do |dep_provide|
136
- response.write "goog.provide(#{dep_provide.dump});\n"
137
- end
138
- elsif dep[:path]
134
+ if dep[:path]
139
135
  path = Pathname.new(dep[:path]).relative_path_from(base)
140
136
  path = "#{path}?#{dep[:mtime].to_i}"
141
137
  response.write "goog.addDependency(#{path.dump}, #{dep[:provide].inspect}, #{dep[:require].inspect});\n"
@@ -192,28 +188,45 @@ class Closure
192
188
  calcdeps(ns, namespace, filenames)
193
189
  end
194
190
 
191
+
195
192
  # Calculate the file server path for a filename
196
193
  # @param (String) filename
197
194
  # @return (String)
198
195
  def src_for(filename, env={})
199
196
  @semaphore.synchronize do
200
197
  refresh(env)
201
- f, dep = @files.find {|f, dep| f == filename}
202
- unless dep and dep.has_key? :path
198
+ file = @files[filename]
199
+ unless file and file.has_key? :path
203
200
  raise "#{filename.dump} is not available from file server"
204
201
  end
205
- "#{dep[:path]}?#{dep[:mtime].to_i}"
202
+ "#{file[:path]}?#{file[:mtime].to_i}"
206
203
  end
207
204
  end
208
205
 
206
+
207
+ # Return all provided and required namespaces for a file.
208
+ # @param (String) filename
209
+ # @return (String)
210
+ def namespaces_for(filename, env={})
211
+ @semaphore.synchronize do
212
+ refresh(env)
213
+ file = @files[filename]
214
+ raise "#{filename.dump} not found" unless file
215
+ file[:provide] + file[:require]
216
+ end
217
+ end
218
+
219
+
209
220
  # Certain Script operations, such as building Templates, will need
210
221
  # to invalidate the cache.
211
222
  def invalidate(env)
212
223
  env.delete ENV_FLAG
213
224
  @last_been_run = Time.at 0
214
225
  end
226
+
215
227
 
216
228
  protected
229
+
217
230
 
218
231
  # Namespace recursion with circular stop on the filename
219
232
  def calcdeps(ns, namespace, filenames, prev = nil)
@@ -248,7 +261,7 @@ class Closure
248
261
  # Scan filesystem for changes.
249
262
  @sources.each do |dir, path|
250
263
  dir_range = (dir.length..-1)
251
- Dir.glob(File.join(dir,'**','*.{js,externs}')).each do |filename|
264
+ Dir.glob(File.join(dir,'**','*.js')).each do |filename|
252
265
  dep = (@files[filename] ||= {})
253
266
  dep.delete(:not_found)
254
267
  mtime = File.mtime(filename)
@@ -14,5 +14,5 @@
14
14
 
15
15
 
16
16
  class Closure
17
- VERSION = "1.3.1"
17
+ VERSION = "1.4.2"
18
18
  end
@@ -10,7 +10,6 @@ Closure.add_source '.', '/'
10
10
  # Add some useful built-ins.
11
11
  Closure.add_source :soy, '/soy'
12
12
  Closure.add_source :docs, '/docs'
13
- Closure.add_source :externs
14
13
 
15
14
  # Feel free to use your own compilers.
16
15
  # Closure.config.compiler_jar = 'closure-compiler/compiler.jar'
@@ -1,5 +1,5 @@
1
- var c=this;Math.floor(Math.random()*2147483648).toString(36);function d(a){if(!e.test(a))return a;a.indexOf("&")!=-1&&(a=a.replace(f,"&amp;"));a.indexOf("<")!=-1&&(a=a.replace(h,"&lt;"));a.indexOf(">")!=-1&&(a=a.replace(i,"&gt;"));a.indexOf('"')!=-1&&(a=a.replace(l,"&quot;"));return a}var f=/&/g,h=/</g,i=/>/g,l=/\"/g,e=/[&<>\"]/;function m(a,b){if(a<b)return-1;else if(a>b)return 1;return 0};var n,o,p,q;function t(){return c.navigator?c.navigator.userAgent:null}q=p=o=n=!1;var u;if(u=t()){var v=c.navigator;n=u.indexOf("Opera")==0;o=!n&&u.indexOf("MSIE")!=-1;p=!n&&u.indexOf("WebKit")!=-1;q=!n&&!p&&v.product=="Gecko"}var w=o,x=q,y=p,z;
2
- a:{var A="",B;if(n&&c.opera)var C=c.opera.version,A=typeof C=="function"?C():C;else if(x?B=/rv\:([^\);]+)(\)|;)/:w?B=/MSIE\s+([^\);]+)(\)|;)/:y&&(B=/WebKit\/(\S+)/),B)var D=B.exec(t()),A=D?D[1]:"";if(w){var E,F=c.document;E=F?F.documentMode:void 0;if(E>parseFloat(A)){z=String(E);break a}}z=A}var G={};
3
- function H(a){if(!G[a]){for(var b=0,r=String(z).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),g=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),Q=Math.max(r.length,g.length),s=0;b==0&&s<Q;s++){var R=r[s]||"",S=g[s]||"",T=RegExp("(\\d*)(\\D*)","g"),U=RegExp("(\\d*)(\\D*)","g");do{var j=T.exec(R)||["","",""],k=U.exec(S)||["","",""];if(j[0].length==0&&k[0].length==0)break;b=m(j[1].length==0?0:parseInt(j[1],10),k[1].length==0?0:parseInt(k[1],10))||m(j[2].length==0,k[2].length==0)||m(j[2],
4
- k[2])}while(b==0)}G[a]=b>=0}}var I={};function J(){return I[9]||(I[9]=w&&document.documentMode&&document.documentMode>=9)};!w||J();!x&&!w||w&&J()||x&&H("1.9.1");w&&H("9");w&&H(8);var K;(K="ScriptEngine"in c&&c.ScriptEngine()=="JScript")&&(c.ScriptEngineMajorVersion(),c.ScriptEngineMinorVersion(),c.ScriptEngineBuildVersion());function L(a,b){this.a=K?[]:"";a!=null&&this.append.apply(this,arguments)}K?(L.prototype.b=0,L.prototype.append=function(a,b,r){b==null?this.a[this.b++]=a:(this.a.push.apply(this.a,arguments),this.b=this.a.length);return this}):L.prototype.append=function(a,b,r){this.a+=a;if(b!=null)for(var g=1;g<arguments.length;g++)this.a+=arguments[g];return this};L.prototype.clear=function(){K?this.b=this.a.length=0:this.a=""};
5
- L.prototype.toString=function(){if(K){var a=this.a.join("");this.clear();a&&this.append(a);return a}else return this.a};function M(a){var b=new L;b.append("\tHello ",d(String(a.c)),"!");return b.toString()};function N(a){document.write(M({c:a}))}var O="hello".split("."),P=c;!(O[0]in P)&&P.execScript&&P.execScript("var "+O[0]);for(var V;O.length&&(V=O.shift());)!O.length&&N!==void 0?P[V]=N:P=P[V]?P[V]:P[V]={};
1
+ var c=this;Math.floor(Math.random()*2147483648).toString(36);function d(a,b){if(a<b)return-1;else if(a>b)return 1;return 0};var e,f,h,i;function l(){return c.navigator?c.navigator.userAgent:null}i=h=f=e=false;var m;if(m=l()){var n=c.navigator;e=m.indexOf("Opera")==0;f=!e&&m.indexOf("MSIE")!=-1;h=!e&&m.indexOf("WebKit")!=-1;i=!e&&!h&&n.product=="Gecko"}var o=f,p=i,q=h,t;
2
+ a:{var u="",v;if(e&&c.opera)var w=c.opera.version,u=typeof w=="function"?w():w;else if(p?v=/rv\:([^\);]+)(\)|;)/:o?v=/MSIE\s+([^\);]+)(\)|;)/:q&&(v=/WebKit\/(\S+)/),v)var x=v.exec(l()),u=x?x[1]:"";if(o){var y,z=c.document;y=z?z.documentMode:void 0;if(y>parseFloat(u)){t=String(y);break a}}t=u}var A={};
3
+ function B(a){if(!A[a]){for(var b=0,r=String(t).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),g=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),K=Math.max(r.length,g.length),s=0;b==0&&s<K;s++){var L=r[s]||"",M=g[s]||"",N=RegExp("(\\d*)(\\D*)","g"),O=RegExp("(\\d*)(\\D*)","g");do{var j=N.exec(L)||["","",""],k=O.exec(M)||["","",""];if(j[0].length==0&&k[0].length==0)break;b=d(j[1].length==0?0:parseInt(j[1],10),k[1].length==0?0:parseInt(k[1],10))||d(j[2].length==0,k[2].length==0)||d(j[2],
4
+ k[2])}while(b==0)}A[a]=b>=0}}var C={};function D(){return C[9]||(C[9]=o&&document.documentMode&&document.documentMode>=9)};!o||D();!p&&!o||o&&D()||p&&B("1.9.1");o&&B("9");o&&B(8);var E;(E="ScriptEngine"in c&&c.ScriptEngine()=="JScript")&&(c.ScriptEngineMajorVersion(),c.ScriptEngineMinorVersion(),c.ScriptEngineBuildVersion());function F(a,b){this.a=E?[]:"";a!=null&&this.append.apply(this,arguments)}E?(F.prototype.c=0,F.prototype.append=function(a,b,r){b==null?this.a[this.c++]=a:(this.a.push.apply(this.a,arguments),this.c=this.a.length);return this}):F.prototype.append=function(a,b,r){this.a+=a;if(b!=null)for(var g=1;g<arguments.length;g++)this.a+=arguments[g];return this};F.prototype.clear=function(){E?this.c=this.a.length=0:this.a=""};
5
+ F.prototype.toString=function(){if(E){var a=this.a.join("");this.clear();a&&this.append(a);return a}else return this.a};var G={"\x00":"&#0;",'"':"&quot;","&":"&amp;","'":"&#39;","<":"&lt;",">":"&gt;","\t":"&#9;","\n":"&#10;","\u000b":"&#11;","\u000c":"&#12;","\r":"&#13;"," ":"&#32;","-":"&#45;","/":"&#47;","=":"&#61;","`":"&#96;","\u0085":"&#133;","\u00a0":"&#160;","\u2028":"&#8232;","\u2029":"&#8233;"};function H(a){return G[a]}var I=/[\x00\x22\x26\x27\x3c\x3e]/g;function J(a){var b=new F;b.append("\tHello ",typeof a.b==="object"&&a.b&&a.b.d===0?a.b.content:String(a.b).replace(I,H),"!");return b.toString()};function P(a){document.write(J({b:a}))}var Q="hello".split("."),R=c;!(Q[0]in R)&&R.execScript&&R.execScript("var "+Q[0]);for(var S;Q.length&&(S=Q.shift());)!Q.length&&P!==void 0?R[S]=P:R=R[S]?R[S]:R[S]={};