medivo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +39 -0
  4. data/app/assets/images/medivo/arrow.png +0 -0
  5. data/app/assets/images/medivo/lab.png +0 -0
  6. data/app/assets/javascripts/medivo/application.js +5 -0
  7. data/app/assets/javascripts/medivo/handlebars.js +1494 -0
  8. data/app/assets/javascripts/medivo/map.coffee +59 -0
  9. data/app/assets/javascripts/medivo/models.coffee +37 -0
  10. data/app/assets/javascripts/medivo/show_labs.coffee +10 -0
  11. data/app/assets/stylesheets/medivo/application.css +7 -0
  12. data/app/controllers/medivo/application_controller.rb +4 -0
  13. data/app/controllers/medivo/labs_controller.rb +8 -0
  14. data/app/models/medivo/insurance_order.rb +39 -0
  15. data/app/models/medivo/lab.rb +33 -0
  16. data/app/models/medivo/order.rb +61 -0
  17. data/app/models/medivo/resource.rb +24 -0
  18. data/app/models/medivo/zip_code.rb +10 -0
  19. data/app/views/layouts/medivo/application.html.erb +14 -0
  20. data/config/routes.rb +3 -0
  21. data/db/zip_codes.sqlite3 +0 -0
  22. data/lib/generators/medivo/install/install_generator.rb +42 -0
  23. data/lib/medivo.rb +6 -0
  24. data/lib/medivo/engine.rb +5 -0
  25. data/lib/medivo/validators.rb +20 -0
  26. data/lib/medivo/version.rb +3 -0
  27. data/lib/tasks/load_zips.thor +16 -0
  28. data/lib/tasks/medivo_tasks.rake +4 -0
  29. data/spec/dummy/Rakefile +7 -0
  30. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  31. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  32. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  33. data/spec/dummy/app/controllers/labs_controller.rb +8 -0
  34. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  35. data/spec/dummy/app/views/labs/search.html.haml +13 -0
  36. data/spec/dummy/app/views/layouts/application.html.haml +11 -0
  37. data/spec/dummy/config.ru +4 -0
  38. data/spec/dummy/config/application.rb +45 -0
  39. data/spec/dummy/config/boot.rb +10 -0
  40. data/spec/dummy/config/database.yml +25 -0
  41. data/spec/dummy/config/environment.rb +5 -0
  42. data/spec/dummy/config/environments/development.rb +30 -0
  43. data/spec/dummy/config/environments/production.rb +60 -0
  44. data/spec/dummy/config/environments/test.rb +42 -0
  45. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  46. data/spec/dummy/config/initializers/inflections.rb +10 -0
  47. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  48. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  49. data/spec/dummy/config/initializers/session_store.rb +8 -0
  50. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  51. data/spec/dummy/config/locales/en.yml +5 -0
  52. data/spec/dummy/config/medivo.yml +9 -0
  53. data/spec/dummy/config/routes.rb +4 -0
  54. data/spec/dummy/db/development.sqlite3 +0 -0
  55. data/spec/dummy/db/test.sqlite3 +0 -0
  56. data/spec/dummy/log/development.log +2304 -0
  57. data/spec/dummy/log/test.log +637 -0
  58. data/spec/dummy/public/404.html +26 -0
  59. data/spec/dummy/public/422.html +26 -0
  60. data/spec/dummy/public/500.html +26 -0
  61. data/spec/dummy/public/favicon.ico +0 -0
  62. data/spec/dummy/script/rails +6 -0
  63. data/spec/dummy/tmp/cache/assets/C36/810/sprockets%2F5159467797298fb14cdd1716691362d5 +0 -0
  64. data/spec/dummy/tmp/cache/assets/C46/F00/sprockets%2F2281d588b540056c5a7306c32a3761b9 +0 -0
  65. data/spec/dummy/tmp/cache/assets/CAB/970/sprockets%2F6aa4308273851c94a14158394d4dcdc4 +0 -0
  66. data/spec/dummy/tmp/cache/assets/CC3/EF0/sprockets%2F453b504c1f8f374578636f699eaa455d +0 -0
  67. data/spec/dummy/tmp/cache/assets/CE4/E70/sprockets%2F091ec16b8699113092ce35de93ca1d87 +0 -0
  68. data/spec/dummy/tmp/cache/assets/CEE/250/sprockets%2F96688f33f2f8aa261bf6701c1d6d7575 +0 -0
  69. data/spec/dummy/tmp/cache/assets/CFF/7F0/sprockets%2F4007fd53da973506c55bc273a05c5c0d +0 -0
  70. data/spec/dummy/tmp/cache/assets/CFF/8D0/sprockets%2Fc1053414055bf81a6d316dc14f12f9fd +0 -0
  71. data/spec/dummy/tmp/cache/assets/D19/310/sprockets%2F110931639fc185699ea1aaaf87dd488b +0 -0
  72. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  73. data/spec/dummy/tmp/cache/assets/D54/ED0/sprockets%2F71c9fa01091d432b131da3bb73faf3d4 +0 -0
  74. data/spec/dummy/tmp/cache/assets/D62/380/sprockets%2F712d93afe40570cc939133bddca13bc7 +0 -0
  75. data/spec/dummy/tmp/cache/assets/D84/210/sprockets%2Fabd0103ccec2b428ac62c94e4c40b384 +0 -0
  76. data/spec/dummy/tmp/cache/assets/D9C/F50/sprockets%2F224e78bb9e1c414a2d518a3aaffd6f77 +0 -0
  77. data/spec/dummy/tmp/cache/assets/D9D/4E0/sprockets%2Fe9dab92986b1516fca08474613ccadcb +0 -0
  78. data/spec/dummy/tmp/cache/assets/DA2/040/sprockets%2F6ab79dcced8cc9933b734e7b21c3a183 +0 -0
  79. data/spec/dummy/tmp/cache/assets/DD2/A50/sprockets%2Fecb5dd9066b50eb678cd8c9dbb21d229 +0 -0
  80. data/spec/dummy/tmp/cache/assets/DD4/2B0/sprockets%2Fef214a63f29afe7f3cbffc65af943108 +0 -0
  81. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  82. data/spec/dummy/tmp/cache/assets/E59/D50/sprockets%2Fbe1cc4d9b0efb617e58baa16dd1dee58 +0 -0
  83. data/spec/dummy/tmp/pids/server.pid +1 -0
  84. data/spec/models/labs_spec.rb +13 -0
  85. data/spec/models/orders_spec.rb +59 -0
  86. data/spec/requests/labs_spec.rb +32 -0
  87. data/spec/spec_helper.rb +44 -0
  88. data/spec/support/blueprints.rb +54 -0
  89. metadata +278 -0
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = Medivo
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Medivo'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+ Bundler::GemHelper.install_tasks
28
+
29
+ require 'rake/testtask'
30
+
31
+ Rake::TestTask.new(:spec) do |t|
32
+ t.libs << 'lib'
33
+ t.libs << 'test'
34
+ t.pattern = 'test/**/*_test.rb'
35
+ t.verbose = false
36
+ end
37
+
38
+
39
+ task :default => :spec
Binary file
Binary file
@@ -0,0 +1,5 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
@@ -0,0 +1,1494 @@
1
+ // version 1.0.0.beta.3
2
+ // lib/handlebars/parser.js
3
+ /* Jison generated parser */
4
+ var handlebars = (function(){
5
+ var parser = {trace: function trace() { },
6
+ yy: {},
7
+ symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"INTEGER":29,"BOOLEAN":30,"hashSegments":31,"hashSegment":32,"ID":33,"EQUALS":34,"pathSegments":35,"SEP":36,"$accept":0,"$end":1},
8
+ terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",29:"INTEGER",30:"BOOLEAN",33:"ID",34:"EQUALS",36:"SEP"},
9
+ productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[26,1],[31,2],[31,1],[32,3],[32,3],[32,3],[32,3],[21,1],[35,3],[35,1]],
10
+ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
11
+
12
+ var $0 = $$.length - 1;
13
+ switch (yystate) {
14
+ case 1: return $$[$0-1]
15
+ break;
16
+ case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0])
17
+ break;
18
+ case 3: this.$ = new yy.ProgramNode($$[$0])
19
+ break;
20
+ case 4: this.$ = new yy.ProgramNode([])
21
+ break;
22
+ case 5: this.$ = [$$[$0]]
23
+ break;
24
+ case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
25
+ break;
26
+ case 7: this.$ = new yy.InverseNode($$[$0-2], $$[$0-1], $$[$0])
27
+ break;
28
+ case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0])
29
+ break;
30
+ case 9: this.$ = $$[$0]
31
+ break;
32
+ case 10: this.$ = $$[$0]
33
+ break;
34
+ case 11: this.$ = new yy.ContentNode($$[$0])
35
+ break;
36
+ case 12: this.$ = new yy.CommentNode($$[$0])
37
+ break;
38
+ case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
39
+ break;
40
+ case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
41
+ break;
42
+ case 15: this.$ = $$[$0-1]
43
+ break;
44
+ case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
45
+ break;
46
+ case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true)
47
+ break;
48
+ case 18: this.$ = new yy.PartialNode($$[$0-1])
49
+ break;
50
+ case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1])
51
+ break;
52
+ case 20:
53
+ break;
54
+ case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]
55
+ break;
56
+ case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null]
57
+ break;
58
+ case 23: this.$ = [[$$[$0-1]], $$[$0]]
59
+ break;
60
+ case 24: this.$ = [[$$[$0]], null]
61
+ break;
62
+ case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
63
+ break;
64
+ case 26: this.$ = [$$[$0]]
65
+ break;
66
+ case 27: this.$ = $$[$0]
67
+ break;
68
+ case 28: this.$ = new yy.StringNode($$[$0])
69
+ break;
70
+ case 29: this.$ = new yy.IntegerNode($$[$0])
71
+ break;
72
+ case 30: this.$ = new yy.BooleanNode($$[$0])
73
+ break;
74
+ case 31: this.$ = new yy.HashNode($$[$0])
75
+ break;
76
+ case 32: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
77
+ break;
78
+ case 33: this.$ = [$$[$0]]
79
+ break;
80
+ case 34: this.$ = [$$[$0-2], $$[$0]]
81
+ break;
82
+ case 35: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]
83
+ break;
84
+ case 36: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])]
85
+ break;
86
+ case 37: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])]
87
+ break;
88
+ case 38: this.$ = new yy.IdNode($$[$0])
89
+ break;
90
+ case 39: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
91
+ break;
92
+ case 40: this.$ = [$$[$0]]
93
+ break;
94
+ }
95
+ },
96
+ table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,33:[1,25],35:24},{17:26,21:23,33:[1,25],35:24},{17:27,21:23,33:[1,25],35:24},{17:28,21:23,33:[1,25],35:24},{21:29,33:[1,25],35:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,33:[1,25],35:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,38],28:[2,38],29:[2,38],30:[2,38],33:[2,38],36:[1,46]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],36:[2,40]},{18:[1,47]},{18:[1,48]},{18:[1,49]},{18:[1,50],21:51,33:[1,25],35:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:52,33:[1,25],35:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:53,27:54,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,23]},{18:[2,26],28:[2,26],29:[2,26],30:[2,26],33:[2,26]},{18:[2,31],32:55,33:[1,56]},{18:[2,27],28:[2,27],29:[2,27],30:[2,27],33:[2,27]},{18:[2,28],28:[2,28],29:[2,28],30:[2,28],33:[2,28]},{18:[2,29],28:[2,29],29:[2,29],30:[2,29],33:[2,29]},{18:[2,30],28:[2,30],29:[2,30],30:[2,30],33:[2,30]},{18:[2,33],33:[2,33]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],34:[1,57],36:[2,40]},{33:[1,58]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,59]},{18:[1,60]},{18:[2,21]},{18:[2,25],28:[2,25],29:[2,25],30:[2,25],33:[2,25]},{18:[2,32],33:[2,32]},{34:[1,57]},{21:61,28:[1,62],29:[1,63],30:[1,64],33:[1,25],35:24},{18:[2,39],28:[2,39],29:[2,39],30:[2,39],33:[2,39],36:[2,39]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,34],33:[2,34]},{18:[2,35],33:[2,35]},{18:[2,36],33:[2,36]},{18:[2,37],33:[2,37]}],
97
+ defaultActions: {16:[2,1],37:[2,23],53:[2,21]},
98
+ parseError: function parseError(str, hash) {
99
+ throw new Error(str);
100
+ },
101
+ parse: function parse(input) {
102
+ var self = this,
103
+ stack = [0],
104
+ vstack = [null], // semantic value stack
105
+ lstack = [], // location stack
106
+ table = this.table,
107
+ yytext = '',
108
+ yylineno = 0,
109
+ yyleng = 0,
110
+ recovering = 0,
111
+ TERROR = 2,
112
+ EOF = 1;
113
+
114
+ //this.reductionCount = this.shiftCount = 0;
115
+
116
+ this.lexer.setInput(input);
117
+ this.lexer.yy = this.yy;
118
+ this.yy.lexer = this.lexer;
119
+ if (typeof this.lexer.yylloc == 'undefined')
120
+ this.lexer.yylloc = {};
121
+ var yyloc = this.lexer.yylloc;
122
+ lstack.push(yyloc);
123
+
124
+ if (typeof this.yy.parseError === 'function')
125
+ this.parseError = this.yy.parseError;
126
+
127
+ function popStack (n) {
128
+ stack.length = stack.length - 2*n;
129
+ vstack.length = vstack.length - n;
130
+ lstack.length = lstack.length - n;
131
+ }
132
+
133
+ function lex() {
134
+ var token;
135
+ token = self.lexer.lex() || 1; // $end = 1
136
+ // if token isn't its numeric value, convert
137
+ if (typeof token !== 'number') {
138
+ token = self.symbols_[token] || token;
139
+ }
140
+ return token;
141
+ };
142
+
143
+ var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
144
+ while (true) {
145
+ // retreive state number from top of stack
146
+ state = stack[stack.length-1];
147
+
148
+ // use default actions if available
149
+ if (this.defaultActions[state]) {
150
+ action = this.defaultActions[state];
151
+ } else {
152
+ if (symbol == null)
153
+ symbol = lex();
154
+ // read action for current state and first input
155
+ action = table[state] && table[state][symbol];
156
+ }
157
+
158
+ // handle parse error
159
+ if (typeof action === 'undefined' || !action.length || !action[0]) {
160
+
161
+ if (!recovering) {
162
+ // Report error
163
+ expected = [];
164
+ for (p in table[state]) if (this.terminals_[p] && p > 2) {
165
+ expected.push("'"+this.terminals_[p]+"'");
166
+ }
167
+ var errStr = '';
168
+ if (this.lexer.showPosition) {
169
+ errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', ');
170
+ } else {
171
+ errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
172
+ (symbol == 1 /*EOF*/ ? "end of input" :
173
+ ("'"+(this.terminals_[symbol] || symbol)+"'"));
174
+ }
175
+ this.parseError(errStr,
176
+ {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
177
+ }
178
+
179
+ // just recovered from another error
180
+ if (recovering == 3) {
181
+ if (symbol == EOF) {
182
+ throw new Error(errStr || 'Parsing halted.');
183
+ }
184
+
185
+ // discard current lookahead and grab another
186
+ yyleng = this.lexer.yyleng;
187
+ yytext = this.lexer.yytext;
188
+ yylineno = this.lexer.yylineno;
189
+ yyloc = this.lexer.yylloc;
190
+ symbol = lex();
191
+ }
192
+
193
+ // try to recover from error
194
+ while (1) {
195
+ // check for error recovery rule in this state
196
+ if ((TERROR.toString()) in table[state]) {
197
+ break;
198
+ }
199
+ if (state == 0) {
200
+ throw new Error(errStr || 'Parsing halted.');
201
+ }
202
+ popStack(1);
203
+ state = stack[stack.length-1];
204
+ }
205
+
206
+ preErrorSymbol = symbol; // save the lookahead token
207
+ symbol = TERROR; // insert generic error symbol as new lookahead
208
+ state = stack[stack.length-1];
209
+ action = table[state] && table[state][TERROR];
210
+ recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
211
+ }
212
+
213
+ // this shouldn't happen, unless resolve defaults are off
214
+ if (action[0] instanceof Array && action.length > 1) {
215
+ throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
216
+ }
217
+
218
+ switch (action[0]) {
219
+
220
+ case 1: // shift
221
+ //this.shiftCount++;
222
+
223
+ stack.push(symbol);
224
+ vstack.push(this.lexer.yytext);
225
+ lstack.push(this.lexer.yylloc);
226
+ stack.push(action[1]); // push state
227
+ symbol = null;
228
+ if (!preErrorSymbol) { // normal execution/no error
229
+ yyleng = this.lexer.yyleng;
230
+ yytext = this.lexer.yytext;
231
+ yylineno = this.lexer.yylineno;
232
+ yyloc = this.lexer.yylloc;
233
+ if (recovering > 0)
234
+ recovering--;
235
+ } else { // error just occurred, resume old lookahead f/ before error
236
+ symbol = preErrorSymbol;
237
+ preErrorSymbol = null;
238
+ }
239
+ break;
240
+
241
+ case 2: // reduce
242
+ //this.reductionCount++;
243
+
244
+ len = this.productions_[action[1]][1];
245
+
246
+ // perform semantic action
247
+ yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
248
+ // default location, uses first token for firsts, last for lasts
249
+ yyval._$ = {
250
+ first_line: lstack[lstack.length-(len||1)].first_line,
251
+ last_line: lstack[lstack.length-1].last_line,
252
+ first_column: lstack[lstack.length-(len||1)].first_column,
253
+ last_column: lstack[lstack.length-1].last_column
254
+ };
255
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
256
+
257
+ if (typeof r !== 'undefined') {
258
+ return r;
259
+ }
260
+
261
+ // pop off stack
262
+ if (len) {
263
+ stack = stack.slice(0,-1*len*2);
264
+ vstack = vstack.slice(0, -1*len);
265
+ lstack = lstack.slice(0, -1*len);
266
+ }
267
+
268
+ stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
269
+ vstack.push(yyval.$);
270
+ lstack.push(yyval._$);
271
+ // goto new state = table[STATE][NONTERMINAL]
272
+ newState = table[stack[stack.length-2]][stack[stack.length-1]];
273
+ stack.push(newState);
274
+ break;
275
+
276
+ case 3: // accept
277
+ return true;
278
+ }
279
+
280
+ }
281
+
282
+ return true;
283
+ }};/* Jison generated lexer */
284
+ var lexer = (function(){var lexer = ({EOF:1,
285
+ parseError:function parseError(str, hash) {
286
+ if (this.yy.parseError) {
287
+ this.yy.parseError(str, hash);
288
+ } else {
289
+ throw new Error(str);
290
+ }
291
+ },
292
+ setInput:function (input) {
293
+ this._input = input;
294
+ this._more = this._less = this.done = false;
295
+ this.yylineno = this.yyleng = 0;
296
+ this.yytext = this.matched = this.match = '';
297
+ this.conditionStack = ['INITIAL'];
298
+ this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
299
+ return this;
300
+ },
301
+ input:function () {
302
+ var ch = this._input[0];
303
+ this.yytext+=ch;
304
+ this.yyleng++;
305
+ this.match+=ch;
306
+ this.matched+=ch;
307
+ var lines = ch.match(/\n/);
308
+ if (lines) this.yylineno++;
309
+ this._input = this._input.slice(1);
310
+ return ch;
311
+ },
312
+ unput:function (ch) {
313
+ this._input = ch + this._input;
314
+ return this;
315
+ },
316
+ more:function () {
317
+ this._more = true;
318
+ return this;
319
+ },
320
+ pastInput:function () {
321
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
322
+ return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
323
+ },
324
+ upcomingInput:function () {
325
+ var next = this.match;
326
+ if (next.length < 20) {
327
+ next += this._input.substr(0, 20-next.length);
328
+ }
329
+ return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
330
+ },
331
+ showPosition:function () {
332
+ var pre = this.pastInput();
333
+ var c = new Array(pre.length + 1).join("-");
334
+ return pre + this.upcomingInput() + "\n" + c+"^";
335
+ },
336
+ next:function () {
337
+ if (this.done) {
338
+ return this.EOF;
339
+ }
340
+ if (!this._input) this.done = true;
341
+
342
+ var token,
343
+ match,
344
+ col,
345
+ lines;
346
+ if (!this._more) {
347
+ this.yytext = '';
348
+ this.match = '';
349
+ }
350
+ var rules = this._currentRules();
351
+ for (var i=0;i < rules.length; i++) {
352
+ match = this._input.match(this.rules[rules[i]]);
353
+ if (match) {
354
+ lines = match[0].match(/\n.*/g);
355
+ if (lines) this.yylineno += lines.length;
356
+ this.yylloc = {first_line: this.yylloc.last_line,
357
+ last_line: this.yylineno+1,
358
+ first_column: this.yylloc.last_column,
359
+ last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
360
+ this.yytext += match[0];
361
+ this.match += match[0];
362
+ this.matches = match;
363
+ this.yyleng = this.yytext.length;
364
+ this._more = false;
365
+ this._input = this._input.slice(match[0].length);
366
+ this.matched += match[0];
367
+ token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
368
+ if (token) return token;
369
+ else return;
370
+ }
371
+ }
372
+ if (this._input === "") {
373
+ return this.EOF;
374
+ } else {
375
+ this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
376
+ {text: "", token: null, line: this.yylineno});
377
+ }
378
+ },
379
+ lex:function lex() {
380
+ var r = this.next();
381
+ if (typeof r !== 'undefined') {
382
+ return r;
383
+ } else {
384
+ return this.lex();
385
+ }
386
+ },
387
+ begin:function begin(condition) {
388
+ this.conditionStack.push(condition);
389
+ },
390
+ popState:function popState() {
391
+ return this.conditionStack.pop();
392
+ },
393
+ _currentRules:function _currentRules() {
394
+ return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
395
+ }});
396
+ lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
397
+
398
+ var YYSTATE=YY_START
399
+ switch($avoiding_name_collisions) {
400
+ case 0: this.begin("mu"); if (yy_.yytext) return 14;
401
+ break;
402
+ case 1: return 14;
403
+ break;
404
+ case 2: return 24;
405
+ break;
406
+ case 3: return 16;
407
+ break;
408
+ case 4: return 20;
409
+ break;
410
+ case 5: return 19;
411
+ break;
412
+ case 6: return 19;
413
+ break;
414
+ case 7: return 23;
415
+ break;
416
+ case 8: return 23;
417
+ break;
418
+ case 9: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.begin("INITIAL"); return 15;
419
+ break;
420
+ case 10: return 22;
421
+ break;
422
+ case 11: return 34;
423
+ break;
424
+ case 12: return 33;
425
+ break;
426
+ case 13: return 33;
427
+ break;
428
+ case 14: return 36;
429
+ break;
430
+ case 15: /*ignore whitespace*/
431
+ break;
432
+ case 16: this.begin("INITIAL"); return 18;
433
+ break;
434
+ case 17: this.begin("INITIAL"); return 18;
435
+ break;
436
+ case 18: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28;
437
+ break;
438
+ case 19: return 30;
439
+ break;
440
+ case 20: return 30;
441
+ break;
442
+ case 21: return 29;
443
+ break;
444
+ case 22: return 33;
445
+ break;
446
+ case 23: return 'INVALID';
447
+ break;
448
+ case 24: return 5;
449
+ break;
450
+ }
451
+ };
452
+ lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s/.])/,/^./,/^$/];
453
+ lexer.conditions = {"mu":{"rules":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],"inclusive":false},"INITIAL":{"rules":[0,1,24],"inclusive":true}};return lexer;})()
454
+ parser.lexer = lexer;
455
+ return parser;
456
+ })();
457
+ if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
458
+ exports.parser = handlebars;
459
+ exports.parse = function () { return handlebars.parse.apply(handlebars, arguments); }
460
+ exports.main = function commonjsMain(args) {
461
+ if (!args[1])
462
+ throw new Error('Usage: '+args[0]+' FILE');
463
+ if (typeof process !== 'undefined') {
464
+ var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
465
+ } else {
466
+ var cwd = require("file").path(require("file").cwd());
467
+ var source = cwd.join(args[1]).read({charset: "utf-8"});
468
+ }
469
+ return exports.parser.parse(source);
470
+ }
471
+ if (typeof module !== 'undefined' && require.main === module) {
472
+ exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
473
+ }
474
+ };
475
+ ;
476
+ // lib/handlebars/base.js
477
+ var Handlebars = {};
478
+
479
+ Handlebars.VERSION = "1.0.beta.2";
480
+
481
+ Handlebars.Parser = handlebars;
482
+
483
+ Handlebars.parse = function(string) {
484
+ Handlebars.Parser.yy = Handlebars.AST;
485
+ return Handlebars.Parser.parse(string);
486
+ };
487
+
488
+ Handlebars.print = function(ast) {
489
+ return new Handlebars.PrintVisitor().accept(ast);
490
+ };
491
+
492
+ Handlebars.helpers = {};
493
+ Handlebars.partials = {};
494
+
495
+ Handlebars.registerHelper = function(name, fn, inverse) {
496
+ if(inverse) { fn.not = inverse; }
497
+ this.helpers[name] = fn;
498
+ };
499
+
500
+ Handlebars.registerPartial = function(name, str) {
501
+ this.partials[name] = str;
502
+ };
503
+
504
+ Handlebars.registerHelper('helperMissing', function(arg) {
505
+ if(arguments.length === 2) {
506
+ return undefined;
507
+ } else {
508
+ throw new Error("Could not find property '" + arg + "'");
509
+ }
510
+ });
511
+
512
+ Handlebars.registerHelper('blockHelperMissing', function(context, fn, inverse) {
513
+ inverse = inverse || function() {};
514
+
515
+ var ret = "";
516
+ var type = Object.prototype.toString.call(context);
517
+
518
+ if(type === "[object Function]") {
519
+ context = context();
520
+ }
521
+
522
+ if(context === true) {
523
+ return fn(this);
524
+ } else if(context === false || context == null) {
525
+ return inverse(this);
526
+ } else if(type === "[object Array]") {
527
+ if(context.length > 0) {
528
+ for(var i=0, j=context.length; i<j; i++) {
529
+ ret = ret + fn(context[i]);
530
+ }
531
+ } else {
532
+ ret = inverse(this);
533
+ }
534
+ return ret;
535
+ } else {
536
+ return fn(context);
537
+ }
538
+ }, function(context, fn) {
539
+ return fn(context);
540
+ });
541
+
542
+ Handlebars.registerHelper('each', function(context, fn, inverse) {
543
+ var ret = "";
544
+
545
+ if(context && context.length > 0) {
546
+ for(var i=0, j=context.length; i<j; i++) {
547
+ ret = ret + fn(context[i]);
548
+ }
549
+ } else {
550
+ ret = inverse(this);
551
+ }
552
+ return ret;
553
+ });
554
+
555
+ Handlebars.registerHelper('if', function(context, fn, inverse) {
556
+ if(!context || context == []) {
557
+ return inverse(this);
558
+ } else {
559
+ return fn(this);
560
+ }
561
+ });
562
+
563
+ Handlebars.registerHelper('unless', function(context, fn, inverse) {
564
+ return Handlebars.helpers['if'].call(this, context, inverse, fn);
565
+ });
566
+
567
+ Handlebars.registerHelper('with', function(context, fn) {
568
+ return fn(context);
569
+ });
570
+
571
+ Handlebars.logger = {
572
+ DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
573
+
574
+ // override in the host environment
575
+ log: function(level, str) {}
576
+ };
577
+
578
+ Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
579
+ ;
580
+ // lib/handlebars/ast.js
581
+ (function() {
582
+
583
+ Handlebars.AST = {};
584
+
585
+ Handlebars.AST.ProgramNode = function(statements, inverse) {
586
+ this.type = "program";
587
+ this.statements = statements;
588
+ if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
589
+ };
590
+
591
+ Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
592
+ this.type = "mustache";
593
+ this.id = params[0];
594
+ this.params = params.slice(1);
595
+ this.hash = hash;
596
+ this.escaped = !unescaped;
597
+ };
598
+
599
+ Handlebars.AST.PartialNode = function(id, context) {
600
+ this.type = "partial";
601
+
602
+ // TODO: disallow complex IDs
603
+
604
+ this.id = id;
605
+ this.context = context;
606
+ };
607
+
608
+ var verifyMatch = function(open, close) {
609
+ if(open.original !== close.original) {
610
+ throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
611
+ }
612
+ };
613
+
614
+ Handlebars.AST.BlockNode = function(mustache, program, close) {
615
+ verifyMatch(mustache.id, close);
616
+ this.type = "block";
617
+ this.mustache = mustache;
618
+ this.program = program;
619
+ };
620
+
621
+ Handlebars.AST.InverseNode = function(mustache, program, close) {
622
+ verifyMatch(mustache.id, close);
623
+ this.type = "inverse";
624
+ this.mustache = mustache;
625
+ this.program = program;
626
+ };
627
+
628
+ Handlebars.AST.ContentNode = function(string) {
629
+ this.type = "content";
630
+ this.string = string;
631
+ };
632
+
633
+ Handlebars.AST.HashNode = function(pairs) {
634
+ this.type = "hash";
635
+ this.pairs = pairs;
636
+ };
637
+
638
+ Handlebars.AST.IdNode = function(parts) {
639
+ this.type = "ID";
640
+ this.original = parts.join(".");
641
+
642
+ var dig = [], depth = 0;
643
+
644
+ for(var i=0,l=parts.length; i<l; i++) {
645
+ var part = parts[i];
646
+
647
+ if(part === "..") { depth++; }
648
+ else if(part === "." || part === "this") { continue; }
649
+ else { dig.push(part); }
650
+ }
651
+
652
+ this.parts = dig;
653
+ this.string = dig.join('.');
654
+ this.depth = depth;
655
+ this.isSimple = (dig.length === 1) && (depth === 0);
656
+ };
657
+
658
+ Handlebars.AST.StringNode = function(string) {
659
+ this.type = "STRING";
660
+ this.string = string;
661
+ };
662
+
663
+ Handlebars.AST.IntegerNode = function(integer) {
664
+ this.type = "INTEGER";
665
+ this.integer = integer;
666
+ };
667
+
668
+ Handlebars.AST.BooleanNode = function(boolean) {
669
+ this.type = "BOOLEAN";
670
+ this.boolean = boolean;
671
+ };
672
+
673
+ Handlebars.AST.CommentNode = function(comment) {
674
+ this.type = "comment";
675
+ this.comment = comment;
676
+ };
677
+
678
+ })();;
679
+ // lib/handlebars/visitor.js
680
+
681
+ Handlebars.Visitor = function() {};
682
+
683
+ Handlebars.Visitor.prototype = {
684
+ accept: function(object) {
685
+ return this[object.type](object);
686
+ }
687
+ };;
688
+ // lib/handlebars/utils.js
689
+ Handlebars.Exception = function(message) {
690
+ this.message = message;
691
+ };
692
+
693
+ // Build out our basic SafeString type
694
+ Handlebars.SafeString = function(string) {
695
+ this.string = string;
696
+ };
697
+ Handlebars.SafeString.prototype.toString = function() {
698
+ return this.string.toString();
699
+ };
700
+
701
+ (function() {
702
+ var escape = {
703
+ "<": "&lt;",
704
+ ">": "&gt;",
705
+ '"': "&quot;",
706
+ "'": "&#x27;",
707
+ "`": "&#x60;"
708
+ };
709
+
710
+ var badChars = /&(?!\w+;)|[<>"'`]/g;
711
+ var possible = /[&<>"'`]/;
712
+
713
+ var escapeChar = function(chr) {
714
+ return escape[chr] || "&amp;"
715
+ };
716
+
717
+ Handlebars.Utils = {
718
+ escapeExpression: function(string) {
719
+ // don't escape SafeStrings, since they're already safe
720
+ if (string instanceof Handlebars.SafeString) {
721
+ return string.toString();
722
+ } else if (string == null || string === false) {
723
+ return "";
724
+ }
725
+
726
+ if(!possible.test(string)) { return string; }
727
+ return string.replace(badChars, escapeChar);
728
+ },
729
+
730
+ isEmpty: function(value) {
731
+ if (typeof value === "undefined") {
732
+ return true;
733
+ } else if (value === null) {
734
+ return true;
735
+ } else if (value === false) {
736
+ return true;
737
+ } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
738
+ return true;
739
+ } else {
740
+ return false;
741
+ }
742
+ }
743
+ };
744
+ })();;
745
+ // lib/handlebars/compiler.js
746
+ Handlebars.Compiler = function() {};
747
+ Handlebars.JavaScriptCompiler = function() {};
748
+
749
+ (function(Compiler, JavaScriptCompiler) {
750
+ Compiler.OPCODE_MAP = {
751
+ appendContent: 1,
752
+ getContext: 2,
753
+ lookupWithHelpers: 3,
754
+ lookup: 4,
755
+ append: 5,
756
+ invokeMustache: 6,
757
+ appendEscaped: 7,
758
+ pushString: 8,
759
+ truthyOrFallback: 9,
760
+ functionOrFallback: 10,
761
+ invokeProgram: 11,
762
+ invokePartial: 12,
763
+ push: 13,
764
+ invokeInverse: 14,
765
+ assignToHash: 15,
766
+ pushStringParam: 16
767
+ };
768
+
769
+ Compiler.MULTI_PARAM_OPCODES = {
770
+ appendContent: 1,
771
+ getContext: 1,
772
+ lookupWithHelpers: 1,
773
+ lookup: 1,
774
+ invokeMustache: 2,
775
+ pushString: 1,
776
+ truthyOrFallback: 1,
777
+ functionOrFallback: 1,
778
+ invokeProgram: 2,
779
+ invokePartial: 1,
780
+ push: 1,
781
+ invokeInverse: 1,
782
+ assignToHash: 1,
783
+ pushStringParam: 1
784
+ };
785
+
786
+ Compiler.DISASSEMBLE_MAP = {};
787
+
788
+ for(var prop in Compiler.OPCODE_MAP) {
789
+ var value = Compiler.OPCODE_MAP[prop];
790
+ Compiler.DISASSEMBLE_MAP[value] = prop;
791
+ }
792
+
793
+ Compiler.multiParamSize = function(code) {
794
+ return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
795
+ };
796
+
797
+ Compiler.prototype = {
798
+ compiler: Compiler,
799
+
800
+ disassemble: function() {
801
+ var opcodes = this.opcodes, opcode, nextCode;
802
+ var out = [], str, name, value;
803
+
804
+ for(var i=0, l=opcodes.length; i<l; i++) {
805
+ opcode = opcodes[i];
806
+
807
+ if(opcode === 'DECLARE') {
808
+ name = opcodes[++i];
809
+ value = opcodes[++i];
810
+ out.push("DECLARE " + name + " = " + value);
811
+ } else {
812
+ str = Compiler.DISASSEMBLE_MAP[opcode];
813
+
814
+ var extraParams = Compiler.multiParamSize(opcode);
815
+ var codes = [];
816
+
817
+ for(var j=0; j<extraParams; j++) {
818
+ nextCode = opcodes[++i];
819
+
820
+ if(typeof nextCode === "string") {
821
+ nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
822
+ }
823
+
824
+ codes.push(nextCode);
825
+ }
826
+
827
+ str = str + " " + codes.join(" ");
828
+
829
+ out.push(str);
830
+ }
831
+ }
832
+
833
+ return out.join("\n");
834
+ },
835
+
836
+ guid: 0,
837
+
838
+ compile: function(program, options) {
839
+ this.children = [];
840
+ this.depths = {list: []};
841
+ this.options = options || {};
842
+ return this.program(program);
843
+ },
844
+
845
+ accept: function(node) {
846
+ return this[node.type](node);
847
+ },
848
+
849
+ program: function(program) {
850
+ var statements = program.statements, statement;
851
+ this.opcodes = [];
852
+
853
+ for(var i=0, l=statements.length; i<l; i++) {
854
+ statement = statements[i];
855
+ this[statement.type](statement);
856
+ }
857
+
858
+ this.depths.list = this.depths.list.sort(function(a, b) {
859
+ return a - b;
860
+ });
861
+
862
+ return this;
863
+ },
864
+
865
+ compileProgram: function(program) {
866
+ var result = new this.compiler().compile(program, this.options);
867
+ var guid = this.guid++;
868
+
869
+ this.usePartial = this.usePartial || result.usePartial;
870
+
871
+ this.children[guid] = result;
872
+
873
+ for(var i=0, l=result.depths.list.length; i<l; i++) {
874
+ depth = result.depths.list[i];
875
+
876
+ if(depth < 2) { continue; }
877
+ else { this.addDepth(depth - 1); }
878
+ }
879
+
880
+ return guid;
881
+ },
882
+
883
+ block: function(block) {
884
+ var mustache = block.mustache;
885
+ var depth, child, inverse, inverseGuid;
886
+
887
+ var params = this.setupStackForMustache(mustache);
888
+
889
+ var programGuid = this.compileProgram(block.program);
890
+
891
+ if(block.program.inverse) {
892
+ inverseGuid = this.compileProgram(block.program.inverse);
893
+ this.declare('inverse', inverseGuid);
894
+ }
895
+
896
+ this.opcode('invokeProgram', programGuid, params.length);
897
+ this.declare('inverse', null);
898
+ this.opcode('append');
899
+ },
900
+
901
+ inverse: function(block) {
902
+ this.ID(block.mustache.id);
903
+ var programGuid = this.compileProgram(block.program);
904
+
905
+ this.opcode('invokeInverse', programGuid);
906
+ this.opcode('append');
907
+ },
908
+
909
+ hash: function(hash) {
910
+ var pairs = hash.pairs, pair, val;
911
+
912
+ this.opcode('push', '{}');
913
+
914
+ for(var i=0, l=pairs.length; i<l; i++) {
915
+ pair = pairs[i];
916
+ val = pair[1];
917
+
918
+ this.accept(val);
919
+ this.opcode('assignToHash', pair[0]);
920
+ }
921
+ },
922
+
923
+ partial: function(partial) {
924
+ var id = partial.id;
925
+ this.usePartial = true;
926
+
927
+ if(partial.context) {
928
+ this.ID(partial.context);
929
+ } else {
930
+ this.opcode('push', 'context');
931
+ }
932
+
933
+ this.opcode('invokePartial', id.original);
934
+ this.opcode('append');
935
+ },
936
+
937
+ content: function(content) {
938
+ this.opcode('appendContent', content.string);
939
+ },
940
+
941
+ mustache: function(mustache) {
942
+ var params = this.setupStackForMustache(mustache);
943
+
944
+ this.opcode('invokeMustache', params.length, mustache.id.original);
945
+
946
+ if(mustache.escaped) {
947
+ this.opcode('appendEscaped');
948
+ } else {
949
+ this.opcode('append');
950
+ }
951
+ },
952
+
953
+ ID: function(id) {
954
+ this.addDepth(id.depth);
955
+
956
+ this.opcode('getContext', id.depth);
957
+
958
+ this.opcode('lookupWithHelpers', id.parts[0] || null);
959
+
960
+ for(var i=1, l=id.parts.length; i<l; i++) {
961
+ this.opcode('lookup', id.parts[i]);
962
+ }
963
+ },
964
+
965
+ STRING: function(string) {
966
+ this.opcode('pushString', string.string);
967
+ },
968
+
969
+ INTEGER: function(integer) {
970
+ this.opcode('push', integer.integer);
971
+ },
972
+
973
+ BOOLEAN: function(boolean) {
974
+ this.opcode('push', boolean.boolean);
975
+ },
976
+
977
+ comment: function() {},
978
+
979
+ // HELPERS
980
+ pushParams: function(params) {
981
+ var i = params.length, param;
982
+
983
+ while(i--) {
984
+ param = params[i];
985
+
986
+ if(this.options.stringParams) {
987
+ if(param.depth) {
988
+ this.addDepth(param.depth);
989
+ }
990
+
991
+ this.opcode('getContext', param.depth || 0);
992
+ this.opcode('pushStringParam', param.string);
993
+ } else {
994
+ this[param.type](param);
995
+ }
996
+ }
997
+ },
998
+
999
+ opcode: function(name, val1, val2) {
1000
+ this.opcodes.push(Compiler.OPCODE_MAP[name]);
1001
+ if(val1 !== undefined) { this.opcodes.push(val1); }
1002
+ if(val2 !== undefined) { this.opcodes.push(val2); }
1003
+ },
1004
+
1005
+ declare: function(name, value) {
1006
+ this.opcodes.push('DECLARE');
1007
+ this.opcodes.push(name);
1008
+ this.opcodes.push(value);
1009
+ },
1010
+
1011
+ addDepth: function(depth) {
1012
+ if(depth === 0) { return; }
1013
+
1014
+ if(!this.depths[depth]) {
1015
+ this.depths[depth] = true;
1016
+ this.depths.list.push(depth);
1017
+ }
1018
+ },
1019
+
1020
+ setupStackForMustache: function(mustache) {
1021
+ var params = mustache.params;
1022
+
1023
+ this.pushParams(params);
1024
+
1025
+ if(mustache.hash) {
1026
+ this.hash(mustache.hash);
1027
+ } else {
1028
+ this.opcode('push', '{}');
1029
+ }
1030
+
1031
+ this.ID(mustache.id);
1032
+
1033
+ return params;
1034
+ }
1035
+ };
1036
+
1037
+ JavaScriptCompiler.prototype = {
1038
+ // PUBLIC API: You can override these methods in a subclass to provide
1039
+ // alternative compiled forms for name lookup and buffering semantics
1040
+ nameLookup: function(parent, name, type) {
1041
+ if(JavaScriptCompiler.RESERVED_WORDS[name] || name.indexOf('-') !== -1 || !isNaN(name)) {
1042
+ return parent + "['" + name + "']";
1043
+ } else if (/^[0-9]+$/.test(name)) {
1044
+ return parent + "[" + name + "]";
1045
+ } else {
1046
+ return parent + "." + name;
1047
+ }
1048
+ },
1049
+
1050
+ appendToBuffer: function(string) {
1051
+ return "buffer = buffer + " + string + ";";
1052
+ },
1053
+
1054
+ initializeBuffer: function() {
1055
+ return this.quotedString("");
1056
+ },
1057
+ // END PUBLIC API
1058
+
1059
+ compile: function(environment, options) {
1060
+ this.environment = environment;
1061
+ this.options = options || {};
1062
+
1063
+ this.preamble();
1064
+
1065
+ this.stackSlot = 0;
1066
+ this.stackVars = [];
1067
+ this.registers = {list: []};
1068
+
1069
+ this.compileChildren(environment, options);
1070
+
1071
+ Handlebars.log(Handlebars.logger.DEBUG, environment.disassemble() + "\n\n");
1072
+
1073
+ var opcodes = environment.opcodes, opcode, name, declareName, declareVal;
1074
+
1075
+ this.i = 0;
1076
+
1077
+ for(l=opcodes.length; this.i<l; this.i++) {
1078
+ opcode = this.nextOpcode(0);
1079
+
1080
+ if(opcode[0] === 'DECLARE') {
1081
+ this.i = this.i + 2;
1082
+ this[opcode[1]] = opcode[2];
1083
+ } else {
1084
+ this.i = this.i + opcode[1].length;
1085
+ this[opcode[0]].apply(this, opcode[1]);
1086
+ }
1087
+ }
1088
+
1089
+ return this.createFunction();
1090
+ },
1091
+
1092
+ nextOpcode: function(n) {
1093
+ var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
1094
+ var extraParams, codes;
1095
+
1096
+ if(opcode === 'DECLARE') {
1097
+ name = opcodes[this.i + 1];
1098
+ val = opcodes[this.i + 2];
1099
+ return ['DECLARE', name, val];
1100
+ } else {
1101
+ name = Compiler.DISASSEMBLE_MAP[opcode];
1102
+
1103
+ extraParams = Compiler.multiParamSize(opcode);
1104
+ codes = [];
1105
+
1106
+ for(var j=0; j<extraParams; j++) {
1107
+ codes.push(opcodes[this.i + j + 1 + n]);
1108
+ }
1109
+
1110
+ return [name, codes];
1111
+ }
1112
+ },
1113
+
1114
+ eat: function(opcode) {
1115
+ this.i = this.i + opcode.length;
1116
+ },
1117
+
1118
+ preamble: function() {
1119
+ var out = [];
1120
+ out.push("var buffer = " + this.initializeBuffer() + ", currentContext = context");
1121
+
1122
+ var copies = "helpers = helpers || Handlebars.helpers;";
1123
+ if(this.environment.usePartial) { copies = copies + " partials = partials || Handlebars.partials;"; }
1124
+ out.push(copies);
1125
+
1126
+ // track the last context pushed into place to allow skipping the
1127
+ // getContext opcode when it would be a noop
1128
+ this.lastContext = 0;
1129
+ this.source = out;
1130
+ },
1131
+
1132
+ createFunction: function() {
1133
+ var container = {
1134
+ escapeExpression: Handlebars.Utils.escapeExpression,
1135
+ invokePartial: Handlebars.VM.invokePartial,
1136
+ programs: [],
1137
+ program: function(i, helpers, partials, data) {
1138
+ var programWrapper = this.programs[i];
1139
+ if(data) {
1140
+ return Handlebars.VM.program(this.children[i], helpers, partials, data);
1141
+ } else if(programWrapper) {
1142
+ return programWrapper;
1143
+ } else {
1144
+ programWrapper = this.programs[i] = Handlebars.VM.program(this.children[i], helpers, partials);
1145
+ return programWrapper;
1146
+ }
1147
+ },
1148
+ programWithDepth: Handlebars.VM.programWithDepth,
1149
+ noop: Handlebars.VM.noop
1150
+ };
1151
+ var locals = this.stackVars.concat(this.registers.list);
1152
+
1153
+ if(locals.length > 0) {
1154
+ this.source[0] = this.source[0] + ", " + locals.join(", ");
1155
+ }
1156
+
1157
+ this.source[0] = this.source[0] + ";";
1158
+
1159
+ this.source.push("return buffer;");
1160
+
1161
+ var params = ["Handlebars", "context", "helpers", "partials"];
1162
+
1163
+ if(this.options.data) { params.push("data"); }
1164
+
1165
+ for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1166
+ params.push("depth" + this.environment.depths.list[i]);
1167
+ }
1168
+
1169
+ if(params.length === 4 && !this.environment.usePartial) { params.pop(); }
1170
+
1171
+ params.push(this.source.join("\n"));
1172
+
1173
+ var fn = Function.apply(this, params);
1174
+ fn.displayName = "Handlebars.js";
1175
+
1176
+ Handlebars.log(Handlebars.logger.DEBUG, fn.toString() + "\n\n");
1177
+
1178
+ container.render = fn;
1179
+
1180
+ container.children = this.environment.children;
1181
+
1182
+ return function(context, options, $depth) {
1183
+ try {
1184
+ options = options || {};
1185
+ var args = [Handlebars, context, options.helpers, options.partials, options.data];
1186
+ var depth = Array.prototype.slice.call(arguments, 2);
1187
+ args = args.concat(depth);
1188
+ return container.render.apply(container, args);
1189
+ } catch(e) {
1190
+ throw e;
1191
+ }
1192
+ };
1193
+ },
1194
+
1195
+ appendContent: function(content) {
1196
+ this.source.push(this.appendToBuffer(this.quotedString(content)));
1197
+ },
1198
+
1199
+ append: function() {
1200
+ var local = this.popStack();
1201
+ this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
1202
+ },
1203
+
1204
+ appendEscaped: function() {
1205
+ var opcode = this.nextOpcode(1), extra = "";
1206
+
1207
+ if(opcode[0] === 'appendContent') {
1208
+ extra = " + " + this.quotedString(opcode[1][0]);
1209
+ this.eat(opcode);
1210
+ }
1211
+
1212
+ this.source.push(this.appendToBuffer("this.escapeExpression(" + this.popStack() + ")" + extra));
1213
+ },
1214
+
1215
+ getContext: function(depth) {
1216
+ if(this.lastContext !== depth) {
1217
+ this.lastContext = depth;
1218
+
1219
+ if(depth === 0) {
1220
+ this.source.push("currentContext = context;");
1221
+ } else {
1222
+ this.source.push("currentContext = depth" + depth + ";");
1223
+ }
1224
+ }
1225
+ },
1226
+
1227
+ lookupWithHelpers: function(name) {
1228
+ if(name) {
1229
+ var topStack = this.nextStack();
1230
+
1231
+ var toPush = "if('" + name + "' in helpers) { " + topStack +
1232
+ " = " + this.nameLookup('helpers', name, 'helper') +
1233
+ "; } else { " + topStack + " = " +
1234
+ this.nameLookup('currentContext', name, 'context') +
1235
+ "; }";
1236
+
1237
+ this.source.push(toPush);
1238
+ } else {
1239
+ this.pushStack("currentContext");
1240
+ }
1241
+ },
1242
+
1243
+ lookup: function(name) {
1244
+ var topStack = this.topStack();
1245
+ this.source.push(topStack + " = " + this.nameLookup(topStack, name, 'context') + ";");
1246
+ },
1247
+
1248
+ pushStringParam: function(string) {
1249
+ this.pushStack("currentContext");
1250
+ this.pushString(string);
1251
+ },
1252
+
1253
+ pushString: function(string) {
1254
+ this.pushStack(this.quotedString(string));
1255
+ },
1256
+
1257
+ push: function(name) {
1258
+ this.pushStack(name);
1259
+ },
1260
+
1261
+ invokeMustache: function(paramSize, original) {
1262
+ this.populateParams(paramSize, this.quotedString(original), "{}", null, function(nextStack, helperMissingString, id) {
1263
+ this.source.push("else if(" + id + "=== undefined) { " + nextStack + " = helpers.helperMissing.call(" + helperMissingString + "); }");
1264
+ this.source.push("else { " + nextStack + " = " + id + "; }");
1265
+ });
1266
+ },
1267
+
1268
+ invokeProgram: function(guid, paramSize) {
1269
+ var inverse = this.programExpression(this.inverse);
1270
+ var mainProgram = this.programExpression(guid);
1271
+
1272
+ this.populateParams(paramSize, null, mainProgram, inverse, function(nextStack, helperMissingString, id) {
1273
+ this.source.push("else { " + nextStack + " = helpers.blockHelperMissing.call(" + helperMissingString + "); }");
1274
+ });
1275
+ },
1276
+
1277
+ populateParams: function(paramSize, helperId, program, inverse, fn) {
1278
+ var id = this.popStack(), nextStack;
1279
+ var params = [], param, stringParam;
1280
+
1281
+ var hash = this.popStack();
1282
+
1283
+ this.register('tmp1', program);
1284
+ this.source.push('tmp1.hash = ' + hash + ';');
1285
+
1286
+ if(this.options.stringParams) {
1287
+ this.source.push('tmp1.contexts = [];');
1288
+ }
1289
+
1290
+ for(var i=0; i<paramSize; i++) {
1291
+ param = this.popStack();
1292
+ params.push(param);
1293
+
1294
+ if(this.options.stringParams) {
1295
+ this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
1296
+ }
1297
+ }
1298
+
1299
+ if(inverse) {
1300
+ this.source.push('tmp1.fn = tmp1;');
1301
+ this.source.push('tmp1.inverse = ' + inverse + ';');
1302
+ }
1303
+
1304
+ if(this.options.data) {
1305
+ this.source.push('tmp1.data = data;');
1306
+ }
1307
+
1308
+ params.push('tmp1');
1309
+
1310
+ // TODO: This is legacy behavior. Deprecate and remove.
1311
+ if(inverse) {
1312
+ params.push(inverse);
1313
+ }
1314
+
1315
+ this.populateCall(params, id, helperId || id, fn);
1316
+ },
1317
+
1318
+ populateCall: function(params, id, helperId, fn) {
1319
+ var paramString = ["context"].concat(params).join(", ");
1320
+ var helperMissingString = ["context"].concat(helperId).concat(params).join(", ");
1321
+
1322
+ nextStack = this.nextStack();
1323
+
1324
+ this.source.push("if(typeof " + id + " === 'function') { " + nextStack + " = " + id + ".call(" + paramString + "); }");
1325
+ fn.call(this, nextStack, helperMissingString, id);
1326
+ },
1327
+
1328
+ invokeInverse: function(guid) {
1329
+ var program = this.programExpression(guid);
1330
+
1331
+ var blockMissingParams = ["context", this.topStack(), "this.noop", program];
1332
+ this.pushStack("helpers.blockHelperMissing.call(" + blockMissingParams.join(", ") + ")");
1333
+ },
1334
+
1335
+ invokePartial: function(context) {
1336
+ this.pushStack("this.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
1337
+ },
1338
+
1339
+ assignToHash: function(key) {
1340
+ var value = this.popStack();
1341
+ var hash = this.topStack();
1342
+
1343
+ this.source.push(hash + "['" + key + "'] = " + value + ";");
1344
+ },
1345
+
1346
+ // HELPERS
1347
+
1348
+ compiler: JavaScriptCompiler,
1349
+
1350
+ compileChildren: function(environment, options) {
1351
+ var children = environment.children, child, compiler;
1352
+ var compiled = [];
1353
+
1354
+ for(var i=0, l=children.length; i<l; i++) {
1355
+ child = children[i];
1356
+ compiler = new this.compiler();
1357
+
1358
+ compiled[i] = compiler.compile(child, options);
1359
+ }
1360
+
1361
+ environment.rawChildren = children;
1362
+ environment.children = compiled;
1363
+ },
1364
+
1365
+ programExpression: function(guid) {
1366
+ if(guid == null) { return "this.noop"; }
1367
+
1368
+ var programParams = [guid, "helpers", "partials"];
1369
+
1370
+ var depths = this.environment.rawChildren[guid].depths.list;
1371
+
1372
+ if(this.options.data) { programParams.push("data"); }
1373
+
1374
+ for(var i=0, l = depths.length; i<l; i++) {
1375
+ depth = depths[i];
1376
+
1377
+ if(depth === 1) { programParams.push("context"); }
1378
+ else { programParams.push("depth" + (depth - 1)); }
1379
+ }
1380
+
1381
+ if(!this.environment.usePartial) {
1382
+ if(programParams[3]) {
1383
+ programParams[2] = "null";
1384
+ } else {
1385
+ programParams.pop();
1386
+ }
1387
+ }
1388
+
1389
+ if(depths.length === 0) {
1390
+ return "this.program(" + programParams.join(", ") + ")";
1391
+ } else {
1392
+ programParams[0] = "this.children[" + guid + "]";
1393
+ return "this.programWithDepth(" + programParams.join(", ") + ")";
1394
+ }
1395
+ },
1396
+
1397
+ register: function(name, val) {
1398
+ this.useRegister(name);
1399
+ this.source.push(name + " = " + val + ";");
1400
+ },
1401
+
1402
+ useRegister: function(name) {
1403
+ if(!this.registers[name]) {
1404
+ this.registers[name] = true;
1405
+ this.registers.list.push(name);
1406
+ }
1407
+ },
1408
+
1409
+ pushStack: function(item) {
1410
+ this.source.push(this.nextStack() + " = " + item + ";");
1411
+ return "stack" + this.stackSlot;
1412
+ },
1413
+
1414
+ nextStack: function() {
1415
+ this.stackSlot++;
1416
+ if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
1417
+ return "stack" + this.stackSlot;
1418
+ },
1419
+
1420
+ popStack: function() {
1421
+ return "stack" + this.stackSlot--;
1422
+ },
1423
+
1424
+ topStack: function() {
1425
+ return "stack" + this.stackSlot;
1426
+ },
1427
+
1428
+ quotedString: function(str) {
1429
+ return '"' + str
1430
+ .replace(/\\/g, '\\\\')
1431
+ .replace(/"/g, '\\"')
1432
+ .replace(/\n/g, '\\n')
1433
+ .replace(/\r/g, '\\r') + '"';
1434
+ }
1435
+ };
1436
+
1437
+ var reservedWords = ("break case catch continue default delete do else finally " +
1438
+ "for function if in instanceof new return switch this throw " +
1439
+ "try typeof var void while with null true false").split(" ");
1440
+
1441
+ compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
1442
+
1443
+ for(var i=0, l=reservedWords.length; i<l; i++) {
1444
+ compilerWords[reservedWords[i]] = true;
1445
+ }
1446
+
1447
+ })(Handlebars.Compiler, Handlebars.JavaScriptCompiler);
1448
+
1449
+ Handlebars.VM = {
1450
+ programWithDepth: function(fn, helpers, partials, data, $depth) {
1451
+ var args = Array.prototype.slice.call(arguments, 4);
1452
+
1453
+ return function(context, options) {
1454
+ options = options || {};
1455
+
1456
+ options = {
1457
+ helpers: options.helpers || helpers,
1458
+ partials: options.partials || partials,
1459
+ data: options.data || data
1460
+ };
1461
+
1462
+ return fn.apply(this, [context, options].concat(args));
1463
+ };
1464
+ },
1465
+ program: function(fn, helpers, partials, data) {
1466
+ return function(context, options) {
1467
+ options = options || {};
1468
+
1469
+ return fn(context, {
1470
+ helpers: options.helpers || helpers,
1471
+ partials: options.partials || partials,
1472
+ data: options.data || data
1473
+ });
1474
+ };
1475
+ },
1476
+ noop: function() { return ""; },
1477
+ compile: function(string, options) {
1478
+ var ast = Handlebars.parse(string);
1479
+ var environment = new Handlebars.Compiler().compile(ast, options);
1480
+ return new Handlebars.JavaScriptCompiler().compile(environment, options);
1481
+ },
1482
+ invokePartial: function(partial, name, context, helpers, partials) {
1483
+ if(partial === undefined) {
1484
+ throw new Handlebars.Exception("The partial " + name + " could not be found");
1485
+ } else if(partial instanceof Function) {
1486
+ return partial(context, {helpers: helpers, partials: partials});
1487
+ } else {
1488
+ partials[name] = Handlebars.VM.compile(partial);
1489
+ return partials[name](context, {helpers: helpers, partials: partials});
1490
+ }
1491
+ }
1492
+ };
1493
+
1494
+ Handlebars.compile = Handlebars.VM.compile;;